File Lambda.ML
(* Title: Lambda.ML
Author: James Brotherston / Rene Vestergaard
Revised: 24th July, 2000
- Proposition of Renaming Sanity (plus auxiliary lemma)
- Proof of _[_:=_] = _<_:=_> when substitution is enabled
- plus a host of useful lemmas linking the notions of capturing and free
variables in a term under substitution
*)
(* Proposition of Renaming Sanity and lemmas *)
Goal "y:(Capt x e) --> x:FV(e)";
by(induct_tac "e" 1);
by(Auto_tac);
qed "aux_renaming_lemma_1";
Addsimps [aux_renaming_lemma_1];
Goal "e[x:=Var x] = e";
by(induct_tac "e" 1);
by(Auto_tac);
qed "renaming_sanity_1";
Goal "x~:FV(e) --> (e[x:=e'] = e)";
by(induct_tac "e" 1);
by(Auto_tac);
qed "renaming_sanity_2";
Goal "((x~:FV(e')) & ((Capt x e) Int FV(e')) = {}) --> (x~:FV(e[x:=e']))";
by(induct_tac "e" 1);
by(Auto_tac);
qed "renaming_sanity_3";
(* the more user-friendly version of the above *)
Goal "[|x~:FV(e'); ((Capt x e) Int FV(e')) = {}|] ==> x~:FV(e[x:=e'])";
by(rtac (renaming_sanity_3 RS mp) 1);
by(Fast_tac 1);
qed "renaming_sanity_3";
Goal "(y~:FV(e)) --> (e[x:=Var y][y:=Var x] = e)";
by(induct_tac "e" 1);
by(Auto_tac);
qed "renaming_sanity_4";
Addsimps[renaming_sanity_1, renaming_sanity_2];
(* Some useful Capt / FV / substitution - type lemmas *)
Goal "[|A<=B; x~:B|] ==> x~:A";
by(Blast_tac 1);
qed "subset_lemma_1";
Goal "[|A-{x} <= B-{x}; y:A; x~=y|] ==> y:B";
by(Blast_tac 1);
qed "subset_lemma_2";
Goal "y~:FV(e) --> Capt y e = {}";
by(induct_tac "e" 1);
by(ALLGOALS Full_simp_tac);
by(Fast_tac 1);
qed "Capt_FV_lemma_1";
Goal "y~:BV(e) --> y~:Capt x e";
by(induct_tac "e" 1);
by(Auto_tac);
qed "Capt_BV_lemma_1";
Goal "[|(Capt y (Abs z e)) Int FV(e') = {}; y~=z|] ==> z~:FV(e') | y~:FV(e)";
by(Auto_tac);
qed "Capt_Int_FV_lemma_1";
Goal "x:FV(e[y:=e']) ==> x:FV(e') | x:FV(e)";
by(rtac mp 1);
by(atac 2);
by(induct_tac "e" 1);
by(Auto_tac);
qed "FV_subst_lemma_1";
Goal "x:FV(e) --> x~=y --> x:FV(e[y:=e'])";
by(induct_tac "e" 1);
by(Auto_tac);
qed "FV_subst_lemma_2";
Goal "x:FV(e') ==> x:FV(e) --> x:FV(e[y:=e'])";
by(induct_tac "e" 1);
by(ALLGOALS strip_tac);
by(Auto_tac);
qed "FV_subst_lemma_3";
Goal "x:FV(e1) --> y:FV(e2) --> y:FV(e1[x:=e2]) | e1[x:=e2] = e1";
by(induct_tac "e1" 1);
by(ALLGOALS strip_tac);
by(Asm_full_simp_tac 1);
by(Asm_full_simp_tac 1);
by(Auto_tac);
qed "FV_subst_lemma_4";
Goal "A --> B --> C ==> ~C --> ~A | ~B";
by(Blast_tac 1);
qed "special_contrapositive";
Goal "x~:FV(e[y:=e']) ==> x~:FV(e) | x=y";
by(cut_facts_tac [(FV_subst_lemma_2 RS special_contrapositive)] 1);
by(Fast_tac 1);
qed "FV_subst_lemma_5";
Goal "x:FV(e') ==> (Capt y e) Int FV(e') = {} --> y:FV(e) --> x:FV(e[y:=e'])";
by(induct_tac "e" 1);
by(ALLGOALS strip_tac);
by(Auto_tac);
qed "FV_subst_lemma_6";
Goal "(Capt x e) <= BV(e)";
by(induct_tac "e" 1);
by(Auto_tac);
qed "capt_in_bound_var";
Goal "x:BV(e[y:=e']) ==> x:BV(e) | x:BV(e')";
by(rtac mp 1);
by(atac 2);
by(thin_tac "x:BV(e[y:=e'])" 1);
by(induct_tac "e" 1);
by(Auto_tac);
qed "BV_subst_lemma_1";
Goal "x~:FV(e) & x~:FV(e') --> x~:FV(e[y:=e'])";
by(induct_tac "e" 1);
by(Asm_simp_tac 1);
by(Asm_simp_tac 1);
by(strip_tac 1);
by(Simp_tac 1);
by(resolve_tac [conjI] 1);
by(resolve_tac [conjI] 2);
by(ALLGOALS strip_tac);
by(Auto_tac);
qed "FV_lemma_1";
Goal "[|y~:FV(e); y~=z|] ==> y~:FV(e[x:=Var z])";
by(rtac (FV_lemma_1 RS mp) 1);
by(Asm_simp_tac 1);
qed "FV_var_subst_lemma_1";
Goal "y~:BV(e) ==> y~:BV(e[x:=Var z])";
by(rtac mp 1);
by(atac 2);
by(thin_tac "y~:BV(e)" 1);
by(induct_tac "e" 1);
by(Auto_tac);
qed "BV_var_subst_lemma_1";
(* Induction principles for the (parallel-) beta side condition *)
Goal "Capt y (e1 $ e2) Int A = {} ==> Capt y e1 Int A = {} & Capt y e2 Int A = {}";
by(Auto_tac);
qed "Capt_induct_1";
Goal "(Capt x (e1 $ e2) Un A) Int B = {} ==> (Capt x e1 Un A) Int B = {} & (Capt x e2 Un A) Int B = {}";
by(Auto_tac);
qed "Capt_induct_2";
Goal "[|x~=y; Capt y (Abs x e) Int A = {}|] ==> Capt y e Int A = {}";
by(dtac not_sym 1);
by(Asm_full_simp_tac 1);
by(case_tac "y:FV(e)" 1);
by(ALLGOALS Asm_full_simp_tac);
by(Fast_tac 1);
by(asm_simp_tac (simpset() addsimps[Capt_FV_lemma_1]) 1);
qed "Capt_induct_3";
Goal "[|y~=x; (Capt x (Abs y e) Un A) Int B = {} |] ==> (Capt x e Un A) Int B = {}";
by(dtac not_sym 1);
by(Asm_full_simp_tac 1);
by(case_tac "x:FV(e)" 1);
by(ALLGOALS Asm_full_simp_tac);
by(Fast_tac 1);
by(asm_simp_tac (simpset() addsimps[Capt_FV_lemma_1]) 1);
qed "Capt_induct_4";
Goal "[|Capt x (Abs y (e1 $ e2)) Int A = {}; y~=x|] ==> Capt x (Abs y e1) Int A = {} & Capt x (Abs y e2) Int A = {}";
by(Auto_tac);
qed "Capt_induct_5";
Goal "[|Capt x (Abs y (Abs z e)) Int A = {}; y~=x; z~=x |] ==> Capt x (Abs y e) Int A = {}";
by(Auto_tac);
qed "Capt_induct_6";
(* Proof of "sharp" = "normal" substitution under suitable conditions *)
Goal "(Capt x e1) Int FV(e2) = {} ==> e1[x:=e2] = e1<x:=e2>";
by(rtac mp 1);
by(atac 2);
by(induct_tac "e1" 1);
by(ALLGOALS strip_tac);
by(ALLGOALS Simp_tac);
by(dtac Capt_induct_1 1);
by(Fast_tac 1);
by(rtac conjI 1);
by(ALLGOALS strip_tac);
by(ALLGOALS (fatac Capt_induct_3 1));
by(ALLGOALS (mp_tac));
by(atac 1);
by(dtac not_sym 1);
by(case_tac "x:FV(lterm)" 1);
by(Auto_tac);
qed "subst_equivalence";