Tutorial/Tutorial1.thy
changeset 2693 2abc8cb46a5c
parent 2692 da9bed7baf23
child 2694 3485111c7d62
equal deleted inserted replaced
2692:da9bed7baf23 2693:2abc8cb46a5c
     1 
       
     2 header {* 
     1 header {* 
     3 
     2 
     4   Nominal Isabelle Tutorial at POPL'11
     3   Nominal Isabelle Tutorial at POPL'11
     5   ====================================
     4   ====================================
     6 
     5 
    59 
    58 
    60         \<sharp>    sharp     (freshness)
    59         \<sharp>    sharp     (freshness)
    61         \<bullet>    bullet    (permutation application)
    60         \<bullet>    bullet    (permutation application)
    62 *}
    61 *}
    63 
    62 
    64 
       
    65 theory Tutorial1
    63 theory Tutorial1
    66 imports Lambda
    64 imports Lambda
    67 begin
    65 begin
    68 
    66 
    69 section {* Theories *}
    67 section {* Theories *}
   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 *}
   604   filling :: "ctx \<Rightarrow> lam \<Rightarrow> lam" ("_\<lbrakk>_\<rbrakk>" [100, 100] 100)
   652   filling :: "ctx \<Rightarrow> lam \<Rightarrow> lam" ("_\<lbrakk>_\<rbrakk>" [100, 100] 100)
   605 where
   653 where
   606   "\<box>\<lbrakk>t\<rbrakk> = t"
   654   "\<box>\<lbrakk>t\<rbrakk> = t"
   607 | "(CAppL E t')\<lbrakk>t\<rbrakk> = App (E\<lbrakk>t\<rbrakk>) t'"
   655 | "(CAppL E t')\<lbrakk>t\<rbrakk> = App (E\<lbrakk>t\<rbrakk>) t'"
   608 | "(CAppR t' E)\<lbrakk>t\<rbrakk> = App t' (E\<lbrakk>t\<rbrakk>)"
   656 | "(CAppR t' E)\<lbrakk>t\<rbrakk> = App t' (E\<lbrakk>t\<rbrakk>)"
       
   657 
   609 
   658 
   610 text {* 
   659 text {* 
   611   After this definition Isabelle will be able to simplify
   660   After this definition Isabelle will be able to simplify
   612   statements like: 
   661   statements like: 
   613 *}
   662 *}