src/HOL/Nominal/Examples/SN.thy
changeset 22418 49e2d9744ae1
parent 22271 51a80e238b29
child 22420 4ccc8c1b08a3
equal deleted inserted replaced
22417:014e7696ac6b 22418:49e2d9744ae1
     6 
     6 
     7 text {* Strong Normalisation proof from the Proofs and Types book *}
     7 text {* Strong Normalisation proof from the Proofs and Types book *}
     8 
     8 
     9 section {* Beta Reduction *}
     9 section {* Beta Reduction *}
    10 
    10 
    11 lemma subst_rename[rule_format]: 
    11 lemma subst_rename: 
    12   shows "c\<sharp>t1 \<longrightarrow> (t1[a::=t2] = ([(c,a)]\<bullet>t1)[c::=t2])"
    12   assumes a: "c\<sharp>t1"
    13 apply(nominal_induct t1 avoiding: a c t2 rule: lam.induct)
    13   shows "t1[a::=t2] = ([(c,a)]\<bullet>t1)[c::=t2]"
    14 apply(auto simp add: calc_atm fresh_atm abs_fresh)
    14 using a
    15 done
    15 by (nominal_induct t1 avoiding: a c t2 rule: lam.induct)
       
    16    (auto simp add: calc_atm fresh_atm abs_fresh)
    16 
    17 
    17 lemma forget: 
    18 lemma forget: 
    18   assumes a: "a\<sharp>t1"
    19   assumes a: "a\<sharp>t1"
    19   shows "t1[a::=t2] = t1"
    20   shows "t1[a::=t2] = t1"
    20   using a
    21   using a
    21 apply (nominal_induct t1 avoiding: a t2 rule: lam.induct)
    22 by (nominal_induct t1 avoiding: a t2 rule: lam.induct)
    22 apply(auto simp add: abs_fresh fresh_atm)
    23    (auto simp add: abs_fresh fresh_atm)
    23 done
       
    24 
    24 
    25 lemma fresh_fact: 
    25 lemma fresh_fact: 
    26   fixes a::"name"
    26   fixes a::"name"
    27   assumes a: "a\<sharp>t1"
    27   assumes a: "a\<sharp>t1"
    28   and     b: "a\<sharp>t2"
    28   and     b: "a\<sharp>t2"
    29   shows "a\<sharp>(t1[b::=t2])"
    29   shows "a\<sharp>(t1[b::=t2])"
    30 using a b
    30 using a b
    31 apply(nominal_induct t1 avoiding: a b t2 rule: lam.induct)
    31 by (nominal_induct t1 avoiding: a b t2 rule: lam.induct)
    32 apply(auto simp add: abs_fresh fresh_atm)
    32    (auto simp add: abs_fresh fresh_atm)
    33 done
       
    34 
    33 
    35 lemma subst_lemma:  
    34 lemma subst_lemma:  
    36   assumes a: "x\<noteq>y"
    35   assumes a: "x\<noteq>y"
    37   and     b: "x\<sharp>L"
    36   and     b: "x\<sharp>L"
    38   shows "M[x::=N][y::=L] = M[y::=L][x::=N[y::=L]]"
    37   shows "M[x::=N][y::=L] = M[y::=L][x::=N[y::=L]]"
    39 using a b
    38 using a b
    40 by (nominal_induct M avoiding: x y N L rule: lam.induct)
    39 by (nominal_induct M avoiding: x y N L rule: lam.induct)
    41    (auto simp add: fresh_fact forget)
    40    (auto simp add: fresh_fact forget)
    42 
    41 
    43 lemma id_subs: "t[x::=Var x] = t"
    42 lemma id_subs: 
    44 apply(nominal_induct t avoiding: x rule: lam.induct)
    43   shows "t[x::=Var x] = t"
    45 apply(simp_all add: fresh_atm)
    44   by (nominal_induct t avoiding: x rule: lam.induct)
    46 done
    45      (simp_all add: fresh_atm)
       
    46 
       
    47 lemma subst_eqvt[eqvt]:
       
    48   fixes pi::"name prm" 
       
    49   and   t::"lam"
       
    50   shows "pi\<bullet>(t[x::=t']) = (pi\<bullet>t)[(pi\<bullet>x)::=(pi\<bullet>t')]"
       
    51 by (nominal_induct t avoiding: x t' rule: lam.induct)
       
    52    (perm_simp add: fresh_bij)+
    47 
    53 
    48 inductive2 Beta :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<longrightarrow>\<^isub>\<beta> _" [80,80] 80)
    54 inductive2 Beta :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<longrightarrow>\<^isub>\<beta> _" [80,80] 80)
    49 where
    55 where
    50   b1[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (App s1 t)\<longrightarrow>\<^isub>\<beta>(App s2 t)"
    56   b1[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (App s1 t)\<longrightarrow>\<^isub>\<beta>(App s2 t)"
    51 | b2[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (App t s1)\<longrightarrow>\<^isub>\<beta>(App t s2)"
    57 | b2[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (App t s1)\<longrightarrow>\<^isub>\<beta>(App t s2)"
    52 | b3[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (Lam [a].s1)\<longrightarrow>\<^isub>\<beta> (Lam [(a::name)].s2)"
    58 | b3[intro!]: "s1\<longrightarrow>\<^isub>\<beta>s2 \<Longrightarrow> (Lam [a].s1)\<longrightarrow>\<^isub>\<beta> (Lam [(a::name)].s2)"
    53 | b4[intro!]: "(App (Lam [(a::name)].s1) s2)\<longrightarrow>\<^isub>\<beta>(s1[a::=s2])"
    59 | b4[intro!]: "(App (Lam [(a::name)].s1) s2)\<longrightarrow>\<^isub>\<beta>(s1[a::=s2])"
    54 
    60 
    55 abbreviation "Beta_star"  :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<longrightarrow>\<^isub>\<beta>\<^sup>* _" [80,80] 80) where
    61 abbreviation "Beta_star"  :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<longrightarrow>\<^isub>\<beta>\<^sup>* _" [80,80] 80) where
    56   "t1 \<longrightarrow>\<^isub>\<beta>\<^sup>* t2 \<equiv> Beta\<^sup>*\<^sup>* t1 t2"
    62   "t1 \<longrightarrow>\<^isub>\<beta>\<^sup>* t2 \<equiv> Beta\<^sup>*\<^sup>* t1 t2"
       
    63 
       
    64 nominal_inductive Beta
    57  
    65  
    58 lemma eqvt_beta: 
       
    59   fixes pi :: "name prm"
       
    60   and   t  :: "lam"
       
    61   and   s  :: "lam"
       
    62   assumes a: "t\<longrightarrow>\<^isub>\<beta>s"
       
    63   shows "(pi\<bullet>t)\<longrightarrow>\<^isub>\<beta>(pi\<bullet>s)"
       
    64   using a by (induct, auto)
       
    65 
       
    66 lemma beta_induct[consumes 1, case_names b1 b2 b3 b4]:
    66 lemma beta_induct[consumes 1, case_names b1 b2 b3 b4]:
    67   fixes  P :: "'a::fs_name\<Rightarrow>lam \<Rightarrow> lam \<Rightarrow>bool"
    67   fixes  P :: "'a::fs_name\<Rightarrow>lam \<Rightarrow> lam \<Rightarrow>bool"
    68   and    t :: "lam"
    68   and    t :: "lam"
    69   and    s :: "lam"
    69   and    s :: "lam"
    70   and    x :: "'a::fs_name"
    70   and    x :: "'a::fs_name"
    75   and a4:    "\<And>a t1 s1 x. a\<sharp>x \<Longrightarrow> P x (App (Lam [a].t1) s1) (t1[a::=s1])"
    75   and a4:    "\<And>a t1 s1 x. a\<sharp>x \<Longrightarrow> P x (App (Lam [a].t1) s1) (t1[a::=s1])"
    76   shows "P x t s"
    76   shows "P x t s"
    77 proof -
    77 proof -
    78   from a have "\<And>(pi::name prm) x. P x (pi\<bullet>t) (pi\<bullet>s)"
    78   from a have "\<And>(pi::name prm) x. P x (pi\<bullet>t) (pi\<bullet>s)"
    79   proof (induct)
    79   proof (induct)
    80     case b1 thus ?case using a1 by (simp, blast intro: eqvt_beta)
    80     case b1 thus ?case using a1 by (simp, blast intro: eqvt)
    81   next
    81   next
    82     case b2 thus ?case using a2 by (simp, blast intro: eqvt_beta)
    82     case b2 thus ?case using a2 by (simp, blast intro: eqvt)
    83   next
    83   next
    84     case (b3 s1 s2 a)
    84     case (b3 s1 s2 a)
    85     have j1: "s1 \<longrightarrow>\<^isub>\<beta> s2" by fact
    85     have j1: "s1 \<longrightarrow>\<^isub>\<beta> s2" by fact
    86     have j2: "\<And>x (pi::name prm). P x (pi\<bullet>s1) (pi\<bullet>s2)" by fact
    86     have j2: "\<And>x (pi::name prm). P x (pi\<bullet>s1) (pi\<bullet>s2)" by fact
    87     show ?case 
    87     show ?case 
    90 	by (rule exists_fresh', simp add: fs_name1)
    90 	by (rule exists_fresh', simp add: fs_name1)
    91       then obtain c::"name" 
    91       then obtain c::"name" 
    92 	where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>x" and f3: "c\<sharp>(pi\<bullet>s1)" and f4: "c\<sharp>(pi\<bullet>s2)"
    92 	where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>x" and f3: "c\<sharp>(pi\<bullet>s1)" and f4: "c\<sharp>(pi\<bullet>s2)"
    93 	by (force simp add: fresh_prod fresh_atm)
    93 	by (force simp add: fresh_prod fresh_atm)
    94       have x: "P x (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s1)) (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s2))"
    94       have x: "P x (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s1)) (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s2))"
    95 	using a3 f2 j1 j2 by (simp, blast intro: eqvt_beta)
    95 	using a3 f2 j1 j2 by (simp, blast intro: eqvt)
    96       have alpha1: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s1))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s1))" using f1 f3
    96       have alpha1: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s1))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s1))" using f1 f3
    97 	by (simp add: lam.inject alpha)
    97 	by (simp add: lam.inject alpha)
    98       have alpha2: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s2))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s2))" using f1 f3
    98       have alpha2: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s2))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s2))" using f1 f3
    99 	by (simp add: lam.inject alpha)
    99 	by (simp add: lam.inject alpha)
   100       show " P x (Lam [(pi\<bullet>a)].(pi\<bullet>s1)) (Lam [(pi\<bullet>a)].(pi\<bullet>s2))"
   100       show " P x (Lam [(pi\<bullet>a)].(pi\<bullet>s1)) (Lam [(pi\<bullet>a)].(pi\<bullet>s2))"
   108 	by (rule exists_fresh', simp add: fs_name1)
   108 	by (rule exists_fresh', simp add: fs_name1)
   109       then obtain c::"name" 
   109       then obtain c::"name" 
   110 	where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>x" and f3: "c\<sharp>(pi\<bullet>s1)" and f4: "c\<sharp>(pi\<bullet>s2)"
   110 	where f1: "c\<noteq>(pi\<bullet>a)" and f2: "c\<sharp>x" and f3: "c\<sharp>(pi\<bullet>s1)" and f4: "c\<sharp>(pi\<bullet>s2)"
   111 	by (force simp add: fresh_prod fresh_atm)
   111 	by (force simp add: fresh_prod fresh_atm)
   112       have x: "P x (App (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s1)) (pi\<bullet>s2)) ((([(c,pi\<bullet>a)]@pi)\<bullet>s1)[c::=(pi\<bullet>s2)])"
   112       have x: "P x (App (Lam [c].(([(c,pi\<bullet>a)]@pi)\<bullet>s1)) (pi\<bullet>s2)) ((([(c,pi\<bullet>a)]@pi)\<bullet>s1)[c::=(pi\<bullet>s2)])"
   113 	using a4 f2 by (blast intro!: eqvt_beta)
   113 	using a4 f2 by (blast intro!: eqvt)
   114       have alpha1: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s1))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s1))" using f1 f3
   114       have alpha1: "(Lam [c].([(c,pi\<bullet>a)]\<bullet>(pi\<bullet>s1))) = (Lam [(pi\<bullet>a)].(pi\<bullet>s1))" using f1 f3
   115 	by (simp add: lam.inject alpha)
   115 	by (simp add: lam.inject alpha)
   116       have alpha2: "(([(c,pi\<bullet>a)]@pi)\<bullet>s1)[c::=(pi\<bullet>s2)] = (pi\<bullet>s1)[(pi\<bullet>a)::=(pi\<bullet>s2)]"
   116       have alpha2: "(([(c,pi\<bullet>a)]@pi)\<bullet>s1)[c::=(pi\<bullet>s2)] = (pi\<bullet>s1)[(pi\<bullet>a)::=(pi\<bullet>s2)]"
   117 	using f3 by (simp only: subst_rename[symmetric] pt_name2)
   117 	using f3 by (simp only: subst_rename[symmetric] pt_name2)
   118       show "P x (App (Lam [(pi\<bullet>a)].(pi\<bullet>s1)) (pi\<bullet>s2)) ((pi\<bullet>s1)[(pi\<bullet>a)::=(pi\<bullet>s2)])"
   118       show "P x (App (Lam [(pi\<bullet>a)].(pi\<bullet>s1)) (pi\<bullet>s2)) ((pi\<bullet>s1)[(pi\<bullet>a)::=(pi\<bullet>s2)])"
   143 apply(rule pt_name3)
   143 apply(rule pt_name3)
   144 apply(simp add: at_ds5[OF at_name_inst])
   144 apply(simp add: at_ds5[OF at_name_inst])
   145 apply(rule conjI)
   145 apply(rule conjI)
   146 apply(simp add: pt_fresh_left[OF pt_name_inst, OF at_name_inst] calc_atm)
   146 apply(simp add: pt_fresh_left[OF pt_name_inst, OF at_name_inst] calc_atm)
   147 apply(force dest!: supp_beta simp add: fresh_def)
   147 apply(force dest!: supp_beta simp add: fresh_def)
   148 apply(force intro!: eqvt_beta)
   148 apply(force intro!: eqvt)
   149 done
   149 done
   150 
   150 
   151 lemma beta_subst: 
   151 lemma beta_subst: 
   152   assumes a: "M \<longrightarrow>\<^isub>\<beta> M'"
   152   assumes a: "M \<longrightarrow>\<^isub>\<beta> M'"
   153   shows "M[x::=N]\<longrightarrow>\<^isub>\<beta> M'[x::=N]" 
   153   shows "M[x::=N]\<longrightarrow>\<^isub>\<beta> M'[x::=N]" 
   156 apply(auto simp add: fresh_atm subst_lemma)
   156 apply(auto simp add: fresh_atm subst_lemma)
   157 done
   157 done
   158 
   158 
   159 section {* types *}
   159 section {* types *}
   160 
   160 
   161 datatype ty =
   161 nominal_datatype ty =
   162     TVar "string"
   162     TVar "nat"
   163   | TArr "ty" "ty" (infix "\<rightarrow>" 200)
   163   | TArr "ty" "ty" (infix "\<rightarrow>" 200)
   164 
       
   165 primrec (unchecked)
       
   166  "pi\<bullet>(TVar s) = TVar s"
       
   167  "pi\<bullet>(\<tau> \<rightarrow> \<sigma>) = (\<tau> \<rightarrow> \<sigma>)"
       
   168 
   164 
   169 lemma perm_ty[simp]:
   165 lemma perm_ty[simp]:
   170   fixes pi ::"name prm"
   166   fixes pi ::"name prm"
   171   and   \<tau>  ::"ty"
   167   and   \<tau>  ::"ty"
   172   shows "pi\<bullet>\<tau> = \<tau>"
   168   shows "pi\<bullet>\<tau> = \<tau>"
   173   by (cases \<tau>, simp_all)
   169 by (nominal_induct \<tau> rule: ty.induct) 
       
   170    (simp_all add: perm_nat_def)
   174 
   171 
   175 lemma fresh_ty:
   172 lemma fresh_ty:
   176   fixes a ::"name"
   173   fixes a ::"name"
   177   and   \<tau>  ::"ty"
   174   and   \<tau>  ::"ty"
   178   shows "a\<sharp>\<tau>"
   175   shows "a\<sharp>\<tau>"
   179   by (simp add: fresh_def supp_def)
   176   by (simp add: fresh_def supp_def)
   180 
   177 
   181 instance ty :: pt_name
       
   182 apply(intro_classes)   
       
   183 apply(simp_all)
       
   184 done
       
   185 
       
   186 instance ty :: fs_name
       
   187 apply(intro_classes)
       
   188 apply(simp add: supp_def)
       
   189 done
       
   190 
       
   191 (* valid contexts *)
   178 (* valid contexts *)
   192 
   179 
   193 consts
   180 consts
   194   "dom_ty" :: "(name\<times>ty) list \<Rightarrow> (name list)"
   181   "dom_ty" :: "(name\<times>ty) list \<Rightarrow> (name list)"
   195 primrec
   182 primrec
   199 inductive2 valid :: "(name\<times>ty) list \<Rightarrow> bool"
   186 inductive2 valid :: "(name\<times>ty) list \<Rightarrow> bool"
   200 where
   187 where
   201   v1[intro]: "valid []"
   188   v1[intro]: "valid []"
   202 | v2[intro]: "\<lbrakk>valid \<Gamma>;a\<sharp>\<Gamma>\<rbrakk>\<Longrightarrow> valid ((a,\<sigma>)#\<Gamma>)"
   189 | v2[intro]: "\<lbrakk>valid \<Gamma>;a\<sharp>\<Gamma>\<rbrakk>\<Longrightarrow> valid ((a,\<sigma>)#\<Gamma>)"
   203 
   190 
   204 lemma valid_eqvt:
   191 nominal_inductive valid
   205   fixes   pi:: "name prm"
       
   206   assumes a: "valid \<Gamma>"
       
   207   shows   "valid (pi\<bullet>\<Gamma>)"
       
   208 using a
       
   209 apply(induct)
       
   210 apply(auto simp add: fresh_bij)
       
   211 done
       
   212 
   192 
   213 (* typing judgements *)
   193 (* typing judgements *)
   214 
   194 
   215 lemma fresh_context[rule_format]: 
   195 lemma fresh_context: 
   216   fixes  \<Gamma> :: "(name\<times>ty)list"
   196   fixes  \<Gamma> :: "(name\<times>ty)list"
   217   and    a :: "name"
   197   and    a :: "name"
   218   assumes a: "a\<sharp>\<Gamma>"
   198   assumes a: "a\<sharp>\<Gamma>"
   219   shows "\<not>(\<exists>\<tau>::ty. (a,\<tau>)\<in>set \<Gamma>)"
   199   shows "\<not>(\<exists>\<tau>::ty. (a,\<tau>)\<in>set \<Gamma>)"
   220 using a
   200 using a
   221 apply(induct \<Gamma>)
   201 apply(induct \<Gamma>)
   222 apply(auto simp add: fresh_prod fresh_list_cons fresh_atm)
   202 apply(auto simp add: fresh_prod fresh_list_cons fresh_atm)
   223 done
   203 done
   224 
   204 
   225 lemma valid_elim: 
   205 inductive_cases2 valid_elim[elim]: "valid ((a,\<tau>)#\<Gamma>)"
   226   fixes  \<Gamma> :: "(name\<times>ty)list"
   206 
   227   and    pi:: "name prm"
   207 lemma valid_unicity: 
   228   and    a :: "name"
       
   229   and    \<tau> :: "ty"
       
   230   shows "valid ((a,\<tau>)#\<Gamma>) \<Longrightarrow> valid \<Gamma> \<and> a\<sharp>\<Gamma>"
       
   231 apply(ind_cases2 "valid ((a,\<tau>)#\<Gamma>)", simp)
       
   232 done
       
   233 
       
   234 lemma valid_unicity[rule_format]: 
       
   235   assumes a: "valid \<Gamma>"
   208   assumes a: "valid \<Gamma>"
   236   and     b: "(c,\<sigma>)\<in>set \<Gamma>"
   209   and     b: "(c,\<sigma>)\<in>set \<Gamma>"
   237   and     c: "(c,\<tau>)\<in>set \<Gamma>"
   210   and     c: "(c,\<tau>)\<in>set \<Gamma>"
   238   shows "\<sigma>=\<tau>" 
   211   shows "\<sigma>=\<tau>" 
   239 using a b c
   212 using a b c
   240 apply(induct \<Gamma>)
   213 by (induct \<Gamma>) (auto dest!: fresh_context)
   241 apply(auto dest!: valid_elim fresh_context)
       
   242 done
       
   243 
   214 
   244 inductive2 typing :: "(name\<times>ty) list\<Rightarrow>lam\<Rightarrow>ty\<Rightarrow>bool" (" _ \<turnstile> _ : _ " [80,80,80] 80)
   215 inductive2 typing :: "(name\<times>ty) list\<Rightarrow>lam\<Rightarrow>ty\<Rightarrow>bool" (" _ \<turnstile> _ : _ " [80,80,80] 80)
   245 where
   216 where
   246   t1[intro]: "\<lbrakk>valid \<Gamma>; (a,\<tau>)\<in>set \<Gamma>\<rbrakk>\<Longrightarrow> \<Gamma> \<turnstile> Var a : \<tau>"
   217   t1[intro]: "\<lbrakk>valid \<Gamma>; (a,\<tau>)\<in>set \<Gamma>\<rbrakk>\<Longrightarrow> \<Gamma> \<turnstile> Var a : \<tau>"
   247 | t2[intro]: "\<lbrakk>\<Gamma> \<turnstile> t1 : \<tau>\<rightarrow>\<sigma>; \<Gamma> \<turnstile> t2 : \<tau>\<rbrakk>\<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : \<sigma>"
   218 | t2[intro]: "\<lbrakk>\<Gamma> \<turnstile> t1 : \<tau>\<rightarrow>\<sigma>; \<Gamma> \<turnstile> t2 : \<tau>\<rbrakk>\<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : \<sigma>"
   259   case (t1 \<Gamma> a \<tau>)
   230   case (t1 \<Gamma> a \<tau>)
   260   have "valid (pi\<bullet>\<Gamma>)" by (rule valid_eqvt)
   231   have "valid (pi\<bullet>\<Gamma>)" by (rule valid_eqvt)
   261   moreover
   232   moreover
   262   have "(pi\<bullet>(a,\<tau>))\<in>((pi::name prm)\<bullet>set \<Gamma>)" by (rule pt_set_bij2[OF pt_name_inst, OF at_name_inst])
   233   have "(pi\<bullet>(a,\<tau>))\<in>((pi::name prm)\<bullet>set \<Gamma>)" by (rule pt_set_bij2[OF pt_name_inst, OF at_name_inst])
   263   ultimately show "(pi\<bullet>\<Gamma>) \<turnstile> ((pi::name prm)\<bullet>Var a) : \<tau>"
   234   ultimately show "(pi\<bullet>\<Gamma>) \<turnstile> ((pi::name prm)\<bullet>Var a) : \<tau>"
   264     using typing.t1 by (force simp add: pt_list_set_pi[OF pt_name_inst, symmetric])
   235     using typing.t1 by (force simp add: set_eqvt[symmetric])
   265 next 
   236 next 
   266   case (t3 a \<Gamma> \<tau> t \<sigma>)
   237   case (t3 a \<Gamma> \<tau> t \<sigma>)
   267   moreover have "(pi\<bullet>a)\<sharp>(pi\<bullet>\<Gamma>)" by (simp add: fresh_bij)
   238   moreover have "(pi\<bullet>a)\<sharp>(pi\<bullet>\<Gamma>)" by (simp add: fresh_bij)
   268   ultimately show "(pi\<bullet>\<Gamma>) \<turnstile> (pi\<bullet>Lam [a].t) :\<tau>\<rightarrow>\<sigma>" by force 
   239   ultimately show "(pi\<bullet>\<Gamma>) \<turnstile> (pi\<bullet>Lam [a].t) :\<tau>\<rightarrow>\<sigma>" by force 
   269 qed (auto)
   240 qed (auto)
   288     case (t1 \<Gamma> a \<tau>)
   259     case (t1 \<Gamma> a \<tau>)
   289     have j1: "valid \<Gamma>" by fact
   260     have j1: "valid \<Gamma>" by fact
   290     have j2: "(a,\<tau>)\<in>set \<Gamma>" by fact
   261     have j2: "(a,\<tau>)\<in>set \<Gamma>" by fact
   291     from j1 have j3: "valid (pi\<bullet>\<Gamma>)" by (rule valid_eqvt)
   262     from j1 have j3: "valid (pi\<bullet>\<Gamma>)" by (rule valid_eqvt)
   292     from j2 have "pi\<bullet>(a,\<tau>)\<in>pi\<bullet>(set \<Gamma>)" by (simp only: pt_set_bij[OF pt_name_inst, OF at_name_inst])  
   263     from j2 have "pi\<bullet>(a,\<tau>)\<in>pi\<bullet>(set \<Gamma>)" by (simp only: pt_set_bij[OF pt_name_inst, OF at_name_inst])  
   293     hence j4: "(pi\<bullet>a,\<tau>)\<in>set (pi\<bullet>\<Gamma>)" by (simp add: pt_list_set_pi[OF pt_name_inst])
   264     hence j4: "(pi\<bullet>a,\<tau>)\<in>set (pi\<bullet>\<Gamma>)" by (simp add: eqvt)
   294     show "P x (pi\<bullet>\<Gamma>) (pi\<bullet>(Var a)) \<tau>" using a1 j3 j4 by simp
   265     show "P x (pi\<bullet>\<Gamma>) (pi\<bullet>(Var a)) \<tau>" using a1 j3 j4 by simp
   295   next
   266   next
   296     case (t2 \<Gamma> t1 \<tau> \<sigma> t2)
   267     case (t2 \<Gamma> t1 \<tau> \<sigma> t2)
   297     thus ?case using a2 by (simp, blast intro: eqvt_typing)
   268     thus ?case using a2 by (simp, blast intro: eqvt_typing)
   298   next
   269   next
   344 
   315 
   345 lemma in_ctxt: 
   316 lemma in_ctxt: 
   346   assumes a: "(a,\<tau>)\<in>set \<Gamma>"
   317   assumes a: "(a,\<tau>)\<in>set \<Gamma>"
   347   shows "a\<in>set(dom_ty \<Gamma>)"
   318   shows "a\<in>set(dom_ty \<Gamma>)"
   348 using a
   319 using a
   349 apply(induct \<Gamma>, auto)
   320 by (induct \<Gamma>) (auto)
   350 done
       
   351 
   321 
   352 lemma free_vars: 
   322 lemma free_vars: 
   353   assumes a: "\<Gamma> \<turnstile> t : \<tau>"
   323   assumes a: "\<Gamma> \<turnstile> t : \<tau>"
   354   shows " (supp t)\<subseteq>set(dom_ty \<Gamma>)"
   324   shows " (supp t)\<subseteq>set(dom_ty \<Gamma>)"
   355 using a
   325 using a
   356 apply(nominal_induct \<Gamma> t \<tau> rule: typing_induct)
   326 by (nominal_induct \<Gamma> t \<tau> rule: typing_induct)
   357 apply(auto simp add: lam.supp abs_supp supp_atm in_ctxt)
   327    (auto simp add: lam.supp abs_supp supp_atm in_ctxt)
   358 done
       
   359 
   328 
   360 lemma t1_elim: "\<Gamma> \<turnstile> Var a : \<tau> \<Longrightarrow> valid \<Gamma> \<and> (a,\<tau>) \<in> set \<Gamma>"
   329 lemma t1_elim: "\<Gamma> \<turnstile> Var a : \<tau> \<Longrightarrow> valid \<Gamma> \<and> (a,\<tau>) \<in> set \<Gamma>"
   361 apply(ind_cases2 "\<Gamma> \<turnstile> Var a : \<tau>")
   330 apply(ind_cases2 "\<Gamma> \<turnstile> Var a : \<tau>")
   362 apply(auto simp add: lam.inject lam.distinct)
   331 apply(auto simp add: lam.inject lam.distinct)
   363 done
   332 done
   379 done
   348 done
   380 
   349 
   381 lemma typing_valid: 
   350 lemma typing_valid: 
   382   assumes a: "\<Gamma> \<turnstile> t : \<tau>" 
   351   assumes a: "\<Gamma> \<turnstile> t : \<tau>" 
   383   shows "valid \<Gamma>"
   352   shows "valid \<Gamma>"
   384 using a by (induct, auto dest!: valid_elim)
   353 using a by (induct, auto)
   385 
   354 
   386 lemma ty_subs:
   355 lemma ty_subs:
   387   assumes a: "((c,\<sigma>)#\<Gamma>) \<turnstile> t1:\<tau>"
   356   assumes a: "((c,\<sigma>)#\<Gamma>) \<turnstile> t1:\<tau>"
   388   and     b: "\<Gamma>\<turnstile> t2:\<sigma>"
   357   and     b: "\<Gamma>\<turnstile> t2:\<sigma>"
   389   shows  "\<Gamma> \<turnstile> t1[c::=t2]:\<tau>"
   358   shows  "\<Gamma> \<turnstile> t1[c::=t2]:\<tau>"
   432   have c1: "((c,\<sigma>)#\<Gamma>)\<turnstile>Lam [a].s : \<tau>" by fact
   401   have c1: "((c,\<sigma>)#\<Gamma>)\<turnstile>Lam [a].s : \<tau>" by fact
   433   hence "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" using f4 by (auto dest: t3_elim) 
   402   hence "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" using f4 by (auto dest: t3_elim) 
   434   then obtain \<tau>1 \<tau>2 where c11: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and c12: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" by force
   403   then obtain \<tau>1 \<tau>2 where c11: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and c12: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<turnstile> s : \<tau>2" by force
   435   from c12 have "valid ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>)" by (rule typing_valid)
   404   from c12 have "valid ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>)" by (rule typing_valid)
   436   hence ca: "valid \<Gamma>" and cb: "a\<sharp>\<Gamma>" and cc: "c\<sharp>\<Gamma>" 
   405   hence ca: "valid \<Gamma>" and cb: "a\<sharp>\<Gamma>" and cc: "c\<sharp>\<Gamma>" 
   437     by (auto dest: valid_elim simp add: fresh_list_cons) 
   406     by (auto simp add: fresh_list_cons) 
   438   from c12 have c14: "((c,\<sigma>)#(a,\<tau>1)#\<Gamma>) \<turnstile> s : \<tau>2"
   407   from c12 have c14: "((c,\<sigma>)#(a,\<tau>1)#\<Gamma>) \<turnstile> s : \<tau>2"
   439   proof -
   408   proof -
   440     have c2: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<lless> ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" by force
   409     have c2: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<lless> ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" by force
   441     have c3: "valid ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)"
   410     have c3: "valid ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)"
   442       by (rule v2, rule v2, auto simp add: fresh_list_cons fresh_prod ca cb cc f2' fresh_ty)
   411       by (rule v2, rule v2, auto simp add: fresh_list_cons fresh_prod ca cb cc f2' fresh_ty)
   484   case (b4 a s1 s2) --"Beta-redex"
   453   case (b4 a s1 s2) --"Beta-redex"
   485   have fr: "a\<sharp>\<Gamma>" by fact
   454   have fr: "a\<sharp>\<Gamma>" by fact
   486   have "\<Gamma> \<turnstile> App (Lam [a].s1) s2 : \<tau>" by fact
   455   have "\<Gamma> \<turnstile> App (Lam [a].s1) s2 : \<tau>" by fact
   487   hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s2 : \<sigma>)" by (simp add: t2_elim)
   456   hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s2 : \<sigma>)" by (simp add: t2_elim)
   488   then obtain \<sigma> where a1: "\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s2 : \<sigma>" by blast
   457   then obtain \<sigma> where a1: "\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s2 : \<sigma>" by blast
   489   from a1 have "((a,\<sigma>)#\<Gamma>) \<turnstile> s1 : \<tau>" using fr by (blast dest!: t3_elim)
   458   from a1 have "((a,\<sigma>)#\<Gamma>) \<turnstile> s1 : \<tau>" using fr by (auto dest!: t3_elim simp add: ty.inject) 
   490   with a2 show "\<Gamma> \<turnstile> s1[a::=s2] : \<tau>" by (simp add: ty_subs)
   459   with a2 show "\<Gamma> \<turnstile> s1[a::=s2] : \<tau>" by (simp add: ty_subs)
   491 qed
   460 qed
   492 
   461 
   493 lemma subject_automatic: 
   462 lemma subject_automatic: 
   494   assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2"
   463   assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2"
   495   and     b: "\<Gamma> \<turnstile> t1:\<tau>"
   464   and     b: "\<Gamma> \<turnstile> t1:\<tau>"
   496   shows "\<Gamma> \<turnstile> t2:\<tau>"
   465   shows "\<Gamma> \<turnstile> t2:\<tau>"
   497 using a b
   466 using a b
   498 apply(nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct)
   467 apply(nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct)
   499 apply(auto dest!: t2_elim t3_elim intro: ty_subs)
   468 apply(auto dest!: t2_elim t3_elim intro: ty_subs simp add: ty.inject)
   500 done
   469 done
   501 
   470 
   502 subsection {* some facts about beta *}
   471 subsection {* some facts about beta *}
   503 
   472 
   504 constdefs
   473 constdefs
   531 apply(auto)
   500 apply(auto)
   532 done
   501 done
   533 
   502 
   534 section {* Candidates *}
   503 section {* Candidates *}
   535 
   504 
   536 consts
   505 lemma ty_cases:
       
   506   fixes x::ty
       
   507   shows "(\<exists>X. x= TVar X) \<or> (\<exists>T1 T2. x=T1\<rightarrow>T2)"
       
   508 by (induct x rule: ty.induct_weak) (auto)
       
   509 
       
   510 function
   537   RED :: "ty \<Rightarrow> lam set"
   511   RED :: "ty \<Rightarrow> lam set"
   538 primrec
   512 where
   539  "RED (TVar X) = {t. SN(t)}"
   513   "RED (TVar X) = {t. SN(t)}"
   540  "RED (\<tau>\<rightarrow>\<sigma>) =   {t. \<forall>u. (u\<in>RED \<tau> \<longrightarrow> (App t u)\<in>RED \<sigma>)}"
   514 | "RED (\<tau>\<rightarrow>\<sigma>) =   {t. \<forall>u. (u\<in>RED \<tau> \<longrightarrow> (App t u)\<in>RED \<sigma>)}"
       
   515 apply(auto simp add: ty.inject)
       
   516 apply(subgoal_tac "(\<exists>X. x= TVar X) \<or> (\<exists>T1 T2. x=T1\<rightarrow>T2)")
       
   517 apply(blast)
       
   518 apply(rule ty_cases)
       
   519 done
       
   520 
       
   521 instance ty :: size ..
       
   522 
       
   523 nominal_primrec
       
   524   "size (TVar X) = 1"
       
   525   "size (T\<^isub>1\<rightarrow>T\<^isub>2) = size T\<^isub>1 + size T\<^isub>2"
       
   526 by (rule TrueI)+
       
   527 
       
   528 lemma ty_size_greater_zero[simp]:
       
   529   fixes T::"ty"
       
   530   shows "size T > 0"
       
   531 by (nominal_induct T rule: ty.induct) (simp_all)
       
   532 
       
   533 termination
       
   534 apply(relation "measure size") 
       
   535 apply(auto)
       
   536 done
   541 
   537 
   542 constdefs
   538 constdefs
   543   NEUT :: "lam \<Rightarrow> bool"
   539   NEUT :: "lam \<Rightarrow> bool"
   544   "NEUT t \<equiv> (\<exists>a. t=Var a)\<or>(\<exists>t1 t2. t=App t1 t2)" 
   540   "NEUT t \<equiv> (\<exists>a. t=Var a)\<or>(\<exists>t1 t2. t=App t1 t2)" 
   545 
   541 
   546 (* a slight hack to get the first element of applications *)
   542 (* a slight hack to get the first element of applications *)
   547 inductive2 FST :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<guillemotright> _" [80,80] 80)
   543 inductive2 FST :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<guillemotright> _" [80,80] 80)
   548 where
   544 where
   549 fst[intro!]:  "(App t s) \<guillemotright> t"
   545   fst[intro!]:  "(App t s) \<guillemotright> t"
   550 
   546 
   551 lemma fst_elim[elim!]: 
   547 lemma fst_elim[elim!]: 
   552   shows "(App t s) \<guillemotright> t' \<Longrightarrow> t=t'"
   548   shows "(App t s) \<guillemotright> t' \<Longrightarrow> t=t'"
   553 apply(ind_cases2 "App t s \<guillemotright> t'")
   549 apply(ind_cases2 "App t s \<guillemotright> t'")
   554 apply(simp add: lam.inject)
   550 apply(simp add: lam.inject)
   618 apply(auto simp only: NEUT_def lam.inject lam.distinct)
   614 apply(auto simp only: NEUT_def lam.inject lam.distinct)
   619 done
   615 done
   620 
   616 
   621 lemma RED_props: 
   617 lemma RED_props: 
   622   shows "CR1 \<tau>" and "CR2 \<tau>" and "CR3 \<tau>"
   618   shows "CR1 \<tau>" and "CR2 \<tau>" and "CR3 \<tau>"
   623 proof (induct \<tau>)
   619 proof (nominal_induct \<tau> rule: ty.induct)
   624   case (TVar a)
   620   case (TVar a)
   625   { case 1 show "CR1 (TVar a)" by (simp add: CR1_def)
   621   { case 1 show "CR1 (TVar a)" by (simp add: CR1_def)
   626   next
   622   next
   627     case 2 show "CR2 (TVar a)" by (force intro: SN_preserved simp add: CR2_def)
   623     case 2 show "CR2 (TVar a)" by (force intro: SN_preserved simp add: CR2_def)
   628   next
   624   next
   798 apply(simp add: CR1_def SN_def)
   794 apply(simp add: CR1_def SN_def)
   799 (*3*)
   795 (*3*)
   800 apply(force simp add: RED_props)
   796 apply(force simp add: RED_props)
   801 done
   797 done
   802 
   798 
       
   799 (* HERE *)
       
   800 
       
   801 (*
   803 lemma fresh_domain: 
   802 lemma fresh_domain: 
   804   assumes a: "a\<sharp>\<theta>"
   803   assumes a: "a\<sharp>\<theta>"
   805   shows "a\<notin>set(domain \<theta>)"
   804   shows "a\<notin>set(domain \<theta>)"
   806 using a
   805 using a
   807 apply(induct \<theta>)
   806 apply(induct \<theta>)
   815 using a b
   814 using a b
   816 apply(induct \<theta>)   
   815 apply(induct \<theta>)   
   817 apply(auto simp add: fresh_prod fresh_list_cons)
   816 apply(auto simp add: fresh_prod fresh_list_cons)
   818 done
   817 done
   819 
   818 
   820 lemma psubst_subst: 
   819 lemma fresh_psubst: 
   821   assumes a: "c\<sharp>\<theta>"
   820   fixes z::"name"
       
   821   and   t::"lam"
       
   822   assumes "z\<sharp>t" "z\<sharp>\<theta>"
       
   823   shows "z\<sharp>(t[<\<theta>>])"
       
   824 using assms
       
   825 by (nominal_induct t avoiding: z \<theta> t rule: lam.induct)
       
   826    (auto simp add: abs_fresh lookup_fresh)
       
   827 
       
   828 lemma psubst_subst:
       
   829   assumes h:"c\<sharp>\<theta>"
   822   shows "(t[<\<theta>>])[c::=s] = t[<((c,s)#\<theta>)>]"
   830   shows "(t[<\<theta>>])[c::=s] = t[<((c,s)#\<theta>)>]"
   823 using a
   831   using h
   824 apply(nominal_induct t avoiding: \<theta> c s rule: lam.induct)
   832 by (nominal_induct t avoiding: \<theta> c s rule: lam.induct)
   825 apply(auto dest: fresh_domain)
   833  (auto simp add: fresh_list_cons fresh_atm forget lookup_fresh lookup_fresh' fresh_psubst)
   826 apply(drule fresh_at)
   834 
   827 apply(assumption)
       
   828 apply(rule forget)
       
   829 apply(assumption)
       
   830 apply(subgoal_tac "name\<sharp>((c,s)#\<theta>)")(*A*)
       
   831 apply(simp)
       
   832 (*A*)
       
   833 apply(simp add: fresh_list_cons fresh_prod)
       
   834 done
       
   835 
   835 
   836 lemma all_RED: 
   836 lemma all_RED: 
   837   assumes a: "\<Gamma>\<turnstile>t:\<tau>"
   837   assumes a: "\<Gamma>\<turnstile>t:\<tau>"
   838   and     b: "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain \<theta>)\<and>\<theta><a>\<in>RED \<sigma>)" 
   838   and     b: "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain \<theta>)\<and>\<theta><a>\<in>RED \<sigma>)" 
   839   shows "t[<\<theta>>]\<in>RED \<tau>"
   839   shows "t[<\<theta>>]\<in>RED \<tau>"
   840 using a b
   840 using a b
       
   841 sorry
       
   842 
   841 proof(nominal_induct t avoiding: \<Gamma> \<tau> \<theta> rule: lam.induct)
   843 proof(nominal_induct t avoiding: \<Gamma> \<tau> \<theta> rule: lam.induct)
   842   case (Lam a t) --"lambda case"
   844   case (Lam a t) --"lambda case"
   843   have ih: "\<And>\<Gamma> \<tau> \<theta>. \<Gamma> \<turnstile> t:\<tau> \<Longrightarrow> 
   845   have ih: "\<And>\<Gamma> \<tau> \<theta>. \<Gamma> \<turnstile> t:\<tau> \<Longrightarrow> 
   844                     (\<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and>  \<theta><c>\<in>RED \<sigma>) 
   846                     (\<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and>  \<theta><c>\<in>RED \<sigma>) 
   845                     \<Longrightarrow> t[<\<theta>>]\<in>RED \<tau>" 
   847                     \<Longrightarrow> t[<\<theta>>]\<in>RED \<tau>" 
   858 lemma all_RED: 
   860 lemma all_RED: 
   859   assumes a: "\<Gamma>\<turnstile>t:\<tau>"
   861   assumes a: "\<Gamma>\<turnstile>t:\<tau>"
   860   and     b: "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain \<theta>)\<and>\<theta><a>\<in>RED \<sigma>)" 
   862   and     b: "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain \<theta>)\<and>\<theta><a>\<in>RED \<sigma>)" 
   861   shows "t[<\<theta>>]\<in>RED \<tau>"
   863   shows "t[<\<theta>>]\<in>RED \<tau>"
   862 using a b
   864 using a b
       
   865 sorry
       
   866 
   863 proof(nominal_induct t avoiding: \<Gamma> \<tau> \<theta> rule: lam.induct)
   867 proof(nominal_induct t avoiding: \<Gamma> \<tau> \<theta> rule: lam.induct)
   864   case (Lam a t) --"lambda case"
   868   case (Lam a t) --"lambda case"
   865   have ih: "\<And>\<Gamma> \<tau> \<theta>. \<lbrakk>\<Gamma> \<turnstile> t:\<tau>; \<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and>  \<theta><c>\<in>RED \<sigma>\<rbrakk> 
   869   have ih: "\<And>\<Gamma> \<tau> \<theta>. \<lbrakk>\<Gamma> \<turnstile> t:\<tau>; \<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and>  \<theta><c>\<in>RED \<sigma>\<rbrakk> 
   866                     \<Longrightarrow> t[<\<theta>>]\<in>RED \<tau>" 
   870                     \<Longrightarrow> t[<\<theta>>]\<in>RED \<tau>" 
   867   and  \<theta>_cond: "\<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and>  \<theta><c>\<in>RED \<sigma>" 
   871   and  \<theta>_cond: "\<forall>c \<sigma>. (c,\<sigma>)\<in>set \<Gamma> \<longrightarrow> c\<in>set (domain \<theta>) \<and>  \<theta><c>\<in>RED \<sigma>" 
   872   from ih have "\<forall>s\<in>RED \<tau>1. t[<\<theta>>][a::=s] \<in> RED \<tau>2" using fresh typing \<theta>_cond
   876   from ih have "\<forall>s\<in>RED \<tau>1. t[<\<theta>>][a::=s] \<in> RED \<tau>2" using fresh typing \<theta>_cond
   873     by (force dest: fresh_context simp add: psubst_subst)
   877     by (force dest: fresh_context simp add: psubst_subst)
   874   hence "(Lam [a].(t[<\<theta>>])) \<in> RED (\<tau>1 \<rightarrow> \<tau>2)" by (simp only: abs_RED)
   878   hence "(Lam [a].(t[<\<theta>>])) \<in> RED (\<tau>1 \<rightarrow> \<tau>2)" by (simp only: abs_RED)
   875   thus "(Lam [a].t)[<\<theta>>] \<in> RED \<tau>" using fresh \<tau>_inst by simp
   879   thus "(Lam [a].t)[<\<theta>>] \<in> RED \<tau>" using fresh \<tau>_inst by simp
   876 qed (force dest!: t1_elim t2_elim)+
   880 qed (force dest!: t1_elim t2_elim)+
       
   881 *)
   877 
   882 
   878 (* identity substitution generated from a context \<Gamma> *)
   883 (* identity substitution generated from a context \<Gamma> *)
       
   884 (*
   879 consts
   885 consts
   880   "id" :: "(name\<times>ty) list \<Rightarrow> (name\<times>lam) list"
   886   "id" :: "(name\<times>ty) list \<Rightarrow> (name\<times>lam) list"
   881 primrec
   887 primrec
   882   "id []    = []"
   888   "id []    = []"
   883   "id (x#\<Gamma>) = ((fst x),Var (fst x))#(id \<Gamma>)"
   889   "id (x#\<Gamma>) = ((fst x),Var (fst x))#(id \<Gamma>)"
   900 
   906 
   901 lemma id_apply:  
   907 lemma id_apply:  
   902   shows "t[<(id \<Gamma>)>] = t"
   908   shows "t[<(id \<Gamma>)>] = t"
   903 apply(nominal_induct t avoiding: \<Gamma> rule: lam.induct)
   909 apply(nominal_induct t avoiding: \<Gamma> rule: lam.induct)
   904 apply(auto)
   910 apply(auto)
       
   911 sorry
       
   912 
   905 apply(simp add: id_var)
   913 apply(simp add: id_var)
   906 apply(drule id_fresh)+
   914 apply(drule id_fresh)+
   907 apply(simp)
   915 apply(simp)
   908 done
   916 done
       
   917 
   909 
   918 
   910 lemma id_mem:
   919 lemma id_mem:
   911   assumes a: "(a,\<tau>)\<in>set \<Gamma>"
   920   assumes a: "(a,\<tau>)\<in>set \<Gamma>"
   912   shows "a \<in> set (domain (id \<Gamma>))"
   921   shows "a \<in> set (domain (id \<Gamma>))"
   913 using a
   922 using a
   918   shows "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain (id \<Gamma>))\<and>(id \<Gamma>)<a>\<in>RED \<sigma>)"
   927   shows "\<forall>a \<sigma>. (a,\<sigma>)\<in>set(\<Gamma>) \<longrightarrow> (a\<in>set(domain (id \<Gamma>))\<and>(id \<Gamma>)<a>\<in>RED \<sigma>)"
   919 apply(auto)
   928 apply(auto)
   920 apply(simp add: id_mem)
   929 apply(simp add: id_mem)
   921 apply(frule id_mem)
   930 apply(frule id_mem)
   922 apply(simp add: id_var)
   931 apply(simp add: id_var)
   923 apply(subgoal_tac "CR3 \<sigma>")(*A*)
   932 apply(subgoal_tac "CR3 \<sigma>") --"A"
   924 apply(drule CR3_CR4)
   933 apply(drule CR3_CR4)
   925 apply(simp add: CR4_def)
   934 apply(simp add: CR4_def)
   926 apply(drule_tac x="Var a" in spec)
   935 apply(drule_tac x="Var a" in spec)
   927 apply(force simp add: NEUT_def NORMAL_Var)
   936 apply(force simp add: NEUT_def NORMAL_Var)
   928 (*A*)
   937 --"A"
   929 apply(rule RED_props)
   938 apply(rule RED_props)
   930 done
   939 done
   931 
   940 
   932 lemma typing_implies_RED:  
   941 lemma typing_implies_RED:  
   933   assumes a: "\<Gamma>\<turnstile>t:\<tau>"
   942   assumes a: "\<Gamma>\<turnstile>t:\<tau>"
   949   moreover
   958   moreover
   950   have "CR1 \<tau>" by (rule RED_props)
   959   have "CR1 \<tau>" by (rule RED_props)
   951   ultimately show "SN(t)" by (simp add: CR1_def)
   960   ultimately show "SN(t)" by (simp add: CR1_def)
   952 qed
   961 qed
   953 
   962 
       
   963 *)
   954 end
   964 end