Tutorial/Tutorial1.thy
changeset 2706 8ae1c2e6369e
parent 2705 67451725fb41
parent 2704 b4bad45dbc0f
child 3132 87eca760dcba
equal deleted inserted replaced
2705:67451725fb41 2706:8ae1c2e6369e
     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 
   181 
   180 
   182 section {* Inductive Definitions: Evaluation Relation *}
   181 section {* Inductive Definitions: Evaluation Relation *}
   183 
   182 
   184 text {*
   183 text {*
   185   In this section we want to define inductively the evaluation
   184   In this section we want to define inductively the evaluation
   186   relation for lambda terms.
   185   relation and for cbv-reduction relation.
   187 
   186 
   188   Inductive definitions in Isabelle start with the keyword "inductive" 
   187   Inductive definitions in Isabelle start with the keyword "inductive" 
   189   and a predicate name.  One can optionally provide a type for the predicate. 
   188   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 
   189   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 
   190   two clauses need to be separated by "|". One can also give a name to each 
   206 
   205 
   207   Below we give two definitions for the transitive closure
   206   Below we give two definitions for the transitive closure
   208 *}
   207 *}
   209 
   208 
   210 inductive
   209 inductive
   211   eval :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<Down> _" [60, 60] 60) 
   210   eval :: "lam \<Rightarrow> lam \<Rightarrow> bool" (infixr "\<Down>" 60)
   212 where
   211 where
   213   e_Lam[intro]:  "Lam [x].t \<Down> Lam [x].t"
   212   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"
   213 | 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 
   214 
   216 
   215 text {* 
   217 text {* 
   216   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 *}
   217 *}
   221 
   218 
   222 inductive
   219 inductive
   223   val :: "lam \<Rightarrow> bool" 
   220   val :: "lam \<Rightarrow> bool" 
   224 where
   221 where
   225   v_Lam[intro]:   "val (Lam [x].t)"
   222   v_Lam[intro]:   "val (Lam [x].t)"
   226 
       
   227 
   223 
   228 section {* Theorems *}
   224 section {* Theorems *}
   229 
   225 
   230 text {*
   226 text {*
   231   A central concept in Isabelle is that of theorems. Isabelle's theorem
   227   A central concept in Isabelle is that of theorems. Isabelle's theorem
   360      qed
   356      qed
   361 
   357 
   362    Two very simple example proofs are as follows.
   358    Two very simple example proofs are as follows.
   363 *}
   359 *}
   364 
   360 
       
   361 subsection {* EXERCISE 1 *}
   365 
   362 
   366 lemma eval_val:
   363 lemma eval_val:
   367   assumes a: "val t"
   364   assumes a: "val t"
   368   shows "t \<Down> t"
   365   shows "t \<Down> t"
   369 using a
   366 using a
   370 proof (induct)
   367 proof (induct)
   371   case (v_Lam x t)
   368   case (v_Lam x t)
   372   show "Lam [x]. t \<Down> Lam [x]. t" sorry
   369   show "Lam [x]. t \<Down> Lam [x]. t" sorry
   373 qed
   370 qed
   374 
   371 
   375 lemma eavl_to_val:
   372 subsection {* EXERCISE 2 *}
       
   373 
       
   374 text {* Fill the gaps in the proof below. *}
       
   375 
       
   376 lemma eval_to_val:
   376   assumes a: "t \<Down> t'"
   377   assumes a: "t \<Down> t'"
   377   shows "val t'"
   378   shows "val t'"
   378 using a
   379 using a
   379 proof (induct)
   380 proof (induct)
   380   case (e_Lam x t)
   381   case (e_Lam x t)
   381   show "val (Lam [x].t)" sorry
   382   show "val (Lam [x].t)" sorry
   382 next
   383 next
   383   case (e_App t1 x t t2 v v')
   384   case (e_App t1 x t t2 v v')
       
   385   -- {* all assumptions in this case *}
   384   have "t1 \<Down> Lam [x].t" by fact
   386   have "t1 \<Down> Lam [x].t" by fact
   385   have ih1: "val (Lam [x]. t)" by fact
   387   have ih1: "val (Lam [x]. t)" by fact
   386   have "t2 \<Down> v" by fact
   388   have "t2 \<Down> v" by fact
   387   have ih2: "val v" by fact
   389   have ih2: "val v" by fact
   388   have "t [x ::= v] \<Down> v'" by fact
   390   have "t [x ::= v] \<Down> v'" by fact
   389   have ih3: "val v'" by fact
   391   have ih3: "val v'" by fact
       
   392 
   390   show "val v'" sorry
   393   show "val v'" sorry
   391 qed
   394 qed
   392   
   395 
   393  
   396 
   394 text {* 
   397 section {* Datatypes: Evaluation Contexts*}
   395   Just like gotos in the Basic programming language, labels often reduce 
   398 
   396   the readability of proofs. Therefore one can use in Isar the notation
   399 text {*
   397   "then have" in order to feed a have-statement to the proof of 
       
   398   the next have-statement. This is used in the 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 rearrange 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 
   400   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 
   401   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 
   402   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
   403   can also contain some information about pretty syntax. For example, we like
   440   to write "\<box>" for holes.
   404   to write "\<box>" for holes.
   441 *}
   405 *}
   442 
   406   
   443 datatype ctx = 
   407 datatype ctx = 
   444     Hole ("\<box>")  
   408     Hole ("\<box>")  
   445   | CAppL "ctx" "lam"
   409   | CAppL "ctx" "lam"
   446   | CAppR "lam" "ctx"
   410   | CAppR "lam" "ctx"
   447 
   411 
   456 
   420 
   457 text {*
   421 text {*
   458   Try and see what happens if you apply a Hole to a Hole? 
   422   Try and see what happens if you apply a Hole to a Hole? 
   459 *}
   423 *}
   460 
   424 
       
   425 
       
   426 section {* Machines for Evaluation *}
       
   427 
   461 type_synonym ctxs = "ctx list"
   428 type_synonym ctxs = "ctx list"
   462 
   429 
   463 inductive
   430 inductive
   464   machine :: "lam \<Rightarrow> ctxs \<Rightarrow>lam \<Rightarrow> ctxs \<Rightarrow> bool" ("<_,_> \<mapsto> <_,_>" [60, 60, 60, 60] 60)
   431   machine :: "lam \<Rightarrow> ctxs \<Rightarrow>lam \<Rightarrow> ctxs \<Rightarrow> bool" ("<_,_> \<mapsto> <_,_>" [60, 60, 60, 60] 60)
   465 where
   432 where
   466   m1[intro]: "<App t1 t2,Es> \<mapsto> <t1,(CAppL \<box> t2) # Es>"
   433   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>"
   434 | 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>"
   435 | m3: "val v \<Longrightarrow> <v, (CAppR (Lam [x].t) \<box>) # Es> \<mapsto> <t[x ::= v], Es>"
   469 
       
   470 
   436 
   471 text {*
   437 text {*
   472   Since the machine defined above only performs a single reduction,
   438   Since the machine defined above only performs a single reduction,
   473   we need to define the transitive closure of this machine. *}
   439   we need to define the transitive closure of this machine. *}
   474 
   440 
   475 inductive 
   441 inductive 
   476   machines :: "lam \<Rightarrow> ctxs \<Rightarrow> lam \<Rightarrow> ctxs \<Rightarrow> bool" ("<_,_> \<mapsto>* <_,_>" [60, 60, 60, 60] 60)
   442   machines :: "lam \<Rightarrow> ctxs \<Rightarrow> lam \<Rightarrow> ctxs \<Rightarrow> bool" ("<_,_> \<mapsto>* <_,_>" [60, 60, 60, 60] 60)
   477 where
   443 where
   478   ms1[intro]: "<t,Es> \<mapsto>* <t,Es>"
   444   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>"
   445 | ms2: "\<lbrakk><t1,Es1> \<mapsto> <t2,Es2>; <t2,Es2> \<mapsto>* <t3,Es3>\<rbrakk> \<Longrightarrow> <t1,Es1> \<mapsto>* <t3,Es3>"
   480 
   446 
   481 lemma 
   447 declare machine.intros[intro] machines.intros[intro]
       
   448 
       
   449 section {* EXERCISE 3 *}
       
   450 
       
   451 text {*
       
   452   We need to show that the machines-relation is transitive.
       
   453   Fill in the gaps below.   
       
   454 *}
       
   455 
       
   456 lemma ms3[intro]:
   482   assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" 
   457   assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" 
   483   and     b: "<e2, Es2> \<mapsto>* <e3, Es3>"
   458   and     b: "<e2, Es2> \<mapsto>* <e3, Es3>"
   484   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   459   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   485 using a b
   460 using a b
   486 proof(induct)
   461 proof(induct)
   487   case (ms1 e1 Es1)
   462   case (ms1 e1 Es1)
   488   have c: "<e1, Es1> \<mapsto>* <e3, Es3>" by fact
   463   have c: "<e1, Es1> \<mapsto>* <e3, Es3>" by fact
   489   then show "<e1, Es1> \<mapsto>* <e3, Es3>" by simp
   464   
       
   465   show "<e1, Es1> \<mapsto>* <e3, Es3>" sorry
   490 next
   466 next
   491   case (ms2 e1 Es1 e2 Es2 e2' Es2') 
   467   case (ms2 e1 Es1 e2 Es2 e2' Es2') 
   492   have ih: "<e2', Es2'> \<mapsto>* <e3, Es3> \<Longrightarrow> <e2, Es2> \<mapsto>* <e3, Es3>" by fact
   468   have ih: "<e2', Es2'> \<mapsto>* <e3, Es3> \<Longrightarrow> <e2, Es2> \<mapsto>* <e3, Es3>" by fact
   493   have d1: "<e2', Es2'> \<mapsto>* <e3, Es3>" by fact
   469   have d1: "<e2', Es2'> \<mapsto>* <e3, Es3>" by fact
   494   have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact
   470   have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact
   495   show "<e1, Es1> \<mapsto>* <e3, Es3>" using d1 d2 ih by blast
   471 
   496 qed
   472   show "<e1, Es1> \<mapsto>* <e3, Es3>" sorry
   497 
   473 qed
   498 text {* 
   474 
   499   Just like gotos in the Basic programming language, labels can reduce 
   475 text {* 
       
   476   Just like gotos in the Basic programming language, labels often reduce 
   500   the readability of proofs. Therefore one can use in Isar the notation
   477   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 
   478   "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
   479   the next have-statement. This is used in the second case below.
   503   in order to get rid of the labels c and d1. 
   480 *}
   504 *}
   481  
   505 
       
   506 lemma 
   482 lemma 
   507   assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" 
   483   assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" 
   508   and     b: "<e2, Es2> \<mapsto>* <e3, Es3>"
   484   and     b: "<e2, Es2> \<mapsto>* <e3, Es3>"
   509   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   485   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   510 using a b
   486 using a b
   518   then have d3: "<e2, Es2> \<mapsto>* <e3, Es3>" using ih by simp
   494   then have d3: "<e2, Es2> \<mapsto>* <e3, Es3>" using ih by simp
   519   have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact
   495   have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact
   520   show "<e1, Es1> \<mapsto>* <e3, Es3>" using d2 d3 by auto
   496   show "<e1, Es1> \<mapsto>* <e3, Es3>" using d2 d3 by auto
   521 qed
   497 qed
   522 
   498 
       
   499 text {* 
       
   500   The label ih2 cannot be got rid of in this way, because it is used 
       
   501   two lines below and we cannot rearrange them. We can still avoid the
       
   502   label by feeding a sequence of facts into a proof using the 
       
   503   "moreover"-chaining mechanism:
       
   504 
       
   505    have "statement_1" \<dots>
       
   506    moreover
       
   507    have "statement_2" \<dots>
       
   508    \<dots>
       
   509    moreover
       
   510    have "statement_n" \<dots>
       
   511    ultimately have "statement" \<dots>
       
   512 
       
   513   In this chain, all "statement_i" can be used in the proof of the final 
       
   514   "statement". With this we can simplify our proof further to:
       
   515 *}
       
   516 
   523 lemma 
   517 lemma 
   524   assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" 
   518   assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" 
   525   and     b: "<e2, Es2> \<mapsto>* <e3, Es3>"
   519   and     b: "<e2, Es2> \<mapsto>* <e3, Es3>"
   526   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   520   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   527 using a b
   521 using a b
   537   have "<e1, Es1> \<mapsto> <e2, Es2>" by fact
   531   have "<e1, Es1> \<mapsto> <e2, Es2>" by fact
   538   ultimately show "<e1, Es1> \<mapsto>* <e3, Es3>" by auto
   532   ultimately show "<e1, Es1> \<mapsto>* <e3, Es3>" by auto
   539 qed
   533 qed
   540 
   534 
   541 
   535 
   542 lemma ms3[intro]:
   536 text {* 
       
   537   While automatic proof procedures in Isabelle are not able to prove statements
       
   538   like "P = NP" assuming usual definitions for P and NP, they can automatically
       
   539   discharge the lemmas we just proved. For this we only have to set up the induction
       
   540   and auto will take care of the rest. This means we can write:
       
   541 *}
       
   542 
       
   543 lemma 
       
   544   assumes a: "val t"
       
   545   shows "t \<Down> t"
       
   546 using a by (induct) (auto)
       
   547 
       
   548 lemma 
       
   549   assumes a: "t \<Down> t'"
       
   550   shows "val t'"
       
   551 using a by (induct) (auto)
       
   552 
       
   553 lemma
   543   assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" 
   554   assumes a: "<e1, Es1> \<mapsto>* <e2, Es2>" 
   544   and     b: "<e2, Es2> \<mapsto>* <e3, Es3>"
   555   and     b: "<e2, Es2> \<mapsto>* <e3, Es3>"
   545   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   556   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   546 using a b by (induct) (auto)
   557 using a b by (induct) (auto)
   547 
   558 
   548 lemma eval_to_val:  (* fixme: done above *)
   559 
   549   assumes a: "t \<Down> t'"
   560 section {* EXERCISE 4 *}
   550   shows "val t'"
   561 
   551 using a by (induct) (auto)
   562 text {*
       
   563   The point of the machine is that it simulates the evaluation
       
   564   relation. Therefore we like to prove the following:
       
   565 *}
   552 
   566 
   553 theorem 
   567 theorem 
   554   assumes a: "t \<Down> t'"
   568   assumes a: "t \<Down> t'"
   555   shows "<t, []> \<mapsto>* <t', []>"
   569   shows "<t, []> \<mapsto>* <t', []>"
   556 using a 
   570 using a 
   565   have ih1: "<t1, []> \<mapsto>* <Lam [x].t, []>" by fact
   579   have ih1: "<t1, []> \<mapsto>* <Lam [x].t, []>" by fact
   566   have a2: "t2 \<Down> v'" by fact
   580   have a2: "t2 \<Down> v'" by fact
   567   have ih2: "<t2, []> \<mapsto>* <v', []>" by fact
   581   have ih2: "<t2, []> \<mapsto>* <v', []>" by fact
   568   have a3: "t[x::=v'] \<Down> v" by fact
   582   have a3: "t[x::=v'] \<Down> v" by fact
   569   have ih3: "<t[x::=v'], []> \<mapsto>* <v, []>" by fact
   583   have ih3: "<t[x::=v'], []> \<mapsto>* <v, []>" by fact
       
   584 
   570   -- {* your reasoning *}
   585   -- {* your reasoning *}
   571   show "<App t1 t2, []> \<mapsto>* <v, []>" sorry
   586   show "<App t1 t2, []> \<mapsto>* <v, []>" sorry
   572 qed
   587 qed
       
   588 
   573 
   589 
   574 text {* 
   590 text {* 
   575   Again the automatic tools in Isabelle can discharge automatically 
   591   Again the automatic tools in Isabelle can discharge automatically 
   576   of the routine work in these proofs. We can write: 
   592   of the routine work in these proofs. We can write: 
   577 *}
   593 *}
   587   assumes a: "t \<Down> t'"
   603   assumes a: "t \<Down> t'"
   588   shows "<t, []> \<mapsto>* <t', []>"
   604   shows "<t, []> \<mapsto>* <t', []>"
   589 using a eval_implies_machines_ctx by simp
   605 using a eval_implies_machines_ctx by simp
   590 
   606 
   591 
   607 
   592 
       
   593 section {* Function Definitions: Filling a Lambda-Term into a Context *}
   608 section {* Function Definitions: Filling a Lambda-Term into a Context *}
   594  
   609  
   595 text {*
   610 text {*
   596   Many functions over datatypes can be defined by recursion on the
   611   Many functions over datatypes can be defined by recursion on the
   597   structure. For this purpose, Isabelle provides "fun". To use it one needs 
   612   structure. For this purpose, Isabelle provides "fun". To use it one needs 
   605 where
   620 where
   606   "\<box>\<lbrakk>t\<rbrakk> = t"
   621   "\<box>\<lbrakk>t\<rbrakk> = t"
   607 | "(CAppL E t')\<lbrakk>t\<rbrakk> = App (E\<lbrakk>t\<rbrakk>) t'"
   622 | "(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>)"
   623 | "(CAppR t' E)\<lbrakk>t\<rbrakk> = App t' (E\<lbrakk>t\<rbrakk>)"
   609 
   624 
       
   625 
   610 text {* 
   626 text {* 
   611   After this definition Isabelle will be able to simplify
   627   After this definition Isabelle will be able to simplify
   612   statements like: 
   628   statements like: 
   613 *}
   629 *}
   614 
   630 
   615 lemma 
   631 lemma 
   616   shows "(CAppL \<box> (Var x))\<lbrakk>Var y\<rbrakk> = App (Var y) (Var x)"
   632   shows "(CAppL \<box> (Var x))\<lbrakk>Var y\<rbrakk> = App (Var y) (Var x)"
   617   by simp
   633   by simp
   618 
   634 
   619 fun 
   635 fun 
   620  ctx_compose :: "ctx \<Rightarrow> ctx \<Rightarrow> ctx" ("_ \<odot> _" [99,98] 99)
   636  ctx_compose :: "ctx \<Rightarrow> ctx \<Rightarrow> ctx" (infixr "\<odot>" 99)
   621 where
   637 where
   622   "\<box> \<odot> E' = E'"
   638   "\<box> \<odot> E' = E'"
   623 | "(CAppL E t') \<odot> E' = CAppL (E \<odot> E') t'"
   639 | "(CAppL E t') \<odot> E' = CAppL (E \<odot> E') t'"
   624 | "(CAppR t' E) \<odot> E' = CAppR t' (E \<odot> E')"
   640 | "(CAppR t' E) \<odot> E' = CAppR t' (E \<odot> E')"
   625 
   641 
   664   case (CAppR t' E1)
   680   case (CAppR t' E1)
   665   have ih: "(E1 \<odot> E2)\<lbrakk>t\<rbrakk> = E1\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" by fact
   681   have ih: "(E1 \<odot> E2)\<lbrakk>t\<rbrakk> = E1\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" by fact
   666   show "((CAppR t' E1) \<odot> E2)\<lbrakk>t\<rbrakk> = (CAppR t' E1)\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" sorry
   682   show "((CAppR t' E1) \<odot> E2)\<lbrakk>t\<rbrakk> = (CAppR t' E1)\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" sorry
   667 qed
   683 qed
   668 
   684 
       
   685 
       
   686 subsection {* EXERCISE 6 *}
       
   687 
       
   688 text {*
       
   689   Remove the sorries in the ctx_append proof below. You can make 
       
   690   use of the following two properties.    
       
   691 *}
       
   692 
   669 lemma neut_hole:
   693 lemma neut_hole:
   670   shows "E \<odot> \<box> = E"
   694   shows "E \<odot> \<box> = E"
   671 by (induct E) (simp_all)
   695 by (induct E) (simp_all)
   672 
   696 
   673 lemma odot_assoc: (* fixme call compose *)
   697 lemma compose_assoc:  
   674   shows "(E1 \<odot> E2) \<odot> E3 = E1 \<odot> (E2 \<odot> E3)"
   698   shows "(E1 \<odot> E2) \<odot> E3 = E1 \<odot> (E2 \<odot> E3)"
   675 by (induct E1) (simp_all)
   699 by (induct E1) (simp_all)
   676 
   700 
   677 lemma
   701 lemma
   678   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<odot> (Es1\<down>)"
   702   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<odot> (Es1\<down>)"
   684   have ih: "(Es1 @ Es2)\<down> = Es2\<down> \<odot> Es1\<down>" by fact
   708   have ih: "(Es1 @ Es2)\<down> = Es2\<down> \<odot> Es1\<down>" by fact
   685 
   709 
   686   show "((E # Es1) @ Es2)\<down> = Es2\<down> \<odot> (E # Es1)\<down>" sorry
   710   show "((E # Es1) @ Es2)\<down> = Es2\<down> \<odot> (E # Es1)\<down>" sorry
   687 qed
   711 qed
   688 
   712 
   689 
       
   690 text {* 
   713 text {* 
   691   The last proof involves several steps of equational reasoning.
   714   The last proof involves several steps of equational reasoning.
   692   Isar provides some convenient means to express such equational 
   715   Isar provides some convenient means to express such equational 
   693   reasoning in a much cleaner fashion using the "also have" 
   716   reasoning in a much cleaner fashion using the "also have" 
   694   construction. 
   717   construction. 
   695 *}
   718 *}
   696 
       
   697 
   719 
   698 lemma 
   720 lemma 
   699   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<odot> (Es1\<down>)"
   721   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<odot> (Es1\<down>)"
   700 proof (induct Es1)
   722 proof (induct Es1)
   701   case Nil
   723   case Nil
   702   show "([] @ Es2)\<down> = Es2\<down> \<odot> []\<down>" using neut_hole by simp
   724   show "([] @ Es2)\<down> = Es2\<down> \<odot> []\<down>" using neut_hole by simp
   703 next
   725 next
   704   case (Cons E Es1)
   726   case (Cons E Es1)
   705   have ih: "(Es1 @ Es2)\<down> = Es2\<down> \<odot> Es1\<down>" by fact
   727   have ih: "(Es1 @ Es2)\<down> = Es2\<down> \<odot> Es1\<down>" by fact
   706   have "((E # Es1) @ Es2)\<down> = (Es1 @ Es2)\<down> \<odot> E" by simp
   728   have "((E # Es1) @ Es2)\<down> = (E # (Es1 @ Es2))\<down>" by simp
       
   729   also have "\<dots> = (Es1 @ Es2)\<down> \<odot> E" by simp
   707   also have "\<dots> = (Es2\<down> \<odot> Es1\<down>) \<odot> E" using ih by simp
   730   also have "\<dots> = (Es2\<down> \<odot> Es1\<down>) \<odot> E" using ih by simp
   708   also have "\<dots> = Es2\<down> \<odot> (Es1\<down> \<odot> E)" using odot_assoc by simp
   731   also have "\<dots> = Es2\<down> \<odot> (Es1\<down> \<odot> E)" using compose_assoc by simp
   709   also have "\<dots> = Es2\<down> \<odot> (E # Es1)\<down>" by simp
   732   also have "\<dots> = Es2\<down> \<odot> (E # Es1)\<down>" by simp
   710   finally show "((E # Es1) @ Es2)\<down> = Es2\<down> \<odot> (E # Es1)\<down>" by simp
   733   finally show "((E # Es1) @ Es2)\<down> = Es2\<down> \<odot> (E # Es1)\<down>" by simp
   711 qed
   734 qed
   712 
   735 
   713 
   736 
   714 
       
   715 end  
   737 end  
   716 
   738