181 |
179 |
182 section {* Inductive Definitions: Evaluation Relation *} |
180 section {* Inductive Definitions: Evaluation Relation *} |
183 |
181 |
184 text {* |
182 text {* |
185 In this section we want to define inductively the evaluation |
183 In this section we want to define inductively the evaluation |
186 relation for lambda terms. |
184 relation and for cbv-reduction relation. |
187 |
185 |
188 Inductive definitions in Isabelle start with the keyword "inductive" |
186 Inductive definitions in Isabelle start with the keyword "inductive" |
189 and a predicate name. One can optionally provide a type for the predicate. |
187 and a predicate name. One can optionally provide a type for the predicate. |
190 Clauses of the inductive predicate are introduced by "where" and more than |
188 Clauses of the inductive predicate are introduced by "where" and more than |
191 two clauses need to be separated by "|". One can also give a name to each |
189 two clauses need to be separated by "|". One can also give a name to each |
211 eval :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<Down> _" [60, 60] 60) |
209 eval :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<Down> _" [60, 60] 60) |
212 where |
210 where |
213 e_Lam[intro]: "Lam [x].t \<Down> Lam [x].t" |
211 e_Lam[intro]: "Lam [x].t \<Down> Lam [x].t" |
214 | e_App[intro]: "\<lbrakk>t1 \<Down> Lam [x].t; t2 \<Down> v'; t[x::=v'] \<Down> v\<rbrakk> \<Longrightarrow> App t1 t2 \<Down> v" |
212 | e_App[intro]: "\<lbrakk>t1 \<Down> Lam [x].t; t2 \<Down> v'; t[x::=v'] \<Down> v\<rbrakk> \<Longrightarrow> App t1 t2 \<Down> v" |
215 |
213 |
216 |
214 text {* |
217 text {* |
215 Values and cbv are also defined using inductive. |
218 Values are also defined using inductive. In our case values |
|
219 are just lambda-abstractions. |
|
220 *} |
216 *} |
221 |
217 |
222 inductive |
218 inductive |
223 val :: "lam \<Rightarrow> bool" |
219 val :: "lam \<Rightarrow> bool" |
224 where |
220 where |
225 v_Lam[intro]: "val (Lam [x].t)" |
221 v_Lam[intro]: "val (Lam [x].t)" |
226 |
|
227 |
222 |
228 section {* Theorems *} |
223 section {* Theorems *} |
229 |
224 |
230 text {* |
225 text {* |
231 A central concept in Isabelle is that of theorems. Isabelle's theorem |
226 A central concept in Isabelle is that of theorems. Isabelle's theorem |
360 qed |
355 qed |
361 |
356 |
362 Two very simple example proofs are as follows. |
357 Two very simple example proofs are as follows. |
363 *} |
358 *} |
364 |
359 |
|
360 subsection {* EXERCISE 1 *} |
365 |
361 |
366 lemma eval_val: |
362 lemma eval_val: |
367 assumes a: "val t" |
363 assumes a: "val t" |
368 shows "t \<Down> t" |
364 shows "t \<Down> t" |
369 using a |
365 using a |
370 proof (induct) |
366 proof (induct) |
371 case (v_Lam x t) |
367 case (v_Lam x t) |
372 show "Lam [x]. t \<Down> Lam [x]. t" sorry |
368 show "Lam [x]. t \<Down> Lam [x]. t" sorry |
373 qed |
369 qed |
374 |
370 |
375 lemma eavl_to_val: |
371 subsection {* EXERCISE 2 *} |
|
372 |
|
373 text {* Fill the gaps in the proof below. *} |
|
374 |
|
375 lemma eval_to_val: |
376 assumes a: "t \<Down> t'" |
376 assumes a: "t \<Down> t'" |
377 shows "val t'" |
377 shows "val t'" |
378 using a |
378 using a |
379 proof (induct) |
379 proof (induct) |
380 case (e_Lam x t) |
380 case (e_Lam x t) |
381 show "val (Lam [x].t)" sorry |
381 show "val (Lam [x].t)" sorry |
382 next |
382 next |
383 case (e_App t1 x t t2 v v') |
383 case (e_App t1 x t t2 v v') |
|
384 -- {* all assumptions in this case *} |
384 have "t1 \<Down> Lam [x].t" by fact |
385 have "t1 \<Down> Lam [x].t" by fact |
385 have ih1: "val (Lam [x]. t)" by fact |
386 have ih1: "val (Lam [x]. t)" by fact |
386 have "t2 \<Down> v" by fact |
387 have "t2 \<Down> v" by fact |
387 have ih2: "val v" by fact |
388 have ih2: "val v" by fact |
388 have "t [x ::= v] \<Down> v'" by fact |
389 have "t [x ::= v] \<Down> v'" by fact |
389 have ih3: "val v'" by fact |
390 have ih3: "val v'" by fact |
|
391 |
390 show "val v'" sorry |
392 show "val v'" sorry |
391 qed |
393 qed |
392 |
394 |
393 |
395 |
394 text {* |
396 section {* Datatypes: Evaluation Contexts*} |
395 Just like gotos in the Basic programming language, labels often reduce |
397 |
396 the readability of proofs. Therefore one can use in Isar the notation |
398 text {* |
397 "then have" in order to feed a have-statement to the proof of |
|
398 the next have-statement. This is used in teh second case below. |
|
399 *} |
|
400 |
|
401 |
|
402 |
|
403 text {* |
|
404 The label ih2 cannot be got rid of in this way, because it is used |
|
405 two lines below and we cannot rearange them. We can still avoid the |
|
406 label by feeding a sequence of facts into a proof using the |
|
407 "moreover"-chaining mechanism: |
|
408 |
|
409 have "statement_1" \<dots> |
|
410 moreover |
|
411 have "statement_2" \<dots> |
|
412 \<dots> |
|
413 moreover |
|
414 have "statement_n" \<dots> |
|
415 ultimately have "statement" \<dots> |
|
416 |
|
417 In this chain, all "statement_i" can be used in the proof of the final |
|
418 "statement". With this we can simplify our proof further to: |
|
419 *} |
|
420 |
|
421 |
|
422 text {* |
|
423 While automatic proof procedures in Isabelle are not able to prove statements |
|
424 like "P = NP" assuming usual definitions for P and NP, they can automatically |
|
425 discharge the lemmas we just proved. For this we only have to set up the induction |
|
426 and auto will take care of the rest. This means we can write: |
|
427 *} |
|
428 |
|
429 |
|
430 |
|
431 |
|
432 section {* Datatypes: Evaluation Contexts *} |
|
433 |
|
434 text {* |
|
435 |
|
436 Datatypes can be defined in Isabelle as follows: we have to provide the name |
399 Datatypes can be defined in Isabelle as follows: we have to provide the name |
437 of the datatype and list its type-constructors. Each type-constructor needs |
400 of the datatype and a list its type-constructors. Each type-constructor needs |
438 to have the information about the types of its arguments, and optionally |
401 to have the information about the types of its arguments, and optionally |
439 can also contain some information about pretty syntax. For example, we like |
402 can also contain some information about pretty syntax. For example, we like |
440 to write "\<box>" for holes. |
403 to write "\<box>" for holes. |
441 *} |
404 *} |
442 |
405 |
443 datatype ctx = |
406 datatype ctx = |
444 Hole ("\<box>") |
407 Hole ("\<box>") |
445 | CAppL "ctx" "lam" |
408 | CAppL "ctx" "lam" |
446 | CAppR "lam" "ctx" |
409 | CAppR "lam" "ctx" |
447 |
410 |
456 |
419 |
457 text {* |
420 text {* |
458 Try and see what happens if you apply a Hole to a Hole? |
421 Try and see what happens if you apply a Hole to a Hole? |
459 *} |
422 *} |
460 |
423 |
|
424 |
|
425 section {* Machines for Evaluation *} |
|
426 |
461 type_synonym ctxs = "ctx list" |
427 type_synonym ctxs = "ctx list" |
462 |
428 |
463 inductive |
429 inductive |
464 machine :: "lam \<Rightarrow> ctxs \<Rightarrow>lam \<Rightarrow> ctxs \<Rightarrow> bool" ("<_,_> \<mapsto> <_,_>" [60, 60, 60, 60] 60) |
430 machine :: "lam \<Rightarrow> ctxs \<Rightarrow>lam \<Rightarrow> ctxs \<Rightarrow> bool" ("<_,_> \<mapsto> <_,_>" [60, 60, 60, 60] 60) |
465 where |
431 where |
466 m1[intro]: "<App t1 t2,Es> \<mapsto> <t1,(CAppL \<box> t2) # Es>" |
432 m1: "<App t1 t2, Es> \<mapsto> <t1, (CAppL \<box> t2) # Es>" |
467 | m2[intro]: "val v \<Longrightarrow> <v,(CAppL \<box> t2) # Es> \<mapsto> <t2,(CAppR v \<box>) # Es>" |
433 | m2: "val v \<Longrightarrow> <v, (CAppL \<box> t2) # Es> \<mapsto> <t2, (CAppR v \<box>) # Es>" |
468 | m3[intro]: "val v \<Longrightarrow> <v,(CAppR (Lam [x].t) \<box>) # Es> \<mapsto> <t[x ::= v],Es>" |
434 | m3: "val v \<Longrightarrow> <v, (CAppR (Lam [x].t) \<box>) # Es> \<mapsto> <t[x ::= v], Es>" |
469 |
|
470 |
435 |
471 text {* |
436 text {* |
472 Since the machine defined above only performs a single reduction, |
437 Since the machine defined above only performs a single reduction, |
473 we need to define the transitive closure of this machine. *} |
438 we need to define the transitive closure of this machine. *} |
474 |
439 |
475 inductive |
440 inductive |
476 machines :: "lam \<Rightarrow> ctxs \<Rightarrow> lam \<Rightarrow> ctxs \<Rightarrow> bool" ("<_,_> \<mapsto>* <_,_>" [60, 60, 60, 60] 60) |
441 machines :: "lam \<Rightarrow> ctxs \<Rightarrow> lam \<Rightarrow> ctxs \<Rightarrow> bool" ("<_,_> \<mapsto>* <_,_>" [60, 60, 60, 60] 60) |
477 where |
442 where |
478 ms1[intro]: "<t,Es> \<mapsto>* <t,Es>" |
443 ms1: "<t,Es> \<mapsto>* <t,Es>" |
479 | ms2[intro]: "\<lbrakk><t1,Es1> \<mapsto> <t2,Es2>; <t2,Es2> \<mapsto>* <t3,Es3>\<rbrakk> \<Longrightarrow> <t1,Es1> \<mapsto>* <t3,Es3>" |
444 | ms2: "\<lbrakk><t1,Es1> \<mapsto> <t2,Es2>; <t2,Es2> \<mapsto>* <t3,Es3>\<rbrakk> \<Longrightarrow> <t1,Es1> \<mapsto>* <t3,Es3>" |
480 |
445 |
481 lemma |
446 declare machine.intros[intro] machines.intros[intro] |
|
447 |
|
448 section {* EXERCISE 3 *} |
|
449 |
|
450 text {* |
|
451 We need to show that the machines-relation is transitive. |
|
452 Fill in the gaps below. |
|
453 *} |
|
454 |
|
455 lemma ms3[intro]: |
482 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
456 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
483 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
457 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
484 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
458 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
485 using a b |
459 using a b |
486 proof(induct) |
460 proof(induct) |
494 have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact |
468 have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact |
495 show "<e1, Es1> \<mapsto>* <e3, Es3>" using d1 d2 ih by blast |
469 show "<e1, Es1> \<mapsto>* <e3, Es3>" using d1 d2 ih by blast |
496 qed |
470 qed |
497 |
471 |
498 text {* |
472 text {* |
499 Just like gotos in the Basic programming language, labels can reduce |
473 Just like gotos in the Basic programming language, labels often reduce |
500 the readability of proofs. Therefore one can use in Isar the notation |
474 the readability of proofs. Therefore one can use in Isar the notation |
501 "then have" in order to feed a have-statement to the proof of |
475 "then have" in order to feed a have-statement to the proof of |
502 the next have-statement. In the proof below this has been used |
476 the next have-statement. This is used in teh second case below. |
503 in order to get rid of the labels c and d1. |
477 *} |
504 *} |
478 |
505 |
|
506 lemma |
479 lemma |
507 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
480 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
508 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
481 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
509 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
482 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
510 using a b |
483 using a b |
518 then have d3: "<e2, Es2> \<mapsto>* <e3, Es3>" using ih by simp |
491 then have d3: "<e2, Es2> \<mapsto>* <e3, Es3>" using ih by simp |
519 have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact |
492 have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact |
520 show "<e1, Es1> \<mapsto>* <e3, Es3>" using d2 d3 by auto |
493 show "<e1, Es1> \<mapsto>* <e3, Es3>" using d2 d3 by auto |
521 qed |
494 qed |
522 |
495 |
|
496 text {* |
|
497 The label ih2 cannot be got rid of in this way, because it is used |
|
498 two lines below and we cannot rearange them. We can still avoid the |
|
499 label by feeding a sequence of facts into a proof using the |
|
500 "moreover"-chaining mechanism: |
|
501 |
|
502 have "statement_1" \<dots> |
|
503 moreover |
|
504 have "statement_2" \<dots> |
|
505 \<dots> |
|
506 moreover |
|
507 have "statement_n" \<dots> |
|
508 ultimately have "statement" \<dots> |
|
509 |
|
510 In this chain, all "statement_i" can be used in the proof of the final |
|
511 "statement". With this we can simplify our proof further to: |
|
512 *} |
|
513 |
523 lemma |
514 lemma |
524 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
515 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
525 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
516 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
526 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
517 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
527 using a b |
518 using a b |
537 have "<e1, Es1> \<mapsto> <e2, Es2>" by fact |
528 have "<e1, Es1> \<mapsto> <e2, Es2>" by fact |
538 ultimately show "<e1, Es1> \<mapsto>* <e3, Es3>" by auto |
529 ultimately show "<e1, Es1> \<mapsto>* <e3, Es3>" by auto |
539 qed |
530 qed |
540 |
531 |
541 |
532 |
542 lemma ms3[intro]: |
533 text {* |
|
534 While automatic proof procedures in Isabelle are not able to prove statements |
|
535 like "P = NP" assuming usual definitions for P and NP, they can automatically |
|
536 discharge the lemmas we just proved. For this we only have to set up the induction |
|
537 and auto will take care of the rest. This means we can write: |
|
538 *} |
|
539 |
|
540 lemma |
|
541 assumes a: "val t" |
|
542 shows "t \<Down> t" |
|
543 using a by (induct) (auto) |
|
544 |
|
545 lemma |
|
546 assumes a: "t \<Down> t'" |
|
547 shows "val t'" |
|
548 using a by (induct) (auto) |
|
549 |
|
550 lemma |
543 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
551 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
544 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
552 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
545 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
553 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
546 using a b by (induct) (auto) |
554 using a b by (induct) (auto) |
547 |
555 |
548 lemma eval_to_val: (* fixme: done above *) |
556 |
549 assumes a: "t \<Down> t'" |
557 section {* EXERCISE 4 *} |
550 shows "val t'" |
558 |
551 using a by (induct) (auto) |
559 text {* |
|
560 The point of the machine is that it simulates the evaluation |
|
561 relation. Therefore we like to prove the following: |
|
562 *} |
552 |
563 |
553 theorem |
564 theorem |
554 assumes a: "t \<Down> t'" |
565 assumes a: "t \<Down> t'" |
555 shows "<t, []> \<mapsto>* <t', []>" |
566 shows "<t, []> \<mapsto>* <t', []>" |
556 using a |
567 using a |
565 have ih1: "<t1, []> \<mapsto>* <Lam [x].t, []>" by fact |
576 have ih1: "<t1, []> \<mapsto>* <Lam [x].t, []>" by fact |
566 have a2: "t2 \<Down> v'" by fact |
577 have a2: "t2 \<Down> v'" by fact |
567 have ih2: "<t2, []> \<mapsto>* <v', []>" by fact |
578 have ih2: "<t2, []> \<mapsto>* <v', []>" by fact |
568 have a3: "t[x::=v'] \<Down> v" by fact |
579 have a3: "t[x::=v'] \<Down> v" by fact |
569 have ih3: "<t[x::=v'], []> \<mapsto>* <v, []>" by fact |
580 have ih3: "<t[x::=v'], []> \<mapsto>* <v, []>" by fact |
|
581 |
570 -- {* your reasoning *} |
582 -- {* your reasoning *} |
571 show "<App t1 t2, []> \<mapsto>* <v, []>" sorry |
583 show "<App t1 t2, []> \<mapsto>* <v, []>" sorry |
572 qed |
584 qed |
|
585 |
|
586 |
|
587 theorem |
|
588 assumes a: "t \<Down> t'" |
|
589 shows "<t, Es> \<mapsto>* <t', Es>" |
|
590 using a |
|
591 proof (induct arbitrary: Es) |
|
592 case (e_Lam x t Es) |
|
593 -- {* no assumptions *} |
|
594 show "<Lam [x].t, Es> \<mapsto>* <Lam [x].t, Es>" by auto |
|
595 next |
|
596 case (e_App t1 x t t2 v' v Es) |
|
597 -- {* all assumptions in this case *} |
|
598 have a1: "t1 \<Down> Lam [x].t" by fact |
|
599 have ih1: "\<And>Es. <t1, Es> \<mapsto>* <Lam [x].t, Es>" by fact |
|
600 have a2: "t2 \<Down> v'" by fact |
|
601 have ih2: "\<And>Es. <t2, Es> \<mapsto>* <v', Es>" by fact |
|
602 have a3: "t[x::=v'] \<Down> v" by fact |
|
603 have ih3: "\<And>Es. <t[x::=v'], Es> \<mapsto>* <v, Es>" by fact |
|
604 -- {* your reasoning *} |
|
605 have "<App t1 t2, Es> \<mapsto>* <t1, CAppL \<box> t2 # Es>" by auto |
|
606 moreover |
|
607 have "<t1, CAppL \<box> t2 # Es> \<mapsto>* <Lam [x].t, CAppL \<box> t2 # Es>" using ih1 by auto |
|
608 moreover |
|
609 have "<Lam [x].t, CAppL \<box> t2 # Es> \<mapsto>* <t2, CAppR (Lam [x].t) \<box> # Es>" by auto |
|
610 moreover |
|
611 have "<t2, CAppR (Lam [x].t) \<box> # Es> \<mapsto>* <v', CAppR (Lam [x].t) \<box> # Es>" |
|
612 using ih2 by auto |
|
613 moreover |
|
614 have "val v'" using a2 eval_to_val by auto |
|
615 then have "<v', CAppR (Lam [x].t) \<box> # Es> \<mapsto>* <t[x::=v'], Es>" by auto |
|
616 moreover |
|
617 have "<t[x::=v'], Es> \<mapsto>* <v, Es>" using ih3 by auto |
|
618 ultimately show "<App t1 t2, Es> \<mapsto>* <v, Es>" by blast |
|
619 qed |
|
620 |
573 |
621 |
574 text {* |
622 text {* |
575 Again the automatic tools in Isabelle can discharge automatically |
623 Again the automatic tools in Isabelle can discharge automatically |
576 of the routine work in these proofs. We can write: |
624 of the routine work in these proofs. We can write: |
577 *} |
625 *} |