src/HOL/Nominal/Examples/SN.thy
changeset 18378 35fba71ec6ef
parent 18348 b5d7649f8aca
child 18382 44578c918349
equal deleted inserted replaced
18377:0e1d025d57b3 18378:35fba71ec6ef
     5 begin
     5 begin
     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 
       
    11 
    10 
    12 lemma subst_rename[rule_format]: 
    11 lemma subst_rename[rule_format]: 
    13   shows "c\<sharp>t1 \<longrightarrow> (t1[a::=t2] = ([(c,a)]\<bullet>t1)[c::=t2])"
    12   shows "c\<sharp>t1 \<longrightarrow> (t1[a::=t2] = ([(c,a)]\<bullet>t1)[c::=t2])"
    14 apply(nominal_induct t1 avoiding: a c t2 rule: lam_induct)
    13 apply(nominal_induct t1 avoiding: a c t2 rule: lam_induct)
    15 apply(auto simp add: calc_atm fresh_atm abs_fresh)
    14 apply(auto simp add: calc_atm fresh_atm abs_fresh)
   127   qed
   126   qed
   128   hence "P x (([]::name prm)\<bullet>t) (([]::name prm)\<bullet>s)" by blast 
   127   hence "P x (([]::name prm)\<bullet>t) (([]::name prm)\<bullet>s)" by blast 
   129   thus ?thesis by simp
   128   thus ?thesis by simp
   130 qed
   129 qed
   131 
   130 
   132 lemma supp_beta: "t\<longrightarrow>\<^isub>\<beta> s\<Longrightarrow>(supp s)\<subseteq>((supp t)::name set)"
   131 lemma supp_beta: 
   133 apply(erule Beta.induct)
   132   assumes a: "t\<longrightarrow>\<^isub>\<beta> s"
   134 apply(auto intro!: simp add: abs_supp lam.supp subst_supp)
   133   shows "(supp s)\<subseteq>((supp t)::name set)"
   135 done
   134 using a
       
   135 by (induct)
       
   136    (auto intro!: simp add: abs_supp lam.supp subst_supp)
       
   137 
   136 
   138 
   137 lemma beta_abs: "Lam [a].t\<longrightarrow>\<^isub>\<beta> t'\<Longrightarrow>\<exists>t''. t'=Lam [a].t'' \<and> t\<longrightarrow>\<^isub>\<beta> t''"
   139 lemma beta_abs: "Lam [a].t\<longrightarrow>\<^isub>\<beta> t'\<Longrightarrow>\<exists>t''. t'=Lam [a].t'' \<and> t\<longrightarrow>\<^isub>\<beta> t''"
   138 apply(ind_cases "Lam [a].t  \<longrightarrow>\<^isub>\<beta> t'")
   140 apply(ind_cases "Lam [a].t  \<longrightarrow>\<^isub>\<beta> t'")
   139 apply(auto simp add: lam.distinct lam.inject)
   141 apply(auto simp add: lam.distinct lam.inject)
   140 apply(auto simp add: alpha)
   142 apply(auto simp add: alpha)
   219 (* typing judgements *)
   221 (* typing judgements *)
   220 
   222 
   221 lemma fresh_context[rule_format]: 
   223 lemma fresh_context[rule_format]: 
   222   fixes  \<Gamma> :: "(name\<times>ty)list"
   224   fixes  \<Gamma> :: "(name\<times>ty)list"
   223   and    a :: "name"
   225   and    a :: "name"
   224   shows "a\<sharp>\<Gamma>\<longrightarrow>\<not>(\<exists>\<tau>::ty. (a,\<tau>)\<in>set \<Gamma>)"
   226   assumes a: "a\<sharp>\<Gamma>"
   225 apply(induct_tac \<Gamma>)
   227   shows "\<not>(\<exists>\<tau>::ty. (a,\<tau>)\<in>set \<Gamma>)"
       
   228 using a
       
   229 apply(induct \<Gamma>)
   226 apply(auto simp add: fresh_prod fresh_list_cons fresh_atm)
   230 apply(auto simp add: fresh_prod fresh_list_cons fresh_atm)
   227 done
   231 done
   228 
   232 
   229 lemma valid_elim: 
   233 lemma valid_elim: 
   230   fixes  \<Gamma> :: "(name\<times>ty)list"
   234   fixes  \<Gamma> :: "(name\<times>ty)list"
   234   shows "valid ((a,\<tau>)#\<Gamma>) \<Longrightarrow> valid \<Gamma> \<and> a\<sharp>\<Gamma>"
   238   shows "valid ((a,\<tau>)#\<Gamma>) \<Longrightarrow> valid \<Gamma> \<and> a\<sharp>\<Gamma>"
   235 apply(ind_cases "valid ((a,\<tau>)#\<Gamma>)", simp)
   239 apply(ind_cases "valid ((a,\<tau>)#\<Gamma>)", simp)
   236 done
   240 done
   237 
   241 
   238 lemma valid_unicity[rule_format]: 
   242 lemma valid_unicity[rule_format]: 
   239   shows "valid \<Gamma>\<longrightarrow>(c,\<sigma>)\<in>set \<Gamma>\<longrightarrow>(c,\<tau>)\<in>set \<Gamma>\<longrightarrow>\<sigma>=\<tau>" 
   243   assumes a: "valid \<Gamma>"
   240 apply(induct_tac \<Gamma>)
   244   and     b: "(c,\<sigma>)\<in>set \<Gamma>"
       
   245   and     c: "(c,\<tau>)\<in>set \<Gamma>"
       
   246   shows "\<sigma>=\<tau>" 
       
   247 using a b c
       
   248 apply(induct \<Gamma>)
   241 apply(auto dest!: valid_elim fresh_context)
   249 apply(auto dest!: valid_elim fresh_context)
   242 done
   250 done
   243 
   251 
   244 consts
   252 consts
   245   typing :: "(((name\<times>ty) list)\<times>lam\<times>ty) set" 
   253   typing :: "(((name\<times>ty) list)\<times>lam\<times>ty) set" 
   349 (* method, this was completely automatic *)
   357 (* method, this was completely automatic *)
   350 apply(atomize)
   358 apply(atomize)
   351 apply(auto)
   359 apply(auto)
   352 done
   360 done
   353 
   361 
   354 lemma in_ctxt[rule_format]: "(a,\<tau>)\<in>set \<Gamma> \<longrightarrow> (a\<in>set(dom_ty \<Gamma>))"
   362 lemma in_ctxt: 
   355 apply(induct_tac \<Gamma>)
   363   assumes a: "(a,\<tau>)\<in>set \<Gamma>"
       
   364   shows "a\<in>set(dom_ty \<Gamma>)"
       
   365 using a
       
   366 apply(induct \<Gamma>)
   356 apply(auto)
   367 apply(auto)
   357 done
   368 done
   358 
   369 
   359 lemma free_vars: 
   370 lemma free_vars: 
   360   assumes a: "\<Gamma> \<turnstile> t : \<tau>"
   371   assumes a: "\<Gamma> \<turnstile> t : \<tau>"
   388 lemma typing_valid: 
   399 lemma typing_valid: 
   389   assumes a: "\<Gamma> \<turnstile> t : \<tau>" 
   400   assumes a: "\<Gamma> \<turnstile> t : \<tau>" 
   390   shows "valid \<Gamma>"
   401   shows "valid \<Gamma>"
   391 using a by (induct, auto dest!: valid_elim)
   402 using a by (induct, auto dest!: valid_elim)
   392 
   403 
   393 lemma ty_subs[rule_format]:
   404 lemma ty_subs:
   394   fixes \<Gamma> ::"(name\<times>ty) list"
   405   assumes a: "((c,\<sigma>)#\<Gamma>) \<turnstile> t1:\<tau>"
   395   and   t1 ::"lam"
   406   and     b: "\<Gamma>\<turnstile> t2:\<sigma>"
   396   and   t2 ::"lam"
   407   shows  "\<Gamma> \<turnstile> t1[c::=t2]:\<tau>"
   397   and   \<tau>  ::"ty"
   408 using a b
   398   and   \<sigma>  ::"ty" 
       
   399   and   c  ::"name"
       
   400   shows  "((c,\<sigma>)#\<Gamma>) \<turnstile> t1:\<tau>\<longrightarrow> \<Gamma>\<turnstile> t2:\<sigma>\<longrightarrow> \<Gamma> \<turnstile> t1[c::=t2]:\<tau>"
       
   401 proof(nominal_induct t1 avoiding: \<Gamma> \<sigma> \<tau> c t2 rule: lam_induct)
   409 proof(nominal_induct t1 avoiding: \<Gamma> \<sigma> \<tau> c t2 rule: lam_induct)
   402   case (Var a) 
   410   case (Var a) 
   403   show ?case
   411   have a1: "\<Gamma> \<turnstile>t2:\<sigma>" by fact
   404   proof(intro strip)
   412   have a2: "((c,\<sigma>)#\<Gamma>) \<turnstile> Var a:\<tau>" by fact
   405     assume a1: "\<Gamma> \<turnstile>t2:\<sigma>"
   413   hence a21: "(a,\<tau>)\<in>set((c,\<sigma>)#\<Gamma>)" and a22: "valid((c,\<sigma>)#\<Gamma>)" by (auto dest: t1_elim)
   406     assume a2: "((c,\<sigma>)#\<Gamma>) \<turnstile> Var a:\<tau>"
   414   from a22 have a23: "valid \<Gamma>" and a24: "c\<sharp>\<Gamma>" by (auto dest: valid_elim) 
   407     hence a21: "(a,\<tau>)\<in>set((c,\<sigma>)#\<Gamma>)" and a22: "valid((c,\<sigma>)#\<Gamma>)" by (auto dest: t1_elim)
   415   from a24 have a25: "\<not>(\<exists>\<tau>. (c,\<tau>)\<in>set \<Gamma>)" by (rule fresh_context)
   408     from a22 have a23: "valid \<Gamma>" and a24: "c\<sharp>\<Gamma>" by (auto dest: valid_elim) 
   416   show "\<Gamma>\<turnstile>(Var a)[c::=t2] : \<tau>"
   409     from a24 have a25: "\<not>(\<exists>\<tau>. (c,\<tau>)\<in>set \<Gamma>)" by (rule fresh_context)
   417   proof (cases "a=c", simp_all)
   410     show "\<Gamma>\<turnstile>(Var a)[c::=t2] : \<tau>"
   418     assume case1: "a=c"
   411     proof (cases "a=c", simp_all)
   419     show "\<Gamma> \<turnstile> t2:\<tau>" using a1
   412       assume case1: "a=c"
   420     proof (cases "\<sigma>=\<tau>")
   413       show "\<Gamma> \<turnstile> t2:\<tau>" using a1
   421       assume "\<sigma>=\<tau>" thus ?thesis using a1 by simp 
   414       proof (cases "\<sigma>=\<tau>")
   422     next
   415 	assume "\<sigma>=\<tau>" thus ?thesis using a1 by simp 
   423       assume a3: "\<sigma>\<noteq>\<tau>"
   416       next
   424       show ?thesis
   417 	assume a3: "\<sigma>\<noteq>\<tau>"
   425       proof (rule ccontr)
   418 	show ?thesis
   426 	from a3 a21 have "(a,\<tau>)\<in>set \<Gamma>" by force
   419 	proof (rule ccontr)
   427 	with case1 a25 show False by force 
   420 	  from a3 a21 have "(a,\<tau>)\<in>set \<Gamma>" by force
       
   421 	  with case1 a25 show False by force 
       
   422 	qed
       
   423       qed
   428       qed
   424     next
       
   425       assume case2: "a\<noteq>c"
       
   426       with a21 have a26: "(a,\<tau>)\<in>set \<Gamma>" by force 
       
   427       from a23 a26 show "\<Gamma> \<turnstile> Var a:\<tau>" by force
       
   428     qed
   429     qed
       
   430   next
       
   431     assume case2: "a\<noteq>c"
       
   432     with a21 have a26: "(a,\<tau>)\<in>set \<Gamma>" by force 
       
   433     from a23 a26 show "\<Gamma> \<turnstile> Var a:\<tau>" by force
   429   qed
   434   qed
   430 next
   435 next
   431   case (App s1 s2)
   436   case (App s1 s2)
   432   show ?case
   437   have b1: "\<Gamma> \<turnstile>t2:\<sigma>" by fact
   433   proof (intro strip, simp)
   438   have b2: "((c,\<sigma>)#\<Gamma>)\<turnstile>App s1 s2 : \<tau>" by fact
   434     assume b1: "\<Gamma> \<turnstile>t2:\<sigma>" 
   439   hence "\<exists>\<tau>'. (((c,\<sigma>)#\<Gamma>)\<turnstile>s1:\<tau>'\<rightarrow>\<tau> \<and> ((c,\<sigma>)#\<Gamma>)\<turnstile>s2:\<tau>')" by (rule t2_elim) 
   435     assume b2: " ((c,\<sigma>)#\<Gamma>)\<turnstile>App s1 s2 : \<tau>"
   440   then obtain \<tau>' where b3a: "((c,\<sigma>)#\<Gamma>)\<turnstile>s1:\<tau>'\<rightarrow>\<tau>" and b3b: "((c,\<sigma>)#\<Gamma>)\<turnstile>s2:\<tau>'" by force
   436     hence "\<exists>\<tau>'. (((c,\<sigma>)#\<Gamma>)\<turnstile>s1:\<tau>'\<rightarrow>\<tau> \<and> ((c,\<sigma>)#\<Gamma>)\<turnstile>s2:\<tau>')" by (rule t2_elim) 
   441   show "\<Gamma> \<turnstile>  (App s1 s2)[c::=t2] : \<tau>" 
   437     then obtain \<tau>' where b3a: "((c,\<sigma>)#\<Gamma>)\<turnstile>s1:\<tau>'\<rightarrow>\<tau>" and b3b: "((c,\<sigma>)#\<Gamma>)\<turnstile>s2:\<tau>'" by force
   442     using b1 b3a b3b prems by (simp, rule_tac \<tau>="\<tau>'" in t2, auto)
   438     show "\<Gamma> \<turnstile>  App (s1[c::=t2]) (s2[c::=t2]) : \<tau>" 
       
   439       using b1 b3a b3b App by (rule_tac \<tau>="\<tau>'" in t2, auto)
       
   440   qed
       
   441 next
   443 next
   442   case (Lam a s)
   444   case (Lam a s)
   443   have "a\<sharp>\<Gamma>" "a\<sharp>\<sigma>" "a\<sharp>\<tau>" "a\<sharp>c" "a\<sharp>t2" by fact 
   445   have "a\<sharp>\<Gamma>" "a\<sharp>\<sigma>" "a\<sharp>\<tau>" "a\<sharp>c" "a\<sharp>t2" by fact 
   444   hence f1: "a\<sharp>\<Gamma>" and f2: "a\<noteq>c" and f2': "c\<sharp>a" and f3: "a\<sharp>t2" and f4: "a\<sharp>((c,\<sigma>)#\<Gamma>)"
   446   hence f1: "a\<sharp>\<Gamma>" and f2: "a\<noteq>c" and f2': "c\<sharp>a" and f3: "a\<sharp>t2" and f4: "a\<sharp>((c,\<sigma>)#\<Gamma>)"
   445     by (auto simp add: fresh_atm fresh_prod fresh_list_cons)
   447     by (auto simp add: fresh_atm fresh_prod fresh_list_cons)
   446   show ?case using f2 f3
   448   have c1: "((c,\<sigma>)#\<Gamma>)\<turnstile>Lam [a].s : \<tau>" by fact
   447   proof(intro strip, simp)
   449   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) 
   448     assume c1: "((c,\<sigma>)#\<Gamma>)\<turnstile>Lam [a].s : \<tau>"
   450   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
   449     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) 
   451   from c12 have "valid ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>)" by (rule typing_valid)
   450     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
   452   hence ca: "valid \<Gamma>" and cb: "a\<sharp>\<Gamma>" and cc: "c\<sharp>\<Gamma>" 
   451     from c12 have "valid ((a,\<tau>1)#(c,\<sigma>)#\<Gamma>)" by (rule typing_valid)
   453     by (auto dest: valid_elim simp add: fresh_list_cons) 
   452     hence ca: "valid \<Gamma>" and cb: "a\<sharp>\<Gamma>" and cc: "c\<sharp>\<Gamma>" 
   454   from c12 have c14: "((c,\<sigma>)#(a,\<tau>1)#\<Gamma>) \<turnstile> s : \<tau>2"
   453       by (auto dest: valid_elim simp add: fresh_list_cons) 
   455   proof -
   454     from c12 have c14: "((c,\<sigma>)#(a,\<tau>1)#\<Gamma>) \<turnstile> s : \<tau>2"
   456     have c2: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<lless> ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" by (force simp add: sub_def)
   455     proof -
   457     have c3: "valid ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)"
   456       have c2: "((a,\<tau>1)#(c,\<sigma>)#\<Gamma>) \<lless> ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)" by (force simp add: sub_def)
   458       by (rule v2, rule v2, auto simp add: fresh_list_cons fresh_prod ca cb cc f2' fresh_ty)
   457       have c3: "valid ((c,\<sigma>)#(a,\<tau>1)#\<Gamma>)"
   459     from c12 c2 c3 show ?thesis by (force intro: weakening)
   458 	by (rule v2, rule v2, auto simp add: fresh_list_cons fresh_prod ca cb cc f2' fresh_ty)
       
   459       from c12 c2 c3 show ?thesis by (force intro: weakening)
       
   460     qed
       
   461     assume c8: "\<Gamma> \<turnstile> t2 : \<sigma>"
       
   462     have c81: "((a,\<tau>1)#\<Gamma>)\<turnstile>t2 :\<sigma>"
       
   463     proof -
       
   464       have c82: "\<Gamma> \<lless> ((a,\<tau>1)#\<Gamma>)" by (force simp add: sub_def)
       
   465       have c83: "valid ((a,\<tau>1)#\<Gamma>)" using f1 ca by force
       
   466       with c8 c82 c83 show ?thesis by (force intro: weakening)
       
   467     qed
       
   468     show "\<Gamma> \<turnstile> Lam [a].(s[c::=t2]) : \<tau>"
       
   469       using c11 Lam c14 c81 f1 by force
       
   470   qed
   460   qed
       
   461   assume c8: "\<Gamma> \<turnstile> t2 : \<sigma>"
       
   462   have c81: "((a,\<tau>1)#\<Gamma>)\<turnstile>t2 :\<sigma>"
       
   463   proof -
       
   464     have c82: "\<Gamma> \<lless> ((a,\<tau>1)#\<Gamma>)" by (force simp add: sub_def)
       
   465     have c83: "valid ((a,\<tau>1)#\<Gamma>)" using f1 ca by force
       
   466     with c8 c82 c83 show ?thesis by (force intro: weakening)
       
   467   qed
       
   468   show "\<Gamma> \<turnstile> (Lam [a].s)[c::=t2] : \<tau>"
       
   469     using c11 prems c14 c81 f1 by force
   471 qed
   470 qed
   472 
   471 
   473 lemma subject[rule_format]: 
   472 lemma subject: 
   474   fixes \<Gamma>  ::"(name\<times>ty) list"
   473   fixes \<Gamma>  ::"(name\<times>ty) list"
   475   and   t1 ::"lam"
   474   and   t1 ::"lam"
   476   and   t2 ::"lam"
   475   and   t2 ::"lam"
   477   and   \<tau>  ::"ty"
   476   and   \<tau>  ::"ty"
   478   assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2"
   477   assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2"
   479   shows "(\<Gamma> \<turnstile> t1:\<tau>) \<longrightarrow> (\<Gamma> \<turnstile> t2:\<tau>)"
   478   and     b: "\<Gamma> \<turnstile> t1:\<tau>"
   480 using a
   479   shows "\<Gamma> \<turnstile> t2:\<tau>"
   481 proof (nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct, auto)
   480 using a b
       
   481 proof (nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct)
   482   case (b1 t s1 s2)
   482   case (b1 t s1 s2)
   483   have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1:\<tau> \<longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact
   483   have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1:\<tau> \<Longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact
   484   assume "\<Gamma> \<turnstile> App s1 t : \<tau>" 
   484   have "\<Gamma> \<turnstile> App s1 t : \<tau>" by fact 
   485   hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> s1 : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> t : \<sigma>)" by (rule t2_elim)
   485   hence "\<exists>\<sigma>. \<Gamma> \<turnstile> s1 : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> t : \<sigma>" by (rule t2_elim)
   486   then obtain \<sigma> where a1: "\<Gamma> \<turnstile> s1 : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> t : \<sigma>" by force
   486   then obtain \<sigma> where a1: "\<Gamma> \<turnstile> s1 : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> t : \<sigma>" by blast
   487   thus "\<Gamma> \<turnstile> App s2 t : \<tau>" using i by force
   487   thus "\<Gamma> \<turnstile> App s2 t : \<tau>" using i by blast
   488 next
   488 next
   489   case (b2 t s1 s2)
   489   case (b2 t s1 s2)
   490   have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1 : \<tau> \<longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact 
   490   have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1 : \<tau> \<Longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact 
   491   assume "\<Gamma> \<turnstile> App t s1 : \<tau>" 
   491   have "\<Gamma> \<turnstile> App t s1 : \<tau>" by fact
   492   hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> t : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s1 : \<sigma>)" by (rule t2_elim)
   492   hence "\<exists>\<sigma>. \<Gamma> \<turnstile> t : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s1 : \<sigma>" by (rule t2_elim)
   493   then obtain \<sigma> where a1: "\<Gamma> \<turnstile> t : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s1 : \<sigma>" by force
   493   then obtain \<sigma> where a1: "\<Gamma> \<turnstile> t : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s1 : \<sigma>" by blast
   494   thus "\<Gamma> \<turnstile> App t s2 : \<tau>" using i by force
   494   thus "\<Gamma> \<turnstile> App t s2 : \<tau>" using i by blast
   495 next
   495 next
   496   case (b3 a s1 s2)
   496   case (b3 a s1 s2)
   497   have f: "a\<sharp>\<Gamma>" and "a\<sharp>\<tau>" by fact+
   497   have f: "a\<sharp>\<Gamma>" and "a\<sharp>\<tau>" by fact
   498   have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1 : \<tau> \<longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact
   498   have i: "\<And>\<Gamma> \<tau>. \<Gamma> \<turnstile> s1 : \<tau> \<Longrightarrow> \<Gamma> \<turnstile> s2 : \<tau>" by fact
   499   assume "\<Gamma> \<turnstile> Lam [a].s1 : \<tau>"
   499   have "\<Gamma> \<turnstile> Lam [a].s1 : \<tau>" by fact
   500   with f have "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#\<Gamma>) \<turnstile> s1 : \<tau>2" by (force dest: t3_elim)
   500   with f have "\<exists>\<tau>1 \<tau>2. \<tau>=\<tau>1\<rightarrow>\<tau>2 \<and> ((a,\<tau>1)#\<Gamma>) \<turnstile> s1 : \<tau>2" by (blast dest: t3_elim)
   501   then obtain \<tau>1 \<tau>2 where a1: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and a2: "((a,\<tau>1)#\<Gamma>) \<turnstile> s1 : \<tau>2" by force
   501   then obtain \<tau>1 \<tau>2 where a1: "\<tau>=\<tau>1\<rightarrow>\<tau>2" and a2: "((a,\<tau>1)#\<Gamma>) \<turnstile> s1 : \<tau>2" by blast
   502   thus "\<Gamma> \<turnstile> Lam [a].s2 : \<tau>" using f i by force 
   502   thus "\<Gamma> \<turnstile> Lam [a].s2 : \<tau>" using f i by blast
   503 next
   503 next
   504   case (b4 a s1 s2)
   504   case (b4 a s1 s2)
   505   have f: "a\<sharp>\<Gamma>" by fact
   505   have f: "a\<sharp>\<Gamma>" by fact
   506   assume "\<Gamma> \<turnstile> App (Lam [a].s1) s2 : \<tau>"
   506   have "\<Gamma> \<turnstile> App (Lam [a].s1) s2 : \<tau>" by fact
   507   hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s2 : \<sigma>)" by (rule t2_elim)
   507   hence "\<exists>\<sigma>. (\<Gamma> \<turnstile> (Lam [a].s1) : \<sigma>\<rightarrow>\<tau> \<and> \<Gamma> \<turnstile> s2 : \<sigma>)" by (rule t2_elim)
   508   then obtain \<sigma> where a1: "\<Gamma> \<turnstile> (Lam [(a::name)].s1) : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s2 : \<sigma>" by force
   508   then obtain \<sigma> where a1: "\<Gamma> \<turnstile> (Lam [(a::name)].s1) : \<sigma>\<rightarrow>\<tau>" and a2: "\<Gamma> \<turnstile> s2 : \<sigma>" by blast
   509   have  "((a,\<sigma>)#\<Gamma>) \<turnstile> s1 : \<tau>" using a1 f by (auto dest!: t3_elim)
   509   have  "((a,\<sigma>)#\<Gamma>) \<turnstile> s1 : \<tau>" using a1 f by (blast dest!: t3_elim)
   510   with a2 show "\<Gamma> \<turnstile>  s1[a::=s2] : \<tau>" by (force intro: ty_subs)
   510   with a2 show "\<Gamma> \<turnstile>  s1[a::=s2] : \<tau>" by (blast intro: ty_subs)
   511 qed
   511 qed
   512 
   512 
   513 lemma subject[rule_format]: 
   513 lemma subject_automatic: 
   514   fixes \<Gamma>  ::"(name\<times>ty) list"
   514   fixes \<Gamma>  ::"(name\<times>ty) list"
   515   and   t1 ::"lam"
   515   and   t1 ::"lam"
   516   and   t2 ::"lam"
   516   and   t2 ::"lam"
   517   and   \<tau>  ::"ty"
   517   and   \<tau>  ::"ty"
   518   assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2"
   518   assumes a: "t1\<longrightarrow>\<^isub>\<beta>t2"
   519   shows "\<Gamma> \<turnstile> t1:\<tau> \<longrightarrow> \<Gamma> \<turnstile> t2:\<tau>"
   519   and     b: "\<Gamma> \<turnstile> t1:\<tau>"
   520 using a
   520   shows "\<Gamma> \<turnstile> t2:\<tau>"
       
   521 using a b
   521 apply(nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct)
   522 apply(nominal_induct t1 t2 avoiding: \<Gamma> \<tau> rule: beta_induct)
   522 apply(auto dest!: t2_elim t3_elim intro: ty_subs)
   523 apply(auto dest!: t2_elim t3_elim intro: ty_subs)
   523 done
   524 done
   524 
   525 
   525 subsection {* some facts about beta *}
   526 subsection {* some facts about beta *}
   541 lemma qq2: "(\<forall>t2. t1\<longrightarrow>\<^isub>\<beta>t2 \<longrightarrow> SN(t2))\<Longrightarrow>SN(t1)"
   542 lemma qq2: "(\<forall>t2. t1\<longrightarrow>\<^isub>\<beta>t2 \<longrightarrow> SN(t2))\<Longrightarrow>SN(t1)"
   542 apply(simp add: SN_def)
   543 apply(simp add: SN_def)
   543 apply(rule accI)
   544 apply(rule accI)
   544 apply(auto)
   545 apply(auto)
   545 done
   546 done
   546 
       
   547 
   547 
   548 section {* Candidates *}
   548 section {* Candidates *}
   549 
   549 
   550 consts
   550 consts
   551   RED :: "ty \<Rightarrow> lam set"
   551   RED :: "ty \<Rightarrow> lam set"
   563 syntax 
   563 syntax 
   564   "FST_judge"   :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<guillemotright> _" [80,80] 80)
   564   "FST_judge"   :: "lam\<Rightarrow>lam\<Rightarrow>bool" (" _ \<guillemotright> _" [80,80] 80)
   565 translations 
   565 translations 
   566   "t1 \<guillemotright> t2" \<rightleftharpoons> "(t1,t2) \<in> FST"
   566   "t1 \<guillemotright> t2" \<rightleftharpoons> "(t1,t2) \<in> FST"
   567 inductive FST
   567 inductive FST
   568 intros
   568   intros
   569 fst[intro!]:  "(App t s) \<guillemotright> t"
   569 fst[intro!]:  "(App t s) \<guillemotright> t"
   570 
   570 
   571 lemma fst_elim[elim!]: "(App t s) \<guillemotright> t' \<Longrightarrow> t=t'"
   571 lemma fst_elim[elim!]: 
       
   572   shows "(App t s) \<guillemotright> t' \<Longrightarrow> t=t'"
   572 apply(ind_cases "App t s \<guillemotright> t'")
   573 apply(ind_cases "App t s \<guillemotright> t'")
   573 apply(simp add: lam.inject)
   574 apply(simp add: lam.inject)
   574 done
   575 done
   575 
   576 
   576 lemma qq3: "SN(App t s)\<Longrightarrow>SN(t)"
   577 lemma qq3: "SN(App t s)\<Longrightarrow>SN(t)"
   824 apply(simp add: CR1_def SN_def)
   825 apply(simp add: CR1_def SN_def)
   825 (*3*)
   826 (*3*)
   826 apply(force simp add: RED_props)
   827 apply(force simp add: RED_props)
   827 done
   828 done
   828 
   829 
   829 lemma fresh_domain[rule_format]: "a\<sharp>\<theta>\<longrightarrow>a\<notin>set(domain \<theta>)"
   830 lemma fresh_domain: 
   830 apply(induct_tac \<theta>)
   831   assumes a: "a\<sharp>\<theta>"
       
   832   shows "a\<notin>set(domain \<theta>)"
       
   833 using a
       
   834 apply(induct \<theta>)
   831 apply(auto simp add: fresh_prod fresh_list_cons fresh_atm)
   835 apply(auto simp add: fresh_prod fresh_list_cons fresh_atm)
   832 done
   836 done
   833 
   837 
   834 lemma fresh_at[rule_format]: "a\<in>set(domain \<theta>) \<longrightarrow> c\<sharp>\<theta>\<longrightarrow>c\<sharp>(\<theta><a>)"
   838 lemma fresh_at[rule_format]: "a\<in>set(domain \<theta>) \<longrightarrow> c\<sharp>\<theta>\<longrightarrow>c\<sharp>(\<theta><a>)"
   835 apply(induct_tac \<theta>)   
   839 apply(induct_tac \<theta>)