src/HOL/Lambda/WeakNorm.thy
changeset 22271 51a80e238b29
parent 21546 268b6bed0cc8
child 22499 68c8a8390e16
equal deleted inserted replaced
22270:4ccb7e6be929 22271:51a80e238b29
    71 lemma listall_cong [cong, extraction_expand]:
    71 lemma listall_cong [cong, extraction_expand]:
    72   "xs = ys \<Longrightarrow> listall P xs = listall P ys"
    72   "xs = ys \<Longrightarrow> listall P xs = listall P ys"
    73   -- {* Currently needed for strange technical reasons *}
    73   -- {* Currently needed for strange technical reasons *}
    74   by (unfold listall_def) simp
    74   by (unfold listall_def) simp
    75 
    75 
    76 consts NF :: "dB set"
    76 inductive2 NF :: "dB \<Rightarrow> bool"
    77 inductive NF
    77 where
    78 intros
    78   App: "listall NF ts \<Longrightarrow> NF (Var x \<degree>\<degree> ts)"
    79   App: "listall (\<lambda>t. t \<in> NF) ts \<Longrightarrow> Var x \<degree>\<degree> ts \<in> NF"
    79 | Abs: "NF t \<Longrightarrow> NF (Abs t)"
    80   Abs: "t \<in> NF \<Longrightarrow> Abs t \<in> NF"
       
    81 monos listall_def
    80 monos listall_def
    82 
    81 
    83 lemma nat_eq_dec: "\<And>n::nat. m = n \<or> m \<noteq> n"
    82 lemma nat_eq_dec: "\<And>n::nat. m = n \<or> m \<noteq> n"
    84   apply (induct m)
    83   apply (induct m)
    85   apply (case_tac n)
    84   apply (case_tac n)
    92   apply (case_tac n)
    91   apply (case_tac n)
    93   apply (case_tac [3] n)
    92   apply (case_tac [3] n)
    94   apply (simp del: simp_thms, iprover?)+
    93   apply (simp del: simp_thms, iprover?)+
    95   done
    94   done
    96 
    95 
    97 lemma App_NF_D: assumes NF: "Var n \<degree>\<degree> ts \<in> NF"
    96 lemma App_NF_D: assumes NF: "NF (Var n \<degree>\<degree> ts)"
    98   shows "listall (\<lambda>t. t \<in> NF) ts" using NF
    97   shows "listall NF ts" using NF
    99   by cases simp_all
    98   by cases simp_all
   100 
    99 
   101 
   100 
   102 subsection {* Properties of @{text NF} *}
   101 subsection {* Properties of @{text NF} *}
   103 
   102 
   104 lemma Var_NF: "Var n \<in> NF"
   103 lemma Var_NF: "NF (Var n)"
   105   apply (subgoal_tac "Var n \<degree>\<degree> [] \<in> NF")
   104   apply (subgoal_tac "NF (Var n \<degree>\<degree> [])")
   106    apply simp
   105    apply simp
   107   apply (rule NF.App)
   106   apply (rule NF.App)
   108   apply simp
   107   apply simp
   109   done
   108   done
   110 
   109 
   111 lemma subst_terms_NF: "listall (\<lambda>t. t \<in> NF) ts \<Longrightarrow>
   110 lemma subst_terms_NF: "listall NF ts \<Longrightarrow>
   112     listall (\<lambda>t. \<forall>i j. t[Var i/j] \<in> NF) ts \<Longrightarrow>
   111     listall (\<lambda>t. \<forall>i j. NF (t[Var i/j])) ts \<Longrightarrow>
   113     listall (\<lambda>t. t \<in> NF) (map (\<lambda>t. t[Var i/j]) ts)"
   112     listall NF (map (\<lambda>t. t[Var i/j]) ts)"
   114   by (induct ts) simp_all
   113   by (induct ts) simp_all
   115 
   114 
   116 lemma subst_Var_NF: "t \<in> NF \<Longrightarrow> t[Var i/j] \<in> NF"
   115 lemma subst_Var_NF: "NF t \<Longrightarrow> NF (t[Var i/j])"
   117   apply (induct arbitrary: i j set: NF)
   116   apply (induct arbitrary: i j set: NF)
   118   apply simp
   117   apply simp
   119   apply (frule listall_conj1)
   118   apply (frule listall_conj1)
   120   apply (drule listall_conj2)
   119   apply (drule listall_conj2)
   121   apply (drule_tac i=i and j=j in subst_terms_NF)
   120   apply (drule_tac i=i and j=j in subst_terms_NF)
   130   apply (iprover intro: NF.App)
   129   apply (iprover intro: NF.App)
   131   apply simp
   130   apply simp
   132   apply (iprover intro: NF.Abs)
   131   apply (iprover intro: NF.Abs)
   133   done
   132   done
   134 
   133 
   135 lemma app_Var_NF: "t \<in> NF \<Longrightarrow> \<exists>t'. t \<degree> Var i \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> t' \<in> NF"
   134 lemma app_Var_NF: "NF t \<Longrightarrow> \<exists>t'. t \<degree> Var i \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'"
   136   apply (induct set: NF)
   135   apply (induct set: NF)
   137   apply (simplesubst app_last)  --{*Using @{text subst} makes extraction fail*}
   136   apply (simplesubst app_last)  --{*Using @{text subst} makes extraction fail*}
   138   apply (rule exI)
   137   apply (rule exI)
   139   apply (rule conjI)
   138   apply (rule conjI)
   140   apply (rule rtrancl_refl)
   139   apply (rule rtrancl.rtrancl_refl)
   141   apply (rule NF.App)
   140   apply (rule NF.App)
   142   apply (drule listall_conj1)
   141   apply (drule listall_conj1)
   143   apply (simp add: listall_app)
   142   apply (simp add: listall_app)
   144   apply (rule Var_NF)
   143   apply (rule Var_NF)
   145   apply (rule exI)
   144   apply (rule exI)
   146   apply (rule conjI)
   145   apply (rule conjI)
   147   apply (rule rtrancl_into_rtrancl)
   146   apply (rule rtrancl.rtrancl_into_rtrancl)
   148   apply (rule rtrancl_refl)
   147   apply (rule rtrancl.rtrancl_refl)
   149   apply (rule beta)
   148   apply (rule beta)
   150   apply (erule subst_Var_NF)
   149   apply (erule subst_Var_NF)
   151   done
   150   done
   152 
   151 
   153 lemma lift_terms_NF: "listall (\<lambda>t. t \<in> NF) ts \<Longrightarrow>
   152 lemma lift_terms_NF: "listall NF ts \<Longrightarrow>
   154     listall (\<lambda>t. \<forall>i. lift t i \<in> NF) ts \<Longrightarrow>
   153     listall (\<lambda>t. \<forall>i. NF (lift t i)) ts \<Longrightarrow>
   155     listall (\<lambda>t. t \<in> NF) (map (\<lambda>t. lift t i) ts)"
   154     listall NF (map (\<lambda>t. lift t i) ts)"
   156   by (induct ts) simp_all
   155   by (induct ts) simp_all
   157 
   156 
   158 lemma lift_NF: "t \<in> NF \<Longrightarrow> lift t i \<in> NF"
   157 lemma lift_NF: "NF t \<Longrightarrow> NF (lift t i)"
   159   apply (induct arbitrary: i set: NF)
   158   apply (induct arbitrary: i set: NF)
   160   apply (frule listall_conj1)
   159   apply (frule listall_conj1)
   161   apply (drule listall_conj2)
   160   apply (drule listall_conj2)
   162   apply (drule_tac i=i in lift_terms_NF)
   161   apply (drule_tac i=i in lift_terms_NF)
   163   apply assumption
   162   apply assumption
   176 
   175 
   177 subsection {* Main theorems *}
   176 subsection {* Main theorems *}
   178 
   177 
   179 lemma norm_list:
   178 lemma norm_list:
   180   assumes f_compat: "\<And>t t'. t \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<Longrightarrow> f t \<rightarrow>\<^sub>\<beta>\<^sup>* f t'"
   179   assumes f_compat: "\<And>t t'. t \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<Longrightarrow> f t \<rightarrow>\<^sub>\<beta>\<^sup>* f t'"
   181   and f_NF: "\<And>t. t \<in> NF \<Longrightarrow> f t \<in> NF"
   180   and f_NF: "\<And>t. NF t \<Longrightarrow> NF (f t)"
   182   and uNF: "u \<in> NF" and uT: "e \<turnstile> u : T"
   181   and uNF: "NF u" and uT: "e \<turnstile> u : T"
   183   shows "\<And>Us. e\<langle>i:T\<rangle> \<tturnstile> as : Us \<Longrightarrow>
   182   shows "\<And>Us. e\<langle>i:T\<rangle> \<tturnstile> as : Us \<Longrightarrow>
   184     listall (\<lambda>t. \<forall>e T' u i. e\<langle>i:T\<rangle> \<turnstile> t : T' \<longrightarrow>
   183     listall (\<lambda>t. \<forall>e T' u i. e\<langle>i:T\<rangle> \<turnstile> t : T' \<longrightarrow>
   185       u \<in> NF \<longrightarrow> e \<turnstile> u : T \<longrightarrow> (\<exists>t'. t[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> t' \<in> NF)) as \<Longrightarrow>
   184       NF u \<longrightarrow> e \<turnstile> u : T \<longrightarrow> (\<exists>t'. t[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t')) as \<Longrightarrow>
   186     \<exists>as'. \<forall>j. Var j \<degree>\<degree> map (\<lambda>t. f (t[u/i])) as \<rightarrow>\<^sub>\<beta>\<^sup>*
   185     \<exists>as'. \<forall>j. Var j \<degree>\<degree> map (\<lambda>t. f (t[u/i])) as \<rightarrow>\<^sub>\<beta>\<^sup>*
   187       Var j \<degree>\<degree> map f as' \<and> Var j \<degree>\<degree> map f as' \<in> NF"
   186       Var j \<degree>\<degree> map f as' \<and> NF (Var j \<degree>\<degree> map f as')"
   188   (is "\<And>Us. _ \<Longrightarrow> listall ?R as \<Longrightarrow> \<exists>as'. ?ex Us as as'")
   187   (is "\<And>Us. _ \<Longrightarrow> listall ?R as \<Longrightarrow> \<exists>as'. ?ex Us as as'")
   189 proof (induct as rule: rev_induct)
   188 proof (induct as rule: rev_induct)
   190   case (Nil Us)
   189   case (Nil Us)
   191   with Var_NF have "?ex Us [] []" by simp
   190   with Var_NF have "?ex Us [] []" by simp
   192   thus ?case ..
   191   thus ?case ..
   198     by (rule types_snocE)
   197     by (rule types_snocE)
   199   from snoc have "listall ?R bs" by simp
   198   from snoc have "listall ?R bs" by simp
   200   with bs have "\<exists>bs'. ?ex Vs bs bs'" by (rule snoc)
   199   with bs have "\<exists>bs'. ?ex Vs bs bs'" by (rule snoc)
   201   then obtain bs' where
   200   then obtain bs' where
   202     bsred: "\<And>j. Var j \<degree>\<degree> map (\<lambda>t. f (t[u/i])) bs \<rightarrow>\<^sub>\<beta>\<^sup>* Var j \<degree>\<degree> map f bs'"
   201     bsred: "\<And>j. Var j \<degree>\<degree> map (\<lambda>t. f (t[u/i])) bs \<rightarrow>\<^sub>\<beta>\<^sup>* Var j \<degree>\<degree> map f bs'"
   203     and bsNF: "\<And>j. Var j \<degree>\<degree> map f bs' \<in> NF" by iprover
   202     and bsNF: "\<And>j. NF (Var j \<degree>\<degree> map f bs')" by iprover
   204   from snoc have "?R b" by simp
   203   from snoc have "?R b" by simp
   205   with bT and uNF and uT have "\<exists>b'. b[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* b' \<and> b' \<in> NF"
   204   with bT and uNF and uT have "\<exists>b'. b[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* b' \<and> NF b'"
   206     by iprover
   205     by iprover
   207   then obtain b' where bred: "b[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* b'" and bNF: "b' \<in> NF"
   206   then obtain b' where bred: "b[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* b'" and bNF: "NF b'"
   208     by iprover
   207     by iprover
   209   from bsNF [of 0] have "listall (\<lambda>t. t \<in> NF) (map f bs')"
   208   from bsNF [of 0] have "listall NF (map f bs')"
   210     by (rule App_NF_D)
   209     by (rule App_NF_D)
   211   moreover have "f b' \<in> NF" by (rule f_NF)
   210   moreover have "NF (f b')" by (rule f_NF)
   212   ultimately have "listall (\<lambda>t. t \<in> NF) (map f (bs' @ [b']))"
   211   ultimately have "listall NF (map f (bs' @ [b']))"
   213     by simp
   212     by simp
   214   hence "\<And>j. Var j \<degree>\<degree> map f (bs' @ [b']) \<in> NF" by (rule NF.App)
   213   hence "\<And>j. NF (Var j \<degree>\<degree> map f (bs' @ [b']))" by (rule NF.App)
   215   moreover from bred have "f (b[u/i]) \<rightarrow>\<^sub>\<beta>\<^sup>* f b'"
   214   moreover from bred have "f (b[u/i]) \<rightarrow>\<^sub>\<beta>\<^sup>* f b'"
   216     by (rule f_compat)
   215     by (rule f_compat)
   217   with bsred have
   216   with bsred have
   218     "\<And>j. (Var j \<degree>\<degree> map (\<lambda>t. f (t[u/i])) bs) \<degree> f (b[u/i]) \<rightarrow>\<^sub>\<beta>\<^sup>*
   217     "\<And>j. (Var j \<degree>\<degree> map (\<lambda>t. f (t[u/i])) bs) \<degree> f (b[u/i]) \<rightarrow>\<^sub>\<beta>\<^sup>*
   219      (Var j \<degree>\<degree> map f bs') \<degree> f b'" by (rule rtrancl_beta_App)
   218      (Var j \<degree>\<degree> map f bs') \<degree> f b'" by (rule rtrancl_beta_App)
   220   ultimately have "?ex Us (bs @ [b]) (bs' @ [b'])" by simp
   219   ultimately have "?ex Us (bs @ [b]) (bs' @ [b'])" by simp
   221   thus ?case ..
   220   thus ?case ..
   222 qed
   221 qed
   223 
   222 
   224 lemma subst_type_NF:
   223 lemma subst_type_NF:
   225   "\<And>t e T u i. t \<in> NF \<Longrightarrow> e\<langle>i:U\<rangle> \<turnstile> t : T \<Longrightarrow> u \<in> NF \<Longrightarrow> e \<turnstile> u : U \<Longrightarrow> \<exists>t'. t[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> t' \<in> NF"
   224   "\<And>t e T u i. NF t \<Longrightarrow> e\<langle>i:U\<rangle> \<turnstile> t : T \<Longrightarrow> NF u \<Longrightarrow> e \<turnstile> u : U \<Longrightarrow> \<exists>t'. t[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'"
   226   (is "PROP ?P U" is "\<And>t e T u i. _ \<Longrightarrow> PROP ?Q t e T u i U")
   225   (is "PROP ?P U" is "\<And>t e T u i. _ \<Longrightarrow> PROP ?Q t e T u i U")
   227 proof (induct U)
   226 proof (induct U)
   228   fix T t
   227   fix T t
   229   let ?R = "\<lambda>t. \<forall>e T' u i.
   228   let ?R = "\<lambda>t. \<forall>e T' u i.
   230     e\<langle>i:T\<rangle> \<turnstile> t : T' \<longrightarrow> u \<in> NF \<longrightarrow> e \<turnstile> u : T \<longrightarrow> (\<exists>t'. t[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> t' \<in> NF)"
   229     e\<langle>i:T\<rangle> \<turnstile> t : T' \<longrightarrow> NF u \<longrightarrow> e \<turnstile> u : T \<longrightarrow> (\<exists>t'. t[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t')"
   231   assume MI1: "\<And>T1 T2. T = T1 \<Rightarrow> T2 \<Longrightarrow> PROP ?P T1"
   230   assume MI1: "\<And>T1 T2. T = T1 \<Rightarrow> T2 \<Longrightarrow> PROP ?P T1"
   232   assume MI2: "\<And>T1 T2. T = T1 \<Rightarrow> T2 \<Longrightarrow> PROP ?P T2"
   231   assume MI2: "\<And>T1 T2. T = T1 \<Rightarrow> T2 \<Longrightarrow> PROP ?P T2"
   233   assume "t \<in> NF"
   232   assume "NF t"
   234   thus "\<And>e T' u i. PROP ?Q t e T' u i T"
   233   thus "\<And>e T' u i. PROP ?Q t e T' u i T"
   235   proof induct
   234   proof induct
   236     fix e T' u i assume uNF: "u \<in> NF" and uT: "e \<turnstile> u : T"
   235     fix e T' u i assume uNF: "NF u" and uT: "e \<turnstile> u : T"
   237     {
   236     {
   238       case (App ts x e_ T'_ u_ i_)
   237       case (App ts x e_ T'_ u_ i_)
   239       assume "e\<langle>i:T\<rangle> \<turnstile> Var x \<degree>\<degree> ts : T'"
   238       assume "e\<langle>i:T\<rangle> \<turnstile> Var x \<degree>\<degree> ts : T'"
   240       then obtain Us
   239       then obtain Us
   241 	where varT: "e\<langle>i:T\<rangle> \<turnstile> Var x : Us \<Rrightarrow> T'"
   240 	where varT: "e\<langle>i:T\<rangle> \<turnstile> Var x : Us \<Rrightarrow> T'"
   242 	and argsT: "e\<langle>i:T\<rangle> \<tturnstile> ts : Us"
   241 	and argsT: "e\<langle>i:T\<rangle> \<tturnstile> ts : Us"
   243 	by (rule var_app_typesE)
   242 	by (rule var_app_typesE)
   244       from nat_eq_dec show "\<exists>t'. (Var x \<degree>\<degree> ts)[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> t' \<in> NF"
   243       from nat_eq_dec show "\<exists>t'. (Var x \<degree>\<degree> ts)[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'"
   245       proof
   244       proof
   246 	assume eq: "x = i"
   245 	assume eq: "x = i"
   247 	show ?thesis
   246 	show ?thesis
   248 	proof (cases ts)
   247 	proof (cases ts)
   249 	  case Nil
   248 	  case Nil
   262 	  from argT uT refl have aT: "e \<turnstile> a[u/i] : T''" by (rule subst_lemma)
   261 	  from argT uT refl have aT: "e \<turnstile> a[u/i] : T''" by (rule subst_lemma)
   263 	  from App and Cons have "listall ?R as" by simp (iprover dest: listall_conj2)
   262 	  from App and Cons have "listall ?R as" by simp (iprover dest: listall_conj2)
   264 	  with lift_preserves_beta' lift_NF uNF uT argsT'
   263 	  with lift_preserves_beta' lift_NF uNF uT argsT'
   265 	  have "\<exists>as'. \<forall>j. Var j \<degree>\<degree> map (\<lambda>t. lift (t[u/i]) 0) as \<rightarrow>\<^sub>\<beta>\<^sup>*
   264 	  have "\<exists>as'. \<forall>j. Var j \<degree>\<degree> map (\<lambda>t. lift (t[u/i]) 0) as \<rightarrow>\<^sub>\<beta>\<^sup>*
   266             Var j \<degree>\<degree> map (\<lambda>t. lift t 0) as' \<and>
   265             Var j \<degree>\<degree> map (\<lambda>t. lift t 0) as' \<and>
   267 	    Var j \<degree>\<degree> map (\<lambda>t. lift t 0) as' \<in> NF" by (rule norm_list)
   266 	    NF (Var j \<degree>\<degree> map (\<lambda>t. lift t 0) as')" by (rule norm_list)
   268 	  then obtain as' where
   267 	  then obtain as' where
   269 	    asred: "Var 0 \<degree>\<degree> map (\<lambda>t. lift (t[u/i]) 0) as \<rightarrow>\<^sub>\<beta>\<^sup>*
   268 	    asred: "Var 0 \<degree>\<degree> map (\<lambda>t. lift (t[u/i]) 0) as \<rightarrow>\<^sub>\<beta>\<^sup>*
   270 	      Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as'"
   269 	      Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as'"
   271 	    and asNF: "Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as' \<in> NF" by iprover
   270 	    and asNF: "NF (Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as')" by iprover
   272 	  from App and Cons have "?R a" by simp
   271 	  from App and Cons have "?R a" by simp
   273 	  with argT and uNF and uT have "\<exists>a'. a[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* a' \<and> a' \<in> NF"
   272 	  with argT and uNF and uT have "\<exists>a'. a[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* a' \<and> NF a'"
   274 	    by iprover
   273 	    by iprover
   275 	  then obtain a' where ared: "a[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* a'" and aNF: "a' \<in> NF" by iprover
   274 	  then obtain a' where ared: "a[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* a'" and aNF: "NF a'" by iprover
   276 	  from uNF have "lift u 0 \<in> NF" by (rule lift_NF)
   275 	  from uNF have "NF (lift u 0)" by (rule lift_NF)
   277 	  hence "\<exists>u'. lift u 0 \<degree> Var 0 \<rightarrow>\<^sub>\<beta>\<^sup>* u' \<and> u' \<in> NF" by (rule app_Var_NF)
   276 	  hence "\<exists>u'. lift u 0 \<degree> Var 0 \<rightarrow>\<^sub>\<beta>\<^sup>* u' \<and> NF u'" by (rule app_Var_NF)
   278 	  then obtain u' where ured: "lift u 0 \<degree> Var 0 \<rightarrow>\<^sub>\<beta>\<^sup>* u'" and u'NF: "u' \<in> NF"
   277 	  then obtain u' where ured: "lift u 0 \<degree> Var 0 \<rightarrow>\<^sub>\<beta>\<^sup>* u'" and u'NF: "NF u'"
   279 	    by iprover
   278 	    by iprover
   280 	  from T and u'NF have "\<exists>ua. u'[a'/0] \<rightarrow>\<^sub>\<beta>\<^sup>* ua \<and> ua \<in> NF"
   279 	  from T and u'NF have "\<exists>ua. u'[a'/0] \<rightarrow>\<^sub>\<beta>\<^sup>* ua \<and> NF ua"
   281 	  proof (rule MI1)
   280 	  proof (rule MI1)
   282 	    have "e\<langle>0:T''\<rangle> \<turnstile> lift u 0 \<degree> Var 0 : Ts \<Rrightarrow> T'"
   281 	    have "e\<langle>0:T''\<rangle> \<turnstile> lift u 0 \<degree> Var 0 : Ts \<Rrightarrow> T'"
   283 	    proof (rule typing.App)
   282 	    proof (rule typing.App)
   284 	      from uT' show "e\<langle>0:T''\<rangle> \<turnstile> lift u 0 : T'' \<Rightarrow> Ts \<Rrightarrow> T'" by (rule lift_type)
   283 	      from uT' show "e\<langle>0:T''\<rangle> \<turnstile> lift u 0 : T'' \<Rightarrow> Ts \<Rrightarrow> T'" by (rule lift_type)
   285 	      show "e\<langle>0:T''\<rangle> \<turnstile> Var 0 : T''" by (rule typing.Var) simp
   284 	      show "e\<langle>0:T''\<rangle> \<turnstile> Var 0 : T''" by (rule typing.Var) simp
   286 	    qed
   285 	    qed
   287 	    with ured show "e\<langle>0:T''\<rangle> \<turnstile> u' : Ts \<Rrightarrow> T'" by (rule subject_reduction')
   286 	    with ured show "e\<langle>0:T''\<rangle> \<turnstile> u' : Ts \<Rrightarrow> T'" by (rule subject_reduction')
   288 	    from ared aT show "e \<turnstile> a' : T''" by (rule subject_reduction')
   287 	    from ared aT show "e \<turnstile> a' : T''" by (rule subject_reduction')
   289 	  qed
   288 	  qed
   290 	  then obtain ua where uared: "u'[a'/0] \<rightarrow>\<^sub>\<beta>\<^sup>* ua" and uaNF: "ua \<in> NF"
   289 	  then obtain ua where uared: "u'[a'/0] \<rightarrow>\<^sub>\<beta>\<^sup>* ua" and uaNF: "NF ua"
   291 	    by iprover
   290 	    by iprover
   292 	  from ared have "(lift u 0 \<degree> Var 0)[a[u/i]/0] \<rightarrow>\<^sub>\<beta>\<^sup>* (lift u 0 \<degree> Var 0)[a'/0]"
   291 	  from ared have "(lift u 0 \<degree> Var 0)[a[u/i]/0] \<rightarrow>\<^sub>\<beta>\<^sup>* (lift u 0 \<degree> Var 0)[a'/0]"
   293 	    by (rule subst_preserves_beta2')
   292 	    by (rule subst_preserves_beta2')
   294 	  also from ured have "(lift u 0 \<degree> Var 0)[a'/0] \<rightarrow>\<^sub>\<beta>\<^sup>* u'[a'/0]"
   293 	  also from ured have "(lift u 0 \<degree> Var 0)[a'/0] \<rightarrow>\<^sub>\<beta>\<^sup>* u'[a'/0]"
   295 	    by (rule subst_preserves_beta')
   294 	    by (rule subst_preserves_beta')
   296 	  also note uared
   295 	  also note uared
   297 	  finally have "(lift u 0 \<degree> Var 0)[a[u/i]/0] \<rightarrow>\<^sub>\<beta>\<^sup>* ua" .
   296 	  finally have "(lift u 0 \<degree> Var 0)[a[u/i]/0] \<rightarrow>\<^sub>\<beta>\<^sup>* ua" .
   298 	  hence uared': "u \<degree> a[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* ua" by simp
   297 	  hence uared': "u \<degree> a[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* ua" by simp
   299 	  from T have "\<exists>r. (Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as')[ua/0] \<rightarrow>\<^sub>\<beta>\<^sup>* r \<and> r \<in> NF"
   298 	  from T have "\<exists>r. (Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as')[ua/0] \<rightarrow>\<^sub>\<beta>\<^sup>* r \<and> NF r"
   300 	  proof (rule MI2)
   299 	  proof (rule MI2)
   301 	    have "e\<langle>0:Ts \<Rrightarrow> T'\<rangle> \<turnstile> Var 0 \<degree>\<degree> map (\<lambda>t. lift (t[u/i]) 0) as : T'"
   300 	    have "e\<langle>0:Ts \<Rrightarrow> T'\<rangle> \<turnstile> Var 0 \<degree>\<degree> map (\<lambda>t. lift (t[u/i]) 0) as : T'"
   302 	    proof (rule list_app_typeI)
   301 	    proof (rule list_app_typeI)
   303 	      show "e\<langle>0:Ts \<Rrightarrow> T'\<rangle> \<turnstile> Var 0 : Ts \<Rrightarrow> T'" by (rule typing.Var) simp
   302 	      show "e\<langle>0:Ts \<Rrightarrow> T'\<rangle> \<turnstile> Var 0 : Ts \<Rrightarrow> T'" by (rule typing.Var) simp
   304 	      from uT argsT' have "e \<tturnstile> map (\<lambda>t. t[u/i]) as : Ts"
   303 	      from uT argsT' have "e \<tturnstile> map (\<lambda>t. t[u/i]) as : Ts"
   313 	    from argT uT refl have "e \<turnstile> a[u/i] : T''" by (rule subst_lemma)
   312 	    from argT uT refl have "e \<turnstile> a[u/i] : T''" by (rule subst_lemma)
   314 	    with uT' have "e \<turnstile> u \<degree> a[u/i] : Ts \<Rrightarrow> T'" by (rule typing.App)
   313 	    with uT' have "e \<turnstile> u \<degree> a[u/i] : Ts \<Rrightarrow> T'" by (rule typing.App)
   315 	    with uared' show "e \<turnstile> ua : Ts \<Rrightarrow> T'" by (rule subject_reduction')
   314 	    with uared' show "e \<turnstile> ua : Ts \<Rrightarrow> T'" by (rule subject_reduction')
   316 	  qed
   315 	  qed
   317 	  then obtain r where rred: "(Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as')[ua/0] \<rightarrow>\<^sub>\<beta>\<^sup>* r"
   316 	  then obtain r where rred: "(Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as')[ua/0] \<rightarrow>\<^sub>\<beta>\<^sup>* r"
   318 	    and rnf: "r \<in> NF" by iprover
   317 	    and rnf: "NF r" by iprover
   319 	  from asred have
   318 	  from asred have
   320 	    "(Var 0 \<degree>\<degree> map (\<lambda>t. lift (t[u/i]) 0) as)[u \<degree> a[u/i]/0] \<rightarrow>\<^sub>\<beta>\<^sup>*
   319 	    "(Var 0 \<degree>\<degree> map (\<lambda>t. lift (t[u/i]) 0) as)[u \<degree> a[u/i]/0] \<rightarrow>\<^sub>\<beta>\<^sup>*
   321 	    (Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as')[u \<degree> a[u/i]/0]"
   320 	    (Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as')[u \<degree> a[u/i]/0]"
   322 	    by (rule subst_preserves_beta')
   321 	    by (rule subst_preserves_beta')
   323 	  also from uared' have "(Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as')[u \<degree> a[u/i]/0] \<rightarrow>\<^sub>\<beta>\<^sup>*
   322 	  also from uared' have "(Var 0 \<degree>\<degree> map (\<lambda>t. lift t 0) as')[u \<degree> a[u/i]/0] \<rightarrow>\<^sub>\<beta>\<^sup>*
   330       next
   329       next
   331 	assume neq: "x \<noteq> i"
   330 	assume neq: "x \<noteq> i"
   332 	from App have "listall ?R ts" by (iprover dest: listall_conj2)
   331 	from App have "listall ?R ts" by (iprover dest: listall_conj2)
   333 	with TrueI TrueI uNF uT argsT
   332 	with TrueI TrueI uNF uT argsT
   334 	have "\<exists>ts'. \<forall>j. Var j \<degree>\<degree> map (\<lambda>t. t[u/i]) ts \<rightarrow>\<^sub>\<beta>\<^sup>* Var j \<degree>\<degree> ts' \<and>
   333 	have "\<exists>ts'. \<forall>j. Var j \<degree>\<degree> map (\<lambda>t. t[u/i]) ts \<rightarrow>\<^sub>\<beta>\<^sup>* Var j \<degree>\<degree> ts' \<and>
   335 	  Var j \<degree>\<degree> ts' \<in> NF" (is "\<exists>ts'. ?ex ts'")
   334 	  NF (Var j \<degree>\<degree> ts')" (is "\<exists>ts'. ?ex ts'")
   336 	  by (rule norm_list [of "\<lambda>t. t", simplified])
   335 	  by (rule norm_list [of "\<lambda>t. t", simplified])
   337 	then obtain ts' where NF: "?ex ts'" ..
   336 	then obtain ts' where NF: "?ex ts'" ..
   338 	from nat_le_dec show ?thesis
   337 	from nat_le_dec show ?thesis
   339 	proof
   338 	proof
   340 	  assume "i < x"
   339 	  assume "i < x"
   346       qed
   345       qed
   347     next
   346     next
   348       case (Abs r e_ T'_ u_ i_)
   347       case (Abs r e_ T'_ u_ i_)
   349       assume absT: "e\<langle>i:T\<rangle> \<turnstile> Abs r : T'"
   348       assume absT: "e\<langle>i:T\<rangle> \<turnstile> Abs r : T'"
   350       then obtain R S where "e\<langle>0:R\<rangle>\<langle>Suc i:T\<rangle>  \<turnstile> r : S" by (rule abs_typeE) simp
   349       then obtain R S where "e\<langle>0:R\<rangle>\<langle>Suc i:T\<rangle>  \<turnstile> r : S" by (rule abs_typeE) simp
   351       moreover have "lift u 0 \<in> NF" by (rule lift_NF)
   350       moreover have "NF (lift u 0)" by (rule lift_NF)
   352       moreover have "e\<langle>0:R\<rangle> \<turnstile> lift u 0 : T" by (rule lift_type)
   351       moreover have "e\<langle>0:R\<rangle> \<turnstile> lift u 0 : T" by (rule lift_type)
   353       ultimately have "\<exists>t'. r[lift u 0/Suc i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> t' \<in> NF" by (rule Abs)
   352       ultimately have "\<exists>t'. r[lift u 0/Suc i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'" by (rule Abs)
   354       thus "\<exists>t'. Abs r[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> t' \<in> NF"
   353       thus "\<exists>t'. Abs r[u/i] \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'"
   355 	by simp (iprover intro: rtrancl_beta_Abs NF.Abs)
   354 	by simp (iprover intro: rtrancl_beta_Abs NF.Abs)
   356     }
   355     }
   357   qed
   356   qed
   358 qed
   357 qed
   359 
   358 
   360 
   359 
   361 consts -- {* A computationally relevant copy of @{term "e \<turnstile> t : T"} *}
   360 -- {* A computationally relevant copy of @{term "e \<turnstile> t : T"} *}
   362   rtyping :: "((nat \<Rightarrow> type) \<times> dB \<times> type) set"
   361 inductive2 rtyping :: "(nat \<Rightarrow> type) \<Rightarrow> dB \<Rightarrow> type \<Rightarrow> bool"  ("_ \<turnstile>\<^sub>R _ : _" [50, 50, 50] 50)
   363 
   362   where
   364 abbreviation
       
   365   rtyping_rel :: "(nat \<Rightarrow> type) \<Rightarrow> dB \<Rightarrow> type \<Rightarrow> bool"  ("_ |-\<^sub>R _ : _" [50, 50, 50] 50) where
       
   366   "e |-\<^sub>R t : T == (e, t, T) \<in> rtyping"
       
   367 
       
   368 notation (xsymbols)
       
   369   rtyping_rel  ("_ \<turnstile>\<^sub>R _ : _" [50, 50, 50] 50)
       
   370 
       
   371 inductive rtyping
       
   372   intros
       
   373     Var: "e x = T \<Longrightarrow> e \<turnstile>\<^sub>R Var x : T"
   363     Var: "e x = T \<Longrightarrow> e \<turnstile>\<^sub>R Var x : T"
   374     Abs: "e\<langle>0:T\<rangle> \<turnstile>\<^sub>R t : U \<Longrightarrow> e \<turnstile>\<^sub>R Abs t : (T \<Rightarrow> U)"
   364   | Abs: "e\<langle>0:T\<rangle> \<turnstile>\<^sub>R t : U \<Longrightarrow> e \<turnstile>\<^sub>R Abs t : (T \<Rightarrow> U)"
   375     App: "e \<turnstile>\<^sub>R s : T \<Rightarrow> U \<Longrightarrow> e \<turnstile>\<^sub>R t : T \<Longrightarrow> e \<turnstile>\<^sub>R (s \<degree> t) : U"
   365   | App: "e \<turnstile>\<^sub>R s : T \<Rightarrow> U \<Longrightarrow> e \<turnstile>\<^sub>R t : T \<Longrightarrow> e \<turnstile>\<^sub>R (s \<degree> t) : U"
   376 
   366 
   377 lemma rtyping_imp_typing: "e \<turnstile>\<^sub>R t : T \<Longrightarrow> e \<turnstile> t : T"
   367 lemma rtyping_imp_typing: "e \<turnstile>\<^sub>R t : T \<Longrightarrow> e \<turnstile> t : T"
   378   apply (induct set: rtyping)
   368   apply (induct set: rtyping)
   379   apply (erule typing.Var)
   369   apply (erule typing.Var)
   380   apply (erule typing.Abs)
   370   apply (erule typing.Abs)
   383   done
   373   done
   384 
   374 
   385 
   375 
   386 theorem type_NF:
   376 theorem type_NF:
   387   assumes "e \<turnstile>\<^sub>R t : T"
   377   assumes "e \<turnstile>\<^sub>R t : T"
   388   shows "\<exists>t'. t \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> t' \<in> NF" using prems
   378   shows "\<exists>t'. t \<rightarrow>\<^sub>\<beta>\<^sup>* t' \<and> NF t'" using prems
   389 proof induct
   379 proof induct
   390   case Var
   380   case Var
   391   show ?case by (iprover intro: Var_NF)
   381   show ?case by (iprover intro: Var_NF)
   392 next
   382 next
   393   case Abs
   383   case Abs
   394   thus ?case by (iprover intro: rtrancl_beta_Abs NF.Abs)
   384   thus ?case by (iprover intro: rtrancl_beta_Abs NF.Abs)
   395 next
   385 next
   396   case (App T U e s t)
   386   case (App e s T U t)
   397   from App obtain s' t' where
   387   from App obtain s' t' where
   398     sred: "s \<rightarrow>\<^sub>\<beta>\<^sup>* s'" and sNF: "s' \<in> NF"
   388     sred: "s \<rightarrow>\<^sub>\<beta>\<^sup>* s'" and sNF: "NF s'"
   399     and tred: "t \<rightarrow>\<^sub>\<beta>\<^sup>* t'" and tNF: "t' \<in> NF" by iprover
   389     and tred: "t \<rightarrow>\<^sub>\<beta>\<^sup>* t'" and tNF: "NF t'" by iprover
   400   have "\<exists>u. (Var 0 \<degree> lift t' 0)[s'/0] \<rightarrow>\<^sub>\<beta>\<^sup>* u \<and> u \<in> NF"
   390   have "\<exists>u. (Var 0 \<degree> lift t' 0)[s'/0] \<rightarrow>\<^sub>\<beta>\<^sup>* u \<and> NF u"
   401   proof (rule subst_type_NF)
   391   proof (rule subst_type_NF)
   402     have "lift t' 0 \<in> NF" by (rule lift_NF)
   392     have "NF (lift t' 0)" by (rule lift_NF)
   403     hence "listall (\<lambda>t. t \<in> NF) [lift t' 0]" by (rule listall_cons) (rule listall_nil)
   393     hence "listall NF [lift t' 0]" by (rule listall_cons) (rule listall_nil)
   404     hence "Var 0 \<degree>\<degree> [lift t' 0] \<in> NF" by (rule NF.App)
   394     hence "NF (Var 0 \<degree>\<degree> [lift t' 0])" by (rule NF.App)
   405     thus "Var 0 \<degree> lift t' 0 \<in> NF" by simp
   395     thus "NF (Var 0 \<degree> lift t' 0)" by simp
   406     show "e\<langle>0:T \<Rightarrow> U\<rangle> \<turnstile> Var 0 \<degree> lift t' 0 : U"
   396     show "e\<langle>0:T \<Rightarrow> U\<rangle> \<turnstile> Var 0 \<degree> lift t' 0 : U"
   407     proof (rule typing.App)
   397     proof (rule typing.App)
   408       show "e\<langle>0:T \<Rightarrow> U\<rangle> \<turnstile> Var 0 : T \<Rightarrow> U"
   398       show "e\<langle>0:T \<Rightarrow> U\<rangle> \<turnstile> Var 0 : T \<Rightarrow> U"
   409       	by (rule typing.Var) simp
   399       	by (rule typing.Var) simp
   410       from tred have "e \<turnstile> t' : T"
   400       from tred have "e \<turnstile> t' : T"
   413       	by (rule lift_type)
   403       	by (rule lift_type)
   414     qed
   404     qed
   415     from sred show "e \<turnstile> s' : T \<Rightarrow> U"
   405     from sred show "e \<turnstile> s' : T \<Rightarrow> U"
   416       by (rule subject_reduction') (rule rtyping_imp_typing)
   406       by (rule subject_reduction') (rule rtyping_imp_typing)
   417   qed
   407   qed
   418   then obtain u where ured: "s' \<degree> t' \<rightarrow>\<^sub>\<beta>\<^sup>* u" and unf: "u \<in> NF" by simp iprover
   408   then obtain u where ured: "s' \<degree> t' \<rightarrow>\<^sub>\<beta>\<^sup>* u" and unf: "NF u" by simp iprover
   419   from sred tred have "s \<degree> t \<rightarrow>\<^sub>\<beta>\<^sup>* s' \<degree> t'" by (rule rtrancl_beta_App)
   409   from sred tred have "s \<degree> t \<rightarrow>\<^sub>\<beta>\<^sup>* s' \<degree> t'" by (rule rtrancl_beta_App)
   420   hence "s \<degree> t \<rightarrow>\<^sub>\<beta>\<^sup>* u" using ured by (rule rtrancl_trans)
   410   hence "s \<degree> t \<rightarrow>\<^sub>\<beta>\<^sup>* u" using ured by (rule rtrancl_trans')
   421   with unf show ?case by iprover
   411   with unf show ?case by iprover
   422 qed
   412 qed
   423 
   413 
   424 
   414 
   425 subsection {* Extracting the program *}
   415 subsection {* Extracting the program *}
   426 
   416 
   427 declare NF.induct [ind_realizer]
   417 declare NF.induct [ind_realizer]
   428 declare rtrancl.induct [ind_realizer irrelevant]
   418 declare rtrancl.induct [ind_realizer irrelevant]
   429 declare rtyping.induct [ind_realizer]
   419 declare rtyping.induct [ind_realizer]
   430 lemmas [extraction_expand] = trans_def conj_assoc listall_cons_eq
   420 lemmas [extraction_expand] = conj_assoc listall_cons_eq
   431 
   421 
   432 extract type_NF
   422 extract type_NF
   433 
   423 
   434 lemma rtranclR_rtrancl_eq: "((a, b) \<in> rtranclR r) = ((a, b) \<in> rtrancl (Collect r))"
   424 lemma rtranclR_rtrancl_eq: "rtranclR r a b = rtrancl r a b"
   435   apply (rule iffI)
   425   apply (rule iffI)
   436   apply (erule rtranclR.induct)
   426   apply (erule rtranclR.induct)
   437   apply (rule rtrancl_refl)
   427   apply (rule rtrancl.rtrancl_refl)
   438   apply (erule rtrancl_into_rtrancl)
   428   apply (erule rtrancl.rtrancl_into_rtrancl)
   439   apply (erule CollectI)
   429   apply assumption
   440   apply (erule rtrancl.induct)
   430   apply (erule rtrancl.induct)
   441   apply (rule rtranclR.rtrancl_refl)
   431   apply (rule rtranclR.rtrancl_refl)
   442   apply (erule rtranclR.rtrancl_into_rtrancl)
   432   apply (erule rtranclR.rtrancl_into_rtrancl)
   443   apply (erule CollectD)
   433   apply assumption
   444   done
   434   done
   445 
   435 
   446 lemma NFR_imp_NF: "(nf, t) \<in> NFR \<Longrightarrow> t \<in> NF"
   436 lemma NFR_imp_NF: "NFR nf t \<Longrightarrow> NF t"
   447   apply (erule NFR.induct)
   437   apply (erule NFR.induct)
   448   apply (rule NF.intros)
   438   apply (rule NF.intros)
   449   apply (simp add: listall_def)
   439   apply (simp add: listall_def)
   450   apply (erule NF.intros)
   440   apply (erule NF.intros)
   451   done
   441   done