2023-06-04 17:10:14 +02:00
|
|
|
module Main where
|
|
|
|
|
2023-06-07 17:36:14 +02:00
|
|
|
import FOLSyntax ( Formula(Conj, Neg, Impl), Term(..) )
|
|
|
|
import Parser ( parseFormula )
|
|
|
|
import Resolution ( CNF, doResolution )
|
|
|
|
import Normalforms
|
|
|
|
( makeNNF,
|
|
|
|
renameBinders,
|
|
|
|
makePNF,
|
|
|
|
makeSkolem,
|
|
|
|
makeCNF,
|
|
|
|
makeClauseSet )
|
2023-06-04 17:10:14 +02:00
|
|
|
|
|
|
|
{-
|
|
|
|
To prove a formula we:
|
|
|
|
1. Construct `Neg phi`
|
|
|
|
2. Transform `Neg phi` to a clause list
|
|
|
|
3. doResolution on clause list
|
|
|
|
-}
|
2023-06-07 17:36:14 +02:00
|
|
|
proveFormula :: Formula -> Either () CNF
|
|
|
|
proveFormula form = doResolution . makeClauseSet . makeCNF . makeSkolem . makePNF . renameBinders . makeNNF $ Neg form
|
2023-06-04 17:10:14 +02:00
|
|
|
|
|
|
|
-- 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
|
2023-06-07 17:36:14 +02:00
|
|
|
formula1 = parseFormula "!((A () \\/ !B()) /\\ (C ()))"
|
2023-06-04 17:10:14 +02:00
|
|
|
|
|
|
|
-- PNF and skolem example from gloin
|
2023-06-07 17:36:14 +02:00
|
|
|
formula2 :: Formula
|
|
|
|
formula2 = parseFormula "forall x. (forall y. L(y,x)) -> exists y.M(x,y)"
|
2023-06-04 17:10:14 +02:00
|
|
|
|
|
|
|
-- Resolution example from gloin script
|
|
|
|
formula3 :: Formula
|
2023-06-07 17:36:14 +02:00
|
|
|
formula3 = parseFormula "P(a()) /\\ (forall x. P(x) -> P(f(x))) -> (exists x. P(f(f(x)))) "
|
2023-06-04 17:10:14 +02:00
|
|
|
|
2023-06-07 17:36:14 +02:00
|
|
|
-- Resolution example from gloin exercises (sheet 11, ex 5) [already in CNF]
|
2023-06-04 17:10:14 +02:00
|
|
|
formula4 :: Formula
|
2023-06-07 17:36:14 +02:00
|
|
|
formula4 = parseFormula "((S(f(x), y)) \\/ (S(y, z)) \\/ (P(y))) /\\ (!(S(f(f(x)), x))) /\\ (!P(f(z)))"
|
2023-06-04 17:10:14 +02:00
|
|
|
|
|
|
|
-- 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
|
2023-06-07 17:36:14 +02:00
|
|
|
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)"
|
2023-06-07 11:04:00 +02:00
|
|
|
|
|
|
|
-- aerzte und quacksalber v2
|
2023-06-07 17:36:14 +02:00
|
|
|
formula6 :: Formula
|
|
|
|
formula6 = Impl (Conj psi1 psi2) psi3
|
2023-06-07 11:04:00 +02:00
|
|
|
where
|
2023-06-07 17:36:14 +02:00
|
|
|
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)"
|
2023-06-07 11:04:00 +02:00
|
|
|
|
2023-06-04 17:10:14 +02:00
|
|
|
main :: IO ()
|
|
|
|
main = do
|
|
|
|
putStrLn $ "Now making NNF of formula: " ++ show formula1
|
|
|
|
print $ makeNNF formula1
|
|
|
|
putStrLn $ "Now making PNF of formula: " ++ show formula2
|
2023-06-07 17:36:14 +02:00
|
|
|
print . makePNF . renameBinders $ makeNNF formula2
|
2023-06-04 17:10:14 +02:00
|
|
|
putStrLn $ "Now making Skolemform of formula: " ++ show formula2
|
2023-06-07 17:36:14 +02:00
|
|
|
print . makeSkolem . makePNF . renameBinders $ makeNNF formula2
|
2023-06-04 17:10:14 +02:00
|
|
|
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
|
2023-06-07 17:36:14 +02:00
|
|
|
case doResolution $ makeClauseSet formula4 of
|
2023-06-07 11:04:00 +02:00
|
|
|
Left _ -> putStrLn "Success!"
|
|
|
|
Right _ -> return ()
|
2023-06-07 17:36:14 +02:00
|
|
|
putStrLn $ "Now Proving formula by resolution: " ++ show formula5
|
|
|
|
case proveFormula formula5 of
|
2023-06-07 11:04:00 +02:00
|
|
|
Left _ -> putStrLn "Success!"
|
|
|
|
Right _ -> return ()
|
2023-06-07 17:36:14 +02:00
|
|
|
putStrLn $ "Now Proving formula by resolution: " ++ show formula6
|
2023-06-08 11:30:41 +02:00
|
|
|
case proveFormula (Neg formula6) of
|
2023-06-04 17:10:14 +02:00
|
|
|
Left _ -> putStrLn "Success!"
|
|
|
|
Right _ -> return ()
|