Haskell-命题逻辑

时间:2019-01-04 22:08:18

标签: forms haskell logic logical-operators

我有以下内容:

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是False和True的常量布尔值。

不代表否定(〜或¬)

:|:和:&:表示析取(/)和结合(/ \)

我们可以写出逻辑命题:

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

我要做的是:通过将Prop设为Show类的实例,用〜,/和/ \代替Not,:|:和:&::,以便满足以下条件:

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 个答案:

答案 0 :(得分:5)

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

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

将适用于以否定开头的任何公式,即使该否定下有一个不变的子公式。

正确设置括号可能很棘手。您需要大方括号或定义showsPrec。如果您是初学者,我建议您使用前者,后者无需处理优先级。

答案 1 :(得分:3)

您要在定义中递归调用show。因此,使用Not的示例为

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