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
(* ========================================================================= *) (* First-order derived rules in the LCF setup. *) (* *) (* Copyright (c) 2003-2007, John Harrison. (See "LICENSE.txt" for details.) *) (* ========================================================================= *) (* ------------------------------------------------------------------------- *) (* ****** *) (* ------------------------------------------ eq_sym *) (* |- s = t ==> t = s *) (* ------------------------------------------------------------------------- *) let eq_sym s t = let rth = axiom_eqrefl s in funpow 2 (fun th -> modusponens (imp_swap th) rth) (axiom_predcong "=" [s; s] [t; s]);; (* ------------------------------------------------------------------------- *) (* |- s = t ==> t = u ==> s = u. *) (* ------------------------------------------------------------------------- *) let eq_trans s t u = let th1 = axiom_predcong "=" [t; u] [s; u] in let th2 = modusponens (imp_swap th1) (axiom_eqrefl u) in imp_trans (eq_sym s t) th2;; (* ------------------------------------------------------------------------- *) (* ---------------------------- icongruence *) (* |- s = t ==> tm[s] = tm[t] *) (* ------------------------------------------------------------------------- *) let rec icongruence s t stm ttm = if stm = ttm then add_assum (mk_eq s t) (axiom_eqrefl stm) else if stm = s & ttm = t then imp_refl (mk_eq s t) else match (stm,ttm) with (Fn(fs,sa),Fn(ft,ta)) when fs = ft & length sa = length ta -> let ths = map2 (icongruence s t) sa ta in let ts = map (consequent ** concl) ths in imp_trans_chain ths (axiom_funcong fs (map lhs ts) (map rhs ts)) | _ -> failwith "icongruence: not congruent";; (* ------------------------------------------------------------------------- *) (* Example. *) (* ------------------------------------------------------------------------- *) START_INTERACTIVE;; icongruence <<|s|>> <<|t|>> <<|f(s,g(s,t,s),u,h(h(s)))|>> <<|f(s,g(t,t,s),u,h(h(t)))|>>;; END_INTERACTIVE;; (* ------------------------------------------------------------------------- *) (* |- (forall x. p ==> q(x)) ==> p ==> (forall x. q(x)) *) (* ------------------------------------------------------------------------- *) let gen_right_th x p q = imp_swap(imp_trans (axiom_impall x p) (imp_swap(axiom_allimp x p q)));; (* ------------------------------------------------------------------------- *) (* |- p ==> q *) (* ------------------------------------- genimp "x" *) (* |- (forall x. p) ==> (forall x. q) *) (* ------------------------------------------------------------------------- *) let genimp x th = let p,q = dest_imp(concl th) in modusponens (axiom_allimp x p q) (gen x th);; (* ------------------------------------------------------------------------- *) (* If |- p ==> q[x] then |- p ==> forall x. q[x] *) (* ------------------------------------------------------------------------- *) let gen_right x th = let p,q = dest_imp(concl th) in modusponens (gen_right_th x p q) (gen x th);; (* ------------------------------------------------------------------------- *) (* |- (forall x. p(x) ==> q) ==> (exists x. p(x)) ==> q *) (* ------------------------------------------------------------------------- *) let exists_left_th x p q = let p' = Imp(p,False) and q' = Imp(q,False) in let th1 = genimp x (imp_swap(imp_trans_th p q False)) in let th2 = imp_trans th1 (gen_right_th x q' p') in let th3 = imp_swap(imp_trans_th q' (Forall(x,p')) False) in let th4 = imp_trans2 (imp_trans th2 th3) (axiom_doubleneg q) in let th5 = imp_add_concl False (genimp x (iff_imp2 (axiom_not p))) in let th6 = imp_trans (iff_imp1 (axiom_not (Forall(x,Not p)))) th5 in let th7 = imp_trans (iff_imp1(axiom_exists x p)) th6 in imp_swap(imp_trans th7 (imp_swap th4));; (* ------------------------------------------------------------------------- *) (* If |- p(x) ==> q then |- (exists x. p(x)) ==> q *) (* ------------------------------------------------------------------------- *) let exists_left x th = let p,q = dest_imp(concl th) in modusponens (exists_left_th x p q) (gen x th);; (* ------------------------------------------------------------------------- *) (* |- x = t ==> p ==> q [x not in t and not free in q] *) (* --------------------------------------------------------------- subspec *) (* |- (forall x. p) ==> q *) (* ------------------------------------------------------------------------- *) let subspec th = match concl th with Imp(Atom(R("=",[Var x;t])) as e,Imp(p,q)) -> let th1 = imp_trans (genimp x (imp_swap th)) (exists_left_th x e q) in modusponens (imp_swap th1) (axiom_existseq x t) | _ -> failwith "subspec: wrong sort of theorem";; (* ------------------------------------------------------------------------- *) (* |- x = y ==> p[x] ==> q[y] [x not in FV(q); y not in FV(p) or x == y] *) (* --------------------------------------------------------- subalpha *) (* |- (forall x. p) ==> (forall y. q) *) (* ------------------------------------------------------------------------- *) let subalpha th = match concl th with Imp(Atom(R("=",[Var x;Var y])),Imp(p,q)) -> if x = y then genimp x (modusponens th (axiom_eqrefl(Var x))) else gen_right y (subspec th) | _ -> failwith "subalpha: wrong sort of theorem";; (* ------------------------------------------------------------------------- *) (* ---------------------------------- isubst *) (* |- s = t ==> p[s] ==> p[t] *) (* ------------------------------------------------------------------------- *) let rec isubst s t sfm tfm = if sfm = tfm then add_assum (mk_eq s t) (imp_refl tfm) else match (sfm,tfm) with Atom(R(p,sa)),Atom(R(p',ta)) when p = p' & length sa = length ta -> let ths = map2 (icongruence s t) sa ta in let ls,rs = unzip (map (dest_eq ** consequent ** concl) ths) in imp_trans_chain ths (axiom_predcong p ls rs) | Imp(sp,sq),Imp(tp,tq) -> let th1 = imp_trans (eq_sym s t) (isubst t s tp sp) and th2 = isubst s t sq tq in imp_trans_chain [th1; th2] (imp_mono_th sp tp sq tq) | Forall(x,p),Forall(y,q) -> if x = y then imp_trans (gen_right x (isubst s t p q)) (axiom_allimp x p q) else let z = Var(variant x (unions [fv p; fv q; fvt s; fvt t])) in let th1 = isubst (Var x) z p (subst (x |=> z) p) and th2 = isubst z (Var y) (subst (y |=> z) q) q in let th3 = subalpha th1 and th4 = subalpha th2 in let th5 = isubst s t (consequent(concl th3)) (antecedent(concl th4)) in imp_swap (imp_trans2 (imp_trans th3 (imp_swap th5)) th4) | _ -> let sth = iff_imp1(expand_connective sfm) and tth = iff_imp2(expand_connective tfm) in let th1 = isubst s t (consequent(concl sth)) (antecedent(concl tth)) in imp_swap(imp_trans sth (imp_swap(imp_trans2 th1 tth)));; (* ------------------------------------------------------------------------- *) (* *) (* -------------------------------------------- alpha "z" <> *) (* |- (forall x. p[x]) ==> (forall z. p'[z]) *) (* *) (* [Restriction that z is not free in the initial p[x].] *) (* ------------------------------------------------------------------------- *) let alpha z fm = match fm with Forall(x,p) -> let p' = subst (x |=> Var z) p in subalpha(isubst (Var x) (Var z) p p') | _ -> failwith "alpha: not a universal formula";; (* ------------------------------------------------------------------------- *) (* *) (* -------------------------------- ispec t <> *) (* |- (forall x. p[x]) ==> p'[t] *) (* ------------------------------------------------------------------------- *) let rec ispec t fm = match fm with Forall(x,p) -> if mem x (fvt t) then let th = alpha (variant x (union (fvt t) (var p))) fm in imp_trans th (ispec t (consequent(concl th))) else subspec(isubst (Var x) t p (subst (x |=> t) p)) | _ -> failwith "ispec: non-universal formula";; (* ------------------------------------------------------------------------- *) (* Specialization rule. *) (* ------------------------------------------------------------------------- *) let spec t th = modusponens (ispec t (concl th)) th;; (* ------------------------------------------------------------------------- *) (* An example. *) (* ------------------------------------------------------------------------- *) START_INTERACTIVE;; ispec <<|y|>> <>;; (* ------------------------------------------------------------------------- *) (* Additional tests not in main text. *) (* ------------------------------------------------------------------------- *) isubst <<|x + x|>> <<|2 * x|>> < x = 0>> <<2 * x = x ==> x = 0>>;; isubst <<|x + x|>> <<|2 * x|>> <<(x + x = y + y) ==> (y + y + y = x + x + x)>> <<2 * x = y + y ==> y + y + y = x + 2 * x>>;; ispec <<|x|>> <> ;; ispec <<|x|>> <> ;; ispec <<|w + y + z|>> <> ;; ispec <<|x + y + z|>> <> ;; ispec <<|x + y + z|>> <> ;; isubst <<|x + x|>> <<|2 * x|>> <<(x + x = y + y) <=> (something \/ y + y + y = x + x + x)>> ;; isubst <<|x + x|>> <<|2 * x|>> <<(exists x. x = 2) <=> exists y. y + x + x = y + y + y>> <<(exists x. x = 2) <=> (exists y. y + 2 * x = y + y + y)>>;; isubst <<|x|>> <<|y|>> <<(forall z. x = z) <=> (exists x. y < z) /\ (forall y. y < x)>> <<(forall z. y = z) <=> (exists x. y < z) /\ (forall y'. y' < y)>>;; (* ------------------------------------------------------------------------- *) (* The bug is now fixed. *) (* ------------------------------------------------------------------------- *) ispec <<|x'|>> <>;; ispec <<|x''|>> <>;; ispec <<|x' + x''|>> <>;; ispec <<|x + x' + x''|>> <>;; ispec <<|2 * x|>> <>;; END_INTERACTIVE;;