176 |
177 |
177 term "\<forall>x. P x" -- {* versus *} |
178 term "\<forall>x. P x" -- {* versus *} |
178 term "\<And>x. P x" |
179 term "\<And>x. P x" |
179 |
180 |
180 |
181 |
181 |
182 section {* Inductive Definitions: Evaluation Relation *} |
182 section {* Inductive Definitions: Transitive Closures of Beta-Reduction *} |
183 |
183 |
184 text {* |
184 text {* |
185 In this section we want to define inductively the evaluation |
185 The theory Lmabda already contains a definition for beta-reduction, written |
186 relation for lambda terms. |
186 *} |
187 |
187 |
188 Inductive definitions in Isabelle start with the keyword "inductive" |
188 term "t \<longrightarrow>b t'" |
189 and a predicate name. One can optionally provide a type for the predicate. |
189 |
190 Clauses of the inductive predicate are introduced by "where" and more than |
190 text {* |
191 two clauses need to be separated by "|". One can also give a name to each |
191 In this section we want to define inductively the transitive closure of |
192 clause and indicate that it should be added to the hints database ("[intro]"). |
192 beta-reduction. |
193 A typical clause has some premises and a conclusion. This is written in |
193 |
194 Isabelle as: |
194 Inductive definitions in Isabelle start with the keyword "inductive" and a predicate |
|
195 name. One can optionally provide a type for the predicate. Clauses of the inductive |
|
196 predicate are introduced by "where" and more than two clauses need to be |
|
197 separated by "|". One can also give a name to each clause and indicate that it |
|
198 should be added to the hints database ("[intro]"). A typical clause has some |
|
199 premises and a conclusion. This is written in Isabelle as: |
|
200 |
195 |
201 "premise \<Longrightarrow> conclusion" |
196 "premise \<Longrightarrow> conclusion" |
202 "premise1 \<Longrightarrow> premise2 \<Longrightarrow> \<dots> premisen \<Longrightarrow> conclusion" |
197 "premise1 \<Longrightarrow> premise2 \<Longrightarrow> \<dots> premisen \<Longrightarrow> conclusion" |
203 |
198 |
204 There is an alternative way of writing the latter clause as |
199 There is an alternative way of writing the latter clause as |
211 |
206 |
212 Below we give two definitions for the transitive closure |
207 Below we give two definitions for the transitive closure |
213 *} |
208 *} |
214 |
209 |
215 inductive |
210 inductive |
216 beta_star1 :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<longrightarrow>b* _" [60, 60] 60) |
211 eval :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<Down> _" [60, 60] 60) |
217 where |
212 where |
218 bs1_refl: "t \<longrightarrow>b* t" |
213 e_Lam[intro]: "Lam [x].t \<Down> Lam [x].t" |
219 | bs1_trans: "\<lbrakk>t1 \<longrightarrow>b t2; t2 \<longrightarrow>b* t3\<rbrakk> \<Longrightarrow> t1 \<longrightarrow>b* t3" |
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" |
220 |
215 |
|
216 |
|
217 text {* |
|
218 Values are also defined using inductive. In our case values |
|
219 are just lambda-abstractions. |
|
220 *} |
221 |
221 |
222 inductive |
222 inductive |
223 beta_star2 :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<longrightarrow>b** _" [60, 60] 60) |
223 val :: "lam \<Rightarrow> bool" |
224 where |
224 where |
225 bs2_refl: "t \<longrightarrow>b** t" |
225 v_Lam[intro]: "val (Lam [x].t)" |
226 | bs2_step: "t1 \<longrightarrow>b t2 \<Longrightarrow> t1 \<longrightarrow>b** t2" |
226 |
227 | bs2_trans: "\<lbrakk>t1 \<longrightarrow>b** t2; t2 \<longrightarrow>b** t3\<rbrakk> \<Longrightarrow> t1 \<longrightarrow>b** t3" |
|
228 |
227 |
229 section {* Theorems *} |
228 section {* Theorems *} |
230 |
229 |
231 text {* |
230 text {* |
232 A central concept in Isabelle is that of theorems. Isabelle's theorem |
231 A central concept in Isabelle is that of theorems. Isabelle's theorem |
233 database can be queried using |
232 database can be queried using |
234 *} |
233 *} |
235 |
234 |
236 thm bs1_refl |
235 thm e_App |
237 thm bs2_trans |
236 thm e_Lam |
238 thm conjI |
237 thm conjI |
239 thm conjunct1 |
238 thm conjunct1 |
240 |
239 |
241 text {* |
240 text {* |
242 Notice that theorems usually contain schematic variables (e.g. ?P, ?Q, \<dots>). |
241 Notice that theorems usually contain schematic variables (e.g. ?P, ?Q, \<dots>). |
359 case \<dots> |
356 case \<dots> |
360 \<dots> |
357 \<dots> |
361 show \<dots> |
358 show \<dots> |
362 \<dots> |
359 \<dots> |
363 qed |
360 qed |
364 *} |
361 |
365 |
362 Two very simple example proofs are as follows. |
366 |
363 *} |
367 subsection {* Exercise I *} |
364 |
368 |
365 |
369 text {* |
366 lemma eval_val: |
370 Remove the sorries in the proof below and fill in the proper |
367 assumes a: "val t" |
371 justifications. |
368 shows "t \<Down> t" |
372 *} |
|
373 |
|
374 |
|
375 lemma |
|
376 assumes a: "t1 \<longrightarrow>b* t2" |
|
377 shows "t1 \<longrightarrow>b** t2" |
|
378 using a |
|
379 proof (induct) |
|
380 case (bs1_refl t) |
|
381 show "t \<longrightarrow>b** t" using bs2_refl by blast |
|
382 next |
|
383 case (bs1_trans t1 t2 t3) |
|
384 have beta: "t1 \<longrightarrow>b t2" by fact |
|
385 have ih: "t2 \<longrightarrow>b** t3" by fact |
|
386 have a: "t1 \<longrightarrow>b** t2" using beta bs2_step by blast |
|
387 show "t1 \<longrightarrow>b** t3" using a ih bs2_trans by blast |
|
388 qed |
|
389 |
|
390 |
|
391 subsection {* Exercise II *} |
|
392 |
|
393 text {* |
|
394 Again remove the sorries in the proof below and fill in the proper |
|
395 justifications. |
|
396 *} |
|
397 |
|
398 lemma bs1_trans2: |
|
399 assumes a: "t1 \<longrightarrow>b* t2" |
|
400 and b: "t2 \<longrightarrow>b* t3" |
|
401 shows "t1 \<longrightarrow>b* t3" |
|
402 using a b |
|
403 proof (induct) |
|
404 case (bs1_refl t1) |
|
405 have a: "t1 \<longrightarrow>b* t3" by fact |
|
406 show "t1 \<longrightarrow>b* t3" using a by blast |
|
407 next |
|
408 case (bs1_trans t1 t2 t3') |
|
409 have ih1: "t1 \<longrightarrow>b t2" by fact |
|
410 have ih2: "t3' \<longrightarrow>b* t3 \<Longrightarrow> t2 \<longrightarrow>b* t3" by fact |
|
411 have asm: "t3' \<longrightarrow>b* t3" by fact |
|
412 have a: "t2 \<longrightarrow>b* t3" using ih2 asm by blast |
|
413 show "t1 \<longrightarrow>b* t3" using ih1 a beta_star1.bs1_trans by blast |
|
414 qed |
|
415 |
|
416 lemma |
|
417 assumes a: "t1 \<longrightarrow>b** t2" |
|
418 shows "t1 \<longrightarrow>b* t2" |
|
419 using a |
369 using a |
420 proof (induct) |
370 proof (induct) |
421 case (bs2_refl t) |
371 case (v_Lam x t) |
422 show "t \<longrightarrow>b* t" using bs1_refl by blast |
372 show "Lam [x]. t \<Down> Lam [x]. t" sorry |
423 next |
373 qed |
424 case (bs2_step t1 t2) |
374 |
425 have ih: "t1 \<longrightarrow>b t2" by fact |
375 lemma eavl_to_val: |
426 have a: "t2 \<longrightarrow>b* t2" using bs1_refl by blast |
376 assumes a: "t \<Down> t'" |
427 show "t1 \<longrightarrow>b* t2" using ih a bs1_trans by blast |
377 shows "val t'" |
428 next |
378 using a |
429 case (bs2_trans t1 t2 t3) |
379 proof (induct) |
430 have ih1: "t1 \<longrightarrow>b* t2" by fact |
380 case (e_Lam x t) |
431 have ih2: "t2 \<longrightarrow>b* t3" by fact |
381 show "val (Lam [x].t)" sorry |
432 show "t1 \<longrightarrow>b* t3" using ih1 ih2 bs1_trans2 by blast |
382 next |
|
383 case (e_App t1 x t t2 v v') |
|
384 have "t1 \<Down> Lam [x].t" by fact |
|
385 have ih1: "val (Lam [x]. t)" by fact |
|
386 have "t2 \<Down> v" by fact |
|
387 have ih2: "val v" by fact |
|
388 have "t [x ::= v] \<Down> v'" by fact |
|
389 have ih3: "val v'" by fact |
|
390 show "val v'" sorry |
433 qed |
391 qed |
434 |
392 |
|
393 |
435 text {* |
394 text {* |
436 Just like gotos in the Basic programming language, labels often reduce |
395 Just like gotos in the Basic programming language, labels often reduce |
437 the readability of proofs. Therefore one can use in Isar the notation |
396 the readability of proofs. Therefore one can use in Isar the notation |
438 "then have" in order to feed a have-statement to the proof of |
397 "then have" in order to feed a have-statement to the proof of |
439 the next have-statement. This is used in teh second case below. |
398 the next have-statement. This is used in teh second case below. |
440 *} |
399 *} |
441 |
400 |
442 lemma |
401 |
443 assumes a: "t1 \<longrightarrow>b* t2" |
|
444 and b: "t2 \<longrightarrow>b* t3" |
|
445 shows "t1 \<longrightarrow>b* t3" |
|
446 using a b |
|
447 proof (induct) |
|
448 case (bs1_refl t1) |
|
449 show "t1 \<longrightarrow>b* t3" by fact |
|
450 next |
|
451 case (bs1_trans t1 t2 t3') |
|
452 have ih1: "t1 \<longrightarrow>b t2" by fact |
|
453 have ih2: "t3' \<longrightarrow>b* t3 \<Longrightarrow> t2 \<longrightarrow>b* t3" by fact |
|
454 have "t3' \<longrightarrow>b* t3" by fact |
|
455 then have "t2 \<longrightarrow>b* t3" using ih2 by blast |
|
456 then show "t1 \<longrightarrow>b* t3" using ih1 beta_star1.bs1_trans by blast |
|
457 qed |
|
458 |
402 |
459 text {* |
403 text {* |
460 The label ih2 cannot be got rid of in this way, because it is used |
404 The label ih2 cannot be got rid of in this way, because it is used |
461 two lines below and we cannot rearange them. We can still avoid the |
405 two lines below and we cannot rearange them. We can still avoid the |
462 label by feeding a sequence of facts into a proof using the |
406 label by feeding a sequence of facts into a proof using the |
472 |
416 |
473 In this chain, all "statement_i" can be used in the proof of the final |
417 In this chain, all "statement_i" can be used in the proof of the final |
474 "statement". With this we can simplify our proof further to: |
418 "statement". With this we can simplify our proof further to: |
475 *} |
419 *} |
476 |
420 |
477 lemma |
|
478 assumes a: "t1 \<longrightarrow>b* t2" |
|
479 and b: "t2 \<longrightarrow>b* t3" |
|
480 shows "t1 \<longrightarrow>b* t3" |
|
481 using a b |
|
482 proof (induct) |
|
483 case (bs1_refl t1) |
|
484 show "t1 \<longrightarrow>b* t3" by fact |
|
485 next |
|
486 case (bs1_trans t1 t2 t3') |
|
487 have "t3' \<longrightarrow>b* t3 \<Longrightarrow> t2 \<longrightarrow>b* t3" by fact |
|
488 moreover |
|
489 have "t3' \<longrightarrow>b* t3" by fact |
|
490 ultimately |
|
491 have "t2 \<longrightarrow>b* t3" by blast |
|
492 moreover |
|
493 have "t1 \<longrightarrow>b t2" by fact |
|
494 ultimately show "t1 \<longrightarrow>b* t3" using beta_star1.bs1_trans by blast |
|
495 qed |
|
496 |
|
497 |
421 |
498 text {* |
422 text {* |
499 While automatic proof procedures in Isabelle are not able to prove statements |
423 While automatic proof procedures in Isabelle are not able to prove statements |
500 like "P = NP" assuming usual definitions for P and NP, they can automatically |
424 like "P = NP" assuming usual definitions for P and NP, they can automatically |
501 discharge the lemmas we just proved. For this we only have to set up the induction |
425 discharge the lemmas we just proved. For this we only have to set up the induction |
502 and auto will take care of the rest. This means we can write: |
426 and auto will take care of the rest. This means we can write: |
503 *} |
427 *} |
504 |
428 |
505 lemma |
429 |
506 assumes a: "t1 \<longrightarrow>b* t2" |
|
507 shows "t1 \<longrightarrow>b** t2" |
|
508 using a |
|
509 by (induct) (auto intro: beta_star2.intros) |
|
510 |
|
511 lemma |
|
512 assumes a: "t1 \<longrightarrow>b* t2" |
|
513 and b: "t2 \<longrightarrow>b* t3" |
|
514 shows "t1 \<longrightarrow>b* t3" |
|
515 using a b |
|
516 by (induct) (auto intro: beta_star1.intros) |
|
517 |
|
518 lemma |
|
519 assumes a: "t1 \<longrightarrow>b** t2" |
|
520 shows "t1 \<longrightarrow>b* t2" |
|
521 using a |
|
522 by (induct) (auto intro: bs1_trans2 beta_star1.intros) |
|
523 |
|
524 inductive |
|
525 eval :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<Down> _" [60, 60] 60) |
|
526 where |
|
527 e_Lam: "Lam [x].t \<Down> Lam [x].t" |
|
528 | e_App: "\<lbrakk>t1 \<Down> Lam [x].t; t2 \<Down> v'; t[x::=v'] \<Down> v\<rbrakk> \<Longrightarrow> App t1 t2 \<Down> v" |
|
529 |
|
530 declare eval.intros[intro] |
|
531 |
|
532 text {* |
|
533 Values are also defined using inductive. In our case values |
|
534 are just lambda-abstractions. *} |
|
535 |
|
536 inductive |
|
537 val :: "lam \<Rightarrow> bool" |
|
538 where |
|
539 v_Lam[intro]: "val (Lam [x].t)" |
|
540 |
430 |
541 |
431 |
542 section {* Datatypes: Evaluation Contexts *} |
432 section {* Datatypes: Evaluation Contexts *} |
543 |
433 |
544 text {* |
434 text {* |
653 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
543 assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" |
654 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
544 and b: "<e2, Es2> \<mapsto>* <e3, Es3>" |
655 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
545 shows "<e1, Es1> \<mapsto>* <e3, Es3>" |
656 using a b by (induct) (auto) |
546 using a b by (induct) (auto) |
657 |
547 |
658 lemma eval_to_val: |
548 lemma eval_to_val: (* fixme: done above *) |
659 assumes a: "t \<Down> t'" |
549 assumes a: "t \<Down> t'" |
660 shows "val t'" |
550 shows "val t'" |
661 using a by (induct) (auto) |
551 using a by (induct) (auto) |
662 |
552 |
663 theorem |
553 theorem |