# HG changeset patch # User Christian Urban # Date 1248269298 -7200 # Node ID 3b260527fc112425d5914145978038f219726842 # Parent 29aed5725acbb9842a9bf40563a6d703046c1b28 tuned proofs and added some lemmas diff -r 29aed5725acb -r 3b260527fc11 src/HOL/Nominal/Examples/W.thy --- a/src/HOL/Nominal/Examples/W.thy Wed Jul 22 11:48:04 2009 +0200 +++ b/src/HOL/Nominal/Examples/W.thy Wed Jul 22 15:28:18 2009 +0200 @@ -25,6 +25,15 @@ using a by (induct Xs) (auto simp add: fresh_list_nil fresh_list_cons fresh_atm) +lemma difference_supset: + fixes xs::"'a list" + and ys::"'a list" + and zs::"'a list" + assumes asm: "set xs \ set ys" + shows "xs - ys = []" +using asm +by (induct xs) (auto) + nominal_datatype ty = TVar "tvar" | Fun "ty" "ty" ("_\_" [100,100] 100) @@ -49,65 +58,44 @@ text {* free type variables *} -class ftv = - fixes ftv :: "'a \ tvar list" +consts ftv :: "'a \ tvar list" -instantiation * :: (ftv, ftv) ftv +overloading + ftv_prod \ "ftv :: ('a \ 'b) \ tvar list" + ftv_tvar \ "ftv :: tvar \ tvar list" + ftv_var \ "ftv :: var \ tvar list" + ftv_list \ "ftv :: 'a list \ tvar list" + ftv_ty \ "ftv :: ty \ tvar list" begin -primrec ftv_prod +primrec + ftv_prod where - "ftv (x::'a::ftv, y::'b::ftv) = (ftv x)@(ftv y)" - -instance .. - -end - -instantiation tvar :: ftv -begin - -definition - ftv_of_tvar[simp]: "ftv X \ [(X::tvar)]" - -instance .. - -end - -instantiation var :: ftv -begin + "ftv_prod (x, y) = (ftv x) @ (ftv y)" definition - ftv_of_var[simp]: "ftv (x::var) \ []" - -instance .. - -end + ftv_tvar :: "tvar \ tvar list" +where +[simp]: "ftv_tvar X \ [(X::tvar)]" -instantiation list :: (ftv) ftv -begin - -primrec ftv_list +definition + ftv_var :: "var \ tvar list" where - "ftv [] = []" -| "ftv (x#xs) = (ftv x)@(ftv xs)" +[simp]: "ftv_var x \ []" -instance .. - -end - -(* free type-variables of types *) +primrec + ftv_list +where + "ftv_list [] = []" +| "ftv_list (x#xs) = (ftv x)@(ftv_list xs)" -instantiation ty :: ftv -begin - -nominal_primrec ftv_ty +nominal_primrec + ftv_ty :: "ty \ tvar list" where - "ftv (TVar X) = [X]" -| "ftv (T\<^isub>1\T\<^isub>2) = (ftv T\<^isub>1)@(ftv T\<^isub>2)" + "ftv_ty (TVar X) = [X]" +| "ftv_ty (T1 \T2) = (ftv_ty T1) @ (ftv_ty T2)" by (rule TrueI)+ -instance .. - end lemma ftv_ty_eqvt[eqvt]: @@ -117,13 +105,15 @@ by (nominal_induct T rule: ty.strong_induct) (perm_simp add: append_eqvt)+ -instantiation tyS :: ftv +overloading + ftv_tyS \ "ftv :: tyS \ tvar list" begin -nominal_primrec ftv_tyS +nominal_primrec + ftv_tyS :: "tyS \ tvar list" where - "ftv (Ty T) = ftv T" -| "ftv (\[X].S) = (ftv S) - [X]" + "ftv_tyS (Ty T) = ((ftv (T::ty))::tvar list)" +| "ftv_tyS (\[X].S) = (ftv_tyS S) - [X]" apply(finite_guess add: ftv_ty_eqvt fs_tvar1)+ apply(rule TrueI)+ apply(rule difference_fresh) @@ -131,8 +121,6 @@ apply(fresh_guess add: ftv_ty_eqvt fs_tvar1)+ done -instance .. - end lemma ftv_tyS_eqvt[eqvt]: @@ -174,6 +162,8 @@ shows "pi\(gen T Xs) = gen (pi\T) (pi\Xs)" by (induct Xs) (simp_all add: eqvts) + + abbreviation close :: "Ctxt \ ty \ tyS" where @@ -188,11 +178,11 @@ types Subst = "(tvar\ty) list" -class psubst = - fixes psubst :: "Subst \ 'a \ 'a" ("_<_>" [100,60] 120) +consts + psubst :: "Subst \ 'a \ 'a" ("_<_>" [100,60] 120) abbreviation - subst :: "'a::psubst \ tvar \ ty \ 'a" ("_[_::=_]" [100,100,100] 100) + subst :: "'a \ tvar \ ty \ 'a" ("_[_::=_]" [100,100,100] 100) where "smth[X::=T] \ ([(X,T)])" @@ -207,34 +197,163 @@ shows "pi\(lookup \ X) = lookup (pi\\) (pi\X)" by (induct \) (auto simp add: eqvts) -instantiation ty :: psubst +lemma lookup_fresh: + fixes X::"tvar" + assumes a: "X\\" + shows "lookup \ X = TVar X" +using a +by (induct \) + (auto simp add: fresh_list_cons fresh_prod fresh_atm) + +overloading + psubst_ty \ "psubst :: Subst \ ty \ ty" begin -nominal_primrec psubst_ty +nominal_primrec + psubst_ty where "\ = lookup \ X" | "\1 \ T\<^isub>2> = (\1>) \ (\2>)" by (rule TrueI)+ -instance .. - end lemma psubst_ty_eqvt[eqvt]: - fixes pi1::"tvar prm" + fixes pi::"tvar prm" and \::"Subst" and T::"ty" - shows "pi1\(\) = (pi1\\)<(pi1\T)>" + shows "pi\(\) = (pi\\)<(pi\T)>" by (induct T rule: ty.induct) (simp_all add: eqvts) -text {* instance *} -inductive - general :: "ty \ tyS \ bool"("_ \ _" [50,51] 50) +overloading + psubst_tyS \ "psubst :: Subst \ tyS \ tyS" +begin + +nominal_primrec + psubst_tyS :: "Subst \ tyS \ tyS" +where + "\<(Ty T)> = Ty (\)" +| "X\\ \ \<(\[X].S)> = \[X].(\)" +apply(finite_guess add: psubst_ty_eqvt fs_tvar1)+ +apply(rule TrueI)+ +apply(simp add: abs_fresh) +apply(fresh_guess add: psubst_ty_eqvt fs_tvar1)+ +done + +end + +overloading + psubst_Ctxt \ "psubst :: Subst \ Ctxt \ Ctxt" +begin + +fun + psubst_Ctxt :: "Subst \ Ctxt \ Ctxt" where - G_Ty[intro]: "T \ (Ty T)" -| G_All[intro]: "\X\T'; (T::ty) \ S\ \ T[X::=T'] \ \[X].S" + "psubst_Ctxt \ [] = []" +| "psubst_Ctxt \ ((x,S)#\) = (x,\)#(psubst_Ctxt \ \)" + +end + +lemma fresh_lookup: + fixes X::"tvar" + and \::"Subst" + and Y::"tvar" + assumes asms: "X\Y" "X\\" + shows "X\(lookup \ Y)" + using asms + by (induct \) + (auto simp add: fresh_list_cons fresh_prod fresh_atm) + +lemma fresh_psubst_ty: + fixes X::"tvar" + and \::"Subst" + and T::"ty" + assumes asms: "X\\" "X\T" + shows "X\\" + using asms + by (nominal_induct T rule: ty.strong_induct) + (auto simp add: fresh_list_append fresh_list_cons fresh_prod fresh_lookup) + +lemma fresh_psubst_tyS: + fixes X::"tvar" + and \::"Subst" + and S::"tyS" + assumes asms: "X\\" "X\S" + shows "X\\" + using asms + by (nominal_induct S avoiding: \ X rule: tyS.strong_induct) + (auto simp add: fresh_psubst_ty abs_fresh) + +lemma fresh_psubst_Ctxt: + fixes X::"tvar" + and \::"Subst" + and \::"Ctxt" + assumes asms: "X\\" "X\\" + shows "X\\<\>" +using asms +by (induct \) + (auto simp add: fresh_psubst_tyS fresh_list_cons) -equivariance general[tvar] +lemma subst_freshfact2_ty: + fixes X::"tvar" + and Y::"tvar" + and T::"ty" + assumes asms: "X\S" + shows "X\T[X::=S]" + using asms +by (nominal_induct T rule: ty.strong_induct) + (auto simp add: fresh_atm) + +text {* instance of a type scheme *} +inductive + inst :: "ty \ tyS \ bool"("_ \ _" [50,51] 50) +where + I_Ty[intro]: "T \ (Ty T)" +| I_All[intro]: "\X\T'; T \ S\ \ T[X::=T'] \ \[X].S" + +equivariance inst[tvar] + +nominal_inductive inst + by (simp_all add: abs_fresh subst_freshfact2_ty) + +lemma subst_forget_ty: + fixes T::"ty" + and X::"tvar" + assumes a: "X\T" + shows "T[X::=S] = T" + using a + by (nominal_induct T rule: ty.strong_induct) + (auto simp add: fresh_atm) + +lemma psubst_ty_lemma: + fixes \::"Subst" + and X::"tvar" + and T'::"ty" + and T::"ty" + assumes a: "X\\" + shows "\ = (\)[X::=\]" +using a +apply(nominal_induct T avoiding: \ X T' rule: ty.strong_induct) +apply(auto simp add: ty.inject lookup_fresh) +apply(rule sym) +apply(rule subst_forget_ty) +apply(rule fresh_lookup) +apply(simp_all add: fresh_atm) +done + +lemma general_preserved: + fixes \::"Subst" + assumes a: "T \ S" + shows "\ \ \" +using a +apply(nominal_induct T S avoiding: \ rule: inst.strong_induct) +apply(auto)[1] +apply(simp add: psubst_ty_lemma) +apply(rule_tac I_All) +apply(simp add: fresh_psubst_ty) +apply(simp) +done + text{* typing judgements *} inductive @@ -243,46 +362,64 @@ T_VAR[intro]: "\valid \; (x,S)\set \; T \ S\\ \ \ Var x : T" | T_APP[intro]: "\\ \ t\<^isub>1 : T\<^isub>1\T\<^isub>2; \ \ t\<^isub>2 : T\<^isub>1\\ \ \ App t\<^isub>1 t\<^isub>2 : T\<^isub>2" | T_LAM[intro]: "\x\\;((x,Ty T\<^isub>1)#\) \ t : T\<^isub>2\ \ \ \ Lam [x].t : T\<^isub>1\T\<^isub>2" -| T_LET[intro]: "\x\\; \ \ t\<^isub>1 : T\<^isub>1; ((x,close \ T\<^isub>1)#\) \ t\<^isub>2 : T\<^isub>2; set (ftv T\<^isub>1 - ftv \) \* T\<^isub>2\ \ \ \ Let x be t\<^isub>1 in t\<^isub>2 : T\<^isub>2" - -lemma fresh_star_tvar_eqvt[eqvt]: - "(pi::tvar prm) \ ((Xs::tvar set) \* (x::'a::{cp_tvar_tvar,pt_tvar})) = (pi \ Xs) \* (pi \ x)" - by (simp only: pt_fresh_star_bij_ineq(1) [OF pt_tvar_inst pt_tvar_inst at_tvar_inst cp_tvar_tvar_inst] perm_bool) +| T_LET[intro]: "\x\\; \ \ t\<^isub>1 : T\<^isub>1; ((x,close \ T\<^isub>1)#\) \ t\<^isub>2 : T\<^isub>2; set (ftv T\<^isub>1 - ftv \) \* T\<^isub>2\ + \ \ \ Let x be t\<^isub>1 in t\<^isub>2 : T\<^isub>2" equivariance typing[tvar] -lemma fresh_tvar_trm: "(X::tvar) \ (t::trm)" - by (nominal_induct t rule: trm.strong_induct) (simp_all add: fresh_atm abs_fresh) +lemma fresh_tvar_trm: + fixes X::"tvar" + and t::"trm" + shows "X\t" +by (nominal_induct t rule: trm.strong_induct) + (simp_all add: fresh_atm abs_fresh) -lemma ftv_ty: "supp (T::ty) = set (ftv T)" - by (nominal_induct T rule: ty.strong_induct) (simp_all add: ty.supp supp_atm) +lemma ftv_ty: + fixes T::"ty" + shows "supp T = set (ftv T)" +by (nominal_induct T rule: ty.strong_induct) + (simp_all add: ty.supp supp_atm) -lemma ftv_tyS: "supp (s::tyS) = set (ftv s)" - by (nominal_induct s rule: tyS.strong_induct) (auto simp add: tyS.supp abs_supp ftv_ty) +lemma ftv_tyS: + fixes S::"tyS" + shows "supp S = set (ftv S)" +by (nominal_induct S rule: tyS.strong_induct) + (auto simp add: tyS.supp abs_supp ftv_ty) -lemma ftv_Ctxt: "supp (\::Ctxt) = set (ftv \)" - apply (induct \) - apply (simp_all add: supp_list_nil supp_list_cons) - apply (case_tac a) - apply (simp add: supp_prod supp_atm ftv_tyS) - done +lemma ftv_Ctxt: + fixes \::"Ctxt" + shows "supp \ = set (ftv \)" +apply (induct \) +apply (simp_all add: supp_list_nil supp_list_cons) +apply (case_tac a) +apply (simp add: supp_prod supp_atm ftv_tyS) +done -lemma ftv_tvars: "supp (Tvs::tvar list) = set Tvs" - by (induct Tvs) (simp_all add: supp_list_nil supp_list_cons supp_atm) +lemma ftv_tvars: + fixes Tvs::"tvar list" + shows "supp Tvs = set Tvs" +by (induct Tvs) + (simp_all add: supp_list_nil supp_list_cons supp_atm) -lemma difference_supp: "((supp ((xs::tvar list) - ys))::tvar set) = supp xs - supp ys" - by (induct xs) (auto simp add: supp_list_nil supp_list_cons ftv_tvars) +lemma difference_supp: + fixes xs ys::"tvar list" + shows "((supp (xs - ys))::tvar set) = supp xs - supp ys" +by (induct xs) + (auto simp add: supp_list_nil supp_list_cons ftv_tvars) -lemma set_supp_eq: "set (xs::tvar list) = supp xs" - by (induct xs) (simp_all add: supp_list_nil supp_list_cons supp_atm) +lemma set_supp_eq: + fixes xs::"tvar list" + shows "set xs = supp xs" +by (induct xs) + (simp_all add: supp_list_nil supp_list_cons supp_atm) nominal_inductive2 typing avoids T_LET: "set (ftv T\<^isub>1 - ftv \)" - apply (simp add: fresh_star_def fresh_def ftv_Ctxt) - apply (simp add: fresh_star_def fresh_tvar_trm) - apply assumption - apply simp - done +apply (simp add: fresh_star_def fresh_def ftv_Ctxt) +apply (simp add: fresh_star_def fresh_tvar_trm) +apply assumption +apply simp +done lemma perm_fresh_fresh_aux: "\(x,y)\set (pi::tvar prm). x \ z \ y \ z \ pi \ (z::'a::pt_tvar) = z" @@ -294,8 +431,12 @@ apply (simp add: perm_fresh_fresh) done -lemma freshs_mem: "x \ (S::tvar set) \ S \* z \ x \ z" - by (simp add: fresh_star_def) +lemma freshs_mem: + fixes S::"tvar set" + assumes "x \ S" + and "S \* z" + shows "x \ z" +using prems by (simp add: fresh_star_def) lemma fresh_gen_set: fixes X::"tvar" @@ -315,13 +456,17 @@ shows "\(X::tvar)\set ((ftv T) - (ftv \)). X\(close \ T)" by (simp add: fresh_gen_set) -lemma gen_supp: "(supp (gen T Xs)::tvar set) = supp T - supp Xs" - by (induct Xs) (auto simp add: supp_list_nil supp_list_cons tyS.supp abs_supp supp_atm) +lemma gen_supp: + shows "(supp (gen T Xs)::tvar set) = supp T - supp Xs" +by (induct Xs) + (auto simp add: supp_list_nil supp_list_cons tyS.supp abs_supp supp_atm) -lemma minus_Int_eq: "T - (T - U) = T \ U" +lemma minus_Int_eq: + shows "T - (T - U) = T \ U" by blast -lemma close_supp: "supp (close \ T) = set (ftv T) \ set (ftv \)" +lemma close_supp: + shows "supp (close \ T) = set (ftv T) \ set (ftv \)" apply (simp add: gen_supp difference_supp ftv_ty ftv_Ctxt) apply (simp only: set_supp_eq minus_Int_eq) done @@ -370,4 +515,162 @@ ultimately show ?thesis by (rule T_LET) qed +lemma ftv_ty_subst: + fixes T::"ty" + and \::"Subst" + and X Y ::"tvar" + assumes a1: "X \ set (ftv T)" + and a2: "Y \ set (ftv (lookup \ X))" + shows "Y \ set (ftv (\))" +using a1 a2 +by (nominal_induct T rule: ty.strong_induct) (auto) + +lemma ftv_tyS_subst: + fixes S::"tyS" + and \::"Subst" + and X Y::"tvar" + assumes a1: "X \ set (ftv S)" + and a2: "Y \ set (ftv (lookup \ X))" + shows "Y \ set (ftv (\))" +using a1 a2 +by (nominal_induct S avoiding: \ Y rule: tyS.strong_induct) + (auto simp add: ftv_ty_subst fresh_atm) + +lemma ftv_Ctxt_subst: + fixes \::"Ctxt" + and \::"Subst" + assumes a1: "X \ set (ftv \)" + and a2: "Y \ set (ftv (lookup \ X))" + shows "Y \ set (ftv (\<\>))" +using a1 a2 +by (induct \) + (auto simp add: ftv_tyS_subst) + +lemma gen_preserved1: + assumes asm: "Xs \* \" + shows "\ = gen (\) Xs" +using asm +by (induct Xs) + (auto simp add: fresh_star_def) + +lemma gen_preserved2: + fixes T::"ty" + and \::"Ctxt" + assumes asm: "((ftv T) - (ftv \)) \* \" + shows "((ftv (\)) - (ftv (\<\>))) = ((ftv T) - (ftv \))" +using asm +apply(nominal_induct T rule: ty.strong_induct) +apply(auto simp add: fresh_star_def) +apply(simp add: lookup_fresh) +apply(simp add: ftv_Ctxt[symmetric]) +apply(fold fresh_def) +apply(rule fresh_psubst_Ctxt) +apply(assumption) +apply(assumption) +apply(rule difference_supset) +apply(auto) +apply(simp add: ftv_Ctxt_subst) +done + +lemma close_preserved: + fixes \::"Ctxt" + assumes asm: "((ftv T) - (ftv \)) \* \" + shows "\ T> = close (\<\>) (\)" +using asm +by (simp add: gen_preserved1 gen_preserved2) + +lemma var_fresh_for_ty: + fixes x::"var" + and T::"ty" + shows "x\T" +by (nominal_induct T rule: ty.strong_induct) + (simp_all add: fresh_atm) + +lemma var_fresh_for_tyS: + fixes x::"var" + and S::"tyS" + shows "x\S" +by (nominal_induct S rule: tyS.strong_induct) + (simp_all add: abs_fresh var_fresh_for_ty) + +lemma psubst_fresh_Ctxt: + fixes x::"var" + and \::"Ctxt" + and \::"Subst" + shows "x\\<\> = x\\" +by (induct \) + (auto simp add: fresh_list_cons fresh_list_nil fresh_prod var_fresh_for_tyS) + +lemma psubst_valid: + fixes \::Subst + and \::Ctxt + assumes a: "valid \" + shows "valid (\<\>)" +using a +by (induct) + (auto simp add: psubst_fresh_Ctxt) + +lemma psubst_in: + fixes \::"Ctxt" + and \::"Subst" + and pi::"tvar prm" + and S::"tyS" + assumes a: "(x,S)\set \" + shows "(x,\)\set (\<\>)" +using a +by (induct \) + (auto simp add: calc_atm) + + +lemma typing_preserved: + fixes \::"Subst" + and pi::"tvar prm" + assumes a: "\ \ t : T" + shows "(\<\>) \ t : (\)" +using a +proof (nominal_induct \ t T avoiding: \ rule: typing.strong_induct) + case (T_VAR \ x S T) + have a1: "valid \" by fact + have a2: "(x, S) \ set \" by fact + have a3: "T \ S" by fact + have "valid (\<\>)" using a1 by (simp add: psubst_valid) + moreover + have "(x,\)\set (\<\>)" using a2 by (simp add: psubst_in) + moreover + have "\ \ \" using a3 by (simp add: general_preserved) + ultimately show "(\<\>) \ Var x : (\)" by (simp add: typing.T_VAR) +next + case (T_APP \ t1 T1 T2 t2) + have "\<\> \ t1 : \ T2>" by fact + then have "\<\> \ t1 : (\) \ (\)" by simp + moreover + have "\<\> \ t2 : \" by fact + ultimately show "\<\> \ App t1 t2 : \" by (simp add: typing.T_APP) +next + case (T_LAM x \ T1 t T2) + fix pi::"tvar prm" and \::"Subst" + have "x\\" by fact + then have "x\\<\>" by (simp add: psubst_fresh_Ctxt) + moreover + have "\<((x, Ty T1)#\)> \ t : \" by fact + then have "((x, Ty (\))#(\<\>)) \ t : \" by (simp add: calc_atm) + ultimately show "\<\> \ Lam [x].t : \ T2>" by (simp add: typing.T_LAM) +next + case (T_LET x \ t1 T1 t2 T2) + have vc: "((ftv T1) - (ftv \)) \* \" by fact + have "x\\" by fact + then have a1: "x\\<\>" by (simp add: calc_atm psubst_fresh_Ctxt) + have a2: "\<\> \ t1 : \" by fact + have a3: "\<((x, close \ T1)#\)> \ t2 : \" by fact + from a2 a3 show "\<\> \ Let x be t1 in t2 : \" + apply - + apply(rule better_T_LET) + apply(rule a1) + apply(rule a2) + apply(simp add: close_preserved vc) + done +qed + + + end