logic-classes-1.1: Data/Logic/Harrison/Tableaux.hs
{-# LANGUAGE RankNTypes, ScopedTypeVariables #-}
{-# OPTIONS_GHC -Wall #-}
module Data.Logic.Harrison.Tableaux
( unify_literals
, unifyAtomsEq
, deepen
) where
import Control.Applicative.Error (Failing(..))
import Data.Logic.Classes.Equals (AtomEq, zipAtomsEq)
import qualified Data.Logic.Classes.Formula as C
import Data.Logic.Classes.Literal (Literal, zipLiterals)
import Data.Logic.Classes.Term (Term(..))
import Data.Logic.Harrison.Unif (unify)
import qualified Data.Map as Map
import Debug.Trace (trace)
-- =========================================================================
-- Tableaux, seen as an optimized version of a Prawitz-like procedure.
--
-- Copyright (c) 2003-2007, John Harrison. (See "LICENSE.txt" for details.)
-- =========================================================================
-- -------------------------------------------------------------------------
-- Unify literals (just pretend the toplevel relation is a function).
-- -------------------------------------------------------------------------
unify_literals :: forall lit atom term v f. (Literal lit atom v, Term term v f, C.Formula atom term v) =>
Map.Map v term -> lit -> lit -> Failing (Map.Map v term)
unify_literals env f1 f2 =
maybe err id (zipLiterals co tf at f1 f2)
where
-- co :: lit -> lit -> Maybe (Failing (Map.Map v term))
co p q = Just $ unify_literals env p q
tf p q = if p == q then Just $ unify env [] else Nothing
-- at :: atom -> atom -> Maybe (Failing (Map.Map v term))
at a1 a2 = Just $ C.unify env a1 a2
err = Failure ["Can't unify literals"]
unifyAtomsEq :: forall v f atom p term.
(AtomEq atom p term, Term term v f) =>
Map.Map v term -> atom -> atom -> Failing (Map.Map v term)
unifyAtomsEq env a1 a2 =
maybe err id (zipAtomsEq ap tf eq a1 a2)
where
ap p1 ts1 p2 ts2 =
if p1 == p2 && length ts1 == length ts2
then Just $ unify env (zip ts1 ts2)
else Nothing
tf p q = if p == q then Just $ unify env [] else Nothing
eq pl pr ql qr = Just $ unify env [(pl, ql), (pr, qr)]
err = Failure ["Can't unify atoms"]
-- -------------------------------------------------------------------------
-- Unify complementary literals.
-- -------------------------------------------------------------------------
{-
unify_complements env (p,q) = unify_literals env (p,negate q)
-- -------------------------------------------------------------------------
-- Unify and refute a set of disjuncts.
-- -------------------------------------------------------------------------
unify_refute djs env =
case djs of
[] -> env
d : odjs -> let (pos,neg) = partition positive d in
tryfind (unify_refute odjs . unify_complements env)
(allpairs (\ p q -> (p,q)) pos neg);;
-- -------------------------------------------------------------------------
-- Hence a Prawitz-like procedure (using unification on DNF).
-- -------------------------------------------------------------------------
prawitz_loop djs0 fvs djs n =
let l = length fvs in
let newvars = map (\ k -> "_" ++ show (n * l + k)) [1..l] in
let inst = fpf fvs (map Var newvars) in
let djs1 = distrib (image (image (subst inst)) djs0) djs in
case (unify_refute djs1 undefined,(n + 1)) of
Left _ -> prawitz_loop djs0 fvs djs1 (n + 1)
Right x -> x
prawitz fm =
let fm0 = skolemize(Not(generalize fm)) in
snd(prawitz_loop (simpdnf fm0) (fv fm0) [[]] 0);;
-- -------------------------------------------------------------------------
-- Examples.
-- -------------------------------------------------------------------------
test01 = TestCase $ assertEqual "p20 - prawitz" expected input
where input = prawitz fm
fm = (for_all "x" (for_all "y" (exists "z" (for_all "w" (pApp "P" [var "x"] .&. pApp "Q" [var "y"] .=>.
pApp "R" [var "z"] .&. pApp "U" [var "w"]))))) .=>.
(exists "x" (exists "y" (pApp "P" [var "x"] .&. pApp "Q" [var "y"]))) .=>. (exists "z" (pApp "R" [var "z"]))
expected = false
-- -------------------------------------------------------------------------
-- Comparison of number of ground instances.
-- -------------------------------------------------------------------------
compare fm =
(prawitz fm, davisputnam fm)
{-
START_INTERACTIVE;;
test02 = TestCase $ assertEqual "p19" expected input
where input = compare (exists "x" (forall "y" (for_all "z" ((pApp "P" [var "y"] .=>. pApp "Q" [var "z"]) .=>. pApp "P" [var "x"] .=>. pApp "Q" [var "x"]))))
let p20 = compare
<<(forall x y. exists z. forall w. P[var "x"] .&. Q[var "y"] .=>. R[var "z"] .&. U[var "w"])
.=>. (exists x y. P[var "x"] .&. Q[var "y"]) .=>. (exists z. R[var "z"])>>;;
let p24 = compare
<<~(exists x. U[var "x"] .&. Q[var "x"]) .&.
(forall x. P[var "x"] .=>. Q[var "x"] .|. R[var "x"]) .&.
~(exists x. P[var "x"] .=>. (exists x. Q[var "x"])) .&.
(forall x. Q[var "x"] .&. R[var "x"] .=>. U[var "x"])
.=>. (exists x. P[var "x"] .&. R[var "x"])>>;;
let p39 = compare
<<~(exists x. forall y. P(y,x) .<=>. ~P(y,y))>>;;
let p42 = compare
<<~(exists y. forall x. P(x,y) .<=>. ~(exists z. P(x,z) .&. P(z,x)))>>;;
{- **** Too slow?
let p43 = compare
<<(forall x y. Q(x,y) .<=>. forall z. P(z,x) .<=>. P(z,y))
.=>. forall x y. Q(x,y) .<=>. Q(y,x)>>;;
***** -}
let p44 = compare
<<(forall x. P[var "x"] .=>. (exists y. G[var "y"] .&. H(x,y)) .&.
(exists y. G[var "y"] .&. ~H(x,y))) .&.
(exists x. J[var "x"] .&. (forall y. G[var "y"] .=>. H(x,y)))
.=>. (exists x. J[var "x"] .&. ~P[var "x"])>>;;
let p59 = compare
<<(forall x. P[var "x"] .<=>. ~P(f[var "x"])) .=>. (exists x. P[var "x"] .&. ~P(f[var "x"]))>>;;
let p60 = compare
<<forall x. P(x,f[var "x"]) .<=>.
exists y. (forall z. P(z,y) .=>. P(z,f[var "x"])) .&. P(x,y)>>;;
END_INTERACTIVE;;
-- -------------------------------------------------------------------------
-- More standard tableau procedure, effectively doing DNF incrementally.
-- -------------------------------------------------------------------------
let rec tableau (fms,lits,n) cont (env,k) =
if n < 0 then error "no proof at this level" else
match fms with
[] -> error "tableau: no proof"
| And(p,q) : unexp ->
tableau (p : q : unexp,lits,n) cont (env,k)
| Or(p,q) : unexp ->
tableau (p : unexp,lits,n) (tableau (q : unexp,lits,n) cont) (env,k)
| Forall(x,p) : unexp ->
let y = Var("_" ++ string_of_int k) in
let p' = subst (x |=> y) p in
tableau (p' : unexp@[Forall(x,p)],lits,n-1) cont (env,k+1)
| fm : unexp ->
try tryfind (\ l -> cont(unify_complements env (fm,l),k)) lits
with Failure _ -> tableau (unexp,fm : lits,n) cont (env,k);;
-}
-}
-- | Try f with higher and higher values of n until it succeeds, or
-- optional maximum depth limit is exceeded.
deepen :: (Int -> Failing t) -> Int -> Maybe Int -> Failing (t, Int)
deepen _ n (Just m) | n > m = Failure ["Exceeded maximum depth limit"]
deepen f n m =
-- If no maximum depth limit is given print a trace of the
-- levels tried. The assumption is that we are running
-- interactively.
let n' = maybe (trace ("Searching with depth limit " ++ show n) n) (const n) m in
case f n' of
Failure _ -> deepen f (n + 1) m
Success x -> Success (x, n)
{-
let tabrefute fms =
deepen (\ n -> tableau (fms,[],n) (\ x -> x) (undefined,0); n) 0;;
let tab fm =
let sfm = askolemize(Not(generalize fm)) in
if sfm = False then 0 else tabrefute [sfm];;
-- -------------------------------------------------------------------------
-- Example.
-- -------------------------------------------------------------------------
START_INTERACTIVE;;
let p38 = tab
<<(forall x.
P[var "a"] .&. (P[var "x"] .=>. (exists y. P[var "y"] .&. R(x,y))) .=>.
(exists z w. P[var "z"] .&. R(x,w) .&. R(w,z))) .<=>.
(forall x.
(~P[var "a"] .|. P[var "x"] .|. (exists z w. P[var "z"] .&. R(x,w) .&. R(w,z))) .&.
(~P[var "a"] .|. ~(exists y. P[var "y"] .&. R(x,y)) .|.
(exists z w. P[var "z"] .&. R(x,w) .&. R(w,z))))>>;;
END_INTERACTIVE;;
-- -------------------------------------------------------------------------
-- Try to split up the initial formula first; often a big improvement.
-- -------------------------------------------------------------------------
let splittab fm =
map tabrefute (simpdnf(askolemize(Not(generalize fm))));;
-- -------------------------------------------------------------------------
-- Example: the Andrews challenge.
-- -------------------------------------------------------------------------
START_INTERACTIVE;;
let p34 = splittab
<<((exists x. forall y. P[var "x"] .<=>. P[var "y"]) .<=>.
((exists x. Q[var "x"]) .<=>. (forall y. Q[var "y"]))) .<=>.
((exists x. forall y. Q[var "x"] .<=>. Q[var "y"]) .<=>.
((exists x. P[var "x"]) .<=>. (forall y. P[var "y"])))>>;;
-- -------------------------------------------------------------------------
-- Another nice example from EWD 1602.
-- -------------------------------------------------------------------------
let ewd1062 = splittab
<<(forall x. x <= x) .&.
(forall x y z. x <= y .&. y <= z .=>. x <= z) .&.
(forall x y. f[var "x"] <= y .<=>. x <= g[var "y"])
.=>. (forall x y. x <= y .=>. f[var "x"] <= f[var "y"]) .&.
(forall x y. x <= y .=>. g[var "x"] <= g[var "y"])>>;;
END_INTERACTIVE;;
-- -------------------------------------------------------------------------
-- Do all the equality-free Pelletier problems, and more, as examples.
-- -------------------------------------------------------------------------
{- **********
let p1 = time splittab
<<p .=>. q .<=>. ~q .=>. ~p>>;;
let p2 = time splittab
<<~ ~p .<=>. p>>;;
let p3 = time splittab
<<~(p .=>. q) .=>. q .=>. p>>;;
let p4 = time splittab
<<~p .=>. q .<=>. ~q .=>. p>>;;
let p5 = time splittab
<<(p .|. q .=>. p .|. r) .=>. p .|. (q .=>. r)>>;;
let p6 = time splittab
<<p .|. ~p>>;;
let p7 = time splittab
<<p .|. ~ ~ ~p>>;;
let p8 = time splittab
<<((p .=>. q) .=>. p) .=>. p>>;;
let p9 = time splittab
<<(p .|. q) .&. (~p .|. q) .&. (p .|. ~q) .=>. ~(~q .|. ~q)>>;;
let p10 = time splittab
<<(q .=>. r) .&. (r .=>. p .&. q) .&. (p .=>. q .&. r) .=>. (p .<=>. q)>>;;
let p11 = time splittab
<<p .<=>. p>>;;
let p12 = time splittab
<<((p .<=>. q) .<=>. r) .<=>. (p .<=>. (q .<=>. r))>>;;
let p13 = time splittab
<<p .|. q .&. r .<=>. (p .|. q) .&. (p .|. r)>>;;
let p14 = time splittab
<<(p .<=>. q) .<=>. (q .|. ~p) .&. (~q .|. p)>>;;
let p15 = time splittab
<<p .=>. q .<=>. ~p .|. q>>;;
let p16 = time splittab
<<(p .=>. q) .|. (q .=>. p)>>;;
let p17 = time splittab
<<p .&. (q .=>. r) .=>. s .<=>. (~p .|. q .|. s) .&. (~p .|. ~r .|. s)>>;;
-- -------------------------------------------------------------------------
-- Pelletier problems: monadic predicate logic.
-- -------------------------------------------------------------------------
let p18 = time splittab
<<exists y. forall x. P[var "y"] .=>. P[var "x"]>>;;
let p19 = time splittab
<<exists x. forall y z. (P[var "y"] .=>. Q[var "z"]) .=>. P[var "x"] .=>. Q[var "x"]>>;;
let p20 = time splittab
<<(forall x y. exists z. forall w. P[var "x"] .&. Q[var "y"] .=>. R[var "z"] .&. U[var "w"])
.=>. (exists x y. P[var "x"] .&. Q[var "y"]) .=>. (exists z. R[var "z"])>>;;
let p21 = time splittab
<<(exists x. P .=>. Q[var "x"]) .&. (exists x. Q[var "x"] .=>. P)
.=>. (exists x. P .<=>. Q[var "x"])>>;;
let p22 = time splittab
<<(forall x. P .<=>. Q[var "x"]) .=>. (P .<=>. (forall x. Q[var "x"]))>>;;
let p23 = time splittab
<<(forall x. P .|. Q[var "x"]) .<=>. P .|. (forall x. Q[var "x"])>>;;
let p24 = time splittab
<<~(exists x. U[var "x"] .&. Q[var "x"]) .&.
(forall x. P[var "x"] .=>. Q[var "x"] .|. R[var "x"]) .&.
~(exists x. P[var "x"] .=>. (exists x. Q[var "x"])) .&.
(forall x. Q[var "x"] .&. R[var "x"] .=>. U[var "x"]) .=>.
(exists x. P[var "x"] .&. R[var "x"])>>;;
let p25 = time splittab
<<(exists x. P[var "x"]) .&.
(forall x. U[var "x"] .=>. ~G[var "x"] .&. R[var "x"]) .&.
(forall x. P[var "x"] .=>. G[var "x"] .&. U[var "x"]) .&.
((forall x. P[var "x"] .=>. Q[var "x"]) .|. (exists x. Q[var "x"] .&. P[var "x"]))
.=>. (exists x. Q[var "x"] .&. P[var "x"])>>;;
let p26 = time splittab
<<((exists x. P[var "x"]) .<=>. (exists x. Q[var "x"])) .&.
(forall x y. P[var "x"] .&. Q[var "y"] .=>. (R[var "x"] .<=>. U[var "y"]))
.=>. ((forall x. P[var "x"] .=>. R[var "x"]) .<=>. (forall x. Q[var "x"] .=>. U[var "x"]))>>;;
let p27 = time splittab
<<(exists x. P[var "x"] .&. ~Q[var "x"]) .&.
(forall x. P[var "x"] .=>. R[var "x"]) .&.
(forall x. U[var "x"] .&. V[var "x"] .=>. P[var "x"]) .&.
(exists x. R[var "x"] .&. ~Q[var "x"])
.=>. (forall x. U[var "x"] .=>. ~R[var "x"])
.=>. (forall x. U[var "x"] .=>. ~V[var "x"])>>;;
let p28 = time splittab
<<(forall x. P[var "x"] .=>. (forall x. Q[var "x"])) .&.
((forall x. Q[var "x"] .|. R[var "x"]) .=>. (exists x. Q[var "x"] .&. R[var "x"])) .&.
((exists x. R[var "x"]) .=>. (forall x. L[var "x"] .=>. M[var "x"])) .=>.
(forall x. P[var "x"] .&. L[var "x"] .=>. M[var "x"])>>;;
let p29 = time splittab
<<(exists x. P[var "x"]) .&. (exists x. G[var "x"]) .=>.
((forall x. P[var "x"] .=>. H[var "x"]) .&. (forall x. G[var "x"] .=>. J[var "x"]) .<=>.
(forall x y. P[var "x"] .&. G[var "y"] .=>. H[var "x"] .&. J[var "y"]))>>;;
let p30 = time splittab
<<(forall x. P[var "x"] .|. G[var "x"] .=>. ~H[var "x"]) .&.
(forall x. (G[var "x"] .=>. ~U[var "x"]) .=>. P[var "x"] .&. H[var "x"])
.=>. (forall x. U[var "x"])>>;;
let p31 = time splittab
<<~(exists x. P[var "x"] .&. (G[var "x"] .|. H[var "x"])) .&.
(exists x. Q[var "x"] .&. P[var "x"]) .&.
(forall x. ~H[var "x"] .=>. J[var "x"])
.=>. (exists x. Q[var "x"] .&. J[var "x"])>>;;
let p32 = time splittab
<<(forall x. P[var "x"] .&. (G[var "x"] .|. H[var "x"]) .=>. Q[var "x"]) .&.
(forall x. Q[var "x"] .&. H[var "x"] .=>. J[var "x"]) .&.
(forall x. R[var "x"] .=>. H[var "x"])
.=>. (forall x. P[var "x"] .&. R[var "x"] .=>. J[var "x"])>>;;
let p33 = time splittab
<<(forall x. P[var "a"] .&. (P[var "x"] .=>. P[var "b"]) .=>. P[var "c"]) .<=>.
(forall x. P[var "a"] .=>. P[var "x"] .|. P[var "c"]) .&. (P[var "a"] .=>. P[var "b"] .=>. P[var "c"])>>;;
let p34 = time splittab
<<((exists x. forall y. P[var "x"] .<=>. P[var "y"]) .<=>.
((exists x. Q[var "x"]) .<=>. (forall y. Q[var "y"]))) .<=>.
((exists x. forall y. Q[var "x"] .<=>. Q[var "y"]) .<=>.
((exists x. P[var "x"]) .<=>. (forall y. P[var "y"])))>>;;
let p35 = time splittab
<<exists x y. P(x,y) .=>. (forall x y. P(x,y))>>;;
-- -------------------------------------------------------------------------
-- Full predicate logic (without identity and functions).
-- -------------------------------------------------------------------------
let p36 = time splittab
<<(forall x. exists y. P(x,y)) .&.
(forall x. exists y. G(x,y)) .&.
(forall x y. P(x,y) .|. G(x,y)
.=>. (forall z. P(y,z) .|. G(y,z) .=>. H(x,z)))
.=>. (forall x. exists y. H(x,y))>>;;
let p37 = time splittab
<<(forall z.
exists w. forall x. exists y. (P(x,z) .=>. P(y,w)) .&. P(y,z) .&.
(P(y,w) .=>. (exists u. Q(u,w)))) .&.
(forall x z. ~P(x,z) .=>. (exists y. Q(y,z))) .&.
((exists x y. Q(x,y)) .=>. (forall x. R(x,x))) .=>.
(forall x. exists y. R(x,y))>>;;
let p38 = time splittab
<<(forall x.
P[var "a"] .&. (P[var "x"] .=>. (exists y. P[var "y"] .&. R(x,y))) .=>.
(exists z w. P[var "z"] .&. R(x,w) .&. R(w,z))) .<=>.
(forall x.
(~P[var "a"] .|. P[var "x"] .|. (exists z w. P[var "z"] .&. R(x,w) .&. R(w,z))) .&.
(~P[var "a"] .|. ~(exists y. P[var "y"] .&. R(x,y)) .|.
(exists z w. P[var "z"] .&. R(x,w) .&. R(w,z))))>>;;
let p39 = time splittab
<<~(exists x. forall y. P(y,x) .<=>. ~P(y,y))>>;;
let p40 = time splittab
<<(exists y. forall x. P(x,y) .<=>. P(x,x))
.=>. ~(forall x. exists y. forall z. P(z,y) .<=>. ~P(z,x))>>;;
let p41 = time splittab
<<(forall z. exists y. forall x. P(x,y) .<=>. P(x,z) .&. ~P(x,x))
.=>. ~(exists z. forall x. P(x,z))>>;;
let p42 = time splittab
<<~(exists y. forall x. P(x,y) .<=>. ~(exists z. P(x,z) .&. P(z,x)))>>;;
let p43 = time splittab
<<(forall x y. Q(x,y) .<=>. forall z. P(z,x) .<=>. P(z,y))
.=>. forall x y. Q(x,y) .<=>. Q(y,x)>>;;
let p44 = time splittab
<<(forall x. P[var "x"] .=>. (exists y. G[var "y"] .&. H(x,y)) .&.
(exists y. G[var "y"] .&. ~H(x,y))) .&.
(exists x. J[var "x"] .&. (forall y. G[var "y"] .=>. H(x,y))) .=>.
(exists x. J[var "x"] .&. ~P[var "x"])>>;;
let p45 = time splittab
<<(forall x.
P[var "x"] .&. (forall y. G[var "y"] .&. H(x,y) .=>. J(x,y)) .=>.
(forall y. G[var "y"] .&. H(x,y) .=>. R[var "y"])) .&.
~(exists y. L[var "y"] .&. R[var "y"]) .&.
(exists x. P[var "x"] .&. (forall y. H(x,y) .=>.
L[var "y"]) .&. (forall y. G[var "y"] .&. H(x,y) .=>. J(x,y))) .=>.
(exists x. P[var "x"] .&. ~(exists y. G[var "y"] .&. H(x,y)))>>;;
let p46 = time splittab
<<(forall x. P[var "x"] .&. (forall y. P[var "y"] .&. H(y,x) .=>. G[var "y"]) .=>. G[var "x"]) .&.
((exists x. P[var "x"] .&. ~G[var "x"]) .=>.
(exists x. P[var "x"] .&. ~G[var "x"] .&.
(forall y. P[var "y"] .&. ~G[var "y"] .=>. J(x,y)))) .&.
(forall x y. P[var "x"] .&. P[var "y"] .&. H(x,y) .=>. ~J(y,x)) .=>.
(forall x. P[var "x"] .=>. G[var "x"])>>;;
-- -------------------------------------------------------------------------
-- Well-known "Agatha" example; cf. Manthey and Bry, CADE-9.
-- -------------------------------------------------------------------------
let p55 = time splittab
<<lives(agatha) .&. lives(butler) .&. lives(charles) .&.
(killed(agatha,agatha) .|. killed(butler,agatha) .|.
killed(charles,agatha)) .&.
(forall x y. killed(x,y) .=>. hates(x,y) .&. ~richer(x,y)) .&.
(forall x. hates(agatha,x) .=>. ~hates(charles,x)) .&.
(hates(agatha,agatha) .&. hates(agatha,charles)) .&.
(forall x. lives[var "x"] .&. ~richer(x,agatha) .=>. hates(butler,x)) .&.
(forall x. hates(agatha,x) .=>. hates(butler,x)) .&.
(forall x. ~hates(x,agatha) .|. ~hates(x,butler) .|. ~hates(x,charles))
.=>. killed(agatha,agatha) .&.
~killed(butler,agatha) .&.
~killed(charles,agatha)>>;;
let p57 = time splittab
<<P(f([var "a"],b),f(b,c)) .&.
P(f(b,c),f(a,c)) .&.
(forall [var "x"] y z. P(x,y) .&. P(y,z) .=>. P(x,z))
.=>. P(f(a,b),f(a,c))>>;;
-- -------------------------------------------------------------------------
-- See info-hol, circa 1500.
-- -------------------------------------------------------------------------
let p58 = time splittab
<<forall P Q R. forall x. exists v. exists w. forall y. forall z.
((P[var "x"] .&. Q[var "y"]) .=>. ((P[var "v"] .|. R[var "w"]) .&. (R[var "z"] .=>. Q[var "v"])))>>;;
let p59 = time splittab
<<(forall x. P[var "x"] .<=>. ~P(f[var "x"])) .=>. (exists x. P[var "x"] .&. ~P(f[var "x"]))>>;;
let p60 = time splittab
<<forall x. P(x,f[var "x"]) .<=>.
exists y. (forall z. P(z,y) .=>. P(z,f[var "x"])) .&. P(x,y)>>;;
-- -------------------------------------------------------------------------
-- From Gilmore's classic paper.
-- -------------------------------------------------------------------------
{- **** This is still too hard for us! Amazing...
let gilmore_1 = time splittab
<<exists x. forall y z.
((F[var "y"] .=>. G[var "y"]) .<=>. F[var "x"]) .&.
((F[var "y"] .=>. H[var "y"]) .<=>. G[var "x"]) .&.
(((F[var "y"] .=>. G[var "y"]) .=>. H[var "y"]) .<=>. H[var "x"])
.=>. F[var "z"] .&. G[var "z"] .&. H[var "z"]>>;;
***** -}
{- ** This is not valid, according to Gilmore
let gilmore_2 = time splittab
<<exists x y. forall z.
(F(x,z) .<=>. F(z,y)) .&. (F(z,y) .<=>. F(z,z)) .&. (F(x,y) .<=>. F(y,x))
.=>. (F(x,y) .<=>. F(x,z))>>;;
** -}
let gilmore_3 = time splittab
<<exists x. forall y z.
((F(y,z) .=>. (G[var "y"] .=>. H[var "x"])) .=>. F(x,x)) .&.
((F(z,x) .=>. G[var "x"]) .=>. H[var "z"]) .&.
F(x,y)
.=>. F(z,z)>>;;
let gilmore_4 = time splittab
<<exists x y. forall z.
(F(x,y) .=>. F(y,z) .&. F(z,z)) .&.
(F(x,y) .&. G(x,y) .=>. G(x,z) .&. G(z,z))>>;;
let gilmore_5 = time splittab
<<(forall x. exists y. F(x,y) .|. F(y,x)) .&.
(forall x y. F(y,x) .=>. F(y,y))
.=>. exists z. F(z,z)>>;;
let gilmore_6 = time splittab
<<forall x. exists y.
(exists u. forall v. F(u,x) .=>. G(v,u) .&. G(u,x))
.=>. (exists u. forall v. F(u,y) .=>. G(v,u) .&. G(u,y)) .|.
(forall u v. exists w. G(v,u) .|. H(w,y,u) .=>. G(u,w))>>;;
let gilmore_7 = time splittab
<<(forall x. K[var "x"] .=>. exists y. L[var "y"] .&. (F(x,y) .=>. G(x,y))) .&.
(exists z. K[var "z"] .&. forall u. L[var "u"] .=>. F(z,u))
.=>. exists v w. K[var "v"] .&. L[var "w"] .&. G(v,w)>>;;
let gilmore_8 = time splittab
<<exists x. forall y z.
((F(y,z) .=>. (G[var "y"] .=>. (forall u. exists v. H(u,v,x)))) .=>. F(x,x)) .&.
((F(z,x) .=>. G[var "x"]) .=>. (forall u. exists v. H(u,v,z))) .&.
F(x,y)
.=>. F(z,z)>>;;
let gilmore_9 = time splittab
<<forall x. exists y. forall z.
((forall u. exists v. F(y,u,v) .&. G(y,u) .&. ~H(y,x))
.=>. (forall u. exists v. F(x,u,v) .&. G(z,u) .&. ~H(x,z))
.=>. (forall u. exists v. F(x,u,v) .&. G(y,u) .&. ~H(x,y))) .&.
((forall u. exists v. F(x,u,v) .&. G(y,u) .&. ~H(x,y))
.=>. ~(forall u. exists v. F(x,u,v) .&. G(z,u) .&. ~H(x,z))
.=>. (forall u. exists v. F(y,u,v) .&. G(y,u) .&. ~H(y,x)) .&.
(forall u. exists v. F(z,u,v) .&. G(y,u) .&. ~H(z,y)))>>;;
-- -------------------------------------------------------------------------
-- Example from Davis-Putnam papers where Gilmore procedure is poor.
-- -------------------------------------------------------------------------
let davis_putnam_example = time splittab
<<exists x. exists y. forall z.
(F(x,y) .=>. (F(y,z) .&. F(z,z))) .&.
((F(x,y) .&. G(x,y)) .=>. (G(x,z) .&. G(z,z)))>>;;
************ -}
-}