I have the following:
type Name = String
data Prop
= Var Name
| F
| T
| Not Prop
| Prop :|: Prop
| Prop :&: Prop
deriving (Eq, Read)
infixr 2 :|:
the type Prop represents a propositional formula. The propositional variables, such as p and q can be represented by Var "p" and Var "q".
F and T are the constant booleans for False and True.
Not represents the negation (~ or ¬)
:|: and :&: represent the disjunction (/) and conjuction (/\)
We can write logical propositions:
( Var "p" :|: Var "q") :&: ( Not (Var "p") :&: Var "q")
What I have to do is: replace Not, :|: and :&: with ~, / and /\ by making Prop an instance of the class Show, so that the following will be true:
test_ShowProp :: Bool
test_ShowProp =
show (Not (Var "P") :&: Var "Q") == "((~P)/\Q)"
This is my implementation so far:
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
But this doesn't cover all the cases, just the basic ones. How should I continue the implementation so that it tackles any propositional formula, not just the hardcoded ones? Because at the moment
(Var "p" :&: Var "q")
outputs: p/\q
but
Not (Var "p" :&: Var "q")
outputs: Non-exhaustive patterns in function show