Mathematical Logic and Programming Languages Exercise #3

This is the third exercise. It is due before class on Monday October 13, 2014 (1:45 PM). You must submit your solution to D2L. It will not be graded, but it I will check that it is submitted and I will glance over it. Be prepared to discuss what you have done. We will spend considerable time discussing this in class on Monday. You may be called upon to elaborate your submission.

In this exercise you will implement an algorithm for proving propositions by the tableau method.

The goal is to write a series of functions that implement a tableau prover. I suggest you read the pages 15-24 in the Smullyan text. The first part of this covered in class on Wed Oct 8. THye big step is recognizing that we don't have to used the "signed formulas" (tagging every formula with True or False.

The first thing is to recognize that the unsigned tableau prover proceeds very much the way that the Discrimator CNF function. Read page 20 carefully and verify that the discrim function below cooresponds to the figure on page 20.

data Discrim a = Alpha a a | Beta a a | Lit a

discrim :: Prop a -> Discrim (Prop a)
discrim TruthP = Lit TruthP
discrim AbsurdP = Lit AbsurdP
discrim (LetterP s) = Lit (LetterP s)
discrim (AndP x y) = Alpha x y
discrim (OrP x y) = Beta x y
discrim (ImpliesP x y) = Beta (NotP x) y
discrim (NotP (OrP x y)) = Alpha (NotP x)  (NotP y)
discrim (NotP (ImpliesP x y)) = Alpha x (NotP y)
discrim (NotP (AndP x y)) = Beta (NotP x) (NotP y)
discrim (NotP (NotP x)) = discrim x
discrim (NotP TruthP) = Lit AbsurdP
discrim (NotP AbsurdP) = Lit TruthP
discrim (NotP (LetterP s)) = Lit (NotP (LetterP s))

processCl :: [Prop a] -> [[Prop a]]
processCl [] = [[]]
processCl (p : ps) =
  case (discrim p) of
    Lit x -> map (x:) (processCl ps)
    Alpha x y -> processCl (x : ps) ++ processCl (y : ps)
    Beta x y -> processCl (x : y : ps)

It is also good to note that the Tableau diagrams of the text also correspond to the lists of the input and output of prcessCl. How?

         F- p0 \/ (p1 /\ p2) => ((p0 \/ p1) /\ (p0 \/ p2))
                        T- p0 \/ (p1 /\ p2)
                    F- (p0 \/ p1) /\ (p0 \/ p2)
+------------------------------+    +------------------------------+
|            T- p0             |    |         T- p1 /\ p2          |
|+-----------+    +-----------+|    |            T- p1             |
||F- p0 \/ p1|    |F- p0 \/ p2||    |            T- p2             |
||F- p0      |    |F- p0      ||    |+-----------+    +-----------+|
||F- p1      |    |F- p2      ||    ||F- p0 \/ p1|    |F- p0 \/ p2||
|+-----------+    +-----------+|    ||F- p0      |    |F- p0      ||
+------------------------------+    ||F- p1      |    |F- p2      ||
                                    |+-----------+    +-----------+|
                                    +------------------------------+


The final thing to note is that in order to close off a Branch we need to keep a list of propositions we have on the current path. How might implement this.