The following datatype represents propositions, as in propositional logic. (e.g., P &Q, Not P, …)
data Proposition = Var String
| F
| T
| Not Proposition
| Proposition :|: Proposition --or
| Proposition :&: Proposition
deriving (Eq, Ord, Show)
a. Write a function
isNorm :: Proposition -> Bool
that returns true when a proposition is in negation normal form. A proposition is in negation normal form if the only occurrences of logical negation (Not
) are applied to variables. For example,
>isNorm (Var "p" :&: Not (Var "q")) = True
>isNorm (Not (Var "p" :|: Var "q")) = False
>isNorm (Not (Not (Var "p")) :|: Not T) = False
>isNorm (Not (Var "p" :&: Not (Var "q"))) = False
b. Write a function
norm :: Proposition -> Proposition
that converts a proposition to an equivalent proposition in negation normal form. A propositon may be converted to normal form by repeated application of the following equivalences:
Not F <-> T
Not T <-> F
Not (Not p) <-> p
Not (p :|: q) <-> Not p :&: Not q
Not (p :&: q) <-> Not p :|: Not q
For example,
>norm (Var "p" :&: Not (Var "q"))
= (Var "p" :&: Not (Var "q"))
>norm (Not (Var "p" :|: Var "q"))
= Not (Var "p") :&: Not (Var "q")
>norm (Not (Not (Var "p")) :|: Not T)
= (Var "p" :|: F)
>norm (Not (Var "p" :&: Not (Var "q")))
= Not (Var "p") :|: Var "q"