# HG changeset patch # User urbanc # Date 1185302051 -7200 # Node ID a252a7da82b9ec2d287ec1c917ae3d967fe0a3ca # Parent ef782bbf2d09f5a5d905d88f04ad94353012ef98 cleaned up the proofs a bit diff -r ef782bbf2d09 -r a252a7da82b9 src/HOL/Nominal/Examples/SN.thy --- a/src/HOL/Nominal/Examples/SN.thy Tue Jul 24 19:58:53 2007 +0200 +++ b/src/HOL/Nominal/Examples/SN.thy Tue Jul 24 20:34:11 2007 +0200 @@ -24,10 +24,9 @@ lemma fresh_fact: fixes a::"name" - assumes a: "a\t1" - and b: "a\t2" + assumes a: "a\t1" "a\t2" shows "a\t1[b::=t2]" -using a b +using a by (nominal_induct t1 avoiding: a b t2 rule: lam.induct) (auto simp add: abs_fresh fresh_atm) @@ -62,21 +61,16 @@ inductive Beta :: "lam\lam\bool" (" _ \\<^isub>\ _" [80,80] 80) where - b1[intro!]: "s1\\<^isub>\s2 \ (App s1 t)\\<^isub>\(App s2 t)" -| b2[intro!]: "s1\\<^isub>\s2 \ (App t s1)\\<^isub>\(App t s2)" -| b3[intro!]: "s1\\<^isub>\s2 \ (Lam [a].s1)\\<^isub>\ (Lam [a].s2)" -| b4[intro!]: "a\s2 \(App (Lam [a].s1) s2)\\<^isub>\(s1[a::=s2])" + b1[intro!]: "s1 \\<^isub>\ s2 \ App s1 t \\<^isub>\ App s2 t" +| b2[intro!]: "s1\\<^isub>\s2 \ App t s1 \\<^isub>\ App t s2" +| b3[intro!]: "s1\\<^isub>\s2 \ Lam [a].s1 \\<^isub>\ Lam [a].s2" +| b4[intro!]: "a\s2 \ App (Lam [a].s1) s2\\<^isub>\ (s1[a::=s2])" equivariance Beta nominal_inductive Beta by (simp_all add: abs_fresh fresh_fact') -abbreviation - "Beta_star" :: "lam\lam\bool" (" _ \\<^isub>\\<^sup>* _" [80,80] 80) -where - "t1 \\<^isub>\\<^sup>* t2 \ Beta\<^sup>*\<^sup>* t1 t2" - lemma supp_beta: assumes a: "t\\<^isub>\ s" shows "(supp s)\((supp t)::name set)" @@ -84,7 +78,11 @@ by (induct) (auto intro!: simp add: abs_supp lam.supp subst_supp) -lemma beta_abs: "Lam [a].t\\<^isub>\ t'\\t''. t'=Lam [a].t'' \ t\\<^isub>\ t''" +lemma beta_abs: + assumes a: "Lam [a].t\\<^isub>\ t'" + shows "\t''. t'=Lam [a].t'' \ t\\<^isub>\ t''" +using a +apply - apply(ind_cases "Lam [a].t \\<^isub>\ t'") apply(auto simp add: lam.distinct lam.inject) apply(auto simp add: alpha) @@ -156,9 +154,8 @@ assumes a: "a\\" shows "\(\\::ty. (a,\)\set \)" using a -apply(induct \) -apply(auto simp add: fresh_prod fresh_list_cons fresh_atm) -done +by (induct \) + (auto simp add: fresh_prod fresh_list_cons fresh_atm) inductive typing :: "(name\ty) list\lam\ty\bool" ("_ \ _ : _" [60,60,60] 60) @@ -193,20 +190,63 @@ thus "NORMAL (Var a)" by (force simp add: NORMAL_def) qed -constdefs - "SN" :: "lam \ bool" - "SN t \ termip Beta t" +inductive + SN :: "lam \ bool" +where + SN_intro: "(\t'. t \\<^isub>\ t' \ SN t') \ SN t" + +lemma SN_elim: + assumes a: "SN M" + shows "(\M. (\N. M \\<^isub>\ N \ P N)\ P M) \ P M" +using a +by (induct rule: SN.SN.induct) (blast) + +lemma SN_preserved: + assumes a: "SN t1" "t1\\<^isub>\ t2" + shows "SN t2" +using a +by (cases) (auto) -lemma SN_preserved: "\SN(t1);t1\\<^isub>\ t2\\SN(t2)" -apply(simp add: SN_def) -apply(drule_tac a="t2" in accp_downward) -apply(auto) -done +lemma double_SN_aux: + assumes a: "SN a" + and b: "SN b" + and hyp: "\x z. + (\y. x \\<^isub>\ y \ SN y) \ + (\y. x \\<^isub>\ y \ P y z) \ + (\u. z \\<^isub>\ u \ SN u) \ + (\u. z \\<^isub>\ u \ P x u) \ P x z" + shows "P a b" +proof - + from a + have r: "\b. SN b \ P a b" + proof (induct a rule: SN.SN.induct) + case (SN_intro x) + note SNI' = SN_intro + have "SN b" by fact + thus ?case + proof (induct b rule: SN.SN.induct) + case (SN_intro y) + show ?case + apply (rule hyp) + apply (erule SNI') + apply (erule SNI') + apply (rule SN.SN_intro) + apply (erule SN_intro)+ + done + qed + qed + from b show ?thesis by (rule r) +qed -lemma SN_intro: "(\t2. t1\\<^isub>\t2 \ SN(t2))\SN(t1)" -apply(simp add: SN_def) -apply(rule accp.accI) -apply(auto) +lemma double_SN[consumes 2]: + assumes a: "SN a" + and b: "SN b" + and c: "\x z. \\y. x \\<^isub>\ y \ P y z; \u. z \\<^isub>\ u \ P x u\ \ P x z" + shows "P a b" +using a b c +apply(rule_tac double_SN_aux) +apply(assumption)+ +apply(blast) done section {* Candidates *} @@ -217,43 +257,35 @@ nominal_primrec "RED (TVar X) = {t. SN(t)}" "RED (\\\) = {t. \u. (u\RED \ \ (App t u)\RED \)}" -apply(rule TrueI)+ -done +by (rule TrueI)+ constdefs NEUT :: "lam \ bool" - "NEUT t \ (\a. t=Var a)\(\t1 t2. t=App t1 t2)" + "NEUT t \ (\a. t = Var a) \ (\t1 t2. t = App t1 t2)" (* a slight hack to get the first element of applications *) +(* this is needed to get (SN t) from SN (App t s) *) inductive FST :: "lam\lam\bool" (" _ \ _" [80,80] 80) where fst[intro!]: "(App t s) \ t" -lemma fst_elim[elim!]: - shows "(App t s) \ t' \ t=t'" -apply(ind_cases "App t s \ t'") -apply(simp add: lam.inject) -done - -lemma qq3: "SN(App t s)\SN(t)" -apply(simp add: SN_def) -apply(subgoal_tac "\z. (App t s \ z) \ termip Beta z")(*A*) -apply(force) -(*A*) -apply(erule accp_induct) -apply(clarify) -apply(ind_cases "x \ z" for x z) -apply(clarify) -apply(rule accp.accI) -apply(auto intro: b1) -done +lemma SN_of_FST_of_App: + assumes a: "SN (App t s)" + shows "SN t" +using a +proof - + from a have "\z. (App t s \ z) \ SN z" + by (induct rule: SN.SN.induct) + (blast elim: FST.cases intro: SN_intro) + then show "SN t" by blast +qed section {* Candidates *} constdefs "CR1" :: "ty \ bool" - "CR1 \ \ \ t. (t\RED \ \ SN(t))" + "CR1 \ \ \t. (t\RED \ \ SN t)" "CR2" :: "ty \ bool" "CR2 \ \ \t t'. (t\RED \ \ t \\<^isub>\ t') \ t'\RED \" @@ -267,59 +299,78 @@ "CR4" :: "ty \ bool" "CR4 \ \ \t. (NEUT t \ NORMAL t) \t\RED \" -lemma CR3_CR4: "CR3 \ \ CR4 \" -apply(simp (no_asm_use) add: CR3_def CR3_RED_def CR4_def NORMAL_def) -apply(blast) -done +lemma CR3_implies_CR4: + assumes a: "CR3 \" + shows "CR4 \" +using a by (auto simp add: CR3_def CR3_RED_def CR4_def NORMAL_def) -lemma sub_ind: - "SN(u)\(u\RED \\(\t. (NEUT t\CR2 \\CR3 \\CR3_RED t (\\\))\(App t u)\RED \))" -apply(simp add: SN_def) -apply(erule accp_induct) -apply(auto) -apply(simp add: CR3_def) -apply(rotate_tac 5) -apply(drule_tac x="App t x" in spec) -apply(drule mp) -apply(rule conjI) -apply(force simp only: NEUT_def) -apply(simp (no_asm) add: CR3_RED_def) -apply(clarify) -apply(ind_cases "App t x \\<^isub>\ t'" for x t t') -apply(simp_all add: lam.inject) -apply(simp only: CR3_RED_def) -apply(drule_tac x="s2" in spec) -apply(simp) -apply(drule_tac x="s2" in spec) -apply(simp) -apply(drule mp) -apply(simp (no_asm_use) add: CR2_def) -apply(blast) -apply(drule_tac x="ta" in spec) -apply(force) -apply(auto simp only: NEUT_def lam.inject lam.distinct) -done +(* sub_induction in the arrow-type case for the next proof *) +lemma sub_induction: + assumes a: "SN(u)" + and b: "u\RED \" + and c1: "NEUT t" + and c2: "CR2 \" + and c3: "CR3 \" + and c4: "CR3_RED t (\\\)" + shows "(App t u)\RED \" +using a b +proof (induct) + fix u + assume as: "u\RED \" + assume ih: " \u'. \u \\<^isub>\ u'; u' \ RED \\ \ App t u' \ RED \" + have "NEUT (App t u)" using c1 by (auto simp add: NEUT_def) + moreover + have "CR3_RED (App t u) \" unfolding CR3_RED_def + proof (intro strip) + fix r + assume red: "App t u \\<^isub>\ r" + moreover + { assume "\t'. t \\<^isub>\ t' \ r = App t' u" + then obtain t' where a1: "t \\<^isub>\ t'" and a2: "r = App t' u" by blast + have "t'\RED (\\\)" using c4 a1 by (simp add: CR3_RED_def) + then have "App t' u\RED \" using as by simp + then have "r\RED \" using a2 by simp + } + moreover + { assume "\u'. u \\<^isub>\ u' \ r = App t u'" + then obtain u' where b1: "u \\<^isub>\ u'" and b2: "r = App t u'" by blast + have "u'\RED \" using as b1 c2 by (auto simp add: CR2_def) + with ih have "App t u' \ RED \" using b1 by simp + then have "r\RED \" using b2 by simp + } + moreover + { assume "\x t'. t = Lam [x].t'" + then obtain x t' where "t = Lam [x].t'" by blast + then have "NEUT (Lam [x].t')" using c1 by simp + then have "False" by (simp add: NEUT_def) + then have "r\RED \" by simp + } + ultimately show "r \ RED \" by (cases) (auto simp add: lam.inject) + qed + ultimately show "App t u \ RED \" using c3 by (simp add: CR3_def) +qed +(* properties of the candiadates *) lemma RED_props: shows "CR1 \" and "CR2 \" and "CR3 \" proof (nominal_induct \ rule: ty.induct) case (TVar a) { case 1 show "CR1 (TVar a)" by (simp add: CR1_def) next - case 2 show "CR2 (TVar a)" by (force intro: SN_preserved simp add: CR2_def) + case 2 show "CR2 (TVar a)" by (auto intro: SN_preserved simp add: CR2_def) next - case 3 show "CR3 (TVar a)" by (force intro: SN_intro simp add: CR3_def CR3_RED_def) + case 3 show "CR3 (TVar a)" by (auto intro: SN_intro simp add: CR3_def CR3_RED_def) } next case (TArr \1 \2) { case 1 have ih_CR3_\1: "CR3 \1" by fact have ih_CR1_\2: "CR1 \2" by fact - show "CR1 (\1 \ \2)" - proof (simp add: CR1_def, intro strip) + show "CR1 (\1 \ \2)" unfolding CR1_def + proof (simp, intro strip) fix t assume a: "\u. u \ RED \1 \ App t u \ RED \2" - from ih_CR3_\1 have "CR4 \1" by (simp add: CR3_CR4) + from ih_CR3_\1 have "CR4 \1" by (simp add: CR3_implies_CR4) moreover have "NEUT (Var a)" by (force simp add: NEUT_def) moreover @@ -327,160 +378,129 @@ ultimately have "(Var a)\ RED \1" by (simp add: CR4_def) with a have "App t (Var a) \ RED \2" by simp hence "SN (App t (Var a))" using ih_CR1_\2 by (simp add: CR1_def) - thus "SN(t)" by (rule qq3) + thus "SN(t)" by (rule SN_of_FST_of_App) qed next case 2 have ih_CR1_\1: "CR1 \1" by fact have ih_CR2_\2: "CR2 \2" by fact - show "CR2 (\1 \ \2)" - proof (simp add: CR2_def, intro strip) + show "CR2 (\1 \ \2)" unfolding CR2_def + proof (simp, intro strip) fix t1 t2 u assume "(\u. u \ RED \1 \ App t1 u \ RED \2) \ t1 \\<^isub>\ t2" and "u \ RED \1" hence "t1 \\<^isub>\ t2" and "App t1 u \ RED \2" by simp_all - thus "App t2 u \ RED \2" using ih_CR2_\2 by (force simp add: CR2_def) + thus "App t2 u \ RED \2" using ih_CR2_\2 by (auto simp add: CR2_def) qed next case 3 have ih_CR1_\1: "CR1 \1" by fact have ih_CR2_\1: "CR2 \1" by fact have ih_CR3_\2: "CR3 \2" by fact - show "CR3 (\1 \ \2)" - proof (simp add: CR3_def, intro strip) + show "CR3 (\1 \ \2)" unfolding CR3_def + proof (simp, intro strip) fix t u assume a1: "u \ RED \1" assume a2: "NEUT t \ CR3_RED t (\1 \ \2)" - from a1 have "SN(u)" using ih_CR1_\1 by (simp add: CR1_def) - hence "u\RED \1\(\t. (NEUT t\CR2 \1\CR3 \2\CR3_RED t (\1\\2))\(App t u)\RED \2)" - by (rule sub_ind) - with a1 a2 show "(App t u)\RED \2" using ih_CR2_\1 ih_CR3_\2 by simp + have "SN(u)" using a1 ih_CR1_\1 by (simp add: CR1_def) + then show "(App t u)\RED \2" using ih_CR2_\1 ih_CR3_\2 a1 a2 by (blast intro: sub_induction) qed } qed - -lemma double_acc_aux: - assumes a_acc: "accp r a" - and b_acc: "accp r b" - and hyp: "\x z. - (\y. r y x \ accp r y) \ - (\y. r y x \ P y z) \ - (\u. r u z \ accp r u) \ - (\u. r u z \ P x u) \ P x z" - shows "P a b" + +(* not as simple as on paper, because of the stronger double_SN induction *) +lemma abs_RED: + assumes asm: "\s\RED \. t[x::=s]\RED \" + shows "Lam [x].t\RED (\\\)" proof - - from a_acc - have r: "\b. accp r b \ P a b" - proof (induct a rule: accp.induct) - case (accI x) - note accI' = accI - have "accp r b" by fact - thus ?case - proof (induct b rule: accp.induct) - case (accI y) - show ?case - apply (rule hyp) - apply (erule accI') - apply (erule accI') - apply (rule accp.accI) - apply (erule accI) - apply (erule accI) - apply (erule accI) + have b1: "SN t" + proof - + have "Var x\RED \" + proof - + have "CR4 \" by (simp add: RED_props CR3_implies_CR4) + moreover + have "NEUT (Var x)" by (auto simp add: NEUT_def) + moreover + have "NORMAL (Var x)" by (auto elim: Beta.cases simp add: NORMAL_def) + ultimately show "Var x\RED \" by (simp add: CR4_def) + qed + then have "t[x::=Var x]\RED \" using asm by simp + then have "t\RED \" by (simp add: id_subs) + moreover + have "CR1 \" by (simp add: RED_props) + ultimately show "SN t" by (simp add: CR1_def) + qed + show "Lam [x].t\RED (\\\)" + proof (simp, intro strip) + fix u + assume b2: "u\RED \" + then have b3: "SN u" using RED_props by (auto simp add: CR1_def) + show "App (Lam [x].t) u \ RED \" using b1 b3 b2 asm + proof(induct t u rule: double_SN) + fix t u + assume ih1: "\t'. \t \\<^isub>\ t'; u\RED \; \s\RED \. t'[x::=s]\RED \\ \ App (Lam [x].t') u \ RED \" + assume ih2: "\u'. \u \\<^isub>\ u'; u'\RED \; \s\RED \. t[x::=s]\RED \\ \ App (Lam [x].t) u' \ RED \" + assume as1: "u \ RED \" + assume as2: "\s\RED \. t[x::=s]\RED \" + have "CR3_RED (App (Lam [x].t) u) \" unfolding CR3_RED_def + proof(intro strip) + fix r + assume red: "App (Lam [x].t) u \\<^isub>\ r" + moreover + { assume "\t'. t \\<^isub>\ t' \ r = App (Lam [x].t') u" + then obtain t' where a1: "t \\<^isub>\ t'" and a2: "r = App (Lam [x].t') u" by blast + have "App (Lam [x].t') u\RED \" using ih1 a1 as1 as2 + apply(auto) + apply(drule_tac x="t'" in meta_spec) + apply(simp) + apply(drule meta_mp) + apply(auto) + apply(drule_tac x="s" in bspec) + apply(simp) + apply(subgoal_tac "CR2 \") + apply(unfold CR2_def)[1] + apply(drule_tac x="t[x::=s]" in spec) + apply(drule_tac x="t'[x::=s]" in spec) + apply(simp add: beta_subst) + apply(simp add: RED_props) + done + then have "r\RED \" using a2 by simp + } + moreover + { assume "\u'. u \\<^isub>\ u' \ r = App (Lam [x].t) u'" + then obtain u' where b1: "u \\<^isub>\ u'" and b2: "r = App (Lam [x].t) u'" by blast + have "App (Lam [x].t) u'\RED \" using ih2 b1 as1 as2 + apply(auto) + apply(drule_tac x="u'" in meta_spec) + apply(simp) + apply(drule meta_mp) + apply(subgoal_tac "CR2 \") + apply(unfold CR2_def)[1] + apply(drule_tac x="u" in spec) + apply(drule_tac x="u'" in spec) + apply(simp) + apply(simp add: RED_props) + apply(simp) + done + then have "r\RED \" using b2 by simp + } + moreover + { assume "r = t[x::=u]" + then have "r\RED \" using as1 as2 by auto + } + ultimately show "r \ RED \" + apply(cases) + apply(auto simp add: lam.inject) + apply(drule beta_abs) + apply(auto simp add: alpha subst_rename) done qed + moreover + have "NEUT (App (Lam [x].t) u)" unfolding NEUT_def by (auto) + ultimately show "App (Lam [x].t) u \ RED \" using RED_props by (simp add: CR3_def) qed - from b_acc show ?thesis by (rule r) qed - -lemma double_acc: - "\accp r a; accp r b; \x z. ((\y. r y x \ P y z) \ (\u. r u z \ P x u)) \ P x z\ \ P a b" -apply(rule_tac r="r" in double_acc_aux) -apply(assumption)+ -apply(blast) -done - -lemma abs_RED: "(\s\RED \. t[x::=s]\RED \)\Lam [x].t\RED (\\\)" -apply(simp) -apply(clarify) -apply(subgoal_tac "termip Beta t")(*1*) -apply(erule rev_mp) -apply(subgoal_tac "u \ RED \")(*A*) -apply(erule rev_mp) -apply(rule_tac a="t" and b="u" in double_acc) -apply(assumption) -apply(subgoal_tac "CR1 \")(*A*) -apply(simp add: CR1_def SN_def) -(*A*) -apply(force simp add: RED_props) -apply(simp) -apply(clarify) -apply(subgoal_tac "CR3 \")(*B*) -apply(simp add: CR3_def) -apply(rotate_tac 6) -apply(drule_tac x="App(Lam[x].xa ) z" in spec) -apply(drule mp) -apply(rule conjI) -apply(force simp add: NEUT_def) -apply(simp add: CR3_RED_def) -apply(clarify) -apply(ind_cases "App(Lam[x].xa) z \\<^isub>\ t'" for xa z t') -apply(auto simp add: lam.inject lam.distinct) -apply(drule beta_abs) -apply(auto) -apply(drule_tac x="t''" in spec) -apply(simp) -apply(drule mp) -apply(clarify) -apply(drule_tac x="s" in bspec) -apply(assumption) -apply(subgoal_tac "xa [ x ::= s ] \\<^isub>\ t'' [ x ::= s ]")(*B*) -apply(subgoal_tac "CR2 \")(*C*) -apply(simp (no_asm_use) add: CR2_def) -apply(blast) -(*C*) -apply(force simp add: RED_props) -(*B*) -apply(force intro!: beta_subst) -apply(assumption) -apply(rotate_tac 3) -apply(drule_tac x="s2" in spec) -apply(subgoal_tac "s2\RED \")(*D*) -apply(simp) -(*D*) -apply(subgoal_tac "CR2 \")(*E*) -apply(simp (no_asm_use) add: CR2_def) -apply(blast) -(*E*) -apply(force simp add: RED_props) -apply(simp add: alpha) -apply(erule disjE) -apply(force) -apply(auto) -apply(simp add: subst_rename) -apply(drule_tac x="z" in bspec) -apply(assumption) -(*B*) -apply(force simp add: RED_props) -(*1*) -apply(drule_tac x="Var x" in bspec) -apply(subgoal_tac "CR3 \")(*2*) -apply(drule CR3_CR4) -apply(simp add: CR4_def) -apply(drule_tac x="Var x" in spec) -apply(drule mp) -apply(rule conjI) -apply(force simp add: NEUT_def) -apply(simp add: NORMAL_def) -apply(clarify) -apply(ind_cases "Var x \\<^isub>\ t'" for t') -apply(auto simp add: lam.inject lam.distinct) -apply(force simp add: RED_props) -apply(simp add: id_subs) -apply(subgoal_tac "CR1 \")(*3*) -apply(simp add: CR1_def SN_def) -(*3*) -apply(force simp add: RED_props) -done +qed abbreviation mapsto :: "(name\lam) list \ name \ lam \ bool" ("_ maps _ to _" [55,55,55] 55) @@ -506,7 +526,7 @@ using fresh \_cond fresh_context by simp then have "\s\RED \. \[a::=s] \ RED \" using fresh by (simp add: psubst_subst) - then have "(Lam [a].(\)) \ RED (\ \ \)" by (simp only: abs_RED) + then have "Lam [a].(\) \ RED (\ \ \)" by (simp only: abs_RED) then show "\<(Lam [a].t)> \ RED (\ \ \)" using fresh by simp qed auto @@ -531,16 +551,15 @@ lemma id_apply: shows "(id \) = t" -apply(nominal_induct t avoiding: \ rule: lam.induct) -apply(auto simp add: id_maps id_fresh) -done +by (nominal_induct t avoiding: \ rule: lam.induct) + (auto simp add: id_maps id_fresh) lemma id_closes: shows "(id \) closes \" apply(auto) apply(simp add: id_maps) apply(subgoal_tac "CR3 T") --"A" -apply(drule CR3_CR4) +apply(drule CR3_implies_CR4) apply(simp add: CR4_def) apply(drule_tac x="Var x" in spec) apply(force simp add: NEUT_def NORMAL_Var)