src/HOL/Nominal/Examples/Pattern.thy
changeset 53015 a1119cf551e8
parent 45129 1fce03e3e8ad
child 58249 180f1b3508ed
equal deleted inserted replaced
53009:bb18eed53ed6 53015:a1119cf551e8
   142 
   142 
   143 inductive
   143 inductive
   144   ptyping :: "pat \<Rightarrow> ty \<Rightarrow> ctx \<Rightarrow> bool"  ("\<turnstile> _ : _ \<Rightarrow> _" [60, 60, 60] 60)
   144   ptyping :: "pat \<Rightarrow> ty \<Rightarrow> ctx \<Rightarrow> bool"  ("\<turnstile> _ : _ \<Rightarrow> _" [60, 60, 60] 60)
   145 where
   145 where
   146   PVar: "\<turnstile> PVar x T : T \<Rightarrow> [(x, T)]"
   146   PVar: "\<turnstile> PVar x T : T \<Rightarrow> [(x, T)]"
   147 | PTuple: "\<turnstile> p : T \<Rightarrow> \<Delta>\<^isub>1 \<Longrightarrow> \<turnstile> q : U \<Rightarrow> \<Delta>\<^isub>2 \<Longrightarrow> \<turnstile> \<langle>\<langle>p, q\<rangle>\<rangle> : T \<otimes> U \<Rightarrow> \<Delta>\<^isub>2 @ \<Delta>\<^isub>1"
   147 | PTuple: "\<turnstile> p : T \<Rightarrow> \<Delta>\<^sub>1 \<Longrightarrow> \<turnstile> q : U \<Rightarrow> \<Delta>\<^sub>2 \<Longrightarrow> \<turnstile> \<langle>\<langle>p, q\<rangle>\<rangle> : T \<otimes> U \<Rightarrow> \<Delta>\<^sub>2 @ \<Delta>\<^sub>1"
   148 
   148 
   149 lemma pat_vars_ptyping:
   149 lemma pat_vars_ptyping:
   150   assumes "\<turnstile> p : T \<Rightarrow> \<Delta>"
   150   assumes "\<turnstile> p : T \<Rightarrow> \<Delta>"
   151   shows "pat_vars p = map fst \<Delta>" using assms
   151   shows "pat_vars p = map fst \<Delta>" using assms
   152   by induct simp_all
   152   by induct simp_all
   166   by (induct \<Gamma>) (auto simp add: fresh_ctxt_set_eq [symmetric])
   166   by (induct \<Gamma>) (auto simp add: fresh_ctxt_set_eq [symmetric])
   167 
   167 
   168 abbreviation
   168 abbreviation
   169   "sub_ctx" :: "ctx \<Rightarrow> ctx \<Rightarrow> bool" ("_ \<sqsubseteq> _") 
   169   "sub_ctx" :: "ctx \<Rightarrow> ctx \<Rightarrow> bool" ("_ \<sqsubseteq> _") 
   170 where
   170 where
   171   "\<Gamma>\<^isub>1 \<sqsubseteq> \<Gamma>\<^isub>2 \<equiv> \<forall>x. x \<in> set \<Gamma>\<^isub>1 \<longrightarrow> x \<in> set \<Gamma>\<^isub>2"
   171   "\<Gamma>\<^sub>1 \<sqsubseteq> \<Gamma>\<^sub>2 \<equiv> \<forall>x. x \<in> set \<Gamma>\<^sub>1 \<longrightarrow> x \<in> set \<Gamma>\<^sub>2"
   172 
   172 
   173 abbreviation
   173 abbreviation
   174   Let_syn :: "pat \<Rightarrow> trm \<Rightarrow> trm \<Rightarrow> trm"  ("(LET (_ =/ _)/ IN (_))" 10)
   174   Let_syn :: "pat \<Rightarrow> trm \<Rightarrow> trm \<Rightarrow> trm"  ("(LET (_ =/ _)/ IN (_))" 10)
   175 where
   175 where
   176   "LET p = t IN u \<equiv> Let (pat_type p) t (\<lambda>[p]. Base u)"
   176   "LET p = t IN u \<equiv> Let (pat_type p) t (\<lambda>[p]. Base u)"
   211   assumes "\<turnstile> p : T \<Rightarrow> \<Delta>"
   211   assumes "\<turnstile> p : T \<Rightarrow> \<Delta>"
   212   shows "(supp p::name set) \<sharp>* c = (supp \<Delta>::name set) \<sharp>* c" using assms
   212   shows "(supp p::name set) \<sharp>* c = (supp \<Delta>::name set) \<sharp>* c" using assms
   213   by (auto simp add: fresh_star_def pat_var)
   213   by (auto simp add: fresh_star_def pat_var)
   214 
   214 
   215 lemma valid_app_mono:
   215 lemma valid_app_mono:
   216   assumes "valid (\<Delta> @ \<Gamma>\<^isub>1)" and "(supp \<Delta>::name set) \<sharp>* \<Gamma>\<^isub>2" and "valid \<Gamma>\<^isub>2" and "\<Gamma>\<^isub>1 \<sqsubseteq> \<Gamma>\<^isub>2"
   216   assumes "valid (\<Delta> @ \<Gamma>\<^sub>1)" and "(supp \<Delta>::name set) \<sharp>* \<Gamma>\<^sub>2" and "valid \<Gamma>\<^sub>2" and "\<Gamma>\<^sub>1 \<sqsubseteq> \<Gamma>\<^sub>2"
   217   shows "valid (\<Delta> @ \<Gamma>\<^isub>2)" using assms
   217   shows "valid (\<Delta> @ \<Gamma>\<^sub>2)" using assms
   218   by (induct \<Delta>)
   218   by (induct \<Delta>)
   219     (auto simp add: supp_list_cons fresh_star_Un_elim supp_prod
   219     (auto simp add: supp_list_cons fresh_star_Un_elim supp_prod
   220        fresh_list_append supp_atm fresh_star_insert_elim fresh_star_empty_elim)
   220        fresh_list_append supp_atm fresh_star_insert_elim fresh_star_empty_elim)
   221 
   221 
   222 nominal_inductive2 typing
   222 nominal_inductive2 typing
   251     by (rule Let)
   251     by (rule Let)
   252   then show ?thesis by (simp add: abs_pat_alpha [OF p_fresh'' pi'] pat_type_perm_eq)
   252   then show ?thesis by (simp add: abs_pat_alpha [OF p_fresh'' pi'] pat_type_perm_eq)
   253 qed
   253 qed
   254 
   254 
   255 lemma weakening: 
   255 lemma weakening: 
   256   assumes "\<Gamma>\<^isub>1 \<turnstile> t : T" and "valid \<Gamma>\<^isub>2" and "\<Gamma>\<^isub>1 \<sqsubseteq> \<Gamma>\<^isub>2"
   256   assumes "\<Gamma>\<^sub>1 \<turnstile> t : T" and "valid \<Gamma>\<^sub>2" and "\<Gamma>\<^sub>1 \<sqsubseteq> \<Gamma>\<^sub>2"
   257   shows "\<Gamma>\<^isub>2 \<turnstile> t : T" using assms
   257   shows "\<Gamma>\<^sub>2 \<turnstile> t : T" using assms
   258   apply (nominal_induct \<Gamma>\<^isub>1 t T avoiding: \<Gamma>\<^isub>2 rule: typing.strong_induct)
   258   apply (nominal_induct \<Gamma>\<^sub>1 t T avoiding: \<Gamma>\<^sub>2 rule: typing.strong_induct)
   259   apply auto
   259   apply auto
   260   apply (drule_tac x="(x, T) # \<Gamma>\<^isub>2" in meta_spec)
   260   apply (drule_tac x="(x, T) # \<Gamma>\<^sub>2" in meta_spec)
   261   apply (auto intro: valid_typing)
   261   apply (auto intro: valid_typing)
   262   apply (drule_tac x="\<Gamma>\<^isub>2" in meta_spec)
   262   apply (drule_tac x="\<Gamma>\<^sub>2" in meta_spec)
   263   apply (drule_tac x="\<Delta> @ \<Gamma>\<^isub>2" in meta_spec)
   263   apply (drule_tac x="\<Delta> @ \<Gamma>\<^sub>2" in meta_spec)
   264   apply (auto intro: valid_typing)
   264   apply (auto intro: valid_typing)
   265   apply (rule typing.Let)
   265   apply (rule typing.Let)
   266   apply assumption+
   266   apply assumption+
   267   apply (drule meta_mp)
   267   apply (drule meta_mp)
   268   apply (rule valid_app_mono)
   268   apply (rule valid_app_mono)
   377   using assms
   377   using assms
   378   by (nominal_induct t and t' avoiding: x u \<theta> rule: trm_btrm.strong_inducts)
   378   by (nominal_induct t and t' avoiding: x u \<theta> rule: trm_btrm.strong_inducts)
   379     (simp_all add: fresh_list_nil fresh_list_cons psubst_forget)
   379     (simp_all add: fresh_list_nil fresh_list_cons psubst_forget)
   380 
   380 
   381 lemma psubst_append:
   381 lemma psubst_append:
   382   "(supp (map fst (\<theta>\<^isub>1 @ \<theta>\<^isub>2))::name set) \<sharp>* map snd (\<theta>\<^isub>1 @ \<theta>\<^isub>2) \<Longrightarrow> (\<theta>\<^isub>1 @ \<theta>\<^isub>2)\<lparr>t\<rparr> = \<theta>\<^isub>2\<lparr>\<theta>\<^isub>1\<lparr>t\<rparr>\<rparr>"
   382   "(supp (map fst (\<theta>\<^sub>1 @ \<theta>\<^sub>2))::name set) \<sharp>* map snd (\<theta>\<^sub>1 @ \<theta>\<^sub>2) \<Longrightarrow> (\<theta>\<^sub>1 @ \<theta>\<^sub>2)\<lparr>t\<rparr> = \<theta>\<^sub>2\<lparr>\<theta>\<^sub>1\<lparr>t\<rparr>\<rparr>"
   383   by (induct \<theta>\<^isub>1 arbitrary: t)
   383   by (induct \<theta>\<^sub>1 arbitrary: t)
   384     (simp_all add: psubst_nil split_paired_all supp_list_cons psubst_cons fresh_star_def
   384     (simp_all add: psubst_nil split_paired_all supp_list_cons psubst_cons fresh_star_def
   385       fresh_list_cons fresh_list_append supp_list_append)
   385       fresh_list_cons fresh_list_append supp_list_append)
   386 
   386 
   387 lemma abs_pat_psubst [simp]:
   387 lemma abs_pat_psubst [simp]:
   388   "(supp p::name set) \<sharp>* \<theta> \<Longrightarrow> \<theta>\<lparr>\<lambda>[p]. t\<rparr>\<^sub>b = (\<lambda>[p]. \<theta>\<lparr>t\<rparr>\<^sub>b)"
   388   "(supp p::name set) \<sharp>* \<theta> \<Longrightarrow> \<theta>\<lparr>\<lambda>[p]. t\<rparr>\<^sub>b = (\<lambda>[p]. \<theta>\<lparr>t\<rparr>\<^sub>b)"
   422     assume ineq: "x \<noteq> y"
   422     assume ineq: "x \<noteq> y"
   423     from Var ineq have "(y, T) \<in> set (\<Delta> @ \<Gamma>)" by simp
   423     from Var ineq have "(y, T) \<in> set (\<Delta> @ \<Gamma>)" by simp
   424     then show "\<Delta> @ \<Gamma> \<turnstile> Var y[x\<mapsto>u] : T" using ineq valid by auto
   424     then show "\<Delta> @ \<Gamma> \<turnstile> Var y[x\<mapsto>u] : T" using ineq valid by auto
   425   qed
   425   qed
   426 next
   426 next
   427   case (Tuple t\<^isub>1 T\<^isub>1 t\<^isub>2 T\<^isub>2)
   427   case (Tuple t\<^sub>1 T\<^sub>1 t\<^sub>2 T\<^sub>2)
   428   from refl `\<Gamma> \<turnstile> u : U`
   428   from refl `\<Gamma> \<turnstile> u : U`
   429   have "\<Delta> @ \<Gamma> \<turnstile> t\<^isub>1[x\<mapsto>u] : T\<^isub>1" by (rule Tuple)
   429   have "\<Delta> @ \<Gamma> \<turnstile> t\<^sub>1[x\<mapsto>u] : T\<^sub>1" by (rule Tuple)
   430   moreover from refl `\<Gamma> \<turnstile> u : U`
   430   moreover from refl `\<Gamma> \<turnstile> u : U`
   431   have "\<Delta> @ \<Gamma> \<turnstile> t\<^isub>2[x\<mapsto>u] : T\<^isub>2" by (rule Tuple)
   431   have "\<Delta> @ \<Gamma> \<turnstile> t\<^sub>2[x\<mapsto>u] : T\<^sub>2" by (rule Tuple)
   432   ultimately have "\<Delta> @ \<Gamma> \<turnstile> \<langle>t\<^isub>1[x\<mapsto>u], t\<^isub>2[x\<mapsto>u]\<rangle> : T\<^isub>1 \<otimes> T\<^isub>2" ..
   432   ultimately have "\<Delta> @ \<Gamma> \<turnstile> \<langle>t\<^sub>1[x\<mapsto>u], t\<^sub>2[x\<mapsto>u]\<rangle> : T\<^sub>1 \<otimes> T\<^sub>2" ..
   433   then show ?case by simp
   433   then show ?case by simp
   434 next
   434 next
   435   case (Let p t T \<Delta>' s S)
   435   case (Let p t T \<Delta>' s S)
   436   from refl `\<Gamma> \<turnstile> u : U`
   436   from refl `\<Gamma> \<turnstile> u : U`
   437   have "\<Delta> @ \<Gamma> \<turnstile> t[x\<mapsto>u] : T" by (rule Let)
   437   have "\<Delta> @ \<Gamma> \<turnstile> t[x\<mapsto>u] : T" by (rule Let)
   454     by (rule typing.Abs)
   454     by (rule typing.Abs)
   455   moreover from Abs have "y \<sharp> [(x, u)]"
   455   moreover from Abs have "y \<sharp> [(x, u)]"
   456     by (simp add: fresh_list_nil fresh_list_cons)
   456     by (simp add: fresh_list_nil fresh_list_cons)
   457   ultimately show ?case by simp
   457   ultimately show ?case by simp
   458 next
   458 next
   459   case (App t\<^isub>1 T S t\<^isub>2)
   459   case (App t\<^sub>1 T S t\<^sub>2)
   460   from refl `\<Gamma> \<turnstile> u : U`
   460   from refl `\<Gamma> \<turnstile> u : U`
   461   have "\<Delta> @ \<Gamma> \<turnstile> t\<^isub>1[x\<mapsto>u] : T \<rightarrow> S" by (rule App)
   461   have "\<Delta> @ \<Gamma> \<turnstile> t\<^sub>1[x\<mapsto>u] : T \<rightarrow> S" by (rule App)
   462   moreover from refl `\<Gamma> \<turnstile> u : U`
   462   moreover from refl `\<Gamma> \<turnstile> u : U`
   463   have "\<Delta> @ \<Gamma> \<turnstile> t\<^isub>2[x\<mapsto>u] : T" by (rule App)
   463   have "\<Delta> @ \<Gamma> \<turnstile> t\<^sub>2[x\<mapsto>u] : T" by (rule App)
   464   ultimately have "\<Delta> @ \<Gamma> \<turnstile> (t\<^isub>1[x\<mapsto>u]) \<cdot> (t\<^isub>2[x\<mapsto>u]) : S"
   464   ultimately have "\<Delta> @ \<Gamma> \<turnstile> (t\<^sub>1[x\<mapsto>u]) \<cdot> (t\<^sub>2[x\<mapsto>u]) : S"
   465     by (rule typing.App)
   465     by (rule typing.App)
   466   then show ?case by simp
   466   then show ?case by simp
   467 qed
   467 qed
   468 
   468 
   469 lemmas subst_type = subst_type_aux [of "[]", simplified]
   469 lemmas subst_type = subst_type_aux [of "[]", simplified]
   480   (supp (map fst \<theta>)::name set) \<sharp>* map snd \<theta>"
   480   (supp (map fst \<theta>)::name set) \<sharp>* map snd \<theta>"
   481   by (simp add: fresh_star_def fresh_def match_supp_fst match_supp_snd)
   481   by (simp add: fresh_star_def fresh_def match_supp_fst match_supp_snd)
   482 
   482 
   483 lemma match_type_aux:
   483 lemma match_type_aux:
   484   assumes "\<turnstile> p : U \<Rightarrow> \<Delta>"
   484   assumes "\<turnstile> p : U \<Rightarrow> \<Delta>"
   485   and "\<Gamma>\<^isub>2 \<turnstile> u : U"
   485   and "\<Gamma>\<^sub>2 \<turnstile> u : U"
   486   and "\<Gamma>\<^isub>1 @ \<Delta> @ \<Gamma>\<^isub>2 \<turnstile> t : T"
   486   and "\<Gamma>\<^sub>1 @ \<Delta> @ \<Gamma>\<^sub>2 \<turnstile> t : T"
   487   and "\<turnstile> p \<rhd> u \<Rightarrow> \<theta>"
   487   and "\<turnstile> p \<rhd> u \<Rightarrow> \<theta>"
   488   and "(supp p::name set) \<sharp>* u"
   488   and "(supp p::name set) \<sharp>* u"
   489   shows "\<Gamma>\<^isub>1 @ \<Gamma>\<^isub>2 \<turnstile> \<theta>\<lparr>t\<rparr> : T" using assms
   489   shows "\<Gamma>\<^sub>1 @ \<Gamma>\<^sub>2 \<turnstile> \<theta>\<lparr>t\<rparr> : T" using assms
   490 proof (induct arbitrary: \<Gamma>\<^isub>1 \<Gamma>\<^isub>2 t u T \<theta>)
   490 proof (induct arbitrary: \<Gamma>\<^sub>1 \<Gamma>\<^sub>2 t u T \<theta>)
   491   case (PVar x U)
   491   case (PVar x U)
   492   from `\<Gamma>\<^isub>1 @ [(x, U)] @ \<Gamma>\<^isub>2 \<turnstile> t : T` `\<Gamma>\<^isub>2 \<turnstile> u : U`
   492   from `\<Gamma>\<^sub>1 @ [(x, U)] @ \<Gamma>\<^sub>2 \<turnstile> t : T` `\<Gamma>\<^sub>2 \<turnstile> u : U`
   493   have "\<Gamma>\<^isub>1 @ \<Gamma>\<^isub>2 \<turnstile> t[x\<mapsto>u] : T" by (rule subst_type_aux)
   493   have "\<Gamma>\<^sub>1 @ \<Gamma>\<^sub>2 \<turnstile> t[x\<mapsto>u] : T" by (rule subst_type_aux)
   494   moreover from `\<turnstile> PVar x U \<rhd> u \<Rightarrow> \<theta>` have "\<theta> = [(x, u)]"
   494   moreover from `\<turnstile> PVar x U \<rhd> u \<Rightarrow> \<theta>` have "\<theta> = [(x, u)]"
   495     by cases simp_all
   495     by cases simp_all
   496   ultimately show ?case by simp
   496   ultimately show ?case by simp
   497 next
   497 next
   498   case (PTuple p S \<Delta>\<^isub>1 q U \<Delta>\<^isub>2)
   498   case (PTuple p S \<Delta>\<^sub>1 q U \<Delta>\<^sub>2)
   499   from `\<turnstile> \<langle>\<langle>p, q\<rangle>\<rangle> \<rhd> u \<Rightarrow> \<theta>` obtain u\<^isub>1 u\<^isub>2 \<theta>\<^isub>1 \<theta>\<^isub>2
   499   from `\<turnstile> \<langle>\<langle>p, q\<rangle>\<rangle> \<rhd> u \<Rightarrow> \<theta>` obtain u\<^sub>1 u\<^sub>2 \<theta>\<^sub>1 \<theta>\<^sub>2
   500     where u: "u = \<langle>u\<^isub>1, u\<^isub>2\<rangle>" and \<theta>: "\<theta> = \<theta>\<^isub>1 @ \<theta>\<^isub>2"
   500     where u: "u = \<langle>u\<^sub>1, u\<^sub>2\<rangle>" and \<theta>: "\<theta> = \<theta>\<^sub>1 @ \<theta>\<^sub>2"
   501     and p: "\<turnstile> p \<rhd> u\<^isub>1 \<Rightarrow> \<theta>\<^isub>1" and q: "\<turnstile> q \<rhd> u\<^isub>2 \<Rightarrow> \<theta>\<^isub>2"
   501     and p: "\<turnstile> p \<rhd> u\<^sub>1 \<Rightarrow> \<theta>\<^sub>1" and q: "\<turnstile> q \<rhd> u\<^sub>2 \<Rightarrow> \<theta>\<^sub>2"
   502     by cases simp_all
   502     by cases simp_all
   503   with PTuple have "\<Gamma>\<^isub>2 \<turnstile> \<langle>u\<^isub>1, u\<^isub>2\<rangle> : S \<otimes> U" by simp
   503   with PTuple have "\<Gamma>\<^sub>2 \<turnstile> \<langle>u\<^sub>1, u\<^sub>2\<rangle> : S \<otimes> U" by simp
   504   then obtain u\<^isub>1: "\<Gamma>\<^isub>2 \<turnstile> u\<^isub>1 : S" and u\<^isub>2: "\<Gamma>\<^isub>2 \<turnstile> u\<^isub>2 : U"
   504   then obtain u\<^sub>1: "\<Gamma>\<^sub>2 \<turnstile> u\<^sub>1 : S" and u\<^sub>2: "\<Gamma>\<^sub>2 \<turnstile> u\<^sub>2 : U"
   505     by cases (simp_all add: ty.inject trm.inject)
   505     by cases (simp_all add: ty.inject trm.inject)
   506   note u\<^isub>1
   506   note u\<^sub>1
   507   moreover from `\<Gamma>\<^isub>1 @ (\<Delta>\<^isub>2 @ \<Delta>\<^isub>1) @ \<Gamma>\<^isub>2 \<turnstile> t : T`
   507   moreover from `\<Gamma>\<^sub>1 @ (\<Delta>\<^sub>2 @ \<Delta>\<^sub>1) @ \<Gamma>\<^sub>2 \<turnstile> t : T`
   508   have "(\<Gamma>\<^isub>1 @ \<Delta>\<^isub>2) @ \<Delta>\<^isub>1 @ \<Gamma>\<^isub>2 \<turnstile> t : T" by simp
   508   have "(\<Gamma>\<^sub>1 @ \<Delta>\<^sub>2) @ \<Delta>\<^sub>1 @ \<Gamma>\<^sub>2 \<turnstile> t : T" by simp
   509   moreover note p
   509   moreover note p
   510   moreover from `supp \<langle>\<langle>p, q\<rangle>\<rangle> \<sharp>* u` and u
   510   moreover from `supp \<langle>\<langle>p, q\<rangle>\<rangle> \<sharp>* u` and u
   511   have "(supp p::name set) \<sharp>* u\<^isub>1" by (simp add: fresh_star_def)
   511   have "(supp p::name set) \<sharp>* u\<^sub>1" by (simp add: fresh_star_def)
   512   ultimately have \<theta>\<^isub>1: "(\<Gamma>\<^isub>1 @ \<Delta>\<^isub>2) @ \<Gamma>\<^isub>2 \<turnstile> \<theta>\<^isub>1\<lparr>t\<rparr> : T"
   512   ultimately have \<theta>\<^sub>1: "(\<Gamma>\<^sub>1 @ \<Delta>\<^sub>2) @ \<Gamma>\<^sub>2 \<turnstile> \<theta>\<^sub>1\<lparr>t\<rparr> : T"
   513     by (rule PTuple)
   513     by (rule PTuple)
   514   note u\<^isub>2
   514   note u\<^sub>2
   515   moreover from \<theta>\<^isub>1
   515   moreover from \<theta>\<^sub>1
   516   have "\<Gamma>\<^isub>1 @ \<Delta>\<^isub>2 @ \<Gamma>\<^isub>2 \<turnstile> \<theta>\<^isub>1\<lparr>t\<rparr> : T" by simp
   516   have "\<Gamma>\<^sub>1 @ \<Delta>\<^sub>2 @ \<Gamma>\<^sub>2 \<turnstile> \<theta>\<^sub>1\<lparr>t\<rparr> : T" by simp
   517   moreover note q
   517   moreover note q
   518   moreover from `supp \<langle>\<langle>p, q\<rangle>\<rangle> \<sharp>* u` and u
   518   moreover from `supp \<langle>\<langle>p, q\<rangle>\<rangle> \<sharp>* u` and u
   519   have "(supp q::name set) \<sharp>* u\<^isub>2" by (simp add: fresh_star_def)
   519   have "(supp q::name set) \<sharp>* u\<^sub>2" by (simp add: fresh_star_def)
   520   ultimately have "\<Gamma>\<^isub>1 @ \<Gamma>\<^isub>2 \<turnstile> \<theta>\<^isub>2\<lparr>\<theta>\<^isub>1\<lparr>t\<rparr>\<rparr> : T"
   520   ultimately have "\<Gamma>\<^sub>1 @ \<Gamma>\<^sub>2 \<turnstile> \<theta>\<^sub>2\<lparr>\<theta>\<^sub>1\<lparr>t\<rparr>\<rparr> : T"
   521     by (rule PTuple)
   521     by (rule PTuple)
   522   moreover from `\<turnstile> \<langle>\<langle>p, q\<rangle>\<rangle> \<rhd> u \<Rightarrow> \<theta>` `supp \<langle>\<langle>p, q\<rangle>\<rangle> \<sharp>* u`
   522   moreover from `\<turnstile> \<langle>\<langle>p, q\<rangle>\<rangle> \<rhd> u \<Rightarrow> \<theta>` `supp \<langle>\<langle>p, q\<rangle>\<rangle> \<sharp>* u`
   523   have "(supp (map fst \<theta>)::name set) \<sharp>* map snd \<theta>"
   523   have "(supp (map fst \<theta>)::name set) \<sharp>* map snd \<theta>"
   524     by (rule match_fresh)
   524     by (rule match_fresh)
   525   ultimately show ?case using \<theta> by (simp add: psubst_append)
   525   ultimately show ?case using \<theta> by (simp add: psubst_append)
   526 qed
   526 qed
   527 
   527 
   528 lemmas match_type = match_type_aux [where \<Gamma>\<^isub>1="[]", simplified]
   528 lemmas match_type = match_type_aux [where \<Gamma>\<^sub>1="[]", simplified]
   529 
   529 
   530 inductive eval :: "trm \<Rightarrow> trm \<Rightarrow> bool" ("_ \<longmapsto> _" [60,60] 60)
   530 inductive eval :: "trm \<Rightarrow> trm \<Rightarrow> bool" ("_ \<longmapsto> _" [60,60] 60)
   531 where
   531 where
   532   TupleL: "t \<longmapsto> t' \<Longrightarrow> \<langle>t, u\<rangle> \<longmapsto> \<langle>t', u\<rangle>"
   532   TupleL: "t \<longmapsto> t' \<Longrightarrow> \<langle>t, u\<rangle> \<longmapsto> \<langle>t', u\<rangle>"
   533 | TupleR: "u \<longmapsto> u' \<Longrightarrow> \<langle>t, u\<rangle> \<longmapsto> \<langle>t, u'\<rangle>"
   533 | TupleR: "u \<longmapsto> u' \<Longrightarrow> \<langle>t, u\<rangle> \<longmapsto> \<langle>t, u'\<rangle>"
   678           (supp (PVar x T) \<union> supp q)"
   678           (supp (PVar x T) \<union> supp q)"
   679         by (simp add: perm_swap swap_simps supp_atm perm_type)
   679         by (simp add: perm_swap swap_simps supp_atm perm_type)
   680       then show ?thesis ..
   680       then show ?thesis ..
   681     qed
   681     qed
   682   next
   682   next
   683     case (PTuple p\<^isub>1 p\<^isub>2)
   683     case (PTuple p\<^sub>1 p\<^sub>2)
   684     with PVar have "ty_size (pat_type p\<^isub>1) < ty_size T" by simp
   684     with PVar have "ty_size (pat_type p\<^sub>1) < ty_size T" by simp
   685     then have "Bind T x t \<noteq> (\<lambda>[p\<^isub>1]. \<lambda>[p\<^isub>2]. u)"
   685     then have "Bind T x t \<noteq> (\<lambda>[p\<^sub>1]. \<lambda>[p\<^sub>2]. u)"
   686       by (rule bind_tuple_ineq)
   686       by (rule bind_tuple_ineq)
   687     moreover from PTuple PVar
   687     moreover from PTuple PVar
   688     have "Bind T x t = (\<lambda>[p\<^isub>1]. \<lambda>[p\<^isub>2]. u)" by simp
   688     have "Bind T x t = (\<lambda>[p\<^sub>1]. \<lambda>[p\<^sub>2]. u)" by simp
   689     ultimately show ?thesis ..
   689     ultimately show ?thesis ..
   690   qed
   690   qed
   691 next
   691 next
   692   case (PTuple p\<^isub>1 p\<^isub>2)
   692   case (PTuple p\<^sub>1 p\<^sub>2)
   693   note PTuple' = this
   693   note PTuple' = this
   694   show ?case
   694   show ?case
   695   proof (cases q)
   695   proof (cases q)
   696     case (PVar x T)
   696     case (PVar x T)
   697     with PTuple have "ty_size (pat_type p\<^isub>1) < ty_size T" by auto
   697     with PTuple have "ty_size (pat_type p\<^sub>1) < ty_size T" by auto
   698     then have "Bind T x u \<noteq> (\<lambda>[p\<^isub>1]. \<lambda>[p\<^isub>2]. t)"
   698     then have "Bind T x u \<noteq> (\<lambda>[p\<^sub>1]. \<lambda>[p\<^sub>2]. t)"
   699       by (rule bind_tuple_ineq)
   699       by (rule bind_tuple_ineq)
   700     moreover from PTuple PVar
   700     moreover from PTuple PVar
   701     have "Bind T x u = (\<lambda>[p\<^isub>1]. \<lambda>[p\<^isub>2]. t)" by simp
   701     have "Bind T x u = (\<lambda>[p\<^sub>1]. \<lambda>[p\<^sub>2]. t)" by simp
   702     ultimately show ?thesis ..
   702     ultimately show ?thesis ..
   703   next
   703   next
   704     case (PTuple p\<^isub>1' p\<^isub>2')
   704     case (PTuple p\<^sub>1' p\<^sub>2')
   705     with PTuple' have "(\<lambda>[p\<^isub>1]. \<lambda>[p\<^isub>2]. t) = (\<lambda>[p\<^isub>1']. \<lambda>[p\<^isub>2']. u)" by simp
   705     with PTuple' have "(\<lambda>[p\<^sub>1]. \<lambda>[p\<^sub>2]. t) = (\<lambda>[p\<^sub>1']. \<lambda>[p\<^sub>2']. u)" by simp
   706     moreover from PTuple PTuple' have "pat_type p\<^isub>1 = pat_type p\<^isub>1'"
   706     moreover from PTuple PTuple' have "pat_type p\<^sub>1 = pat_type p\<^sub>1'"
   707       by (simp add: ty.inject)
   707       by (simp add: ty.inject)
   708     moreover from PTuple' have "distinct (pat_vars p\<^isub>1)" by simp
   708     moreover from PTuple' have "distinct (pat_vars p\<^sub>1)" by simp
   709     moreover from PTuple PTuple' have "distinct (pat_vars p\<^isub>1')" by simp
   709     moreover from PTuple PTuple' have "distinct (pat_vars p\<^sub>1')" by simp
   710     ultimately have "\<exists>pi::name prm. p\<^isub>1 = pi \<bullet> p\<^isub>1' \<and>
   710     ultimately have "\<exists>pi::name prm. p\<^sub>1 = pi \<bullet> p\<^sub>1' \<and>
   711       (\<lambda>[p\<^isub>2]. t) = pi \<bullet> (\<lambda>[p\<^isub>2']. u) \<and>
   711       (\<lambda>[p\<^sub>2]. t) = pi \<bullet> (\<lambda>[p\<^sub>2']. u) \<and>
   712       set pi \<subseteq> (supp p\<^isub>1 \<union> supp p\<^isub>1') \<times> (supp p\<^isub>1 \<union> supp p\<^isub>1')"
   712       set pi \<subseteq> (supp p\<^sub>1 \<union> supp p\<^sub>1') \<times> (supp p\<^sub>1 \<union> supp p\<^sub>1')"
   713       by (rule PTuple')
   713       by (rule PTuple')
   714     then obtain pi::"name prm" where
   714     then obtain pi::"name prm" where
   715       "p\<^isub>1 = pi \<bullet> p\<^isub>1'" "(\<lambda>[p\<^isub>2]. t) = pi \<bullet> (\<lambda>[p\<^isub>2']. u)" and
   715       "p\<^sub>1 = pi \<bullet> p\<^sub>1'" "(\<lambda>[p\<^sub>2]. t) = pi \<bullet> (\<lambda>[p\<^sub>2']. u)" and
   716       pi: "set pi \<subseteq> (supp p\<^isub>1 \<union> supp p\<^isub>1') \<times> (supp p\<^isub>1 \<union> supp p\<^isub>1')" by auto
   716       pi: "set pi \<subseteq> (supp p\<^sub>1 \<union> supp p\<^sub>1') \<times> (supp p\<^sub>1 \<union> supp p\<^sub>1')" by auto
   717     from `(\<lambda>[p\<^isub>2]. t) = pi \<bullet> (\<lambda>[p\<^isub>2']. u)`
   717     from `(\<lambda>[p\<^sub>2]. t) = pi \<bullet> (\<lambda>[p\<^sub>2']. u)`
   718     have "(\<lambda>[p\<^isub>2]. t) = (\<lambda>[pi \<bullet> p\<^isub>2']. pi \<bullet> u)"
   718     have "(\<lambda>[p\<^sub>2]. t) = (\<lambda>[pi \<bullet> p\<^sub>2']. pi \<bullet> u)"
   719       by (simp add: eqvts)
   719       by (simp add: eqvts)
   720     moreover from PTuple PTuple' have "pat_type p\<^isub>2 = pat_type (pi \<bullet> p\<^isub>2')"
   720     moreover from PTuple PTuple' have "pat_type p\<^sub>2 = pat_type (pi \<bullet> p\<^sub>2')"
   721       by (simp add: ty.inject pat_type_perm_eq)
   721       by (simp add: ty.inject pat_type_perm_eq)
   722     moreover from PTuple' have "distinct (pat_vars p\<^isub>2)" by simp
   722     moreover from PTuple' have "distinct (pat_vars p\<^sub>2)" by simp
   723     moreover from PTuple PTuple' have "distinct (pat_vars (pi \<bullet> p\<^isub>2'))"
   723     moreover from PTuple PTuple' have "distinct (pat_vars (pi \<bullet> p\<^sub>2'))"
   724       by (simp add: pat_vars_eqvt [symmetric] distinct_eqvt [symmetric])
   724       by (simp add: pat_vars_eqvt [symmetric] distinct_eqvt [symmetric])
   725     ultimately have "\<exists>pi'::name prm. p\<^isub>2 = pi' \<bullet> pi \<bullet> p\<^isub>2' \<and>
   725     ultimately have "\<exists>pi'::name prm. p\<^sub>2 = pi' \<bullet> pi \<bullet> p\<^sub>2' \<and>
   726       t = pi' \<bullet> pi \<bullet> u \<and>
   726       t = pi' \<bullet> pi \<bullet> u \<and>
   727       set pi' \<subseteq> (supp p\<^isub>2 \<union> supp (pi \<bullet> p\<^isub>2')) \<times> (supp p\<^isub>2 \<union> supp (pi \<bullet> p\<^isub>2'))"
   727       set pi' \<subseteq> (supp p\<^sub>2 \<union> supp (pi \<bullet> p\<^sub>2')) \<times> (supp p\<^sub>2 \<union> supp (pi \<bullet> p\<^sub>2'))"
   728       by (rule PTuple')
   728       by (rule PTuple')
   729     then obtain pi'::"name prm" where
   729     then obtain pi'::"name prm" where
   730       "p\<^isub>2 = pi' \<bullet> pi \<bullet> p\<^isub>2'" "t = pi' \<bullet> pi \<bullet> u" and
   730       "p\<^sub>2 = pi' \<bullet> pi \<bullet> p\<^sub>2'" "t = pi' \<bullet> pi \<bullet> u" and
   731       pi': "set pi' \<subseteq> (supp p\<^isub>2 \<union> supp (pi \<bullet> p\<^isub>2')) \<times>
   731       pi': "set pi' \<subseteq> (supp p\<^sub>2 \<union> supp (pi \<bullet> p\<^sub>2')) \<times>
   732         (supp p\<^isub>2 \<union> supp (pi \<bullet> p\<^isub>2'))" by auto
   732         (supp p\<^sub>2 \<union> supp (pi \<bullet> p\<^sub>2'))" by auto
   733     from PTuple PTuple' have "pi \<bullet> distinct (pat_vars \<langle>\<langle>p\<^isub>1', p\<^isub>2'\<rangle>\<rangle>)" by simp
   733     from PTuple PTuple' have "pi \<bullet> distinct (pat_vars \<langle>\<langle>p\<^sub>1', p\<^sub>2'\<rangle>\<rangle>)" by simp
   734     then have "distinct (pat_vars \<langle>\<langle>pi \<bullet> p\<^isub>1', pi \<bullet> p\<^isub>2'\<rangle>\<rangle>)" by (simp only: eqvts)
   734     then have "distinct (pat_vars \<langle>\<langle>pi \<bullet> p\<^sub>1', pi \<bullet> p\<^sub>2'\<rangle>\<rangle>)" by (simp only: eqvts)
   735     with `p\<^isub>1 = pi \<bullet> p\<^isub>1'` PTuple'
   735     with `p\<^sub>1 = pi \<bullet> p\<^sub>1'` PTuple'
   736     have fresh: "(supp p\<^isub>2 \<union> supp (pi \<bullet> p\<^isub>2') :: name set) \<sharp>* p\<^isub>1"
   736     have fresh: "(supp p\<^sub>2 \<union> supp (pi \<bullet> p\<^sub>2') :: name set) \<sharp>* p\<^sub>1"
   737       by (auto simp add: set_pat_vars_supp fresh_star_def fresh_def eqvts)
   737       by (auto simp add: set_pat_vars_supp fresh_star_def fresh_def eqvts)
   738     from `p\<^isub>1 = pi \<bullet> p\<^isub>1'` have "pi' \<bullet> (p\<^isub>1 = pi \<bullet> p\<^isub>1')" by (rule perm_boolI)
   738     from `p\<^sub>1 = pi \<bullet> p\<^sub>1'` have "pi' \<bullet> (p\<^sub>1 = pi \<bullet> p\<^sub>1')" by (rule perm_boolI)
   739     with pt_freshs_freshs [OF pt_name_inst at_name_inst pi' fresh fresh]
   739     with pt_freshs_freshs [OF pt_name_inst at_name_inst pi' fresh fresh]
   740     have "p\<^isub>1 = pi' \<bullet> pi \<bullet> p\<^isub>1'" by (simp add: eqvts)
   740     have "p\<^sub>1 = pi' \<bullet> pi \<bullet> p\<^sub>1'" by (simp add: eqvts)
   741     with `p\<^isub>2 = pi' \<bullet> pi \<bullet> p\<^isub>2'` have "\<langle>\<langle>p\<^isub>1, p\<^isub>2\<rangle>\<rangle> = (pi' @ pi) \<bullet> \<langle>\<langle>p\<^isub>1', p\<^isub>2'\<rangle>\<rangle>"
   741     with `p\<^sub>2 = pi' \<bullet> pi \<bullet> p\<^sub>2'` have "\<langle>\<langle>p\<^sub>1, p\<^sub>2\<rangle>\<rangle> = (pi' @ pi) \<bullet> \<langle>\<langle>p\<^sub>1', p\<^sub>2'\<rangle>\<rangle>"
   742       by (simp add: pt_name2)
   742       by (simp add: pt_name2)
   743     moreover
   743     moreover
   744     have "((supp p\<^isub>2 \<union> (pi \<bullet> supp p\<^isub>2')) \<times> (supp p\<^isub>2 \<union> (pi \<bullet> supp p\<^isub>2'))::(name \<times> name) set) \<subseteq>
   744     have "((supp p\<^sub>2 \<union> (pi \<bullet> supp p\<^sub>2')) \<times> (supp p\<^sub>2 \<union> (pi \<bullet> supp p\<^sub>2'))::(name \<times> name) set) \<subseteq>
   745       (supp p\<^isub>2 \<union> (supp p\<^isub>1 \<union> supp p\<^isub>1' \<union> supp p\<^isub>2')) \<times> (supp p\<^isub>2 \<union> (supp p\<^isub>1 \<union> supp p\<^isub>1' \<union> supp p\<^isub>2'))"
   745       (supp p\<^sub>2 \<union> (supp p\<^sub>1 \<union> supp p\<^sub>1' \<union> supp p\<^sub>2')) \<times> (supp p\<^sub>2 \<union> (supp p\<^sub>1 \<union> supp p\<^sub>1' \<union> supp p\<^sub>2'))"
   746       by (rule subset_refl Sigma_mono Un_mono perm_cases [OF pi])+
   746       by (rule subset_refl Sigma_mono Un_mono perm_cases [OF pi])+
   747     with pi' have "set pi' \<subseteq> \<dots>" by (simp add: supp_eqvt [symmetric])
   747     with pi' have "set pi' \<subseteq> \<dots>" by (simp add: supp_eqvt [symmetric])
   748     with pi have "set (pi' @ pi) \<subseteq> (supp \<langle>\<langle>p\<^isub>1, p\<^isub>2\<rangle>\<rangle> \<union> supp \<langle>\<langle>p\<^isub>1', p\<^isub>2'\<rangle>\<rangle>) \<times>
   748     with pi have "set (pi' @ pi) \<subseteq> (supp \<langle>\<langle>p\<^sub>1, p\<^sub>2\<rangle>\<rangle> \<union> supp \<langle>\<langle>p\<^sub>1', p\<^sub>2'\<rangle>\<rangle>) \<times>
   749       (supp \<langle>\<langle>p\<^isub>1, p\<^isub>2\<rangle>\<rangle> \<union> supp \<langle>\<langle>p\<^isub>1', p\<^isub>2'\<rangle>\<rangle>)"
   749       (supp \<langle>\<langle>p\<^sub>1, p\<^sub>2\<rangle>\<rangle> \<union> supp \<langle>\<langle>p\<^sub>1', p\<^sub>2'\<rangle>\<rangle>)"
   750       by (simp add: Sigma_Un_distrib1 Sigma_Un_distrib2 Un_ac) blast
   750       by (simp add: Sigma_Un_distrib1 Sigma_Un_distrib2 Un_ac) blast
   751     moreover note `t = pi' \<bullet> pi \<bullet> u`
   751     moreover note `t = pi' \<bullet> pi \<bullet> u`
   752     ultimately have "\<langle>\<langle>p\<^isub>1, p\<^isub>2\<rangle>\<rangle> = (pi' @ pi) \<bullet> q \<and> t = (pi' @ pi) \<bullet> u \<and>
   752     ultimately have "\<langle>\<langle>p\<^sub>1, p\<^sub>2\<rangle>\<rangle> = (pi' @ pi) \<bullet> q \<and> t = (pi' @ pi) \<bullet> u \<and>
   753       set (pi' @ pi) \<subseteq> (supp \<langle>\<langle>p\<^isub>1, p\<^isub>2\<rangle>\<rangle> \<union> supp q) \<times>
   753       set (pi' @ pi) \<subseteq> (supp \<langle>\<langle>p\<^sub>1, p\<^sub>2\<rangle>\<rangle> \<union> supp q) \<times>
   754         (supp \<langle>\<langle>p\<^isub>1, p\<^isub>2\<rangle>\<rangle> \<union> supp q)" using PTuple
   754         (supp \<langle>\<langle>p\<^sub>1, p\<^sub>2\<rangle>\<rangle> \<union> supp q)" using PTuple
   755       by (simp add: pt_name2)
   755       by (simp add: pt_name2)
   756     then show ?thesis ..
   756     then show ?thesis ..
   757   qed
   757   qed
   758 qed
   758 qed
   759 
   759 
   803 lemma preservation:
   803 lemma preservation:
   804   assumes "t \<longmapsto> t'" and "\<Gamma> \<turnstile> t : T"
   804   assumes "t \<longmapsto> t'" and "\<Gamma> \<turnstile> t : T"
   805   shows "\<Gamma> \<turnstile> t' : T" using assms
   805   shows "\<Gamma> \<turnstile> t' : T" using assms
   806 proof (nominal_induct avoiding: \<Gamma> T rule: eval.strong_induct)
   806 proof (nominal_induct avoiding: \<Gamma> T rule: eval.strong_induct)
   807   case (TupleL t t' u)
   807   case (TupleL t t' u)
   808   from `\<Gamma> \<turnstile> \<langle>t, u\<rangle> : T` obtain T\<^isub>1 T\<^isub>2
   808   from `\<Gamma> \<turnstile> \<langle>t, u\<rangle> : T` obtain T\<^sub>1 T\<^sub>2
   809     where "T = T\<^isub>1 \<otimes> T\<^isub>2" "\<Gamma> \<turnstile> t : T\<^isub>1" "\<Gamma> \<turnstile> u : T\<^isub>2"
   809     where "T = T\<^sub>1 \<otimes> T\<^sub>2" "\<Gamma> \<turnstile> t : T\<^sub>1" "\<Gamma> \<turnstile> u : T\<^sub>2"
   810     by cases (simp_all add: trm.inject)
   810     by cases (simp_all add: trm.inject)
   811   from `\<Gamma> \<turnstile> t : T\<^isub>1` have "\<Gamma> \<turnstile> t' : T\<^isub>1" by (rule TupleL)
   811   from `\<Gamma> \<turnstile> t : T\<^sub>1` have "\<Gamma> \<turnstile> t' : T\<^sub>1" by (rule TupleL)
   812   then have "\<Gamma> \<turnstile> \<langle>t', u\<rangle> : T\<^isub>1 \<otimes> T\<^isub>2" using `\<Gamma> \<turnstile> u : T\<^isub>2`
   812   then have "\<Gamma> \<turnstile> \<langle>t', u\<rangle> : T\<^sub>1 \<otimes> T\<^sub>2" using `\<Gamma> \<turnstile> u : T\<^sub>2`
   813     by (rule Tuple)
   813     by (rule Tuple)
   814   with `T = T\<^isub>1 \<otimes> T\<^isub>2` show ?case by simp
   814   with `T = T\<^sub>1 \<otimes> T\<^sub>2` show ?case by simp
   815 next
   815 next
   816   case (TupleR u u' t)
   816   case (TupleR u u' t)
   817   from `\<Gamma> \<turnstile> \<langle>t, u\<rangle> : T` obtain T\<^isub>1 T\<^isub>2
   817   from `\<Gamma> \<turnstile> \<langle>t, u\<rangle> : T` obtain T\<^sub>1 T\<^sub>2
   818     where "T = T\<^isub>1 \<otimes> T\<^isub>2" "\<Gamma> \<turnstile> t : T\<^isub>1" "\<Gamma> \<turnstile> u : T\<^isub>2"
   818     where "T = T\<^sub>1 \<otimes> T\<^sub>2" "\<Gamma> \<turnstile> t : T\<^sub>1" "\<Gamma> \<turnstile> u : T\<^sub>2"
   819     by cases (simp_all add: trm.inject)
   819     by cases (simp_all add: trm.inject)
   820   from `\<Gamma> \<turnstile> u : T\<^isub>2` have "\<Gamma> \<turnstile> u' : T\<^isub>2" by (rule TupleR)
   820   from `\<Gamma> \<turnstile> u : T\<^sub>2` have "\<Gamma> \<turnstile> u' : T\<^sub>2" by (rule TupleR)
   821   with `\<Gamma> \<turnstile> t : T\<^isub>1` have "\<Gamma> \<turnstile> \<langle>t, u'\<rangle> : T\<^isub>1 \<otimes> T\<^isub>2"
   821   with `\<Gamma> \<turnstile> t : T\<^sub>1` have "\<Gamma> \<turnstile> \<langle>t, u'\<rangle> : T\<^sub>1 \<otimes> T\<^sub>2"
   822     by (rule Tuple)
   822     by (rule Tuple)
   823   with `T = T\<^isub>1 \<otimes> T\<^isub>2` show ?case by simp
   823   with `T = T\<^sub>1 \<otimes> T\<^sub>2` show ?case by simp
   824 next
   824 next
   825   case (Abs t t' x S)
   825   case (Abs t t' x S)
   826   from `\<Gamma> \<turnstile> (\<lambda>x:S. t) : T` `x \<sharp> \<Gamma>` obtain U where
   826   from `\<Gamma> \<turnstile> (\<lambda>x:S. t) : T` `x \<sharp> \<Gamma>` obtain U where
   827     T: "T = S \<rightarrow> U" and U: "(x, S) # \<Gamma> \<turnstile> t : U"
   827     T: "T = S \<rightarrow> U" and U: "(x, S) # \<Gamma> \<turnstile> t : U"
   828     by (rule typing_case_Abs)
   828     by (rule typing_case_Abs)