134 arbitrary reductions sequences of the CK machine. *} |
133 arbitrary reductions sequences of the CK machine. *} |
135 |
134 |
136 lemma machines_implies_cbvs_ctx: |
135 lemma machines_implies_cbvs_ctx: |
137 assumes a: "<e, Es> \<mapsto>* <e', Es'>" |
136 assumes a: "<e, Es> \<mapsto>* <e', Es'>" |
138 shows "(Es\<down>)\<lbrakk>e\<rbrakk> \<longrightarrow>cbv* (Es'\<down>)\<lbrakk>e'\<rbrakk>" |
137 shows "(Es\<down>)\<lbrakk>e\<rbrakk> \<longrightarrow>cbv* (Es'\<down>)\<lbrakk>e'\<rbrakk>" |
139 using a |
138 using a machine_implies_cbvs_ctx |
140 by (induct) (auto dest: machine_implies_cbvs_ctx) |
139 by (induct) (blast)+ |
141 |
140 |
142 text {* |
141 text {* |
143 So whenever we let the CL machine start in an initial |
142 So whenever we let the CL machine start in an initial |
144 state and it arrives at a final state, then there exists |
143 state and it arrives at a final state, then there exists |
145 a corresponding cbv-reduction sequence. *} |
144 a corresponding cbv-reduction sequence. |
|
145 *} |
146 |
146 |
147 corollary machines_implies_cbvs: |
147 corollary machines_implies_cbvs: |
148 assumes a: "<e, []> \<mapsto>* <e', []>" |
148 assumes a: "<e, []> \<mapsto>* <e', []>" |
149 shows "e \<longrightarrow>cbv* e'" |
149 shows "e \<longrightarrow>cbv* e'" |
150 using a by (auto dest: machines_implies_cbvs_ctx) |
150 proof - |
|
151 have "[]\<down>\<lbrakk>e\<rbrakk> \<longrightarrow>cbv* []\<down>\<lbrakk>e'\<rbrakk>" |
|
152 using a machines_implies_cbvs_ctx by blast |
|
153 then show "e \<longrightarrow>cbv* e'" by simp |
|
154 qed |
151 |
155 |
152 text {* |
156 text {* |
153 We now want to relate the cbv-reduction to the evaluation |
157 We now want to relate the cbv-reduction to the evaluation |
154 relation. For this we need two auxiliary lemmas. *} |
158 relation. For this we need two auxiliary lemmas. |
|
159 *} |
155 |
160 |
156 lemma eval_val: |
161 lemma eval_val: |
157 assumes a: "val t" |
162 assumes a: "val t" |
158 shows "t \<Down> t" |
163 shows "t \<Down> t" |
159 using a by (induct) (auto) |
164 using a by (induct) (auto) |
160 |
165 |
161 lemma e_App_elim: |
166 lemma e_App_elim: |
162 assumes a: "App t1 t2 \<Down> v" |
167 assumes a: "App t1 t2 \<Down> v" |
163 shows "\<exists>x t v'. t1 \<Down> Lam [x].t \<and> t2 \<Down> v' \<and> t[x::=v'] \<Down> v" |
168 obtains x t v' where "t1 \<Down> Lam [x].t" "t2 \<Down> v'" "t[x::=v'] \<Down> v" |
164 using a by (cases) (auto simp add: lam.eq_iff lam.distinct) |
169 using a by (cases) (auto simp add: lam.eq_iff lam.distinct) |
165 |
170 |
166 text {****************************************************************** |
171 |
167 |
172 subsection {* EXERCISE *} |
168 10.) Exercise |
173 |
169 ------------- |
174 text {* |
170 |
175 Complete the first and second case in the |
171 Complete the first case in the proof below. |
176 proof below. |
172 |
|
173 *} |
177 *} |
174 |
178 |
175 lemma cbv_eval: |
179 lemma cbv_eval: |
176 assumes a: "t1 \<longrightarrow>cbv t2" "t2 \<Down> t3" |
180 assumes a: "t1 \<longrightarrow>cbv t2" "t2 \<Down> t3" |
177 shows "t1 \<Down> t3" |
181 shows "t1 \<Down> t3" |
178 using a |
182 using a |
179 proof(induct arbitrary: t3) |
183 proof(induct arbitrary: t3) |
180 case (cbv1 v x t t3) |
184 case (cbv1 v x t t3) |
181 have a1: "val v" by fact |
185 have a1: "val v" by fact |
182 have a2: "t[x ::= v] \<Down> t3" by fact |
186 have a2: "t[x ::= v] \<Down> t3" by fact |
183 |
187 have a3: "Lam [x].t \<Down> Lam [x].t" by auto |
184 show "App (Lam [x].t) v \<Down> t3" sorry |
188 have a4: "v \<Down> v" using a1 eval_val by auto |
|
189 show "App (Lam [x].t) v \<Down> t3" using a3 a4 a2 by auto |
185 next |
190 next |
186 case (cbv2 t t' t2 t3) |
191 case (cbv2 t t' t2 t3) |
187 have ih: "\<And>t3. t' \<Down> t3 \<Longrightarrow> t \<Down> t3" by fact |
192 have ih: "\<And>t3. t' \<Down> t3 \<Longrightarrow> t \<Down> t3" by fact |
188 have "App t' t2 \<Down> t3" by fact |
193 have "App t' t2 \<Down> t3" by fact |
189 then obtain x t'' v' |
194 then obtain x t'' v' |
190 where a1: "t' \<Down> Lam [x].t''" |
195 where a1: "t' \<Down> Lam [x].t''" |
191 and a2: "t2 \<Down> v'" |
196 and a2: "t2 \<Down> v'" |
192 and a3: "t''[x ::= v'] \<Down> t3" using e_App_elim by blast |
197 and a3: "t''[x ::= v'] \<Down> t3" by (rule e_App_elim) |
193 have "t \<Down> Lam [x].t''" using ih a1 by auto |
198 have "t \<Down> Lam [x].t''" using ih a1 by auto |
194 then show "App t t2 \<Down> t3" using a2 a3 by auto |
199 then show "App t t2 \<Down> t3" using a2 a3 by auto |
195 qed (auto dest!: e_App_elim) |
200 qed (auto elim!: e_App_elim) |
196 |
201 |
197 |
202 |
198 text {* |
203 text {* |
199 Next we extend the lemma above to arbitray initial |
204 Next we extend the lemma above to arbitray initial |
200 sequences of cbv-reductions. *} |
205 sequences of cbv-reductions. *} |
204 shows "t1 \<Down> t3" |
209 shows "t1 \<Down> t3" |
205 using a by (induct) (auto intro: cbv_eval) |
210 using a by (induct) (auto intro: cbv_eval) |
206 |
211 |
207 text {* |
212 text {* |
208 Finally, we can show that if from a term t we reach a value |
213 Finally, we can show that if from a term t we reach a value |
209 by a cbv-reduction sequence, then t evaluates to this value. *} |
214 by a cbv-reduction sequence, then t evaluates to this value. |
|
215 *} |
210 |
216 |
211 lemma cbvs_implies_eval: |
217 lemma cbvs_implies_eval: |
212 assumes a: "t \<longrightarrow>cbv* v" "val v" |
218 assumes a: "t \<longrightarrow>cbv* v" "val v" |
213 shows "t \<Down> v" |
219 shows "t \<Down> v" |
214 using a |
220 using a |
215 by (induct) (auto intro: eval_val cbvs_eval) |
221 by (induct) (auto intro: eval_val cbvs_eval) |
216 |
222 |
217 text {* |
223 text {* |
218 All facts tied together give us the desired property about |
224 All facts tied together give us the desired property about |
219 K machines. *} |
225 machines. |
|
226 *} |
220 |
227 |
221 theorem machines_implies_eval: |
228 theorem machines_implies_eval: |
222 assumes a: "<t1, []> \<mapsto>* <t2, []>" |
229 assumes a: "<t1, []> \<mapsto>* <t2, []>" |
223 and b: "val t2" |
230 and b: "val t2" |
224 shows "t1 \<Down> t2" |
231 shows "t1 \<Down> t2" |
225 proof - |
232 proof - |
226 have "t1 \<longrightarrow>cbv* t2" using a by (simp add: machines_implies_cbvs) |
233 have "t1 \<longrightarrow>cbv* t2" using a machines_implies_cbvs by simp |
227 then show "t1 \<Down> t2" using b by (simp add: cbvs_implies_eval) |
234 then show "t1 \<Down> t2" using b cbvs_implies_eval by simp |
228 qed |
235 qed |
229 |
236 |
230 lemma valid_elim: |
237 lemma valid_elim: |
231 assumes a: "valid ((x, T) # \<Gamma>)" |
238 assumes a: "valid ((x, T) # \<Gamma>)" |
232 shows "atom x \<sharp> \<Gamma> \<and> valid \<Gamma>" |
239 shows "atom x \<sharp> \<Gamma> \<and> valid \<Gamma>" |
250 shows "T = U" |
257 shows "T = U" |
251 using a1 a2 a3 |
258 using a1 a2 a3 |
252 by (induct) (auto simp add: fresh_list fresh_Pair fresh_at_base) |
259 by (induct) (auto simp add: fresh_list fresh_Pair fresh_at_base) |
253 |
260 |
254 lemma type_substitution_aux: |
261 lemma type_substitution_aux: |
255 assumes a: "(\<Delta> @ [(x, T')] @ \<Gamma>) \<turnstile> e : T" |
262 assumes a: "\<Delta> @ [(x, T')] @ \<Gamma> \<turnstile> e : T" |
256 and b: "\<Gamma> \<turnstile> e' : T'" |
263 and b: "\<Gamma> \<turnstile> e' : T'" |
257 shows "(\<Delta> @ \<Gamma>) \<turnstile> e[x ::= e'] : T" |
264 shows "\<Delta> @ \<Gamma> \<turnstile> e[x ::= e'] : T" |
258 using a b |
265 using a b |
259 proof (nominal_induct \<Gamma>'\<equiv>"\<Delta> @ [(x, T')] @ \<Gamma>" e T avoiding: x e' \<Delta> rule: typing.strong_induct) |
266 proof (nominal_induct \<Gamma>'\<equiv>"\<Delta> @ [(x, T')] @ \<Gamma>" e T avoiding: x e' \<Delta> rule: typing.strong_induct) |
260 case (t_Var y T x e' \<Delta>) |
267 case (t_Var y T x e' \<Delta>) |
261 have a1: "valid (\<Delta> @ [(x, T')] @ \<Gamma>)" by fact |
268 have a1: "valid (\<Delta> @ [(x, T')] @ \<Gamma>)" by fact |
262 have a2: "(y,T) \<in> set (\<Delta> @ [(x, T')] @ \<Gamma>)" by fact |
269 have a2: "(y,T) \<in> set (\<Delta> @ [(x, T')] @ \<Gamma>)" by fact |
263 have a3: "\<Gamma> \<turnstile> e' : T'" by fact |
270 have a3: "\<Gamma> \<turnstile> e' : T'" by fact |
264 from a1 have a4: "valid (\<Delta> @ \<Gamma>)" by (rule valid_insert) |
271 from a1 have a4: "valid (\<Delta> @ \<Gamma>)" by (rule valid_insert) |
265 { assume eq: "x = y" |
272 { assume eq: "x = y" |
266 from a1 a2 have "T = T'" using eq by (auto intro: context_unique) |
273 from a1 a2 have "T = T'" using eq by (auto intro: context_unique) |
267 with a3 have "\<Delta> @ \<Gamma> \<turnstile> Var y[x::=e'] : T" using eq a4 by (auto intro: weakening) |
274 with a3 have "\<Delta> @ \<Gamma> \<turnstile> Var y[x ::= e'] : T" using eq a4 by (auto intro: weakening) |
268 } |
275 } |
269 moreover |
276 moreover |
270 { assume ineq: "x \<noteq> y" |
277 { assume ineq: "x \<noteq> y" |
271 from a2 have "(y, T) \<in> set (\<Delta> @ \<Gamma>)" using ineq by simp |
278 from a2 have "(y, T) \<in> set (\<Delta> @ \<Gamma>)" using ineq by simp |
272 then have "\<Delta> @ \<Gamma> \<turnstile> Var y[x::=e'] : T" using ineq a4 by auto |
279 then have "\<Delta> @ \<Gamma> \<turnstile> Var y[x ::= e'] : T" using ineq a4 by auto |
273 } |
280 } |
274 ultimately show "\<Delta> @ \<Gamma> \<turnstile> Var y[x::=e'] : T" by blast |
281 ultimately show "\<Delta> @ \<Gamma> \<turnstile> Var y[x::=e'] : T" by blast |
275 qed (force simp add: fresh_append fresh_Cons)+ |
282 qed (force simp add: fresh_append fresh_Cons)+ |
276 |
283 |
277 corollary type_substitution: |
284 corollary type_substitution: |
278 assumes a: "(x,T') # \<Gamma> \<turnstile> e : T" |
285 assumes a: "(x, T') # \<Gamma> \<turnstile> e : T" |
279 and b: "\<Gamma> \<turnstile> e' : T'" |
286 and b: "\<Gamma> \<turnstile> e' : T'" |
280 shows "\<Gamma> \<turnstile> e[x::=e'] : T" |
287 shows "\<Gamma> \<turnstile> e[x ::= e'] : T" |
281 using a b type_substitution_aux[where \<Delta>="[]"] |
288 using a b type_substitution_aux[where \<Delta>="[]"] |
282 by (auto) |
289 by auto |
283 |
290 |
284 lemma t_App_elim: |
291 lemma t_App_elim: |
285 assumes a: "\<Gamma> \<turnstile> App t1 t2 : T" |
292 assumes a: "\<Gamma> \<turnstile> App t1 t2 : T" |
286 shows "\<exists>T'. \<Gamma> \<turnstile> t1 : T' \<rightarrow> T \<and> \<Gamma> \<turnstile> t2 : T'" |
293 obtains T' where "\<Gamma> \<turnstile> t1 : T' \<rightarrow> T" "\<Gamma> \<turnstile> t2 : T'" |
287 using a |
294 using a |
288 by (cases) (auto simp add: lam.eq_iff lam.distinct) |
295 by (cases) (auto simp add: lam.eq_iff lam.distinct) |
289 |
296 |
|
297 text {* we have not yet generated strong elimination rules *} |
290 lemma t_Lam_elim: |
298 lemma t_Lam_elim: |
291 assumes ty: "\<Gamma> \<turnstile> Lam [x].t : T" |
299 assumes ty: "\<Gamma> \<turnstile> Lam [x].t : T" |
292 and fc: "atom x \<sharp> \<Gamma>" |
300 and fc: "atom x \<sharp> \<Gamma>" |
293 shows "\<exists>T1 T2. T = T1 \<rightarrow> T2 \<and> (x, T1) # \<Gamma> \<turnstile> t : T2" |
301 obtains T1 T2 where "T = T1 \<rightarrow> T2" "(x, T1) # \<Gamma> \<turnstile> t : T2" |
294 using ty fc |
302 using ty fc |
295 apply(cases) |
303 apply(cases) |
296 apply(auto simp add: lam.eq_iff lam.distinct ty.eq_iff) |
304 apply(auto simp add: lam.eq_iff lam.distinct ty.eq_iff) |
297 apply(auto simp add: Abs1_eq_iff) |
305 apply(auto simp add: Abs1_eq_iff) |
298 apply(rule_tac p="(x \<leftrightarrow> xa)" in permute_boolE) |
306 apply(rotate_tac 3) |
|
307 apply(drule_tac p="(x \<leftrightarrow> xa)" in permute_boolI) |
299 apply(perm_simp) |
308 apply(perm_simp) |
300 apply(simp add: flip_def swap_fresh_fresh ty_fresh) |
309 apply(auto simp add: flip_def swap_fresh_fresh ty_fresh) |
301 done |
310 done |
302 |
311 |
303 theorem cbv_type_preservation: |
312 theorem cbv_type_preservation: |
304 assumes a: "t \<longrightarrow>cbv t'" |
313 assumes a: "t \<longrightarrow>cbv t'" |
305 and b: "\<Gamma> \<turnstile> t : T" |
314 and b: "\<Gamma> \<turnstile> t : T" |
306 shows "\<Gamma> \<turnstile> t' : T" |
315 shows "\<Gamma> \<turnstile> t' : T" |
307 using a b |
316 using a b |
308 by (nominal_induct avoiding: \<Gamma> T rule: cbv.strong_induct) |
317 by (nominal_induct avoiding: \<Gamma> T rule: cbv.strong_induct) |
309 (auto dest!: t_Lam_elim t_App_elim simp add: type_substitution ty.eq_iff) |
318 (auto elim!: t_Lam_elim t_App_elim simp add: type_substitution ty.eq_iff) |
310 |
319 |
311 corollary cbvs_type_preservation: |
320 corollary cbvs_type_preservation: |
312 assumes a: "t \<longrightarrow>cbv* t'" |
321 assumes a: "t \<longrightarrow>cbv* t'" |
313 and b: "\<Gamma> \<turnstile> t : T" |
322 and b: "\<Gamma> \<turnstile> t : T" |
314 shows "\<Gamma> \<turnstile> t' : T" |
323 shows "\<Gamma> \<turnstile> t' : T" |
315 using a b |
324 using a b |
316 by (induct) (auto intro: cbv_type_preservation) |
325 by (induct) (auto intro: cbv_type_preservation) |
317 |
326 |
318 text {* |
327 text {* |
319 The Type-Preservation Property for the Machine and Evaluation Relation. *} |
328 The type-preservation property for the machine and |
|
329 evaluation relation. |
|
330 *} |
320 |
331 |
321 theorem machine_type_preservation: |
332 theorem machine_type_preservation: |
322 assumes a: "<t, []> \<mapsto>* <t', []>" |
333 assumes a: "<t, []> \<mapsto>* <t', []>" |
323 and b: "\<Gamma> \<turnstile> t : T" |
334 and b: "\<Gamma> \<turnstile> t : T" |
324 shows "\<Gamma> \<turnstile> t' : T" |
335 shows "\<Gamma> \<turnstile> t' : T" |
325 proof - |
336 proof - |
326 from a have "t \<longrightarrow>cbv* t'" by (simp add: machines_implies_cbvs) |
337 have "t \<longrightarrow>cbv* t'" using a machines_implies_cbvs by simp |
327 then show "\<Gamma> \<turnstile> t' : T" using b by (simp add: cbvs_type_preservation) |
338 then show "\<Gamma> \<turnstile> t' : T" using b cbvs_type_preservation by simp |
328 qed |
339 qed |
329 |
340 |
330 theorem eval_type_preservation: |
341 theorem eval_type_preservation: |
331 assumes a: "t \<Down> t'" |
342 assumes a: "t \<Down> t'" |
332 and b: "\<Gamma> \<turnstile> t : T" |
343 and b: "\<Gamma> \<turnstile> t : T" |
333 shows "\<Gamma> \<turnstile> t' : T" |
344 shows "\<Gamma> \<turnstile> t' : T" |
334 proof - |
345 proof - |
335 from a have "<t, []> \<mapsto>* <t', []>" by (simp add: eval_implies_machines) |
346 have "<t, []> \<mapsto>* <t', []>" using a eval_implies_machines by simp |
336 then show "\<Gamma> \<turnstile> t' : T" using b by (simp add: machine_type_preservation) |
347 then show "\<Gamma> \<turnstile> t' : T" using b machine_type_preservation by simp |
337 qed |
348 qed |
338 |
349 |
339 text {* The Progress Property *} |
350 text {* The Progress Property *} |
340 |
351 |
341 lemma canonical_tArr: |
352 lemma canonical_tArr: |
342 assumes a: "[] \<turnstile> t : T1 \<rightarrow> T2" |
353 assumes a: "[] \<turnstile> t : T1 \<rightarrow> T2" |
343 and b: "val t" |
354 and b: "val t" |
344 shows "\<exists>x t'. t = Lam [x].t'" |
355 obtains x t' where "t = Lam [x].t'" |
345 using b a by (induct) (auto) |
356 using b a by (induct) (auto) |
346 |
357 |
347 theorem progress: |
358 theorem progress: |
348 assumes a: "[] \<turnstile> t : T" |
359 assumes a: "[] \<turnstile> t : T" |
349 shows "(\<exists>t'. t \<longrightarrow>cbv t') \<or> (val t)" |
360 shows "(\<exists>t'. t \<longrightarrow>cbv t') \<or> (val t)" |
350 using a |
361 using a |
351 by (induct \<Gamma>\<equiv>"[]::ty_ctx" t T) |
362 by (induct \<Gamma>\<equiv>"[]::ty_ctx" t T) |
352 (auto intro: cbv.intros dest!: canonical_tArr) |
363 (auto elim: canonical_tArr) |
353 |
364 |
354 |
365 text {* |
|
366 Done! |
|
367 *} |
|
368 |
|
369 end |
|
370 |