resolution/app/Main.hs

93 lines
No EOL
3.3 KiB
Haskell

module Main where
import FOLSyntax ( Formula(Conj, Neg, Impl), Term(..) )
import Parser ( parseFormula )
import Resolution ( CNF, doResolution )
import Normalforms
( makeNNF,
renameBinders,
makePNF,
makeSkolem,
makeCNF,
makeClauseSet )
{-
To prove a formula we:
1. Construct `Neg phi`
2. Transform `Neg phi` to a clause list
3. doResolution on clause list
-}
proveFormula :: Formula -> Either () CNF
proveFormula form = doResolution . makeClauseSet . makeCNF . makeSkolem . makePNF . renameBinders . makeNNF $ Neg form
-- unification examples
terma1 :: Term
terma1 = Fun "f" [Var "x", Fun "g" [Var "y"]]
termb1 :: Term
termb1 = Fun "f" [Fun "g" [Var "z"], Var "z"]
terma2 :: Term
terma2 = Fun "f" [Var "x", Fun "g" [Var "x"], Fun "h" [Var "y"]]
termb2 :: Term
termb2 = Fun "f" [Fun "k" [Var "y"], Fun "g" [Var "z"], Var "z"]
terma3 :: Term
terma3 = Fun "f" [Var "x", Fun "g" [Var "x"]]
termb3 :: Term
termb3 = Fun "f" [Var "z", Var "z"]
-- NNF example from gloin
formula1 :: Formula
formula1 = parseFormula "!((A () \\/ !B()) /\\ (C ()))"
-- PNF and skolem example from gloin
formula2 :: Formula
formula2 = parseFormula "forall x. (forall y. L(y,x)) -> exists y.M(x,y)"
-- Resolution example from gloin script
formula3 :: Formula
formula3 = parseFormula "P(a()) /\\ (forall x. P(x) -> P(f(x))) -> (exists x. P(f(f(x)))) "
-- Resolution example from gloin exercises (sheet 11, ex 5) [already in CNF]
formula4 :: Formula
formula4 = parseFormula "((S(f(x), y)) \\/ (S(y, z)) \\/ (P(y))) /\\ (!(S(f(f(x)), x))) /\\ (!P(f(z)))"
-- now a big example, sheet 11, exercise 6: Drogenschmuggel, this doesn't work yet but I'm sure its just the exercise thats wrong...
formula5 :: Formula
formula5 = Impl (Conj phi1 (Conj phi2 phi3)) psi
where
phi1 = parseFormula "forall x.E(x) /\\ !I(x) -> exists y.Z(y) /\\ S(y,x)"
phi2 = parseFormula "exists x. (D(x) /\\ E(x)) /\\ forall y. S(y,x) -> D(y)"
phi3 = parseFormula "forall x.I(x) -> !D(x)"
psi = parseFormula "exists x. Z(x) /\\ D(x)"
-- aerzte und quacksalber v2
formula6 :: Formula
formula6 = Impl (Conj psi1 psi2) psi3
where
psi1 = parseFormula "forall x. D(x) -> exists y. P(y) /\\ L(y,x)"
psi2 = parseFormula "forall x. P(x) -> forall y. Q(y) -> !L(x, y)"
psi3 = parseFormula "forall x. D(x) -> !Q(x)"
main :: IO ()
main = do
putStrLn $ "Now making NNF of formula: " ++ show formula1
print $ makeNNF formula1
putStrLn $ "Now making PNF of formula: " ++ show formula2
print . makePNF . renameBinders $ makeNNF formula2
putStrLn $ "Now making Skolemform of formula: " ++ show formula2
print . makeSkolem . makePNF . renameBinders $ makeNNF formula2
putStrLn $ "Now proving formula by resolution: " ++ show formula3
case proveFormula formula3 of
Left _ -> putStrLn "Success!"
Right _ -> return ()
putStrLn $ "Now Proving formula by resolution: " ++ show formula4
case doResolution $ makeClauseSet formula4 of
Left _ -> putStrLn "Success!"
Right _ -> return ()
putStrLn $ "Now Proving formula by resolution: " ++ show formula5
case proveFormula formula5 of
Left _ -> putStrLn "Success!"
Right _ -> return ()
putStrLn $ "Now Proving formula by resolution: " ++ show formula6
case proveFormula (Neg formula6) of
Left _ -> putStrLn "Success!"
Right _ -> return ()