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
(* ========================================================================= *) (* Propositional reasoning by derived rules atop the LCF core. *) (* *) (* Copyright (c) 2003-2007, John Harrison. (See "LICENSE.txt" for details.) *) (* ========================================================================= *) (* ------------------------------------------------------------------------- *) (* |- p ==> p *) (* ------------------------------------------------------------------------- *) let imp_refl p = modusponens (modusponens (axiom_distribimp p (Imp(p,p)) p) (axiom_addimp p (Imp(p,p)))) (axiom_addimp p p);; (* ------------------------------------------------------------------------- *) (* |- p ==> p ==> q *) (* -------------------- imp_unduplicate *) (* |- p ==> q *) (* ------------------------------------------------------------------------- *) let imp_unduplicate th = let p,pq = dest_imp(concl th) in let q = consequent pq in modusponens (modusponens (axiom_distribimp p p q) th) (imp_refl p);; (* ------------------------------------------------------------------------- *) (* Some handy syntax operations. *) (* ------------------------------------------------------------------------- *) let negatef fm = match fm with Imp(p,False) -> p | p -> Imp(p,False);; let negativef fm = match fm with Imp(p,False) -> true | _ -> false;; (* ------------------------------------------------------------------------- *) (* |- q *) (* ------------------------------------------------ add_assum (p) *) (* |- p ==> q *) (* ------------------------------------------------------------------------- *) let add_assum p th = modusponens (axiom_addimp (concl th) p) th;; (* ------------------------------------------------------------------------- *) (* |- q ==> r *) (* --------------------------------------- imp_add_assum p *) (* |- (p ==> q) ==> (p ==> r) *) (* ------------------------------------------------------------------------- *) let imp_add_assum p th = let (q,r) = dest_imp(concl th) in modusponens (axiom_distribimp p q r) (add_assum p th);; (* ------------------------------------------------------------------------- *) (* |- p ==> q |- q ==> r *) (* ----------------------------------------- imp_trans *) (* |- p ==> r *) (* ------------------------------------------------------------------------- *) let imp_trans th1 th2 = let p = antecedent(concl th1) in modusponens (imp_add_assum p th2) th1;; (* ------------------------------------------------------------------------- *) (* |- p ==> r *) (* -------------------------- imp_insert q *) (* |- p ==> q ==> r *) (* ------------------------------------------------------------------------- *) let imp_insert q th = let (p,r) = dest_imp(concl th) in imp_trans th (axiom_addimp r q);; (* ------------------------------------------------------------------------- *) (* |- p ==> q ==> r *) (* ---------------------- imp_swap *) (* |- q ==> p ==> r *) (* ------------------------------------------------------------------------- *) let imp_swap th = let p,qr = dest_imp(concl th) in let q,r = dest_imp qr in imp_trans (axiom_addimp q p) (modusponens (axiom_distribimp p q r) th);; (* ------------------------------------------------------------------------- *) (* |- (q ==> r) ==> (p ==> q) ==> (p ==> r) *) (* ------------------------------------------------------------------------- *) let imp_trans_th p q r = imp_trans (axiom_addimp (Imp(q,r)) p) (axiom_distribimp p q r);; (* ------------------------------------------------------------------------- *) (* |- p ==> q *) (* ------------------------------- imp_add_concl r *) (* |- (q ==> r) ==> (p ==> r) *) (* ------------------------------------------------------------------------- *) let imp_add_concl r th = let (p,q) = dest_imp(concl th) in modusponens (imp_swap(imp_trans_th p q r)) th;; (* ------------------------------------------------------------------------- *) (* |- (p ==> q ==> r) ==> (q ==> p ==> r) *) (* ------------------------------------------------------------------------- *) let imp_swap_th p q r = imp_trans (axiom_distribimp p q r) (imp_add_concl (Imp(p,r)) (axiom_addimp q p));; (* ------------------------------------------------------------------------- *) (* |- (p ==> q ==> r) ==> (s ==> t ==> u) *) (* ----------------------------------------- *) (* |- (q ==> p ==> r) ==> (t ==> s ==> u) *) (* ------------------------------------------------------------------------- *) let imp_swap2 th = match concl th with Imp(Imp(p,Imp(q,r)),Imp(s,Imp(t,u))) -> imp_trans (imp_swap_th q p r) (imp_trans th (imp_swap_th s t u)) | _ -> failwith "imp_swap2";; (* ------------------------------------------------------------------------- *) (* If |- p ==> q ==> r and |- p ==> q then |- p ==> r. *) (* ------------------------------------------------------------------------- *) let right_mp ith th = imp_unduplicate(imp_trans th (imp_swap ith));; (* ------------------------------------------------------------------------- *) (* |- p <=> q *) (* ------------ iff_imp1 *) (* |- p ==> q *) (* ------------------------------------------------------------------------- *) let iff_imp1 th = let (p,q) = dest_iff(concl th) in modusponens (axiom_iffimp1 p q) th;; (* ------------------------------------------------------------------------- *) (* |- p <=> q *) (* ------------ iff_imp2 *) (* |- q ==> p *) (* ------------------------------------------------------------------------- *) let iff_imp2 th = let (p,q) = dest_iff(concl th) in modusponens (axiom_iffimp2 p q) th;; (* ------------------------------------------------------------------------- *) (* |- p ==> q |- q ==> p *) (* ---------------------------- imp_antisym *) (* |- p <=> q *) (* ------------------------------------------------------------------------- *) let imp_antisym th1 th2 = let (p,q) = dest_imp(concl th1) in modusponens (modusponens (axiom_impiff p q) th1) th2;; (* ------------------------------------------------------------------------- *) (* |- p ==> (q ==> false) ==> false *) (* ----------------------------------- right_doubleneg *) (* |- p ==> q *) (* ------------------------------------------------------------------------- *) let right_doubleneg th = match concl th with Imp(_,Imp(Imp(p,False),False)) -> imp_trans th (axiom_doubleneg p) | _ -> failwith "right_doubleneg";; (* ------------------------------------------------------------------------- *) (* *) (* ------------------------------------------- ex_falso (p) *) (* |- false ==> p *) (* ------------------------------------------------------------------------- *) let ex_falso p = right_doubleneg(axiom_addimp False (Imp(p,False)));; (* ------------------------------------------------------------------------- *) (* |- p ==> q ==> r |- r ==> s *) (* ------------------------------------ imp_trans2 *) (* |- p ==> q ==> s *) (* ------------------------------------------------------------------------- *) let imp_trans2 th1 th2 = let Imp(p,Imp(q,r)) = concl th1 and Imp(r',s) = concl th2 in let th = imp_add_assum p (modusponens (imp_trans_th q r s) th2) in modusponens th th1;; (* ------------------------------------------------------------------------- *) (* |- p ==> q1 ... |- p ==> qn |- q1 ==> ... ==> qn ==> r *) (* -------------------------------------------------------------- *) (* |- p ==> r *) (* ------------------------------------------------------------------------- *) let imp_trans_chain ths th = itlist (fun a b -> imp_unduplicate (imp_trans a (imp_swap b))) (rev(tl ths)) (imp_trans (hd ths) th);; (* ------------------------------------------------------------------------- *) (* |- (q ==> false) ==> p ==> (p ==> q) ==> false *) (* ------------------------------------------------------------------------- *) let imp_truefalse p q = imp_trans (imp_trans_th p q False) (imp_swap_th (Imp(p,q)) p False);; (* ------------------------------------------------------------------------- *) (* |- (p' ==> p) ==> (q ==> q') ==> (p ==> q) ==> (p' ==> q') *) (* ------------------------------------------------------------------------- *) let imp_mono_th p p' q q' = let th1 = imp_trans_th (Imp(p,q)) (Imp(p',q)) (Imp(p',q')) and th2 = imp_trans_th p' q q' and th3 = imp_swap(imp_trans_th p' p q) in imp_trans th3 (imp_swap(imp_trans th2 th1));; (* ------------------------------------------------------------------------- *) (* |- true *) (* ------------------------------------------------------------------------- *) let truth = modusponens (iff_imp2 axiom_true) (imp_refl False);; (* ------------------------------------------------------------------------- *) (* |- p ==> q *) (* ----------------- contrapos *) (* |- ~q ==> ~p *) (* ------------------------------------------------------------------------- *) let contrapos th = let p,q = dest_imp(concl th) in imp_trans (imp_trans (iff_imp1(axiom_not q)) (imp_add_concl False th)) (iff_imp2(axiom_not p));; (* ------------------------------------------------------------------------- *) (* |- p /\ q ==> p *) (* ------------------------------------------------------------------------- *) let and_left p q = let th1 = imp_add_assum p (axiom_addimp False q) in let th2 = right_doubleneg(imp_add_concl False th1) in imp_trans (iff_imp1(axiom_and p q)) th2;; (* ------------------------------------------------------------------------- *) (* |- p /\ q ==> q *) (* ------------------------------------------------------------------------- *) let and_right p q = let th1 = axiom_addimp (Imp(q,False)) p in let th2 = right_doubleneg(imp_add_concl False th1) in imp_trans (iff_imp1(axiom_and p q)) th2;; (* ------------------------------------------------------------------------- *) (* |- p1 /\ ... /\ pn ==> pi for each 1 <= i <= n (input term right assoc) *) (* ------------------------------------------------------------------------- *) let rec conjths fm = try let p,q = dest_and fm in (and_left p q)::map (imp_trans (and_right p q)) (conjths q) with Failure _ -> [imp_refl fm];; (* ------------------------------------------------------------------------- *) (* |- p ==> q ==> p /\ q *) (* ------------------------------------------------------------------------- *) let and_pair p q = let th1 = iff_imp2(axiom_and p q) and th2 = imp_swap_th (Imp(p,Imp(q,False))) q False in let th3 = imp_add_assum p (imp_trans2 th2 th1) in modusponens th3 (imp_swap (imp_refl (Imp(p,Imp(q,False)))));; (* ------------------------------------------------------------------------- *) (* If |- p /\ q ==> r then |- p ==> q ==> r *) (* ------------------------------------------------------------------------- *) let shunt th = let p,q = dest_and(antecedent(concl th)) in modusponens (itlist imp_add_assum [p;q] th) (and_pair p q);; (* ------------------------------------------------------------------------- *) (* If |- p ==> q ==> r then |- p /\ q ==> r *) (* ------------------------------------------------------------------------- *) let unshunt th = let p,qr = dest_imp(concl th) in let q,r = dest_imp qr in imp_trans_chain [and_left p q; and_right p q] th;; (* ------------------------------------------------------------------------- *) (* Produce |- (p <=> q) <=> (p ==> q) /\ (q ==> p) *) (* ------------------------------------------------------------------------- *) let iff_def p q = let th1 = and_pair (Imp(p,q)) (Imp(q,p)) in let th2 = imp_trans_chain [axiom_iffimp1 p q; axiom_iffimp2 p q] th1 in imp_antisym th2 (unshunt (axiom_impiff p q));; let iff_def p q = let th = and_pair (Imp(p,q)) (Imp(q,p)) and thl = [axiom_iffimp1 p q; axiom_iffimp2 p q] in imp_antisym (imp_trans_chain thl th) (unshunt (axiom_impiff p q));; (* ------------------------------------------------------------------------- *) (* Produce "expansion" theorem for defined connectives. *) (* ------------------------------------------------------------------------- *) let expand_connective fm = match fm with True -> axiom_true | Not p -> axiom_not p | And(p,q) -> axiom_and p q | Or(p,q) -> axiom_or p q | Iff(p,q) -> iff_def p q | Exists(x,p) -> axiom_exists x p | _ -> failwith "expand_connective";; let eliminate_connective fm = if not(negativef fm) then iff_imp1(expand_connective fm) else imp_add_concl False (iff_imp2(expand_connective(negatef fm)));; (* ------------------------------------------------------------------------- *) (* *) (* ------------------------------------------------- imp_false_conseqs *) (* [|- ((p ==> q) ==> false) ==> (q ==> false); *) (* |- ((p ==> q) ==> false) ==> p] *) (* ------------------------------------------------------------------------- *) let imp_false_conseqs p q = [right_doubleneg(imp_add_concl False (imp_add_assum p (ex_falso q))); imp_add_concl False (imp_insert p (imp_refl q))];; (* ------------------------------------------------------------------------- *) (* |- p ==> (q ==> false) ==> r *) (* ------------------------------------ imp_false_rule *) (* |- ((p ==> q) ==> false) ==> r *) (* ------------------------------------------------------------------------- *) let imp_false_rule th = let p,r = dest_imp (concl th) in imp_trans_chain (imp_false_conseqs p (funpow 2 antecedent r)) th;; (* ------------------------------------------------------------------------- *) (* |- (p ==> false) ==> r |- q ==> r *) (* ---------------------------------------------- imp_true_rule *) (* |- (p ==> q) ==> r *) (* ------------------------------------------------------------------------- *) let imp_true_rule th1 th2 = let p = funpow 2 antecedent (concl th1) and q = antecedent(concl th2) and th3 = right_doubleneg(imp_add_concl False th1) and th4 = imp_add_concl False th2 in let th5 = imp_swap(imp_truefalse p q) in let th6 = imp_add_concl False (imp_trans_chain [th3; th4] th5) and th7 = imp_swap(imp_refl(Imp(Imp(p,q),False))) in right_doubleneg(imp_trans th7 th6);; (* ------------------------------------------------------------------------- *) (* * *) (* -------------------------------------- imp_contr *) (* |- p ==> -p ==> q *) (* ------------------------------------------------------------------------- *) let imp_contr p q = if negativef p then imp_add_assum (negatef p) (ex_falso q) else imp_swap (imp_add_assum p (ex_falso q));; (* ------------------------------------------------------------------------- *) (* *) (* --------------------------------------------- imp_front (this antecedent) *) (* |- (p0 ==> p1 ==> ... ==> pn ==> q) *) (* ==> pn ==> p0 ==> p1 ==> .. p(n-1) ==> q *) (* ------------------------------------------------------------------------- *) let rec imp_front_th n fm = if n = 0 then imp_refl fm else let p,qr = dest_imp fm in let th1 = imp_add_assum p (imp_front_th (n - 1) qr) in let q',r' = dest_imp(funpow 2 consequent(concl th1)) in imp_trans th1 (imp_swap_th p q' r');; (* ------------------------------------------------------------------------- *) (* |- p0 ==> p1 ==> ... ==> pn ==> q *) (* ------------------------------------------ imp_front n *) (* |- pn ==> p0 ==> p1 ==> .. p(n-1) ==> q *) (* ------------------------------------------------------------------------- *) let imp_front n th = modusponens (imp_front_th n (concl th)) th;; (* ------------------------------------------------------------------------- *) (* Propositional tableaux procedure. *) (* ------------------------------------------------------------------------- *) let rec lcfptab fms lits = match fms with False::fl -> ex_falso (itlist mk_imp (fl @ lits) False) | (Imp(p,q) as fm)::fl when p = q -> add_assum fm (lcfptab fl lits) | Imp(Imp(p,q),False)::fl -> imp_false_rule(lcfptab (p::Imp(q,False)::fl) lits) | Imp(p,q)::fl when q <> False -> imp_true_rule (lcfptab (Imp(p,False)::fl) lits) (lcfptab (q::fl) lits) | (Atom(_)|Forall(_,_)|Imp((Atom(_)|Forall(_,_)),False) as p)::fl -> if mem (negatef p) lits then let l1,l2 = chop_list (index (negatef p) lits) lits in let th = imp_contr p (itlist mk_imp (tl l2) False) in itlist imp_insert (fl @ l1) th else imp_front (length fl) (lcfptab fl (p::lits)) | fm::fl -> let th = eliminate_connective fm in imp_trans th (lcfptab (consequent(concl th)::fl) lits) | _ -> failwith "lcfptab: no contradiction";; (* ------------------------------------------------------------------------- *) (* In particular, this gives a tautology prover. *) (* ------------------------------------------------------------------------- *) let lcftaut p = modusponens (axiom_doubleneg p) (lcfptab [negatef p] []);; (* ------------------------------------------------------------------------- *) (* The examples in the text. *) (* ------------------------------------------------------------------------- *) START_INTERACTIVE;; lcftaut <<(p ==> q) \/ (q ==> p)>>;; lcftaut <

((p <=> q) <=> p \/ q)>>;; lcftaut <<((p <=> q) <=> r) <=> (p <=> (q <=> r))>>;; END_INTERACTIVE;;