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 |