> and ap' = <
>
and aq = < p'>> and aqq' = <> and aq' = <
>
and app' = <
q'>> in
fun c p p' q q' ->
let pat = Imp(app',Imp(aqq',Iff(c(ap,aq),c(ap',aq')))) in
lcfptaut pat (Imp(Iff(p,p'),Imp(Iff(q,q'),Iff(c(p,q),c(p',q')))));;
(* ------------------------------------------------------------------------- *)
(* |- (forall x. P(x) <=> Q(x)) ==> ((forall x. P(x)) <=> (forall x. Q(x))) *)
(* ------------------------------------------------------------------------- *)
let forall_iff x p q =
imp_trans_chain
[imp_trans (genimp x (axiom_iffimp1 p q)) (axiom_allimp x p q);
imp_trans (genimp x (axiom_iffimp2 p q)) (axiom_allimp x q p)]
(axiom_impiff (Forall(x,p)) (Forall(x,q)));;
(* ------------------------------------------------------------------------- *)
(* |- (forall x. P(x) <=> Q(x)) ==> ((exists x. P(x)) <=> (exists x. Q(x))) *)
(* ------------------------------------------------------------------------- *)
let exists_iff x p q =
let th1 = genimp x (cong_not p q) in
let th2 = imp_trans th1 (forall_iff x (Not p) (Not q)) in
let xnp = Forall(x,Not p) and xnq = Forall(x,Not q) in
let th3 = imp_trans th2 (cong_not xnp xnq) in
let th4 = iff_trans_th (Exists(x,p)) (Not xnp) (Not xnq) in
let th5 = imp_trans th3 (modusponens th4 (axiom_exists x p)) in
let th6 = iff_trans_th (Exists(x,p)) (Not xnq) (Exists(x,q)) in
let th7 = modusponens (imp_swap th6) (iff_sym(axiom_exists x q)) in
imp_trans th5 th7;;
(* ------------------------------------------------------------------------- *)
(* Substitution... *)
(* ------------------------------------------------------------------------- *)
let rec isubst s t fm =
if not (free_in s fm) then add_assum (mk_eq s t) (iff_refl fm) else
match fm with
Atom(R(p,args)) ->
if args = [] then add_assum (mk_eq s t) (iff_refl fm) else
let ths = map (congruence s t) args in
let lts,rts = unzip (map (dest_eq ** consequent ** concl) ths) in
let ths' = map2 imp_trans ths (map2 eq_sym lts rts) in
let th = imp_trans_chain ths (axiom_predcong p lts rts)
and th' = imp_trans_chain ths' (axiom_predcong p rts lts) in
let fm' = consequent(consequent(concl th)) in
imp_trans_chain [th; th'] (axiom_impiff fm fm')
| Not(p) ->
let th = isubst s t p in
let p' = snd(dest_iff(consequent(concl th))) in
imp_trans th (cong_not p p')
| And(p,q) -> isubst_binary (fun (p,q) -> And(p,q)) s t p q
| Or(p,q) -> isubst_binary (fun (p,q) -> Or(p,q)) s t p q
| Imp(p,q) -> isubst_binary (fun (p,q) -> Imp(p,q)) s t p q
| Iff(p,q) -> isubst_binary (fun (p,q) -> Iff(p,q)) s t p q
| Forall(x,p) ->
if mem x (fvt t) then
let z = variant x (union (fvt t) (fv p)) in
let th1 = alpha z fm in
let fm' = consequent(concl th1) in
let th2 = imp_antisym th1 (alpha x fm')
and th3 = isubst s t fm' in
let fm'' = snd(dest_iff(consequent(concl th3))) in
imp_trans th3 (modusponens (iff_trans_th fm fm' fm'') th2)
else
let th = isubst s t p in
let p' = snd(dest_iff(consequent(concl th))) in
imp_trans (gen_right x th) (forall_iff x p p')
| Exists(x,p) ->
let th0 = axiom_exists x p in
let th1 = isubst s t (snd(dest_iff(concl th0))) in
let Imp(_,Iff(fm',(Not(Forall(y,Not(p'))) as q))) = concl th1 in
let th2 = imp_trans th1 (modusponens (iff_trans_th fm fm' q) th0)
and th3 = iff_sym(axiom_exists y p') in
let r = snd(dest_iff(concl th3)) in
imp_trans th2 (modusponens (imp_swap(iff_trans_th fm q r)) th3)
| _ -> add_assum (mk_eq s t) (iff_refl fm)
and isubst_binary cons s t p q =
let th_p = isubst s t p and th_q = isubst s t q in
let p' = snd(dest_iff(consequent(concl th_p)))
and q' = snd(dest_iff(consequent(concl th_q))) in
let th1 = imp_trans th_p (cong_bin cons p p' q q') in
imp_unduplicate (imp_trans th_q (imp_swap th1))
(* ------------------------------------------------------------------------- *)
(* ...specialization... *)
(* ------------------------------------------------------------------------- *)
and ispec t fm =
match fm with
Forall(x,p) ->
if mem x (fvt t) then
let th1 = alpha (variant x (union (fvt t) (fv p))) fm in
imp_trans th1 (ispec t (consequent(concl th1)))
else
let th1 = isubst (Var x) t p in
let eq,bod = dest_imp(concl th1) in
let p' = snd(dest_iff bod) in
let th2 = imp_trans th1 (axiom_iffimp1 p p') in
exists_imp(modusponens (eximp x th2) (axiom_existseq x t))
| _ -> failwith "ispec: non-universal formula"
(* ------------------------------------------------------------------------- *)
(* ...and renaming, all mutually recursive. *)
(* ------------------------------------------------------------------------- *)
and alpha z fm =
let th1 = ispec (Var z) fm in
let ant,cons = dest_imp(concl th1) in
let th2 = modusponens (axiom_allimp z ant cons) (gen z th1) in
imp_trans (axiom_impall z fm) th2;;
(* ------------------------------------------------------------------------- *)
(* Specialization rule. *)
(* ------------------------------------------------------------------------- *)
let spec t th = modusponens (ispec t (concl th)) th;;
(* ------------------------------------------------------------------------- *)
(* Tests. *)
(* ------------------------------------------------------------------------- *)
START_INTERACTIVE;;
isubst <<|x + x|>> <<|2 * x|>> <