# HG changeset patch # User urbanc # Date 1180595654 -7200 # Node ID cb1dbe64a4d54587da2cc933ef20a4e23e11ec7b # Parent 1f6b6a7314cfd0c543180814cdc50f87d8cde455 tuned the proof diff -r 1f6b6a7314cf -r cb1dbe64a4d5 src/HOL/Nominal/Examples/SN.thy --- a/src/HOL/Nominal/Examples/SN.thy Thu May 31 01:36:08 2007 +0200 +++ b/src/HOL/Nominal/Examples/SN.thy Thu May 31 09:14:14 2007 +0200 @@ -52,14 +52,15 @@ by (nominal_induct t avoiding: x rule: lam.induct) (simp_all add: fresh_atm) -lemma subst_eqvt[eqvt]: - fixes pi::"name prm" - and t::"lam" - shows "pi\(t[x::=t']) = (pi\t)[(pi\x)::=(pi\t')]" -by (nominal_induct t avoiding: x t' rule: lam.induct) - (perm_simp add: fresh_bij)+ - -inductive2 Beta :: "lam\lam\bool" (" _ \\<^isub>\ _" [80,80] 80) +lemma psubst_subst: + assumes h:"c\\" + shows "(\)[c::=s] = ((c,s)#\)" + using h +by (nominal_induct t avoiding: \ c s rule: lam.induct) + (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh') + +inductive2 + 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)" @@ -71,7 +72,9 @@ nominal_inductive Beta by (simp_all add: abs_fresh fresh_fact') -abbreviation "Beta_star" :: "lam\lam\bool" (" _ \\<^isub>\\<^sup>* _" [80,80] 80) where +abbreviation + "Beta_star" :: "lam\lam\bool" (" _ \\<^isub>\\<^sup>* _" [80,80] 80) +where "t1 \\<^isub>\\<^sup>* t2 \ Beta\<^sup>*\<^sup>* t1 t2" lemma supp_beta: @@ -102,9 +105,8 @@ assumes a: "M \\<^isub>\ M'" shows "M[x::=N]\\<^isub>\ M'[x::=N]" using a -apply(nominal_induct M M' avoiding: x N rule: Beta.strong_induct) -apply(auto simp add: fresh_atm subst_lemma fresh_fact) -done +by (nominal_induct M M' avoiding: x N rule: Beta.strong_induct) + (auto simp add: fresh_atm subst_lemma fresh_fact) section {* types *} @@ -112,7 +114,7 @@ TVar "nat" | TArr "ty" "ty" (infix "\" 200) -lemma perm_ty[simp]: +lemma perm_ty: fixes pi ::"name prm" and \ ::"ty" shows "pi\\ = \" @@ -123,23 +125,29 @@ fixes a ::"name" and \ ::"ty" shows "a\\" - by (simp add: fresh_def supp_def) + by (simp add: fresh_def perm_ty supp_def) + +(* domain of a typing context *) + +fun + "dom_ty" :: "(name\ty) list \ (name list)" +where + "dom_ty [] = []" +| "dom_ty ((x,\)#\) = (x)#(dom_ty \)" + (* valid contexts *) -consts - "dom_ty" :: "(name\ty) list \ (name list)" -primrec - "dom_ty [] = []" - "dom_ty (x#\) = (fst x)#(dom_ty \)" - -inductive2 valid :: "(name\ty) list \ bool" +inductive2 + valid :: "(name\ty) list \ bool" where v1[intro]: "valid []" | v2[intro]: "\valid \;a\\\\ valid ((a,\)#\)" equivariance valid +inductive_cases2 valid_elim[elim]: "valid ((a,\)#\)" + (* typing judgements *) lemma fresh_context: @@ -152,17 +160,8 @@ apply(auto simp add: fresh_prod fresh_list_cons fresh_atm) done -inductive_cases2 valid_elim[elim]: "valid ((a,\)#\)" - -lemma valid_unicity: - assumes a: "valid \" - and b: "(c,\)\set \" - and c: "(c,\)\set \" - shows "\=\" -using a b c -by (induct \) (auto dest!: fresh_context) - -inductive2 typing :: "(name\ty) list\lam\ty\bool" ("_ \ _ : _" [60,60,60] 60) +inductive2 + typing :: "(name\ty) list\lam\ty\bool" ("_ \ _ : _" [60,60,60] 60) where t1[intro]: "\valid \; (a,\)\set \\ \ \ \ Var a : \" | t2[intro]: "\\ \ t1 : \\\; \ \ t2 : \\ \ \ \ App t1 t2 : \" @@ -178,171 +177,6 @@ where "\1 \ \2 \ \a \. (a,\)\set \1 \ (a,\)\set \2" -lemma weakening: - assumes a: "\1 \ t : \" - and b: "valid \2" - and c: "\1 \ \2" - shows "\2 \ t : \" -using a b c -apply(nominal_induct \1 t \ avoiding: \2 rule: typing.strong_induct) -apply(auto | atomize)+ -done - -lemma in_ctxt: - assumes a: "(a,\)\set \" - shows "a\set(dom_ty \)" -using a -by (induct \) (auto) - -lemma free_vars: - assumes a: "\ \ t : \" - shows " (supp t)\set(dom_ty \)" -using a -by (nominal_induct \ t \ rule: typing.strong_induct) - (auto simp add: lam.supp abs_supp supp_atm in_ctxt) - -lemma t1_elim: "\ \ Var a : \ \ valid \ \ (a,\) \ set \" -apply(ind_cases2 "\ \ Var a : \") -apply(auto simp add: lam.inject lam.distinct) -done - -lemma t2_elim: "\ \ App t1 t2 : \ \ \\. (\ \ t1 : \\\ \ \ \ t2 : \)" -apply(ind_cases2 "\ \ App t1 t2 : \") -apply(auto simp add: lam.inject lam.distinct) -done - -lemma t3_elim: "\\ \ Lam [a].t : \;a\\\ \ \\ \'. \=\\\' \ (a,\)#\ \ t : \'" -apply(ind_cases2 "\ \ Lam [a].t : \") -apply(auto simp add: lam.distinct lam.inject alpha) -apply(drule_tac pi="[(a,aa)]::name prm" in typing.eqvt) -apply(simp) -apply(subgoal_tac "([(a,aa)]::name prm)\\ = \")(*A*) -apply(force simp add: calc_atm) -(*A*) -apply(force intro!: perm_fresh_fresh) -done - -lemma typing_valid: - assumes a: "\ \ t : \" - shows "valid \" -using a by (induct, auto) - -lemma ty_subs: - assumes a: "(c,\)#\ \ t1:\" - and b: "\\ t2:\" - shows "\ \ t1[c::=t2]:\" -using a b -proof(nominal_induct t1 avoiding: \ \ \ c t2 rule: lam.induct) - case (Var a) - have a1: "\ \t2:\" by fact - have a2: "(c,\)#\ \ Var a : \" by fact - hence a21: "(a,\)\set((c,\)#\)" and a22: "valid((c,\)#\)" by (auto dest: t1_elim) - from a22 have a23: "valid \" and a24: "c\\" by (auto dest: valid_elim) - from a24 have a25: "\(\\. (c,\)\set \)" by (rule fresh_context) - show "\\(Var a)[c::=t2] : \" - proof (cases "a=c", simp_all) - assume case1: "a=c" - show "\ \ t2:\" using a1 - proof (cases "\=\") - assume "\=\" thus ?thesis using a1 by simp - next - assume a3: "\\\" - show ?thesis - proof (rule ccontr) - from a3 a21 have "(a,\)\set \" by force - with case1 a25 show False by force - qed - qed - next - assume case2: "a\c" - with a21 have a26: "(a,\)\set \" by force - from a23 a26 show "\ \ Var a:\" by force - qed -next - case (App s1 s2) - have ih_s1: "\c \ \ t2 \. ((c,\)#\) \ s1:\ \ \\ t2: \ \ \ \ s1[c::=t2]:\" by fact - have ih_s2: "\c \ \ t2 \. ((c,\)#\) \ s2:\ \ \\ t2: \ \ \ \ s2[c::=t2]:\" by fact - have "((c,\)#\)\App s1 s2 : \" by fact - hence "\\'. (c,\)#\ \s1:\'\\ \ (c,\)#\ \ s2 : \'" by (rule t2_elim) - then obtain \' where "((c,\)#\)\s1:\'\\" and "((c,\)#\)\s2:\'" by blast - moreover - have "\ \t2:\" by fact - ultimately show "\ \ (App s1 s2)[c::=t2] : \" using ih_s1 ih_s2 by (simp, blast) -next - case (Lam a s) - have "a\\" "a\\" "a\\" "a\c" "a\t2" by fact - hence f1: "a\\" and f2: "a\c" and f2': "c\a" and f3: "a\t2" and f4: "a\((c,\)#\)" - by (auto simp add: fresh_atm fresh_prod fresh_list_cons) - have c1: "(c,\)#\ \ Lam [a].s : \" by fact - hence "\\1 \2. \=\1\\2 \ (a,\1)#(c,\)#\ \ s : \2" using f4 by (auto dest: t3_elim) - then obtain \1 \2 where c11: "\=\1\\2" and c12: "((a,\1)#(c,\)#\) \ s : \2" by force - from c12 have "valid ((a,\1)#(c,\)#\)" by (rule typing_valid) - hence ca: "valid \" and cb: "a\\" and cc: "c\\" - by (auto simp add: fresh_list_cons) - from c12 have c14: "(c,\)#(a,\1)#\ \ s : \2" - proof - - have c2: "(a,\1)#(c,\)#\ \ (c,\)#(a,\1)#\" by force - have c3: "valid ((c,\)#(a,\1)#\)" - by (rule v2, rule v2, auto simp add: fresh_list_cons fresh_prod ca cb cc f2' fresh_ty) - from c12 c2 c3 show ?thesis by (force intro: weakening) - qed - assume c8: "\ \ t2 : \" - have c81: "(a,\1)#\ \ t2 :\" - proof - - have c82: "\ \ (a,\1)#\" by force - have c83: "valid ((a,\1)#\)" using f1 ca by force - with c8 c82 c83 show ?thesis by (force intro: weakening) - qed - show "\ \ (Lam [a].s)[c::=t2] : \" - using c11 prems c14 c81 f1 by force -qed - -lemma subject: - assumes a: "t1\\<^isub>\t2" - and b: "\ \ t1:\" - shows "\ \ t2:\" -using a b -proof (nominal_induct t1 t2 avoiding: \ \ rule: Beta.strong_induct) - case (b1 s1 s2 t) --"App-case left" - have ih: "\\ \. \ \ s1:\ \ \ \ s2 : \" by fact - have "\ \ App s1 t : \" by fact - hence "\\. \ \ s1 : \\\ \ \ \ t : \" by (rule t2_elim) - then obtain \ where "\ \ s1 : \\\" and "\ \ t : \" by blast - with ih show "\ \ App s2 t : \" by blast -next - case (b2 s1 s2 t) --"App-case right" - have ih: "\\ \. \ \ s1 : \ \ \ \ s2 : \" by fact - have "\ \ App t s1 : \" by fact - hence "\\. \ \ t : \\\ \ \ \ s1 : \" by (rule t2_elim) - then obtain \ where "\ \ t : \\\" and "\ \ s1 : \" by blast - with ih show "\ \ App t s2 : \" by blast -next - case (b3 s1 s2 a) --"Lam-case" - have fr: "a\\" "a\\" by fact - have ih: "\\ \. \ \ s1 : \ \ \ \ s2 : \" by fact - have "\ \ Lam [a].s1 : \" by fact - with fr have "\\1 \2. \=\1\\2 \ ((a,\1)#\) \ s1 : \2" by (simp add: t3_elim) - then obtain \1 \2 where "\=\1\\2" and "((a,\1)#\) \ s1 : \2" by blast - with ih show "\ \ Lam [a].s2 : \" using fr by blast -next - case (b4 a s2 s1) --"Beta-redex" - have fr: "a\\" by fact - have "\ \ App (Lam [a].s1) s2 : \" by fact - hence "\\. (\ \ (Lam [a].s1) : \\\ \ \ \ s2 : \)" by (simp add: t2_elim) - then obtain \ where a1: "\ \ (Lam [a].s1) : \\\" and a2: "\ \ s2 : \" by blast - from a1 have "((a,\)#\) \ s1 : \" using fr by (auto dest!: t3_elim simp add: ty.inject) - with a2 show "\ \ s1[a::=s2] : \" by (simp add: ty_subs) -qed - -lemma subject_automatic: - assumes a: "t1\\<^isub>\t2" - and b: "\ \ t1:\" - shows "\ \ t2:\" -using a b -apply(nominal_induct t1 t2 avoiding: \ \ rule: Beta.strong_induct) -apply(auto dest!: t2_elim t3_elim intro: ty_subs simp add: ty.inject) -done - subsection {* some facts about beta *} constdefs @@ -391,7 +225,8 @@ "NEUT t \ (\a. t=Var a)\(\t1 t2. t=App t1 t2)" (* a slight hack to get the first element of applications *) -inductive2 FST :: "lam\lam\bool" (" _ \ _" [80,80] 80) +inductive2 + FST :: "lam\lam\bool" (" _ \ _" [80,80] 80) where fst[intro!]: "(App t s) \ t" @@ -647,14 +482,6 @@ apply(force simp add: RED_props) done -lemma psubst_subst: - assumes h:"c\\" - shows "(\)[c::=s] = ((c,s)#\)" - using h -by (nominal_induct t avoiding: \ c s rule: lam.induct) - (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh') - - abbreviation mapsto :: "(name\lam) list \ name \ lam \ bool" ("_ maps _ to _" [55,55,55] 55) where @@ -670,61 +497,48 @@ and b: "\ closes \" shows "\ \ RED \" using a b -proof(nominal_induct t avoiding: \ \ \ rule: lam.induct) - case (Lam a t) --"lambda case" - have ih: "\\ \ \. \ \ t : \ \ \ closes \ \ \ \ RED \" - and \_cond: "\ closes \" - and fresh: "a\\" "a\\" - and "\ \ Lam [a].t:\" by fact - hence "\\1 \2. \=\1\\2 \ ((a,\1)#\)\t:\2" using t3_elim fresh by simp - then obtain \1 \2 where \_inst: "\=\1\\2" and typing: "((a,\1)#\)\t:\2" by blast - from ih have "\s\RED \1. \[a::=s] \ RED \2" using fresh typing \_cond - by (force dest: fresh_context simp add: psubst_subst) - hence "(Lam [a].(\)) \ RED (\1 \ \2)" by (simp only: abs_RED) - thus "\<(Lam [a].t)> \ RED \" using fresh \_inst by simp -qed (force dest!: t1_elim t2_elim)+ +proof(nominal_induct avoiding: \ rule: typing.strong_induct) + case (t3 a \ \ t \ \) --"lambda case" + have ih: "\\. \ closes ((a,\)#\) \ \ \ RED \" by fact + have \_cond: "\ closes \" by fact + have fresh: "a\\" "a\\" by fact + from ih have "\s\RED \. ((a,s)#\) \ RED \" + 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 show "\<(Lam [a].t)> \ RED (\ \ \)" using fresh by simp +qed auto -(* identity substitution generated from a context \ *) -consts +section {* identity substitution generated from a context \ *} +fun "id" :: "(name\ty) list \ (name\lam) list" -primrec +where "id [] = []" - "id (x#\) = ((fst x),Var (fst x))#(id \)" +| "id ((x,\)#\) = (x,Var x)#(id \)" -lemma id_var: - shows "(id \) maps a to Var a" -apply(induct \, auto) -done +lemma id_maps: + shows "(id \) maps a to (Var a)" +by (induct \) (auto) lemma id_fresh: fixes a::"name" assumes a: "a\\" shows "a\(id \)" using a -apply(induct \) -apply(auto simp add: fresh_list_nil fresh_list_cons fresh_prod) -done +by (induct \) + (auto simp add: fresh_list_nil fresh_list_cons) lemma id_apply: shows "(id \) = t" apply(nominal_induct t avoiding: \ rule: lam.induct) -apply(auto) -apply(rule id_var) -apply(drule id_fresh)+ -apply(simp) +apply(auto simp add: id_maps id_fresh) done -lemma id_mem: - assumes a: "(a,\)\set \" - shows "lookup (id \) a = Var a" -using a -apply(induct \, auto) -done - -lemma id_prop: +lemma id_closes: shows "(id \) closes \" apply(auto) -apply(simp add: id_mem) +apply(simp add: id_maps) apply(subgoal_tac "CR3 T") --"A" apply(drule CR3_CR4) apply(simp add: CR4_def) @@ -735,19 +549,19 @@ done lemma typing_implies_RED: - assumes a: "\\t:\" + assumes a: "\ \ t : \" shows "t \ RED \" proof - have "(id \)\RED \" proof - - have "(id \) closes \" by (rule id_prop) + have "(id \) closes \" by (rule id_closes) with a show ?thesis by (rule all_RED) qed thus"t \ RED \" by (simp add: id_apply) qed lemma typing_implies_SN: - assumes a: "\\t:\" + assumes a: "\ \ t : \" shows "SN(t)" proof - from a have "t \ RED \" by (rule typing_implies_RED)