src/HOL/Nominal/Examples/W.thy
changeset 80140 6d56e85f674e
parent 68386 98cf1c823c48
child 80149 40a3fc07a587
equal deleted inserted replaced
80139:fec5a23017b5 80140:6d56e85f674e
    11 where
    11 where
    12   "xs - ys \<equiv> [x \<leftarrow> xs. x\<notin>set ys]"
    12   "xs - ys \<equiv> [x \<leftarrow> xs. x\<notin>set ys]"
    13 
    13 
    14 lemma difference_eqvt_tvar[eqvt]:
    14 lemma difference_eqvt_tvar[eqvt]:
    15   fixes pi::"tvar prm"
    15   fixes pi::"tvar prm"
    16   and   Xs Ys::"tvar list"
    16     and   Xs Ys::"tvar list"
    17   shows "pi\<bullet>(Xs - Ys) = (pi\<bullet>Xs) - (pi\<bullet>Ys)"
    17   shows "pi\<bullet>(Xs - Ys) = (pi\<bullet>Xs) - (pi\<bullet>Ys)"
    18 by (induct Xs) (simp_all add: eqvts)
    18   by (induct Xs) (simp_all add: eqvts)
    19 
    19 
    20 lemma difference_fresh:
    20 lemma difference_fresh [simp]:
    21   fixes X::"tvar"
    21   fixes X::"tvar"
    22   and   Xs Ys::"tvar list"
    22     and   Xs Ys::"tvar list"
    23   assumes a: "X\<in>set Ys"
    23   shows "X\<sharp>(Xs - Ys) \<longleftrightarrow> X\<sharp>Xs \<or> X\<in>set Ys"
    24   shows "X\<sharp>(Xs - Ys)"
    24   by (induct Xs) (auto simp add: fresh_list_nil fresh_list_cons fresh_atm)
    25 using a
       
    26 by (induct Xs) (auto simp add: fresh_list_nil fresh_list_cons fresh_atm)
       
    27 
    25 
    28 lemma difference_supset:
    26 lemma difference_supset:
    29   fixes xs::"'a list"
    27   fixes xs::"'a list"
    30   and   ys::"'a list"
    28   and   ys::"'a list"
    31   and   zs::"'a list"
    29   and   zs::"'a list"
   112 nominal_primrec 
   110 nominal_primrec 
   113   ftv_tyS :: "tyS \<Rightarrow> tvar list"
   111   ftv_tyS :: "tyS \<Rightarrow> tvar list"
   114 where
   112 where
   115   "ftv_tyS (Ty T)    = ((ftv (T::ty))::tvar list)"
   113   "ftv_tyS (Ty T)    = ((ftv (T::ty))::tvar list)"
   116 | "ftv_tyS (\<forall>[X].S) = (ftv_tyS S) - [X]"
   114 | "ftv_tyS (\<forall>[X].S) = (ftv_tyS S) - [X]"
   117 apply(finite_guess add: ftv_ty_eqvt fs_tvar1)+
   115 apply(finite_guess add: ftv_ty_eqvt fs_tvar1 | rule TrueI)+
   118 apply(rule TrueI)+
   116   apply (metis difference_fresh list.set_intros(1))
   119 apply(rule difference_fresh)
       
   120 apply(simp)
       
   121 apply(fresh_guess add: ftv_ty_eqvt fs_tvar1)+
   117 apply(fresh_guess add: ftv_ty_eqvt fs_tvar1)+
   122 done
   118 done
   123 
   119 
   124 end
   120 end
   125 
   121 
   126 lemma ftv_tyS_eqvt[eqvt]:
   122 lemma ftv_tyS_eqvt[eqvt]:
   127   fixes pi::"tvar prm"
   123   fixes pi::"tvar prm"
   128   and   S::"tyS"
   124   and   S::"tyS"
   129   shows "pi\<bullet>(ftv S) = ftv (pi\<bullet>S)"
   125   shows "pi\<bullet>(ftv S) = ftv (pi\<bullet>S)"
   130 apply(nominal_induct S rule: tyS.strong_induct)
   126 proof (nominal_induct S rule: tyS.strong_induct)
   131 apply(simp add: eqvts)
   127   case (Ty ty)
   132 apply(simp only: ftv_tyS.simps)
   128   then show ?case
   133 apply(simp only: eqvts)
   129     by (simp add: ftv_ty_eqvt)
   134 apply(simp add: eqvts)
   130 next
   135 done 
   131   case (ALL tvar tyS)
       
   132   then show ?case 
       
   133     by (metis difference_eqvt_tvar ftv_ty.simps(1) ftv_tyS.simps(2) ftv_ty_eqvt ty.perm(3) tyS.perm(4))
       
   134 qed
   136 
   135 
   137 lemma ftv_Ctxt_eqvt[eqvt]:
   136 lemma ftv_Ctxt_eqvt[eqvt]:
   138   fixes pi::"tvar prm"
   137   fixes pi::"tvar prm"
   139   and   \<Gamma>::"Ctxt"
   138     and   \<Gamma>::"Ctxt"
   140   shows "pi\<bullet>(ftv \<Gamma>) = ftv (pi\<bullet>\<Gamma>)"
   139   shows "pi\<bullet>(ftv \<Gamma>) = ftv (pi\<bullet>\<Gamma>)"
   141 by (induct \<Gamma>) (auto simp add: eqvts)
   140   by (induct \<Gamma>) (auto simp add: eqvts)
   142 
   141 
   143 text \<open>Valid\<close>
   142 text \<open>Valid\<close>
   144 inductive
   143 inductive
   145   valid :: "Ctxt \<Rightarrow> bool"
   144   valid :: "Ctxt \<Rightarrow> bool"
   146 where
   145 where
   155 | "gen T (X#Xs) = \<forall>[X].(gen T Xs)"
   154 | "gen T (X#Xs) = \<forall>[X].(gen T Xs)"
   156 
   155 
   157 lemma gen_eqvt[eqvt]:
   156 lemma gen_eqvt[eqvt]:
   158   fixes pi::"tvar prm"
   157   fixes pi::"tvar prm"
   159   shows "pi\<bullet>(gen T Xs) = gen (pi\<bullet>T) (pi\<bullet>Xs)"
   158   shows "pi\<bullet>(gen T Xs) = gen (pi\<bullet>T) (pi\<bullet>Xs)"
   160 by (induct Xs) (simp_all add: eqvts)
   159   by (induct Xs) (simp_all add: eqvts)
   161 
   160 
   162 
   161 
   163 
   162 
   164 abbreviation 
   163 abbreviation 
   165   close :: "Ctxt \<Rightarrow> ty \<Rightarrow> tyS"
   164   close :: "Ctxt \<Rightarrow> ty \<Rightarrow> tyS"
   167   "close \<Gamma> T \<equiv> gen T ((ftv T) - (ftv \<Gamma>))"
   166   "close \<Gamma> T \<equiv> gen T ((ftv T) - (ftv \<Gamma>))"
   168 
   167 
   169 lemma close_eqvt[eqvt]:
   168 lemma close_eqvt[eqvt]:
   170   fixes pi::"tvar prm"
   169   fixes pi::"tvar prm"
   171   shows "pi\<bullet>(close \<Gamma> T) = close (pi\<bullet>\<Gamma>) (pi\<bullet>T)"
   170   shows "pi\<bullet>(close \<Gamma> T) = close (pi\<bullet>\<Gamma>) (pi\<bullet>T)"
   172 by (simp_all only: eqvts)
   171   by (simp_all only: eqvts)
   173   
   172   
   174 text \<open>Substitution\<close>
   173 text \<open>Substitution\<close>
   175 
   174 
   176 type_synonym Subst = "(tvar\<times>ty) list"
   175 type_synonym Subst = "(tvar\<times>ty) list"
   177 
   176 
   181 abbreviation 
   180 abbreviation 
   182   subst :: "'a \<Rightarrow> tvar \<Rightarrow> ty \<Rightarrow> 'a"  ("_[_::=_]" [100,100,100] 100)
   181   subst :: "'a \<Rightarrow> tvar \<Rightarrow> ty \<Rightarrow> 'a"  ("_[_::=_]" [100,100,100] 100)
   183 where
   182 where
   184   "smth[X::=T] \<equiv> ([(X,T)])<smth>" 
   183   "smth[X::=T] \<equiv> ([(X,T)])<smth>" 
   185 
   184 
   186 fun
   185 fun lookup :: "Subst \<Rightarrow> tvar \<Rightarrow> ty"   
   187   lookup :: "Subst \<Rightarrow> tvar \<Rightarrow> ty"   
       
   188 where
   186 where
   189   "lookup [] X        = TVar X"
   187   "lookup [] X        = TVar X"
   190 | "lookup ((Y,T)#\<theta>) X = (if X=Y then T else lookup \<theta> X)"
   188 | "lookup ((Y,T)#\<theta>) X = (if X=Y then T else lookup \<theta> X)"
   191 
   189 
   192 lemma lookup_eqvt[eqvt]:
   190 lemma lookup_eqvt[eqvt]:
   193   fixes pi::"tvar prm"
   191   fixes pi::"tvar prm"
   194   shows "pi\<bullet>(lookup \<theta> X) = lookup (pi\<bullet>\<theta>) (pi\<bullet>X)"
   192   shows "pi\<bullet>(lookup \<theta> X) = lookup (pi\<bullet>\<theta>) (pi\<bullet>X)"
   195 by (induct \<theta>) (auto simp add: eqvts)
   193   by (induct \<theta>) (auto simp add: eqvts)
   196 
   194 
   197 lemma lookup_fresh:
   195 lemma lookup_fresh:
   198   fixes X::"tvar"
   196   fixes X::"tvar"
   199   assumes a: "X\<sharp>\<theta>"
   197   assumes a: "X\<sharp>\<theta>"
   200   shows "lookup \<theta> X = TVar X"
   198   shows "lookup \<theta> X = TVar X"
   201 using a
   199   using a
   202 by (induct \<theta>)
   200   by (induct \<theta>)
   203    (auto simp add: fresh_list_cons fresh_prod fresh_atm)
   201     (auto simp add: fresh_list_cons fresh_prod fresh_atm)
   204 
   202 
   205 overloading 
   203 overloading 
   206   psubst_ty \<equiv> "psubst :: Subst \<Rightarrow> ty \<Rightarrow> ty"
   204   psubst_ty \<equiv> "psubst :: Subst \<Rightarrow> ty \<Rightarrow> ty"
   207 begin
   205 begin
   208 
   206 
   229 nominal_primrec 
   227 nominal_primrec 
   230   psubst_tyS :: "Subst \<Rightarrow> tyS \<Rightarrow> tyS"
   228   psubst_tyS :: "Subst \<Rightarrow> tyS \<Rightarrow> tyS"
   231 where 
   229 where 
   232   "\<theta><(Ty T)> = Ty (\<theta><T>)"
   230   "\<theta><(Ty T)> = Ty (\<theta><T>)"
   233 | "X\<sharp>\<theta> \<Longrightarrow> \<theta><(\<forall>[X].S)> = \<forall>[X].(\<theta><S>)"
   231 | "X\<sharp>\<theta> \<Longrightarrow> \<theta><(\<forall>[X].S)> = \<forall>[X].(\<theta><S>)"
   234 apply(finite_guess add: psubst_ty_eqvt fs_tvar1)+
   232 apply(finite_guess add: psubst_ty_eqvt fs_tvar1 | simp add: abs_fresh)+
   235 apply(rule TrueI)+
       
   236 apply(simp add: abs_fresh)
       
   237 apply(fresh_guess add: psubst_ty_eqvt fs_tvar1)+
   233 apply(fresh_guess add: psubst_ty_eqvt fs_tvar1)+
   238 done
   234 done
   239 
   235 
   240 end
   236 end
   241 
   237 
   328   and   T'::"ty"
   324   and   T'::"ty"
   329   and   T::"ty"
   325   and   T::"ty"
   330   assumes a: "X\<sharp>\<theta>" 
   326   assumes a: "X\<sharp>\<theta>" 
   331   shows "\<theta><T[X::=T']> = (\<theta><T>)[X::=\<theta><T'>]"
   327   shows "\<theta><T[X::=T']> = (\<theta><T>)[X::=\<theta><T'>]"
   332 using a
   328 using a
   333 apply(nominal_induct T avoiding: \<theta> X T' rule: ty.strong_induct)
   329 proof (nominal_induct T avoiding: \<theta> X T' rule: ty.strong_induct)
   334 apply(auto simp add: ty.inject lookup_fresh)
   330   case (TVar tvar)
   335 apply(rule sym)
   331   then show ?case
   336 apply(rule subst_forget_ty)
   332     by (simp add: fresh_atm(1) fresh_lookup lookup_fresh subst_forget_ty)
   337 apply(rule fresh_lookup)
   333 qed auto
   338 apply(simp_all add: fresh_atm)
       
   339 done
       
   340 
   334 
   341 lemma general_preserved:
   335 lemma general_preserved:
   342   fixes \<theta>::"Subst"
   336   fixes \<theta>::"Subst"
   343   assumes a: "T \<prec> S"
   337   assumes a: "T \<prec> S"
   344   shows "\<theta><T> \<prec> \<theta><S>"
   338   shows "\<theta><T> \<prec> \<theta><S>"
   345 using a
   339   using a
   346 apply(nominal_induct T S avoiding: \<theta> rule: inst.strong_induct)
   340 proof (nominal_induct T S avoiding: \<theta> rule: inst.strong_induct)
   347 apply(auto)[1]
   341   case (I_Ty T)
   348 apply(simp add: psubst_ty_lemma)
   342   then show ?case
   349 apply(rule_tac I_All)
   343     by (simp add: inst.I_Ty)
   350 apply(simp add: fresh_psubst_ty)
   344 next
   351 apply(simp)
   345   case (I_All X T' T S)
   352 done
   346   then show ?case
       
   347     by (simp add: fresh_psubst_ty inst.I_All psubst_ty_lemma)
       
   348 qed
   353 
   349 
   354 
   350 
   355 text\<open>typing judgements\<close>
   351 text\<open>typing judgements\<close>
   356 inductive
   352 inductive
   357   typing :: "Ctxt \<Rightarrow> trm \<Rightarrow> ty \<Rightarrow> bool" (" _ \<turnstile> _ : _ " [60,60,60] 60) 
   353   typing :: "Ctxt \<Rightarrow> trm \<Rightarrow> ty \<Rightarrow> bool" (" _ \<turnstile> _ : _ " [60,60,60] 60) 
   384    (auto simp add: tyS.supp abs_supp ftv_ty)
   380    (auto simp add: tyS.supp abs_supp ftv_ty)
   385 
   381 
   386 lemma ftv_Ctxt: 
   382 lemma ftv_Ctxt: 
   387   fixes \<Gamma>::"Ctxt"
   383   fixes \<Gamma>::"Ctxt"
   388   shows "supp \<Gamma> = set (ftv \<Gamma>)"
   384   shows "supp \<Gamma> = set (ftv \<Gamma>)"
   389 apply (induct \<Gamma>)
   385 proof (induct \<Gamma>)
   390 apply (simp_all add: supp_list_nil supp_list_cons)
   386   case Nil
   391 apply (rename_tac a \<Gamma>')
   387   then show ?case
   392 apply (case_tac a)
   388     by (simp add: supp_list_nil)
   393 apply (simp add: supp_prod supp_atm ftv_tyS)
   389 next
   394 done
   390   case (Cons c \<Gamma>)
   395 
   391   show ?case
   396 lemma ftv_tvars: 
   392   proof (cases c)
       
   393     case (Pair a b)
       
   394     with Cons show ?thesis
       
   395       by (simp add: ftv_tyS supp_atm(3) supp_list_cons supp_prod)
       
   396   qed
       
   397 qed
       
   398 
       
   399 lemma ftv_tvars:
   397   fixes Tvs::"tvar list"
   400   fixes Tvs::"tvar list"
   398   shows "supp Tvs = set Tvs"
   401   shows "supp Tvs = set Tvs"
   399 by (induct Tvs) 
   402   by (induct Tvs) (simp_all add: supp_list_nil supp_list_cons supp_atm)
   400    (simp_all add: supp_list_nil supp_list_cons supp_atm)
       
   401 
   403 
   402 lemma difference_supp: 
   404 lemma difference_supp: 
   403   fixes xs ys::"tvar list"
   405   fixes xs ys::"tvar list"
   404   shows "((supp (xs - ys))::tvar set) = supp xs - supp ys"
   406   shows "((supp (xs - ys))::tvar set) = supp xs - supp ys"
   405 by (induct xs) 
   407   by (induct xs) (auto simp add: supp_list_nil supp_list_cons ftv_tvars)
   406    (auto simp add: supp_list_nil supp_list_cons ftv_tvars)
       
   407 
   408 
   408 lemma set_supp_eq: 
   409 lemma set_supp_eq: 
   409   fixes xs::"tvar list"
   410   fixes xs::"tvar list"
   410   shows "set xs = supp xs"
   411   shows "set xs = supp xs"
   411 by (induct xs) 
   412   by (induct xs) (simp_all add: supp_list_nil supp_list_cons supp_atm)
   412    (simp_all add: supp_list_nil supp_list_cons supp_atm)
       
   413 
   413 
   414 nominal_inductive2 typing
   414 nominal_inductive2 typing
   415   avoids T_LET: "set (ftv T\<^sub>1 - ftv \<Gamma>)"
   415   avoids T_LET: "set (ftv T\<^sub>1 - ftv \<Gamma>)"
   416 apply (simp add: fresh_star_def fresh_def ftv_Ctxt)
   416      apply (simp_all add: fresh_star_def fresh_def ftv_Ctxt fresh_tvar_trm)
   417 apply (simp add: fresh_star_def fresh_tvar_trm)
   417   by (meson fresh_def fresh_tvar_trm)
   418 apply assumption
   418 
   419 apply simp
       
   420 done
       
   421 
   419 
   422 lemma perm_fresh_fresh_aux:
   420 lemma perm_fresh_fresh_aux:
   423   "\<forall>(x,y)\<in>set (pi::tvar prm). x \<sharp> z \<and> y \<sharp> z \<Longrightarrow> pi \<bullet> (z::'a::pt_tvar) = z"
   421   "\<forall>(x,y)\<in>set (pi::tvar prm). x \<sharp> z \<and> y \<sharp> z \<Longrightarrow> pi \<bullet> (z::'a::pt_tvar) = z"
   424   apply (induct pi rule: rev_induct)
   422 proof (induct pi rule: rev_induct)
   425   apply simp
   423   case Nil
       
   424   then show ?case
       
   425     by simp
       
   426 next
       
   427   case (snoc x xs)
       
   428   then show ?case
   426   apply (simp add: split_paired_all pt_tvar2)
   429   apply (simp add: split_paired_all pt_tvar2)
   427   apply (frule_tac x="(a, b)" in bspec)
   430     using perm_fresh_fresh(1) by fastforce
   428   apply simp
   431 qed
   429   apply (simp add: perm_fresh_fresh)
       
   430   done
       
   431 
   432 
   432 lemma freshs_mem:
   433 lemma freshs_mem:
   433   fixes S::"tvar set"
   434   fixes S::"tvar set"
   434   assumes "x \<in> S"
   435   assumes "x \<in> S"
   435   and     "S \<sharp>* z"
   436     and     "S \<sharp>* z"
   436   shows  "x \<sharp> z"
   437   shows  "x \<sharp> z"
   437 using assms by (simp add: fresh_star_def)
   438   using assms by (simp add: fresh_star_def)
   438 
   439 
   439 lemma fresh_gen_set:
   440 lemma fresh_gen_set:
   440   fixes X::"tvar"
   441   fixes X::"tvar"
   441   and   Xs::"tvar list"
   442   and   Xs::"tvar list"
   442   assumes asm: "X\<in>set Xs" 
   443   assumes "X\<in>set Xs" 
   443   shows "X\<sharp>gen T Xs"
   444   shows "X\<sharp>gen T Xs"
   444 using asm
   445   using assms by (induct Xs) (auto simp: abs_fresh)
   445 apply(induct Xs)
       
   446 apply(simp)
       
   447 apply(rename_tac a Xs')
       
   448 apply(case_tac "X=a")
       
   449 apply(simp add: abs_fresh)
       
   450 apply(simp add: abs_fresh)
       
   451 done
       
   452 
   446 
   453 lemma close_fresh:
   447 lemma close_fresh:
   454   fixes \<Gamma>::"Ctxt"
   448   fixes \<Gamma>::"Ctxt"
   455   shows "\<forall>(X::tvar)\<in>set ((ftv T) - (ftv \<Gamma>)). X\<sharp>(close \<Gamma> T)"
   449   shows "\<forall>(X::tvar)\<in>set ((ftv T) - (ftv \<Gamma>)). X\<sharp>(close \<Gamma> T)"
   456 by (simp add: fresh_gen_set)
   450   by (meson fresh_gen_set)
   457 
   451 
   458 lemma gen_supp: 
   452 lemma gen_supp: 
   459   shows "(supp (gen T Xs)::tvar set) = supp T - supp Xs"
   453   shows "(supp (gen T Xs)::tvar set) = supp T - supp Xs"
   460 by (induct Xs) 
   454 by (induct Xs) 
   461    (auto simp add: supp_list_nil supp_list_cons tyS.supp abs_supp supp_atm)
   455    (auto simp add: supp_list_nil supp_list_cons tyS.supp abs_supp supp_atm)
   464   shows "T - (T - U) = T \<inter> U"
   458   shows "T - (T - U) = T \<inter> U"
   465   by blast
   459   by blast
   466 
   460 
   467 lemma close_supp: 
   461 lemma close_supp: 
   468   shows "supp (close \<Gamma> T) = set (ftv T) \<inter> set (ftv \<Gamma>)"
   462   shows "supp (close \<Gamma> T) = set (ftv T) \<inter> set (ftv \<Gamma>)"
   469   apply (simp add: gen_supp difference_supp ftv_ty ftv_Ctxt)
   463   using difference_supp ftv_ty gen_supp set_supp_eq by auto
   470   apply (simp only: set_supp_eq minus_Int_eq)
       
   471   done
       
   472 
   464 
   473 lemma better_T_LET:
   465 lemma better_T_LET:
   474   assumes x: "x\<sharp>\<Gamma>"
   466   assumes x: "x\<sharp>\<Gamma>"
   475   and t1: "\<Gamma> \<turnstile> t\<^sub>1 : T\<^sub>1"
   467   and t1: "\<Gamma> \<turnstile> t\<^sub>1 : T\<^sub>1"
   476   and t2: "((x,close \<Gamma> T\<^sub>1)#\<Gamma>) \<turnstile> t\<^sub>2 : T\<^sub>2"
   468   and t2: "((x,close \<Gamma> T\<^sub>1)#\<Gamma>) \<turnstile> t\<^sub>2 : T\<^sub>2"
   481     and pi2: "set pi \<subseteq> set (ftv T\<^sub>1 - ftv \<Gamma>) \<times> (pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>))"
   473     and pi2: "set pi \<subseteq> set (ftv T\<^sub>1 - ftv \<Gamma>) \<times> (pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>))"
   482     by (rule at_set_avoiding [OF at_tvar_inst fin fs_tvar1, of "(T\<^sub>2, \<Gamma>)"])
   474     by (rule at_set_avoiding [OF at_tvar_inst fin fs_tvar1, of "(T\<^sub>2, \<Gamma>)"])
   483   from pi1 have pi1': "(pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>)) \<sharp>* \<Gamma>"
   475   from pi1 have pi1': "(pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>)) \<sharp>* \<Gamma>"
   484     by (simp add: fresh_star_prod)
   476     by (simp add: fresh_star_prod)
   485   have Gamma_fresh: "\<forall>(x,y)\<in>set pi. x \<sharp> \<Gamma> \<and> y \<sharp> \<Gamma>"
   477   have Gamma_fresh: "\<forall>(x,y)\<in>set pi. x \<sharp> \<Gamma> \<and> y \<sharp> \<Gamma>"
   486     apply (rule ballI)
   478     using freshs_mem [OF _ pi1'] subsetD [OF pi2] ftv_Ctxt fresh_def by fastforce
   487     apply (simp add: split_paired_all)
   479   have "\<And>x y. \<lbrakk>x \<in> set (ftv T\<^sub>1 - ftv \<Gamma>); y \<in> pi \<bullet> set (ftv T\<^sub>1 - ftv \<Gamma>)\<rbrakk>
   488     apply (drule subsetD [OF pi2])
   480               \<Longrightarrow> x \<sharp> close \<Gamma> T\<^sub>1 \<and> y \<sharp> close \<Gamma> T\<^sub>1"
   489     apply (erule SigmaE)
   481     by (metis DiffE filter_set fresh_def fresh_gen_set freshs_mem ftv_Ctxt ftv_ty gen_supp member_filter pi1')
   490     apply (drule freshs_mem [OF _ pi1'])
   482   then have close_fresh': "\<forall>(x, y)\<in>set pi. x \<sharp> close \<Gamma> T\<^sub>1 \<and> y \<sharp> close \<Gamma> T\<^sub>1"
   491     apply (simp add: ftv_Ctxt [symmetric] fresh_def)
   483     using pi2 by auto
   492     done
       
   493   have close_fresh': "\<forall>(x, y)\<in>set pi. x \<sharp> close \<Gamma> T\<^sub>1 \<and> y \<sharp> close \<Gamma> T\<^sub>1"
       
   494     apply (rule ballI)
       
   495     apply (simp add: split_paired_all)
       
   496     apply (drule subsetD [OF pi2])
       
   497     apply (erule SigmaE)
       
   498     apply (drule bspec [OF close_fresh])
       
   499     apply (drule freshs_mem [OF _ pi1'])
       
   500     apply (simp add: fresh_def close_supp ftv_Ctxt)
       
   501     done
       
   502   note x
   484   note x
   503   moreover from Gamma_fresh perm_boolI [OF t1, of pi]
   485   moreover from Gamma_fresh perm_boolI [OF t1, of pi]
   504   have "\<Gamma> \<turnstile> t\<^sub>1 : pi \<bullet> T\<^sub>1"
   486   have "\<Gamma> \<turnstile> t\<^sub>1 : pi \<bullet> T\<^sub>1"
   505     by (simp add: perm_fresh_fresh_aux eqvts fresh_tvar_trm)
   487     by (simp add: perm_fresh_fresh_aux eqvts fresh_tvar_trm)
   506   moreover from t2 close_fresh'
   488   moreover from t2 close_fresh'
   516 
   498 
   517 lemma ftv_ty_subst:
   499 lemma ftv_ty_subst:
   518   fixes T::"ty"
   500   fixes T::"ty"
   519   and   \<theta>::"Subst"
   501   and   \<theta>::"Subst"
   520   and   X Y ::"tvar"
   502   and   X Y ::"tvar"
   521   assumes a1: "X \<in> set (ftv T)"
   503   assumes "X \<in> set (ftv T)"
   522   and     a2: "Y \<in> set (ftv (lookup \<theta> X))"
   504   and     "Y \<in> set (ftv (lookup \<theta> X))"
   523   shows "Y \<in> set (ftv (\<theta><T>))"
   505   shows "Y \<in> set (ftv (\<theta><T>))"
   524 using a1 a2
   506   using assms
   525 by (nominal_induct T rule: ty.strong_induct) (auto)
   507   by (nominal_induct T rule: ty.strong_induct) (auto)
   526 
   508 
   527 lemma ftv_tyS_subst:
   509 lemma ftv_tyS_subst:
   528   fixes S::"tyS"
   510   fixes S::"tyS"
   529   and   \<theta>::"Subst"
   511   and   \<theta>::"Subst"
   530   and   X Y::"tvar"
   512   and   X Y::"tvar"
   531   assumes a1: "X \<in> set (ftv S)"
   513   assumes "X \<in> set (ftv S)"
   532   and     a2: "Y \<in> set (ftv (lookup \<theta> X))"
   514   and     "Y \<in> set (ftv (lookup \<theta> X))"
   533   shows "Y \<in> set (ftv (\<theta><S>))"
   515   shows "Y \<in> set (ftv (\<theta><S>))"
   534 using a1 a2
   516   using assms
   535 by (nominal_induct S avoiding: \<theta> Y rule: tyS.strong_induct) 
   517 by (nominal_induct S avoiding: \<theta> Y rule: tyS.strong_induct) 
   536    (auto simp add: ftv_ty_subst fresh_atm)
   518    (auto simp add: ftv_ty_subst fresh_atm)
   537 
   519 
   538 lemma ftv_Ctxt_subst:
   520 lemma ftv_Ctxt_subst:
   539   fixes \<Gamma>::"Ctxt"
   521   fixes \<Gamma>::"Ctxt"
   540   and   \<theta>::"Subst"
   522   and   \<theta>::"Subst"
   541   assumes a1: "X \<in> set (ftv \<Gamma>)"
   523 assumes "X \<in> set (ftv \<Gamma>)"
   542   and     a2: "Y \<in> set (ftv (lookup \<theta> X))"
   524   and   "Y \<in> set (ftv (lookup \<theta> X))"
   543   shows "Y \<in> set (ftv (\<theta><\<Gamma>>))"
   525   shows "Y \<in> set (ftv (\<theta><\<Gamma>>))"
   544 using a1 a2
   526   using assms by (induct \<Gamma>) (auto simp add: ftv_tyS_subst)
   545 by (induct \<Gamma>)
       
   546    (auto simp add: ftv_tyS_subst)
       
   547 
   527 
   548 lemma gen_preserved1:
   528 lemma gen_preserved1:
   549   assumes asm: "Xs \<sharp>* \<theta>"
   529   assumes "Xs \<sharp>* \<theta>"
   550   shows "\<theta><gen T Xs> = gen (\<theta><T>) Xs"
   530   shows "\<theta><gen T Xs> = gen (\<theta><T>) Xs"
   551 using asm
   531   using assms by (induct Xs) (auto simp add: fresh_star_def)
   552 by (induct Xs) 
       
   553    (auto simp add: fresh_star_def)
       
   554 
   532 
   555 lemma gen_preserved2:
   533 lemma gen_preserved2:
   556   fixes T::"ty"
   534   fixes T::"ty"
   557   and   \<Gamma>::"Ctxt"
   535   and   \<Gamma>::"Ctxt"
   558   assumes asm: "((ftv T) - (ftv \<Gamma>)) \<sharp>* \<theta>"
   536   assumes "((ftv T) - (ftv \<Gamma>)) \<sharp>* \<theta>"
   559   shows "((ftv (\<theta><T>)) - (ftv (\<theta><\<Gamma>>))) = ((ftv T) - (ftv \<Gamma>))"
   537   shows "((ftv (\<theta><T>)) - (ftv (\<theta><\<Gamma>>))) = ((ftv T) - (ftv \<Gamma>))"
   560 using asm
   538   using assms
   561 apply(nominal_induct T rule: ty.strong_induct)
   539 proof(nominal_induct T rule: ty.strong_induct)
   562 apply(auto simp add: fresh_star_def)
   540   case (TVar tvar)
   563 apply(simp add: lookup_fresh)
   541   then show ?case
   564 apply(simp add: ftv_Ctxt[symmetric])
   542     apply(auto simp add: fresh_star_def ftv_Ctxt_subst)
   565 apply(fold fresh_def)
   543     by (metis filter.simps fresh_def fresh_psubst_Ctxt ftv_Ctxt ftv_ty.simps(1) lookup_fresh)
   566 apply(rule fresh_psubst_Ctxt)
   544 next
   567 apply(assumption)
   545   case (Fun ty1 ty2)
   568 apply(assumption)
   546   then show ?case
   569 apply(rule difference_supset)
   547     by (simp add: fresh_star_list) 
   570 apply(auto)
   548 qed
   571 apply(simp add: ftv_Ctxt_subst)
       
   572 done
       
   573 
   549 
   574 lemma close_preserved:
   550 lemma close_preserved:
   575   fixes \<Gamma>::"Ctxt"
   551   fixes \<Gamma>::"Ctxt"
   576   assumes asm: "((ftv T) - (ftv \<Gamma>)) \<sharp>* \<theta>"
   552   assumes "((ftv T) - (ftv \<Gamma>)) \<sharp>* \<theta>"
   577   shows "\<theta><close \<Gamma> T> = close (\<theta><\<Gamma>>) (\<theta><T>)"
   553   shows "\<theta><close \<Gamma> T> = close (\<theta><\<Gamma>>) (\<theta><T>)"
   578 using asm
   554   using assms by (simp add: gen_preserved1 gen_preserved2)
   579 by (simp add: gen_preserved1 gen_preserved2)
       
   580 
   555 
   581 lemma var_fresh_for_ty:
   556 lemma var_fresh_for_ty:
   582   fixes x::"var"
   557   fixes x::"var"
   583   and   T::"ty"
   558     and   T::"ty"
   584   shows "x\<sharp>T"
   559   shows "x\<sharp>T"
   585 by (nominal_induct T rule: ty.strong_induct)
   560   by (nominal_induct T rule: ty.strong_induct) (simp_all add: fresh_atm)
   586    (simp_all add: fresh_atm)
       
   587 
   561 
   588 lemma var_fresh_for_tyS:
   562 lemma var_fresh_for_tyS:
   589   fixes x::"var"
   563   fixes x::"var" and S::"tyS"
   590   and   S::"tyS"
       
   591   shows "x\<sharp>S"
   564   shows "x\<sharp>S"
   592 by (nominal_induct S rule: tyS.strong_induct)
   565   by (nominal_induct S rule: tyS.strong_induct) (simp_all add: abs_fresh var_fresh_for_ty)
   593    (simp_all add: abs_fresh var_fresh_for_ty)
       
   594 
   566 
   595 lemma psubst_fresh_Ctxt:
   567 lemma psubst_fresh_Ctxt:
   596   fixes x::"var"
   568   fixes x::"var" and \<Gamma>::"Ctxt" and \<theta>::"Subst"
   597   and   \<Gamma>::"Ctxt"
       
   598   and   \<theta>::"Subst"
       
   599   shows "x\<sharp>\<theta><\<Gamma>> = x\<sharp>\<Gamma>"
   569   shows "x\<sharp>\<theta><\<Gamma>> = x\<sharp>\<Gamma>"
   600 by (induct \<Gamma>)
   570   by (induct \<Gamma>) (auto simp add: fresh_list_cons fresh_list_nil fresh_prod var_fresh_for_tyS)
   601    (auto simp add: fresh_list_cons fresh_list_nil fresh_prod var_fresh_for_tyS)
       
   602 
   571 
   603 lemma psubst_valid:
   572 lemma psubst_valid:
   604   fixes \<theta>::Subst
   573   fixes \<theta>::Subst
   605   and   \<Gamma>::Ctxt
   574     and   \<Gamma>::Ctxt
   606   assumes a: "valid \<Gamma>"
   575   assumes "valid \<Gamma>"
   607   shows "valid (\<theta><\<Gamma>>)"
   576   shows "valid (\<theta><\<Gamma>>)"
   608 using a
   577   using assms by (induct) (auto simp add: psubst_fresh_Ctxt)
   609 by (induct) 
       
   610    (auto simp add: psubst_fresh_Ctxt)
       
   611 
   578 
   612 lemma psubst_in:
   579 lemma psubst_in:
   613   fixes \<Gamma>::"Ctxt"
   580   fixes \<Gamma>::"Ctxt"
   614   and   \<theta>::"Subst"
   581   and   \<theta>::"Subst"
   615   and   pi::"tvar prm"
   582   and   pi::"tvar prm"
   616   and   S::"tyS"
   583   and   S::"tyS"
   617   assumes a: "(x,S)\<in>set \<Gamma>"
   584   assumes a: "(x,S)\<in>set \<Gamma>"
   618   shows "(x,\<theta><S>)\<in>set (\<theta><\<Gamma>>)"
   585   shows "(x,\<theta><S>)\<in>set (\<theta><\<Gamma>>)"
   619 using a
   586   using a by (induct \<Gamma>) (auto simp add: calc_atm)
   620 by (induct \<Gamma>)
       
   621    (auto simp add: calc_atm)
       
   622 
       
   623 
   587 
   624 lemma typing_preserved:
   588 lemma typing_preserved:
   625   fixes \<theta>::"Subst"
   589   fixes \<theta>::"Subst"
   626   and   pi::"tvar prm"
   590     and   pi::"tvar prm"
   627   assumes a: "\<Gamma> \<turnstile> t : T"
   591   assumes "\<Gamma> \<turnstile> t : T"
   628   shows "(\<theta><\<Gamma>>) \<turnstile> t : (\<theta><T>)"
   592   shows "(\<theta><\<Gamma>>) \<turnstile> t : (\<theta><T>)"
   629 using a
   593   using assms
   630 proof (nominal_induct \<Gamma> t T avoiding: \<theta> rule: typing.strong_induct)
   594 proof (nominal_induct \<Gamma> t T avoiding: \<theta> rule: typing.strong_induct)
   631   case (T_VAR \<Gamma> x S T)
   595   case (T_VAR \<Gamma> x S T)
   632   have a1: "valid \<Gamma>" by fact
   596   have a1: "valid \<Gamma>" by fact
   633   have a2: "(x, S) \<in> set \<Gamma>" by fact
   597   have a2: "(x, S) \<in> set \<Gamma>" by fact
   634   have a3: "T \<prec> S" by fact
   598   have a3: "T \<prec> S" by fact
   660   have "x\<sharp>\<Gamma>" by fact
   624   have "x\<sharp>\<Gamma>" by fact
   661    then have a1: "x\<sharp>\<theta><\<Gamma>>" by (simp add: calc_atm psubst_fresh_Ctxt)
   625    then have a1: "x\<sharp>\<theta><\<Gamma>>" by (simp add: calc_atm psubst_fresh_Ctxt)
   662   have a2: "\<theta><\<Gamma>> \<turnstile> t1 : \<theta><T1>" by fact 
   626   have a2: "\<theta><\<Gamma>> \<turnstile> t1 : \<theta><T1>" by fact 
   663   have a3: "\<theta><((x, close \<Gamma> T1)#\<Gamma>)> \<turnstile> t2 : \<theta><T2>" by fact
   627   have a3: "\<theta><((x, close \<Gamma> T1)#\<Gamma>)> \<turnstile> t2 : \<theta><T2>" by fact
   664   from a2 a3 show "\<theta><\<Gamma>> \<turnstile> Let x be t1 in t2 : \<theta><T2>"
   628   from a2 a3 show "\<theta><\<Gamma>> \<turnstile> Let x be t1 in t2 : \<theta><T2>"
   665     apply -
   629     by (simp add: a1 better_T_LET close_preserved vc)
   666     apply(rule better_T_LET)
       
   667     apply(rule a1)
       
   668     apply(rule a2)
       
   669     apply(simp add: close_preserved vc)
       
   670     done
       
   671 qed
   630 qed
   672 
   631 
   673 
       
   674 
       
   675 end
   632 end