0
-- | data type definition of WFF: well formed formula
data Wff = Var String 
        | Not Wff
        | And Wff Wff 
        | Or Wff Wff
        | Imply Wff Wff

-- | Negation norm form  nnf function
--   precondition: φ is implication free
--   postcondition: NNF (φ) computes a NNF for φ
nnf :: Wff -> Wff
nnf (Var p) = Var p
nnf (Not (Not p)) = (nnf p)
nnf (And p q) = And (nnf p) (nnf q)
nnf (Or p q) = Or (nnf p) (nnf q)
nnf (Not (And p q)) = Or (nnf(Not p)) (nnf(Not q))
nnf (Not (Or p q)) = And (nnf(Not p)) (nnf(Not q))

Test case: ¬(p ∨ Q)

(*** Exception:: Non-exhaustive patterns in function nnf

However, if I add nnf (Not p) = Not (nnf p) into the function, it will show

Pattern match(es) are overlapped
In an equation for ‘nnf’:
    nnf (Not (Not p)) = ...
    nnf (Not (And p q)) = ...
    nnf (Not (Or p q)) = ...

I am wondering what I am doing wrong?

dfeuer
  • 48,079
  • 5
  • 63
  • 167
Johnny
  • 5
  • 2
  • 4
    Whoever wrote the comment `postcondition: NNF (φ) computes a NNF for φ` deserves a decent spanking. – leftaroundabout Feb 14 '16 at 23:46
  • Why reject implications? – dfeuer Feb 15 '16 at 01:04
  • actually, this nnf function is part of the Conjunction Normal Form(CNF). and the parameter for the nnf is a imply free formulas. I also finish a function called IMPY_FREE. CNF is implemented as: CNF(NNF(IMPY_FREE( Wff ) ) ) – Johnny Feb 16 '16 at 02:28

1 Answers1

3

You're simply inserting the line at the wrong place. nnf (Not p) = ... is a catch-all for negations. If you then later add other clauses that deal with more specific negations like Not (And p q), they can't possibly trigger anymore.

The catch-all clause needs to come last, i.e.

nnf (Var p) = Var p
nnf (Not (Not p)) = (nnf p)
nnf (And p q) = And (nnf p) (nnf q)
nnf (Or p q) = Or (nnf p) (nnf q)
nnf (Not (And p q)) = Or (nnf $ Not p) (nnf $ Not q)
nnf (Not (Or p q)) = And (nnf $ Not p) (nnf $ Not q)
nnf (Not p) = Not $ nnf p
leftaroundabout
  • 117,950
  • 5
  • 174
  • 319