Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
(* ========================================================================= *)
(* Special procedures for decidable subsets of first order logic. *)
(* *)
(* Copyright (c) 2003-2007, John Harrison. (See "LICENSE.txt" for details.) *)
(* ========================================================================= *)
(***
meson <>;;
tab <>;;
***)
(* ------------------------------------------------------------------------- *)
(* Resolution does actually terminate with failure in simple cases! *)
(* ------------------------------------------------------------------------- *)
(***
resolution <>;;
***)
(* ------------------------------------------------------------------------- *)
(* The Los example; see how Skolemized form has no non-nullary functions. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
let los =
<<(forall x y z. P(x,y) /\ P(y,z) ==> P(x,z)) /\
(forall x y z. Q(x,y) /\ Q(y,z) ==> Q(x,z)) /\
(forall x y. P(x,y) ==> P(y,x)) /\
(forall x y. P(x,y) \/ Q(x,y))
==> (forall x y. P(x,y)) \/ (forall x y. Q(x,y))>>;;
skolemize(Not los);;
(* ------------------------------------------------------------------------- *)
(* The old DP procedure works. *)
(* ------------------------------------------------------------------------- *)
davisputnam los;;
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* However, we can just form all the ground instances. *)
(* ------------------------------------------------------------------------- *)
let aedecide fm =
let sfm = skolemize(Not fm) in
let fvs = fv sfm
and cnsts,funcs = partition (fun (_,ar) -> ar = 0) (functions sfm) in
if funcs <> [] then failwith "Not decidable" else
let consts = if cnsts = [] then ["c",0] else cnsts in
let cntms = map (fun (c,_) -> Fn(c,[])) consts in
let alltuples = groundtuples cntms [] 0 (length fvs) in
let cjs = simpcnf sfm in
let grounds = map
(fun tup -> image (image (subst (fpf fvs tup))) cjs) alltuples in
not(dpll(unions grounds));;
(* ------------------------------------------------------------------------- *)
(* In this case it's quicker. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
aedecide los;;
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* Show how we need to do PNF transformation with care. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
let fm = <<(forall x. p(x)) \/ (exists y. p(y))>>;;
pnf fm;;
(* ------------------------------------------------------------------------- *)
(* Also the group theory problem. *)
(* ------------------------------------------------------------------------- *)
aedecide
<<(forall x. P(1,x,x)) /\ (forall x. P(x,x,1)) /\
(forall u v w x y z.
P(x,y,u) /\ P(y,z,w) ==> (P(x,w,v) <=> P(u,z,v)))
==> forall a b c. P(a,b,c) ==> P(b,a,c)>>;;
aedecide
<<(forall x. P(x,x,1)) /\
(forall u v w x y z.
P(x,y,u) /\ P(y,z,w) ==> (P(x,w,v) <=> P(u,z,v)))
==> forall a b c. P(a,b,c) ==> P(b,a,c)>>;;
(* ------------------------------------------------------------------------- *)
(* A bigger example. *)
(* ------------------------------------------------------------------------- *)
aedecide
<<(exists x. P(x)) /\ (exists x. G(x))
==> ((forall x. P(x) ==> H(x)) /\ (forall x. G(x) ==> J(x)) <=>
(forall x y. P(x) /\ G(y) ==> H(x) /\ J(y)))>>;;
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* The following, however, doesn't work with aedecide. *)
(* ------------------------------------------------------------------------- *)
(*** This is p18
aedecide < P(x)>>;;
davisputnam < P(x)>>;;
***)
(* ------------------------------------------------------------------------- *)
(* Simple-minded miniscoping procedure. *)
(* ------------------------------------------------------------------------- *)
let separate x cjs =
let yes,no = partition (mem x ** fv) cjs in
if yes = [] then list_conj no
else if no = [] then Exists(x,list_conj yes)
else And(Exists(x,list_conj yes),list_conj no);;
let rec pushquant x p =
if not (mem x (fv p)) then p else
let djs = purednf(nnf p) in
list_disj (map (separate x) djs);;
let rec miniscope fm =
match fm with
Not p -> Not(miniscope p)
| And(p,q) -> And(miniscope p,miniscope q)
| Or(p,q) -> Or(miniscope p,miniscope q)
| Forall(x,p) -> Not(pushquant x (Not(miniscope p)))
| Exists(x,p) -> pushquant x (miniscope p)
| _ -> fm;;
(* ------------------------------------------------------------------------- *)
(* Examples. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
miniscope(nnf < P(x)>>);;
let fm = miniscope(nnf
<<(forall x y. exists z. forall w. P(x) /\ Q(y) ==> R(z) /\ U(w))
==> (exists x y. P(x) /\ Q(y)) ==> (exists z. R(z))>>);;
pnf(nnf fm);;
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* Stronger version of "aedecide" similar to Wang's classic procedure. *)
(* ------------------------------------------------------------------------- *)
let wang fm = aedecide(miniscope(nnf(simplify fm)));;
(* ------------------------------------------------------------------------- *)
(* It works well on simple monadic formulas. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
wang
<<(forall x y. exists z. forall w. P(x) /\ Q(y) ==> R(z) /\ U(w))
==> (exists x y. P(x) /\ Q(y)) ==> (exists z. R(z))>>;;
(* ------------------------------------------------------------------------- *)
(* But not on this one! *)
(* ------------------------------------------------------------------------- *)
pnf(nnf(miniscope(nnf
<<((exists x. forall y. P(x) <=> P(y)) <=>
((exists x. Q(x)) <=> (forall y. Q(y)))) <=>
((exists x. forall y. Q(x) <=> Q(y)) <=>
((exists x. P(x)) <=> (forall y. P(y))))>>)));;
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* Checking classic Aristotelean syllogisms. *)
(* ------------------------------------------------------------------------- *)
let atom p x = Atom(R(p,[Var x]));;
let premiss_A (p,q) = Forall("x",Imp(atom p "x",atom q "x"))
and premiss_E (p,q) = Forall("x",Imp(atom p "x",Not(atom q "x")))
and premiss_I (p,q) = Exists("x",And(atom p "x",atom q "x"))
and premiss_O (p,q) = Exists("x",And(atom p "x",Not(atom q "x")));;
let anglicize_premiss fm =
match fm with
Forall(_,Imp(Atom(R(p,_)),Atom(R(q,_)))) -> "all "^p^" are "^q
| Forall(_,Imp(Atom(R(p,_)),Not(Atom(R(q,_))))) -> "no "^p^" are "^q
| Exists(_,And(Atom(R(p,_)),Atom(R(q,_)))) -> "some "^p^" are "^q
| Exists(_,And(Atom(R(p,_)),Not(Atom(R(q,_))))) ->
"some "^p^" are not "^q;;
let anglicize_syllogism (Imp(And(t1,t2),t3)) =
"If " ^ anglicize_premiss t1 ^ " and " ^ anglicize_premiss t2 ^
", then " ^ anglicize_premiss t3;;
let all_possible_syllogisms =
let sylltypes = [premiss_A; premiss_E; premiss_I; premiss_O] in
let prems1 = allpairs (fun x -> x) sylltypes ["M","P"; "P","M"]
and prems2 = allpairs (fun x -> x) sylltypes ["S","M"; "M","S"]
and prems3 = allpairs (fun x -> x) sylltypes ["S","P"] in
allpairs mk_imp (allpairs mk_and prems1 prems2) prems3;;
START_INTERACTIVE;;
let all_valid_syllogisms = filter aedecide all_possible_syllogisms;;
length all_valid_syllogisms;;
map anglicize_syllogism all_valid_syllogisms;;
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* We can "fix" the traditional list by assuming nonemptiness. *)
(* ------------------------------------------------------------------------- *)
let all_possible_syllogisms' =
let p =
<<(exists x. P(x)) /\ (exists x. M(x)) /\ (exists x. S(x))>> in
map (fun t -> Imp(p,t)) all_possible_syllogisms;;
START_INTERACTIVE;;
let all_valid_syllogisms' = filter aedecide all_possible_syllogisms';;
length all_valid_syllogisms';;
map (anglicize_syllogism ** consequent) all_valid_syllogisms';;
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* Decide a formula on all models of size n. *)
(* ------------------------------------------------------------------------- *)
let rec alltuples n l =
if n = 0 then [[]] else
let tups = alltuples (n - 1) l in
allpairs (fun h t -> h::t) l tups;;
let allmappings dom ran =
itlist (fun p -> allpairs (valmod p) ran) dom [undef];;
let alldepmappings dom ran =
itlist (fun (p,n) -> allpairs (valmod p) (ran n)) dom [undef];;
let allfunctions dom n = allmappings (alltuples n dom) dom;;
let allpredicates dom n = allmappings (alltuples n dom) [false;true];;
let decide_finite n fm =
let funcs = functions fm and preds = predicates fm and dom = 1--n in
let fints = alldepmappings funcs (allfunctions dom)
and pints = alldepmappings preds (allpredicates dom) in
let interps = allpairs (fun f p -> dom,f,p) fints pints in
let fm' = generalize fm in
forall (fun md -> holds md undefined fm') interps;;
(* ------------------------------------------------------------------------- *)
(* Decision procedure in principle for formulas with finite model property. *)
(* ------------------------------------------------------------------------- *)
let limmeson n fm =
let cls = simpcnf(specialize(pnf fm)) in
let rules = itlist ((@) ** contrapositives) cls [] in
mexpand rules [] False (fun x -> x) (undefined,n,0);;
let limited_meson n fm =
let fm1 = askolemize(Not(generalize fm)) in
map (limmeson n ** list_conj) (simpdnf fm1);;
let decide_fmp fm =
let rec test n =
try limited_meson n fm; true with Failure _ ->
if decide_finite n fm then test (n + 1) else false in
test 1;;
START_INTERACTIVE;;
decide_fmp
<<(forall x y. R(x,y) \/ R(y,x)) ==> forall x. R(x,x)>>;;
decide_fmp
<<(forall x y z. R(x,y) /\ R(y,z) ==> R(x,z)) ==> forall x. R(x,x)>>;;
(*** This fails to terminate: has countermodels, but only infinite ones
decide_fmp
<<~((forall x. ~R(x,x)) /\
(forall x. exists z. R(x,z)) /\
(forall x y z. R(x,y) /\ R(y,z) ==> R(x,z)))>>;;
****)
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* Semantic decision procedure for the monadic fragment. *)
(* ------------------------------------------------------------------------- *)
let decide_monadic fm =
let funcs = functions fm and preds = predicates fm in
let monadic,other = partition (fun (_,ar) -> ar = 1) preds in
if funcs <> [] or exists (fun (_,ar) -> ar > 1) other
then failwith "Not in the monadic subset" else
let n = funpow (length monadic) (( * ) 2) 1 in
decide_finite n fm;;
(* ------------------------------------------------------------------------- *)
(* Example. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
decide_monadic
<<((exists x. forall y. P(x) <=> P(y)) <=>
((exists x. Q(x)) <=> (forall y. Q(y)))) <=>
((exists x. forall y. Q(x) <=> Q(y)) <=>
((exists x. P(x)) <=> (forall y. P(y))))>>;;
(**** This is not feasible
decide_monadic
<<(forall x y. exists z. forall w. P(x) /\ Q(y) ==> R(z) /\ U(w))
==> (exists x y. P(x) /\ Q(y)) ==> (exists z. R(z))>>;;
****)
END_INTERACTIVE;;
(* ------------------------------------------------------------------------- *)
(* Little auxiliary results for failure of finite model property. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
(*** Our claimed equivalences are indeed correct ***)
meson
<<(exists x y z. forall u.
R(x,x) \/ ~R(x,u) \/ (R(x,y) /\ R(y,z) /\ ~R(x,z))) <=>
~((forall x. ~R(x,x)) /\
(forall x. exists z. R(x,z)) /\
(forall x y z. R(x,y) /\ R(y,z) ==> R(x,z)))>>;;
meson
<<(exists x. forall y. exists z. R(x,x) \/ ~R(x,y) \/ (R(y,z) /\ ~R(x,z))) <=>
~((forall x. ~R(x,x)) /\
(forall x. exists y. R(x,y) /\ forall z. R(y,z) ==> R(x,z)))>>;;
(*** The second formula implies the first ***)
meson
<<~((forall x. ~R(x,x)) /\
(forall x. exists y. R(x,y) /\ forall z. R(y,z) ==> R(x,z)))
==> ~((forall x. ~R(x,x)) /\
(forall x. exists z. R(x,z)) /\
(forall x y z. R(x,y) /\ R(y,z) ==> R(x,z)))>>;;
END_INTERACTIVE;;