代码之家  ›  专栏  ›  技术社区  ›  George Cernat

haskell-命题逻辑[复制]

  •  1
  • George Cernat  · 技术社区  · 6 年前

    这个问题已经有了答案:

    我有以下几点:

    type Name = String
    data Prop
    = Var Name
    | F
    | T
    | Not Prop
    | Prop :|: Prop
    | Prop :&: Prop
    deriving (Eq, Read)
    infixr 2 :|:
    

    prop类型表示命题公式。命题变量,如p和q可以用var“p”和var“q”表示。

    F和T是错误和正确的不变的布尔值。

    不代表否定(~或¬)

    ::和:&:表示分离(/)和接合(/\)

    我们可以写逻辑命题:

    ( Var "p" :|: Var "q") :&: ( Not (Var "p") :&: Var "q")
    

    我要做的是:用~、/和/\替换not、::和:&:使prop成为类show的一个实例,以便以下内容为真:

    test_ShowProp :: Bool
    test_ShowProp =
    show (Not (Var "P") :&: Var "Q") == "((~P)/\Q)"
    

    这是迄今为止我的实现:

    instance Show Prop where
        show (Var p) = p 
        show (Not (Var p)) = "(~" ++ p ++ ")" 
        show (Var p :|: Var q) = p ++ "\\/" ++ q
        show (Var p :&: Var q) = p ++ "/\\" ++ q
    

    但这不包括所有的情况,只是基本情况。我应该如何继续实现,以便它处理任何命题公式,而不仅仅是硬编码公式?因为现在

    (Var "p" :&: Var "q")
    

    输出:P/Q

    但是

    Not (Var "p" :&: Var "q")
    

    输出:函数显示中的非穷尽模式

    2 回复  |  直到 6 年前
        1
  •  5
  •   chi    6 年前

    您应该只匹配公式的一个“层”,即只匹配一个构造函数,并利用子公式的递归。例如,

    show (Not f) = "(~" ++ show f ++ ")"
    

    将应用于任何以否定开始的公式,即使在该否定下有一个非变量子公式。

    正确地使用括号可能很难。你要么慷慨地加上括号,要么定义 showsPrec . 如果你是初学者,我推荐前者,它不需要处理优先级。

        2
  •  3
  •   madgen    6 年前

    你想打电话给我 show 在您的定义中递归。所以这个例子 Not 将是

    show (Not p) = "(~" ++ show p ++ ")"