# HG changeset patch # User urbanc # Date 1223873665 -7200 # Node ID e1659c30f48d6d18afdfaeab6fb51da575aee7e0 # Parent 3caee0cd91d882f9c6ca7dcb3e9e13c4e1ceba38 tuned diff -r 3caee0cd91d8 -r e1659c30f48d src/HOL/Nominal/Examples/SOS.thy --- a/src/HOL/Nominal/Examples/SOS.thy Sat Oct 11 03:54:34 2008 +0200 +++ b/src/HOL/Nominal/Examples/SOS.thy Mon Oct 13 06:54:25 2008 +0200 @@ -12,7 +12,7 @@ (* Christian Urban. *) theory SOS - imports "../Nominal" + imports "Nominal" begin atom_decl name @@ -43,8 +43,6 @@ lemma lookup_eqvt[eqvt]: fixes pi::"name prm" - and \::"(name\trm) list" - and X::"name" shows "pi\(lookup \ X) = lookup (pi\\) (pi\X)" by (induct \) (auto simp add: eqvts) @@ -63,6 +61,7 @@ (auto simp add: fresh_list_cons fresh_prod fresh_atm) (* parallel substitution *) + consts psubst :: "(name\trm) list \ trm \ trm" ("_<_>" [95,95] 105) @@ -111,20 +110,9 @@ lemma fresh_subst: fixes z::"name" - and t\<^isub>1::"trm" - and t2::"trm" - assumes a: "z\t\<^isub>1" "z\t\<^isub>2" - shows "z\t\<^isub>1[y::=t\<^isub>2]" -using a -by (nominal_induct t\<^isub>1 avoiding: z y t\<^isub>2 rule: trm.strong_induct) - (auto simp add: abs_fresh fresh_atm) - -lemma fresh_subst': - assumes "x\e'" - shows "x\e[x::=e']" - using assms -by (nominal_induct e avoiding: x e' rule: trm.strong_induct) - (auto simp add: fresh_atm abs_fresh fresh_nat) + shows "\z\s; (z=y \ z\t)\ \ z\t[y::=s]" +by (nominal_induct t avoiding: z y s rule: trm.strong_induct) + (auto simp add: abs_fresh fresh_prod fresh_atm) lemma forget: assumes a: "x\e" @@ -151,37 +139,26 @@ equivariance valid inductive_cases - valid_cons_inv_auto[elim]: "valid ((x,T)#\)" + valid_elim[elim]: "valid ((x,T)#\)" -lemma type_unicity_in_context: - assumes asm1: "(x,t\<^isub>2) \ set ((x,t\<^isub>1)#\)" - and asm2: "valid ((x,t\<^isub>1)#\)" - shows "t\<^isub>1=t\<^isub>2" -proof - - from asm2 have "x\\" by (cases, auto) - then have "(x,t\<^isub>2) \ set \" - by (induct \) (auto simp add: fresh_list_cons fresh_prod fresh_atm) - then have "(x,t\<^isub>2) = (x,t\<^isub>1)" using asm1 by auto - then show "t\<^isub>1 = t\<^isub>2" by auto -qed +lemma valid_insert: + assumes a: "valid (\@[(x,T)]@\)" + shows "valid (\ @ \)" +using a +by (induct \) + (auto simp add: fresh_list_append fresh_list_cons elim!: valid_elim) -lemma case_distinction_on_context: - fixes \::"(name\ty) list" - assumes asm1: "valid ((m,t)#\)" - and asm2: "(n,U) \ set ((m,T)#\)" - shows "(n,U) = (m,T) \ ((n,U) \ set \ \ n \ m)" -proof - - from asm2 have "(n,U) \ set [(m,T)] \ (n,U) \ set \" by auto - moreover - { assume eq: "m=n" - assume "(n,U) \ set \" - then have "\ n\\" - by (induct \) (auto simp add: fresh_list_cons fresh_prod fresh_atm) - moreover have "m\\" using asm1 by auto - ultimately have False using eq by auto - } - ultimately show ?thesis by auto -qed +lemma fresh_set: + shows "y\xs = (\x\set xs. y\x)" +by (induct xs) (simp_all add: fresh_list_nil fresh_list_cons) + +lemma context_unique: + assumes a1: "valid \" + and a2: "(x,T) \ set \" + and a3: "(x,U) \ set \" + shows "T = U" +using a1 a2 a3 +by (induct) (auto simp add: fresh_set fresh_prod fresh_atm) text {* Typing Relation *} @@ -200,8 +177,14 @@ lemma typing_implies_valid: assumes a: "\ \ t : T" shows "valid \" - using a - by (induct) (auto) +using a by (induct) (auto) + + +lemma t_App_elim: + assumes a: "\ \ App t1 t2 : T" + obtains T' where "\ \ t1 : T' \ T" and "\ \ t2 : T'" +using a +by (cases) (auto simp add: trm.inject) lemma t_Lam_elim: assumes a: "\ \ Lam [x].t : T" "x\\" @@ -233,82 +216,35 @@ with vc show "\\<^isub>2 \ Lam [x].t : T\<^isub>1\T\<^isub>2" by auto qed (auto) -lemma context_exchange: - assumes a: "(x\<^isub>1,T\<^isub>1)#(x\<^isub>2,T\<^isub>2)#\ \ e : T" - shows "(x\<^isub>2,T\<^isub>2)#(x\<^isub>1,T\<^isub>1)#\ \ e : T" -proof - - from a have "valid ((x\<^isub>1,T\<^isub>1)#(x\<^isub>2,T\<^isub>2)#\)" by (simp add: typing_implies_valid) - then have "x\<^isub>1\x\<^isub>2" "x\<^isub>1\\" "x\<^isub>2\\" "valid \" - by (auto simp: fresh_list_cons fresh_atm[symmetric]) - then have "valid ((x\<^isub>2,T\<^isub>2)#(x\<^isub>1,T\<^isub>1)#\)" - by (auto simp: fresh_list_cons fresh_atm fresh_ty) - moreover - have "(x\<^isub>1,T\<^isub>1)#(x\<^isub>2,T\<^isub>2)#\ \ (x\<^isub>2,T\<^isub>2)#(x\<^isub>1,T\<^isub>1)#\" by auto - ultimately show "(x\<^isub>2,T\<^isub>2)#(x\<^isub>1,T\<^isub>1)#\ \ e : T" using a by (auto intro: weakening) -qed +lemma type_substitutivity_aux: + assumes a: "(\@[(x,T')]@\) \ e : T" + and b: "\ \ e' : T'" + shows "(\@\) \ e[x::=e'] : T" +using a b +proof (nominal_induct \\"\@[(x,T')]@\" e T avoiding: e' \ rule: typing.strong_induct) + case (t_Var \' y T e' \) + then have a1: "valid (\@[(x,T')]@\)" + and a2: "(y,T) \ set (\@[(x,T')]@\)" + and a3: "\ \ e' : T'" by simp_all + from a1 have a4: "valid (\@\)" by (rule valid_insert) + { assume eq: "x=y" + from a1 a2 have "T=T'" using eq by (auto intro: context_unique) + with a3 have "\@\ \ Var y[x::=e'] : T" using eq a4 by (auto intro: weakening) + } + moreover + { assume ineq: "x\y" + from a2 have "(y,T) \ set (\@\)" using ineq by simp + then have "\@\ \ Var y[x::=e'] : T" using ineq a4 by auto + } + ultimately show "\@\ \ Var y[x::=e'] : T" by blast +qed (force simp add: fresh_list_append fresh_list_cons)+ -lemma typing_var_unicity: - assumes a: "(x,T\<^isub>1)#\ \ Var x : T\<^isub>2" - shows "T\<^isub>1=T\<^isub>2" -proof - - have "(x,T\<^isub>2) \ set ((x,T\<^isub>1)#\)" using a - by (cases) (auto simp add: trm.inject) - moreover - have "valid ((x,T\<^isub>1)#\)" using a by (simp add: typing_implies_valid) - ultimately show "T\<^isub>1=T\<^isub>2" by (simp only: type_unicity_in_context) -qed - -lemma typing_substitution: - fixes \::"(name \ ty) list" - assumes "(x,T')#\ \ e : T" - and "\ \ e': T'" +corollary type_substitutivity: + assumes a: "(x,T')#\ \ e : T" + and b: "\ \ e' : T'" shows "\ \ e[x::=e'] : T" - using assms -proof (nominal_induct e avoiding: \ e' x arbitrary: T rule: trm.strong_induct) - case (Var y \ e' x T) - have h1: "(x,T')#\ \ Var y : T" by fact - have h2: "\ \ e' : T'" by fact - show "\ \ (Var y)[x::=e'] : T" - proof (cases "x=y") - case True - assume as: "x=y" - then have "T=T'" using h1 typing_var_unicity by auto - then show "\ \ (Var y)[x::=e'] : T" using as h2 by simp - next - case False - assume as: "x\y" - have "(y,T) \ set ((x,T')#\)" using h1 by (cases) (auto simp add: trm.inject) - then have "(y,T) \ set \" using as by auto - moreover - have "valid \" using h2 by (simp only: typing_implies_valid) - ultimately show "\ \ (Var y)[x::=e'] : T" using as by (simp add: t_Var) - qed -next - case (Lam y t \ e' x T) - have vc: "y\\" "y\x" "y\e'" by fact - have pr1: "\ \ e' : T'" by fact - have pr2: "(x,T')#\ \ Lam [y].t : T" by fact - then obtain T\<^isub>1 T\<^isub>2 where pr2': "(y,T\<^isub>1)#(x,T')#\ \ t : T\<^isub>2" and eq: "T = T\<^isub>1\T\<^isub>2" - using vc by (auto elim: t_Lam_elim simp add: fresh_list_cons fresh_ty) - then have pr2'':"(x,T')#(y,T\<^isub>1)#\ \ t : T\<^isub>2" by (simp add: context_exchange) - have ih: "\(x,T')#(y,T\<^isub>1)#\ \ t : T\<^isub>2; (y,T\<^isub>1)#\ \ e' : T'\ \ (y,T\<^isub>1)#\ \ t[x::=e'] : T\<^isub>2" by fact - have "valid \" using pr1 by (simp add: typing_implies_valid) - then have "valid ((y,T\<^isub>1)#\)" using vc by auto - then have "(y,T\<^isub>1)#\ \ e' : T'" using pr1 by (simp add: weakening) - then have "(y,T\<^isub>1)#\ \ t[x::=e'] : T\<^isub>2" using ih pr2'' by simp - then have "\ \ Lam [y].(t[x::=e']) : T\<^isub>1\T\<^isub>2" using vc by auto - then show "\ \ (Lam [y].t)[x::=e'] : T" using vc eq by simp -next - case (App e1 e2 \ e' x T) - have "(x,T')#\ \ App e1 e2 : T" by fact - then obtain Tn where a1: "(x,T')#\ \ e1 : Tn \ T" - and a2: "(x,T')#\ \ e2 : Tn" - by (cases) (auto simp add: trm.inject) - have a3: "\ \ e' : T'" by fact - have ih1: "\(x,T')#\ \ e1 : Tn\T; \ \ e' : T'\ \ \ \ e1[x::=e'] : Tn\T" by fact - have ih2: "\(x,T')#\ \ e2 : Tn; \ \ e' : T'\ \ \ \ e2[x::=e'] : Tn" by fact - then show "\ \ (App e1 e2)[x::=e'] : T" using a1 a2 a3 ih1 ih2 by auto -qed +using a b type_substitutivity_aux[where \="[]"] +by (auto) text {* Values *} inductive @@ -368,9 +304,16 @@ by (auto elim: t_Lam_elim simp add: ty.inject) moreover have "\ \ e\<^isub>2': T'" using ih2 a2 by simp - ultimately have "\ \ e[x::=e\<^isub>2'] : T" by (simp add: typing_substitution) + ultimately have "\ \ e[x::=e\<^isub>2'] : T" by (simp add: type_substitutivity) thus "\ \ e' : T" using ih3 by simp -qed (blast)+ +qed (blast) + +lemma subject_reduction2: + assumes a: "e \ e'" and b: "\ \ e : T" + shows "\ \ e' : T" + using a b +by (nominal_induct avoiding: \ T rule: big.strong_induct) + (force elim: t_App_elim t_Lam_elim simp add: ty.inject type_substitutivity)+ lemma unicity_of_evaluation: assumes a: "e \ e\<^isub>1" @@ -390,8 +333,7 @@ have vc: "x\e\<^isub>1" "x\e\<^isub>2" "x\t\<^isub>2" by fact then have "x\App e\<^isub>1 e\<^isub>2" by auto from app vc obtain f\<^isub>1 f\<^isub>2 where x1: "e\<^isub>1 \ Lam [x]. f\<^isub>1" and x2: "e\<^isub>2 \ f\<^isub>2" and x3: "f\<^isub>1[x::=f\<^isub>2] \ t\<^isub>2" - by (cases rule: big.strong_cases[where x="x" and xa="x"]) - (auto simp add: trm.inject) + by (auto elim!: b_App_elim) then have "Lam [x]. f\<^isub>1 = Lam [x]. e\<^isub>1'" using ih1 by simp then have "f\<^isub>1 = e\<^isub>1'" by (auto simp add: trm.inject alpha) @@ -402,9 +344,9 @@ qed lemma reduces_evaluates_to_values: - assumes h:"t \ t'" + assumes h: "t \ t'" shows "val t'" - using h by (induct) (auto) +using h by (induct) (auto) (* Valuation *) consts @@ -415,7 +357,6 @@ "V (T\<^isub>1 \ T\<^isub>2) = {Lam [x].e | x e. \ v \ (V T\<^isub>1). \ v'. e[x::=v] \ v' \ v' \ V T\<^isub>2}" by (rule TrueI)+ -(* can go with strong inversion rules *) lemma V_eqvt: fixes pi::"name prm" assumes a: "x\V T" @@ -439,13 +380,13 @@ lemma V_arrow_elim_weak: assumes h:"u \ V (T\<^isub>1 \ T\<^isub>2)" - obtains a t where "u = Lam[a].t" and "\ v \ (V T\<^isub>1). \ v'. t[a::=v] \ v' \ v' \ V T\<^isub>2" + obtains a t where "u = Lam [a].t" and "\ v \ (V T\<^isub>1). \ v'. t[a::=v] \ v' \ v' \ V T\<^isub>2" using h by (auto) lemma V_arrow_elim_strong: fixes c::"'a::fs_name" assumes h: "u \ V (T\<^isub>1 \ T\<^isub>2)" - obtains a t where "a\c" "u = Lam[a].t" "\v \ (V T\<^isub>1). \ v'. t[a::=v] \ v' \ v' \ V T\<^isub>2" + obtains a t where "a\c" "u = Lam [a].t" "\v \ (V T\<^isub>1). \ v'. t[a::=v] \ v' \ v' \ V T\<^isub>2" using h apply - apply(erule V_arrow_elim_weak) @@ -500,6 +441,24 @@ where "\ Vcloses \ \ \x T. (x,T) \ set \ \ (\v. \ maps x to v \ v \ V T)" +lemma case_distinction_on_context: + fixes \::"(name\ty) list" + assumes asm1: "valid ((m,t)#\)" + and asm2: "(n,U) \ set ((m,T)#\)" + shows "(n,U) = (m,T) \ ((n,U) \ set \ \ n \ m)" +proof - + from asm2 have "(n,U) \ set [(m,T)] \ (n,U) \ set \" by auto + moreover + { assume eq: "m=n" + assume "(n,U) \ set \" + then have "\ n\\" + by (induct \) (auto simp add: fresh_list_cons fresh_prod fresh_atm) + moreover have "m\\" using asm1 by auto + ultimately have False using eq by auto + } + ultimately show ?thesis by auto +qed + lemma monotonicity: fixes m::"name" fixes \::"(name \ trm) list" @@ -533,23 +492,22 @@ using h2 h1 proof(nominal_induct e avoiding: \ \ arbitrary: T rule: trm.strong_induct) case (App e\<^isub>1 e\<^isub>2 \ \ T) - have ih\<^isub>1:"\\ \ T. \\ Vcloses \; \ \ e\<^isub>1 : T\ \ \v. \1> \ v \ v \ V T" by fact - have ih\<^isub>2:"\\ \ T. \\ Vcloses \; \ \ e\<^isub>2 : T\ \ \v. \2> \ v \ v \ V T" by fact - have as\<^isub>1:"\ Vcloses \" by fact + have ih\<^isub>1: "\\ \ T. \\ Vcloses \; \ \ e\<^isub>1 : T\ \ \v. \1> \ v \ v \ V T" by fact + have ih\<^isub>2: "\\ \ T. \\ Vcloses \; \ \ e\<^isub>2 : T\ \ \v. \2> \ v \ v \ V T" by fact + have as\<^isub>1: "\ Vcloses \" by fact have as\<^isub>2: "\ \ App e\<^isub>1 e\<^isub>2 : T" by fact - then obtain T' where "\ \ e\<^isub>1 : T' \ T" and "\ \ e\<^isub>2 : T'" - by (cases) (auto simp add: trm.inject) + then obtain T' where "\ \ e\<^isub>1 : T' \ T" and "\ \ e\<^isub>2 : T'" by (auto elim: t_App_elim) then obtain v\<^isub>1 v\<^isub>2 where "(i)": "\1> \ v\<^isub>1" "v\<^isub>1 \ V (T' \ T)" - and "(ii)":"\2> \ v\<^isub>2" "v\<^isub>2 \ V T'" using ih\<^isub>1 ih\<^isub>2 as\<^isub>1 by blast + and "(ii)": "\2> \ v\<^isub>2" "v\<^isub>2 \ V T'" using ih\<^isub>1 ih\<^isub>2 as\<^isub>1 by blast from "(i)" obtain x e' - where "v\<^isub>1 = Lam[x].e'" + where "v\<^isub>1 = Lam [x].e'" and "(iii)": "(\v \ (V T').\ v'. e'[x::=v] \ v' \ v' \ V T)" and "(iv)": "\1> \ Lam [x].e'" and fr: "x\(\,e\<^isub>1,e\<^isub>2)" by (blast elim: V_arrow_elim_strong) from fr have fr\<^isub>1: "x\\1>" and fr\<^isub>2: "x\\2>" by (simp_all add: fresh_psubst) from "(ii)" "(iii)" obtain v\<^isub>3 where "(v)": "e'[x::=v\<^isub>2] \ v\<^isub>3" "v\<^isub>3 \ V T" by auto from fr\<^isub>2 "(ii)" have "x\v\<^isub>2" by (simp add: big_preserves_fresh) - then have "x\e'[x::=v\<^isub>2]" by (simp add: fresh_subst') + then have "x\e'[x::=v\<^isub>2]" by (simp add: fresh_subst) then have fr\<^isub>3: "x\v\<^isub>3" using "(v)" by (simp add: big_preserves_fresh) from fr\<^isub>1 fr\<^isub>2 fr\<^isub>3 have "x\(\1>,\2>,v\<^isub>3)" by simp with "(iv)" "(ii)" "(v)" have "App (\1>) (\2>) \ v\<^isub>3" by auto @@ -562,8 +520,7 @@ have fs: "x\\" "x\\" by fact from as\<^isub>2 fs obtain T\<^isub>1 T\<^isub>2 where "(i)": "(x,T\<^isub>1)#\ \ e:T\<^isub>2" and "(ii)": "T = T\<^isub>1 \ T\<^isub>2" using fs - by (cases rule: typing.strong_cases[where x="x"]) - (auto simp add: trm.inject alpha abs_fresh fresh_ty) + by (auto elim: t_Lam_elim) from "(i)" have "(iii)": "valid ((x,T\<^isub>1)#\)" by (simp add: typing_implies_valid) have "\v \ (V T\<^isub>1). \v'. (\)[x::=v] \ v' \ v' \ V T\<^isub>2" proof @@ -575,7 +532,7 @@ then show "\v'. \[x::=v] \ v' \ v' \ V T\<^isub>2" by auto qed then have "Lam[x].\ \ V (T\<^isub>1 \ T\<^isub>2)" by auto - then have "\ \ Lam[x].\ \ Lam[x].\ \ V (T\<^isub>1\T\<^isub>2)" using fs by auto + then have "\ \ Lam [x].\ \ Lam [x].\ \ V (T\<^isub>1\T\<^isub>2)" using fs by auto thus "\v. \ \ v \ v \ V T" using "(ii)" by auto next case (Var x \ \ T)