Tutorial/Tutorial1.thy
changeset 2688 87b735f86060
parent 2687 d0fb94035969
child 2689 ddc05a611005
equal deleted inserted replaced
2687:d0fb94035969 2688:87b735f86060
    59 
    59 
    60           \<sharp>       sharp     (freshness)
    60           \<sharp>       sharp     (freshness)
    61           \<bullet>       bullet    (permutations)
    61           \<bullet>       bullet    (permutations)
    62 *}
    62 *}
    63 
    63 
    64 
       
    65 theory Tutorial1
    64 theory Tutorial1
    66 imports Lambda
    65 imports Lambda
    67 begin
    66 begin
    68 
    67 
    69 section {* Theories *}
    68 section {* Theories *}
   663 theorem 
   662 theorem 
   664   assumes a: "t \<Down> t'"
   663   assumes a: "t \<Down> t'"
   665   shows "<t, []> \<mapsto>* <t', []>"
   664   shows "<t, []> \<mapsto>* <t', []>"
   666 using a 
   665 using a 
   667 proof (induct)
   666 proof (induct)
   668   case (e_Lam x t)
   667   case (e_Lam x t) 
   669   (* no assumptions *)
   668   -- {* no assumptions *}
   670   show "<Lam [x].t, []> \<mapsto>* <Lam [x].t, []>" sorry
   669   show "<Lam [x].t, []> \<mapsto>* <Lam [x].t, []>" sorry
   671 next
   670 next
   672   case (e_App t1 x t t2 v' v)
   671   case (e_App t1 x t t2 v' v) 
   673   (* all assumptions in this case *)
   672   -- {* all assumptions in this case *}
   674   have a1: "t1 \<Down> Lam [x].t" by fact
   673   have a1: "t1 \<Down> Lam [x].t" by fact
   675   have ih1: "<t1, []> \<mapsto>* <Lam [x].t, []>" by fact
   674   have ih1: "<t1, []> \<mapsto>* <Lam [x].t, []>" by fact
   676   have a2: "t2 \<Down> v'" by fact
   675   have a2: "t2 \<Down> v'" by fact
   677   have ih2: "<t2, []> \<mapsto>* <v', []>" by fact
   676   have ih2: "<t2, []> \<mapsto>* <v', []>" by fact
   678   have a3: "t[x::=v'] \<Down> v" by fact
   677   have a3: "t[x::=v'] \<Down> v" by fact
   679   have ih3: "<t[x::=v'], []> \<mapsto>* <v, []>" by fact
   678   have ih3: "<t[x::=v'], []> \<mapsto>* <v, []>" by fact
   680   (* your details *)
   679   -- {* your reasoning *}
   681   show "<App t1 t2, []> \<mapsto>* <v, []>" sorry
   680   show "<App t1 t2, []> \<mapsto>* <v, []>" sorry
   682 qed
   681 qed
   683 
   682 
   684 text {* 
   683 text {* 
   685   Again the automatic tools in Isabelle can discharge automatically 
   684   Again the automatic tools in Isabelle can discharge automatically 
   686   of the routine work in these proofs. We can write: *}
   685   of the routine work in these proofs. We can write: 
       
   686 *}
   687 
   687 
   688 theorem eval_implies_machines_ctx:
   688 theorem eval_implies_machines_ctx:
   689   assumes a: "t \<Down> t'"
   689   assumes a: "t \<Down> t'"
   690   shows "<t, Es> \<mapsto>* <t', Es>"
   690   shows "<t, Es> \<mapsto>* <t', Es>"
   691 using a
   691 using a
   695 corollary eval_implies_machines:
   695 corollary eval_implies_machines:
   696   assumes a: "t \<Down> t'"
   696   assumes a: "t \<Down> t'"
   697   shows "<t, []> \<mapsto>* <t', []>"
   697   shows "<t, []> \<mapsto>* <t', []>"
   698 using a eval_implies_machines_ctx by simp
   698 using a eval_implies_machines_ctx by simp
   699 
   699 
       
   700 section {* Types *}
   700 
   701 
   701 nominal_datatype ty =
   702 nominal_datatype ty =
   702   tVar "string"
   703   tVar "string"
   703 | tArr "ty" "ty" ("_ \<rightarrow> _" [100, 100] 100)
   704 | tArr "ty" "ty" ("_ \<rightarrow> _" [100, 100] 100)
   704 
   705 
   705 
   706 
   706 text {* 
   707 text {* 
   707   Having defined them as nominal datatypes gives us additional
   708   Having defined them as nominal datatypes gives us additional
   708   definitions and theorems that come with types (see below).
   709   definitions and theorems that come with types (see below).
   709   *}
   710  
   710 
       
   711 text {* 
       
   712   We next define the type of typing contexts, a predicate that
   711   We next define the type of typing contexts, a predicate that
   713   defines valid contexts (i.e. lists that contain only unique
   712   defines valid contexts (i.e. lists that contain only unique
   714   variables) and the typing judgement.
   713   variables) and the typing judgement.
   715 
   714 
   716 *}
   715 *}
   717 
   716 
   718 type_synonym ty_ctx = "(name \<times> ty) list"
   717 type_synonym ty_ctx = "(name \<times> ty) list"
       
   718 
   719 
   719 
   720 inductive
   720 inductive
   721   valid :: "ty_ctx \<Rightarrow> bool"
   721   valid :: "ty_ctx \<Rightarrow> bool"
   722 where
   722 where
   723   v1[intro]: "valid []"
   723   v1[intro]: "valid []"
   724 | v2[intro]: "\<lbrakk>valid \<Gamma>; atom x \<sharp> \<Gamma>\<rbrakk>\<Longrightarrow> valid ((x, T) # \<Gamma>)"
   724 | v2[intro]: "\<lbrakk>valid \<Gamma>; atom x \<sharp> \<Gamma>\<rbrakk>\<Longrightarrow> valid ((x, T) # \<Gamma>)"
       
   725 
   725 
   726 
   726 inductive
   727 inductive
   727   typing :: "ty_ctx \<Rightarrow> lam \<Rightarrow> ty \<Rightarrow> bool" ("_ \<turnstile> _ : _" [60, 60, 60] 60) 
   728   typing :: "ty_ctx \<Rightarrow> lam \<Rightarrow> ty \<Rightarrow> bool" ("_ \<turnstile> _ : _" [60, 60, 60] 60) 
   728 where
   729 where
   729   t_Var[intro]:  "\<lbrakk>valid \<Gamma>; (x, T) \<in> set \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Var x : T"
   730   t_Var[intro]:  "\<lbrakk>valid \<Gamma>; (x, T) \<in> set \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Var x : T"
   730 | t_App[intro]:  "\<lbrakk>\<Gamma> \<turnstile> t1 : T1 \<rightarrow> T2; \<Gamma> \<turnstile> t2 : T1\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : T2"
   731 | t_App[intro]:  "\<lbrakk>\<Gamma> \<turnstile> t1 : T1 \<rightarrow> T2; \<Gamma> \<turnstile> t2 : T1\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : T2"
   731 | t_Lam[intro]:  "\<lbrakk>atom x \<sharp> \<Gamma>; (x, T1) # \<Gamma> \<turnstile> t : T2\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Lam [x].t : T1 \<rightarrow> T2"
   732 | t_Lam[intro]:  "\<lbrakk>atom x \<sharp> \<Gamma>; (x, T1) # \<Gamma> \<turnstile> t : T2\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Lam [x].t : T1 \<rightarrow> T2"
   732 
   733 
   733 
   734 
   734 text {*
   735 text {*
   735   The predicate x \<sharp> \<Gamma>, read as x fresh for \<Gamma>, is defined by Nominal Isabelle.
   736   The predicate atom x \<sharp> \<Gamma>, read as x fresh for \<Gamma>, is defined by 
   736   Freshness is defined for lambda-terms, products, lists etc. For example
   737   Nominal Isabelle. Freshness is defined for lambda-terms, products, 
   737   we have:
   738   lists etc. For example we have:
   738   *}
   739   *}
   739 
   740 
   740 lemma
   741 lemma
   741   fixes x::"name"
   742   fixes x::"name"
   742   shows "atom x \<sharp> Lam [x].t"
   743   shows "atom x \<sharp> Lam [x].t"
   745   and   "\<lbrakk>atom x \<sharp> t1; atom x \<sharp> t2\<rbrakk> \<Longrightarrow> atom x \<sharp> (t1, t2)"
   746   and   "\<lbrakk>atom x \<sharp> t1; atom x \<sharp> t2\<rbrakk> \<Longrightarrow> atom x \<sharp> (t1, t2)"
   746   and   "\<lbrakk>atom x \<sharp> l1; atom x \<sharp> l2\<rbrakk> \<Longrightarrow> atom x \<sharp> (l1 @ l2)"
   747   and   "\<lbrakk>atom x \<sharp> l1; atom x \<sharp> l2\<rbrakk> \<Longrightarrow> atom x \<sharp> (l1 @ l2)"
   747   and   "atom x \<sharp> y \<Longrightarrow> x \<noteq> y"
   748   and   "atom x \<sharp> y \<Longrightarrow> x \<noteq> y"
   748   by (simp_all add: lam.fresh fresh_append fresh_at_base) 
   749   by (simp_all add: lam.fresh fresh_append fresh_at_base) 
   749 
   750 
   750 text {* We can also prove that every variable is fresh for a type *}
   751 text {* 
       
   752   We can also prove that every variable is fresh for a type. 
       
   753 *}
   751 
   754 
   752 lemma ty_fresh:
   755 lemma ty_fresh:
   753   fixes x::"name"
   756   fixes x::"name"
   754   and   T::"ty"
   757   and   T::"ty"
   755   shows "atom x \<sharp> T"
   758   shows "atom x \<sharp> T"
   756 by (induct T rule: ty.induct)
   759 by (induct T rule: ty.induct)
   757    (simp_all add: ty.fresh pure_fresh)
   760    (simp_all add: ty.fresh pure_fresh)
   758 
   761 
   759 text {* 
   762 text {* 
   760   In order to state the weakening lemma in a convenient form, we overload
   763   In order to state the weakening lemma in a convenient form, we 
   761   the subset-notation and define the abbreviation below. Abbreviations behave
   764   using the following abbreviation. Abbreviations behave like 
   762   like definitions, except that they are always automatically folded and
   765   definitions, except that they are always automatically folded 
   763   unfolded.
   766   and unfolded.
   764 *}
   767 *}
   765 
   768 
   766 abbreviation
   769 abbreviation
   767   "sub_ty_ctx" :: "ty_ctx \<Rightarrow> ty_ctx \<Rightarrow> bool" ("_ \<sqsubseteq> _" [60, 60] 60) 
   770   "sub_ty_ctx" :: "ty_ctx \<Rightarrow> ty_ctx \<Rightarrow> bool" ("_ \<sqsubseteq> _" [60, 60] 60) 
   768 where
   771 where
   769   "\<Gamma>1 \<sqsubseteq> \<Gamma>2 \<equiv> \<forall>x. x \<in> set \<Gamma>1 \<longrightarrow> x \<in> set \<Gamma>2"
   772   "\<Gamma>1 \<sqsubseteq> \<Gamma>2 \<equiv> \<forall>x. x \<in> set \<Gamma>1 \<longrightarrow> x \<in> set \<Gamma>2"
   770 
   773 
   771 text {***************************************************************** 
   774 
   772 
   775 subsection {* EXERCISE 4 *}
   773   4.) Exercise
   776 
   774   ------------
   777 text {*
   775 
       
   776   Fill in the details and give a proof of the weakening lemma. 
   778   Fill in the details and give a proof of the weakening lemma. 
   777 
       
   778 *}
   779 *}
   779 
   780 
   780 lemma 
   781 lemma 
   781   assumes a: "\<Gamma>1 \<turnstile> t : T"
   782   assumes a: "\<Gamma>1 \<turnstile> t : T"
   782   and     b: "valid \<Gamma>2" 
   783   and     b: "valid \<Gamma>2" 
   797   have a0: "atom x \<sharp> \<Gamma>1" by fact
   798   have a0: "atom x \<sharp> \<Gamma>1" by fact
   798   have a1: "valid \<Gamma>2" by fact
   799   have a1: "valid \<Gamma>2" by fact
   799   have a2: "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
   800   have a2: "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
   800 
   801 
   801   show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" sorry
   802   show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" sorry
   802 qed (auto)
   803 qed (auto) -- {* the application case *}
   803 
   804 
   804 
   805 
   805 text {* 
   806 text {* 
   806   Despite the frequent claim that the weakening lemma is trivial,
   807   Despite the frequent claim that the weakening lemma is trivial,
   807   routine or obvious, the proof in the lambda-case does not go 
   808   routine or obvious, the proof in the lambda-case does not go 
   808   smoothly through. Painful variable renamings seem to be necessary. 
   809   through smoothly. Painful variable renamings seem to be necessary. 
   809   But the proof using renamings is horribly complicated. It is really 
   810   But the proof using renamings is horribly complicated (see below). 
   810   interesting whether people who claim this proof is  trivial, routine 
       
   811   or obvious had this proof in mind. 
       
   812 
       
   813   BTW: The following two commands help already with showing that validity 
       
   814   and typing are invariant under variable (permutative) renamings. 
       
   815 *}
   811 *}
   816 
   812 
   817 equivariance valid
   813 equivariance valid
   818 equivariance typing
   814 equivariance typing
   819 
   815 
   820 lemma not_to_be_tried_at_home_weakening: 
   816 lemma weakening_NOT_TO_BE_TRIED_AT_HOME: 
   821   assumes a: "\<Gamma>1 \<turnstile> t : T"
   817   assumes a: "\<Gamma>1 \<turnstile> t : T"
   822   and     b: "valid \<Gamma>2" 
   818   and     b: "valid \<Gamma>2" 
   823   and     c: "\<Gamma>1 \<sqsubseteq> \<Gamma>2"
   819   and     c: "\<Gamma>1 \<sqsubseteq> \<Gamma>2"
   824   shows "\<Gamma>2 \<turnstile> t : T"
   820   shows "\<Gamma>2 \<turnstile> t : T"
   825 using a b c
   821 using a b c
   826 proof (induct arbitrary: \<Gamma>2)
   822 proof (induct arbitrary: \<Gamma>2)
   827   case (t_Lam x \<Gamma>1 T1 t T2) (* lambda case *)
   823   -- {* lambda case *}
       
   824   case (t_Lam x \<Gamma>1 T1 t T2) 
   828   have fc0: "atom x \<sharp> \<Gamma>1" by fact
   825   have fc0: "atom x \<sharp> \<Gamma>1" by fact
   829   have ih: "\<And>\<Gamma>3. \<lbrakk>valid \<Gamma>3; (x, T1) # \<Gamma>1 \<sqsubseteq> \<Gamma>3\<rbrakk> \<Longrightarrow> \<Gamma>3 \<turnstile> t : T2" by fact
   826   have ih: "\<And>\<Gamma>3. \<lbrakk>valid \<Gamma>3; (x, T1) # \<Gamma>1 \<sqsubseteq> \<Gamma>3\<rbrakk> \<Longrightarrow> \<Gamma>3 \<turnstile> t : T2" by fact
       
   827   -- {* we choose a fresh variable *}
   830   obtain c::"name" where fc1: "atom c \<sharp> (x, t, \<Gamma>1, \<Gamma>2)" by (rule obtain_fresh)
   828   obtain c::"name" where fc1: "atom c \<sharp> (x, t, \<Gamma>1, \<Gamma>2)" by (rule obtain_fresh)
   831   have "Lam [c].((c \<leftrightarrow> x) \<bullet> t) = Lam [x].t" using fc1 (* we then alpha-rename the lambda-abstraction *)
   829   -- {* we alpha-rename the abstraction *}
       
   830   have "Lam [c].((c \<leftrightarrow> x) \<bullet> t) = Lam [x].t" using fc1
   832     by (auto simp add: lam.eq_iff Abs1_eq_iff flip_def)
   831     by (auto simp add: lam.eq_iff Abs1_eq_iff flip_def)
   833   moreover
   832   moreover
   834   have "\<Gamma>2 \<turnstile> Lam [c].((c \<leftrightarrow> x) \<bullet> t) : T1 \<rightarrow> T2" (* we can then alpha-rename our original goal *)
   833   -- {* we can then alpha rename the goal *}
       
   834   have "\<Gamma>2 \<turnstile> Lam [c].((c \<leftrightarrow> x) \<bullet> t) : T1 \<rightarrow> T2" 
   835   proof - 
   835   proof - 
   836     (* we establish (x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2) and valid ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2)) *)
   836     -- {* we need to establish 
   837     have "(x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2)" 
   837            *   (x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2) and 
       
   838            **  valid ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2)) *}
       
   839     have *: "(x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2)" 
   838     proof -
   840     proof -
   839       have "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
   841       have "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
   840       then have "(c \<leftrightarrow> x) \<bullet> ((x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2))" using fc0 fc1
   842       then have "(c \<leftrightarrow> x) \<bullet> ((x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2))" using fc0 fc1
   841 	by (perm_simp) (simp add: flip_fresh_fresh)
   843         by (perm_simp) (simp add: flip_fresh_fresh)
   842       then show "(x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2)" by (rule permute_boolE)
   844       then show "(x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2)" by (rule permute_boolE)
   843     qed
   845     qed
   844     moreover 
   846     moreover 
   845     have "valid ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2))" 
   847     have **: "valid ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2))" 
   846     proof -
   848     proof -
   847       have "valid \<Gamma>2" by fact
   849       have "valid \<Gamma>2" by fact
   848       then show "valid ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2))" using fc1
   850       then show "valid ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2))" using fc1
   849 	by (auto simp add: fresh_permute_left atom_eqvt valid.eqvt)	
   851         by (auto simp add: fresh_permute_left atom_eqvt valid.eqvt)	
   850     qed
   852     qed
   851     (* these two facts give us by induction hypothesis the following *)
   853     -- {* these two facts give us by induction hypothesis the following *}
   852     ultimately have "(x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2) \<turnstile> t : T2" using ih by simp 
   854     ultimately have "(x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2) \<turnstile> t : T2" using ih by simp 
   853     (* we now apply renamings to get to our goal *)
   855     -- {* we now apply renamings to get to our goal *}
   854     then have "(c \<leftrightarrow> x) \<bullet> ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2) \<turnstile> t : T2)" by (rule permute_boolI)
   856     then have "(c \<leftrightarrow> x) \<bullet> ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2) \<turnstile> t : T2)" by (rule permute_boolI)
   855     then have "(c, T1) # \<Gamma>2 \<turnstile> ((c \<leftrightarrow> x) \<bullet> t) : T2" using fc1
   857     then have "(c, T1) # \<Gamma>2 \<turnstile> ((c \<leftrightarrow> x) \<bullet> t) : T2" using fc1
   856       by (perm_simp) (simp add: flip_fresh_fresh ty_fresh)
   858       by (perm_simp) (simp add: flip_fresh_fresh ty_fresh)
   857     then show "\<Gamma>2 \<turnstile> Lam [c].((c \<leftrightarrow> x) \<bullet> t) : T1 \<rightarrow> T2" using fc1 by auto
   859     then show "\<Gamma>2 \<turnstile> Lam [c].((c \<leftrightarrow> x) \<bullet> t) : T1 \<rightarrow> T2" using fc1 by auto
   858   qed
   860   qed
   859   ultimately show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" by simp
   861   ultimately show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" by simp
   860 qed (auto) (* var and app cases *)
   862 qed (auto) -- {* var and app cases, luckily, are automatic *}
   861 
   863 
   862 
   864 
   863 text {* 
   865 text {* 
   864   The remedy to the complicated proof of the weakening proof
   866   The remedy is to use a stronger induction principle that
   865   shown above is to use a stronger induction principle that
   867   has the usual "variable convention" already build in. The
   866   has the usual variable convention already build in. The
       
   867   following command derives this induction principle for us.
   868   following command derives this induction principle for us.
   868   (We shall explain what happens here later.)
   869   (We shall explain what happens here later.)
   869 
       
   870 *}
   870 *}
   871 
   871 
   872 nominal_inductive typing
   872 nominal_inductive typing
   873   avoids t_Lam: "x"
   873   avoids t_Lam: "x"
   874   unfolding fresh_star_def
   874   unfolding fresh_star_def
   875   by (simp_all add: fresh_Pair lam.fresh ty_fresh)
   875   by (simp_all add: fresh_Pair lam.fresh ty_fresh)
   876 
   876 
   877 text {* Compare the two induction principles *}
   877 text {* Compare the two induction principles *}
       
   878 
   878 thm typing.induct
   879 thm typing.induct
   879 thm typing.strong_induct
   880 thm typing.strong_induct -- {* has the additional assumption {atom x} \<sharp> c *}
   880 
   881 
   881 text {* 
   882 text {* 
   882   We can use the stronger induction principle by replacing
   883   We can use the stronger induction principle by replacing
   883   the line
   884   the line
   884 
   885 
   885   proof (induct arbitrary: \<Gamma>2)
   886       proof (induct arbitrary: \<Gamma>2)
   886 
   887 
   887   with 
   888   with 
   888   
   889   
   889   proof (nominal_induct avoiding: \<Gamma>2 rule: typing.strong_induct)
   890       proof (nominal_induct avoiding: \<Gamma>2 rule: typing.strong_induct)
   890 
   891 
   891   Try now the proof.
   892   Try now the proof.
   892 
       
   893 *}
   893 *}
   894   
   894   
   895 
   895 
   896 lemma weakening: 
   896 lemma weakening: 
   897   assumes a: "\<Gamma>1 \<turnstile> t : T"
   897   assumes a: "\<Gamma>1 \<turnstile> t : T"
   898   and     b: "valid \<Gamma>2" 
   898   and     b: "valid \<Gamma>2" 
   899   and     c: "\<Gamma>1 \<sqsubseteq> \<Gamma>2"
   899   and     c: "\<Gamma>1 \<sqsubseteq> \<Gamma>2"
   900   shows "\<Gamma>2 \<turnstile> t : T"
   900   shows "\<Gamma>2 \<turnstile> t : T"
   901 using a b c
   901 using a b c
   902 proof (nominal_induct avoiding: \<Gamma>2 rule: typing.strong_induct)
   902 proof (nominal_induct avoiding: \<Gamma>2 rule: typing.strong_induct)
   903   case (t_Var \<Gamma>1 x T)  (* variable case *)
   903   case (t_Var \<Gamma>1 x T)  -- {* variable case is as before *}
   904   have "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact 
   904   have "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact 
   905   moreover  
   905   moreover  
   906   have "valid \<Gamma>2" by fact 
   906   have "valid \<Gamma>2" by fact 
   907   moreover 
   907   moreover 
   908   have "(x, T)\<in> set \<Gamma>1" by fact
   908   have "(x, T)\<in> set \<Gamma>1" by fact
   909   ultimately show "\<Gamma>2 \<turnstile> Var x : T" by auto
   909   ultimately show "\<Gamma>2 \<turnstile> Var x : T" by auto
   910 next
   910 next
   911   case (t_Lam x \<Gamma>1 T1 t T2) 
   911   case (t_Lam x \<Gamma>1 T1 t T2) 
   912   have vc: "atom x \<sharp> \<Gamma>2" by fact   (* additional fact *)
   912   have vc: "atom x \<sharp> \<Gamma>2" by fact  -- {* additional fact afforded by the stron induction *}
   913   have ih: "\<And>\<Gamma>3. \<lbrakk>valid \<Gamma>3; (x, T1) # \<Gamma>1 \<sqsubseteq> \<Gamma>3\<rbrakk> \<Longrightarrow> \<Gamma>3 \<turnstile> t : T2" by fact
   913   have ih: "\<And>\<Gamma>3. \<lbrakk>valid \<Gamma>3; (x, T1) # \<Gamma>1 \<sqsubseteq> \<Gamma>3\<rbrakk> \<Longrightarrow> \<Gamma>3 \<turnstile> t : T2" by fact
   914   have a0: "atom x \<sharp> \<Gamma>1" by fact
   914   have a0: "atom x \<sharp> \<Gamma>1" by fact
   915   have a1: "valid \<Gamma>2" by fact
   915   have a1: "valid \<Gamma>2" by fact
   916   have a2: "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
   916   have a2: "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
   917 
   917   have "valid ((x, T1) # \<Gamma>2)" using a1 vc by auto
   918   show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" sorry
   918   moreover
   919 qed (auto) (* app case *)
   919   have "(x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # \<Gamma>2" using a2 by auto
   920 
   920   ultimately 
   921 
   921   have "(x, T1) # \<Gamma>2 \<turnstile> t : T2" using ih by simp 
   922 text {***************************************************************** 
   922   then show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" using vc by auto
   923 
   923 qed (auto) -- {* app case *}
   924   Function Definitions: Filling a Lambda-Term into a Context
   924 
   925   ----------------------------------------------------------
   925 
   926 
   926 section {* Function Definitions: Filling a Lambda-Term into a Context *}
       
   927  
       
   928 text {*
   927   Many functions over datatypes can be defined by recursion on the
   929   Many functions over datatypes can be defined by recursion on the
   928   structure. For this purpose, Isabelle provides "fun". To use it one needs 
   930   structure. For this purpose, Isabelle provides "fun". To use it one needs 
   929   to give a name for the function, its type, optionally some pretty-syntax 
   931   to give a name for the function, its type, optionally some pretty-syntax 
   930   and then some equations defining the function. Like in "inductive",
   932   and then some equations defining the function. Like in "inductive",
   931   "fun" expects that more than one such equation is separated by "|".
   933   "fun" expects that more than one such equation is separated by "|".
   932 
       
   933 *}
   934 *}
   934 
   935 
   935 fun
   936 fun
   936   filling :: "ctx \<Rightarrow> lam \<Rightarrow> lam" ("_\<lbrakk>_\<rbrakk>" [100, 100] 100)
   937   filling :: "ctx \<Rightarrow> lam \<Rightarrow> lam" ("_\<lbrakk>_\<rbrakk>" [100, 100] 100)
   937 where
   938 where
   939 | "(CAppL E t')\<lbrakk>t\<rbrakk> = App (E\<lbrakk>t\<rbrakk>) t'"
   940 | "(CAppL E t')\<lbrakk>t\<rbrakk> = App (E\<lbrakk>t\<rbrakk>) t'"
   940 | "(CAppR t' E)\<lbrakk>t\<rbrakk> = App t' (E\<lbrakk>t\<rbrakk>)"
   941 | "(CAppR t' E)\<lbrakk>t\<rbrakk> = App t' (E\<lbrakk>t\<rbrakk>)"
   941 
   942 
   942 text {* 
   943 text {* 
   943   After this definition Isabelle will be able to simplify
   944   After this definition Isabelle will be able to simplify
   944   statements like: *}
   945   statements like: 
       
   946 *}
   945 
   947 
   946 lemma 
   948 lemma 
   947   shows "(CAppL \<box> (Var x))\<lbrakk>Var y\<rbrakk> = App (Var y) (Var x)"
   949   shows "(CAppL \<box> (Var x))\<lbrakk>Var y\<rbrakk> = App (Var y) (Var x)"
   948   by simp
   950   by simp
   949 
   951 
   950 
       
   951 fun 
   952 fun 
   952  ctx_compose :: "ctx \<Rightarrow> ctx \<Rightarrow> ctx" ("_ \<cdot> _" [101,100] 100)
   953  ctx_compose :: "ctx \<Rightarrow> ctx \<Rightarrow> ctx" ("_ \<odot> _" [99,98] 99)
   953 where
   954 where
   954   "\<box> \<cdot> E' = E'"
   955   "\<box> \<odot> E' = E'"
   955 | "(CAppL E t') \<cdot> E' = CAppL (E \<cdot> E') t'"
   956 | "(CAppL E t') \<odot> E' = CAppL (E \<odot> E') t'"
   956 | "(CAppR t' E) \<cdot> E' = CAppR t' (E \<cdot> E')"
   957 | "(CAppR t' E) \<odot> E' = CAppR t' (E \<odot> E')"
   957 
   958 
   958 fun
   959 fun
   959   ctx_composes :: "ctxs \<Rightarrow> ctx" ("_\<down>" [110] 110)
   960   ctx_composes :: "ctxs \<Rightarrow> ctx" ("_\<down>" [110] 110)
   960 where
   961 where
   961     "[]\<down> = \<box>"
   962     "[]\<down> = \<box>"
   962   | "(E # Es)\<down> = (Es\<down>) \<cdot> E"
   963   | "(E # Es)\<down> = (Es\<down>) \<odot> E"
   963 
   964 
   964 text {*  
   965 text {*  
   965   Notice that we not just have given a pretty syntax for the functions, but
   966   Notice that we not just have given a pretty syntax for the functions, but
   966   also some precedences..The numbers inside the [\<dots>] stand for the precedences
   967   also some precedences. The numbers inside the [\<dots>] stand for the precedences
   967   of the arguments; the one next to it the precedence of the whole term.
   968   of the arguments; the one next to it the precedence of the whole term.
   968   
   969   
   969   This means we have to write (Es1 \<cdot> Es2) \<cdot> Es3 otherwise Es1 \<cdot> Es2 \<cdot> Es3 is
   970   This means we have to write (Es1 \<odot> Es2) \<odot> Es3 otherwise Es1 \<odot> Es2 \<odot> Es3 is
   970   interpreted as Es1 \<cdot> (Es2 \<cdot> Es3).
   971   interpreted as Es1 \<odot> (Es2 \<odot> Es3).
   971 *}
   972 *}
   972 
   973 
   973 text {******************************************************************
   974 section {* Structural Inductions over Contexts *}
   974   
   975  
   975   Structural Inductions over Contexts
   976 text {*
   976   ------------------------------------
       
   977 
       
   978   So far we have had a look at an induction over an inductive predicate. 
   977   So far we have had a look at an induction over an inductive predicate. 
   979   Another important induction principle is structural inductions for 
   978   Another important induction principle is structural inductions for 
   980   datatypes. To illustrate structural inductions we prove some facts
   979   datatypes. To illustrate structural inductions we prove some facts
   981   about context composition, some of which we will need later on.
   980   about context composition, some of which we will need later on.
   982 
   981 *}
   983 *}
   982 
   984 
   983 subsection {* EXERCISE 5 *}
   985 text {******************************************************************
   984 
   986 
   985 text {* Complete the proof and remove the sorries. *}
   987   5.) EXERCISE
       
   988   ------------
       
   989 
       
   990   Complete the proof and remove the sorries.
       
   991 
       
   992 *}
       
   993 
   986 
   994 lemma ctx_compose:
   987 lemma ctx_compose:
   995   shows "(E1 \<cdot> E2)\<lbrakk>t\<rbrakk> = E1\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>"
   988   shows "(E1 \<odot> E2)\<lbrakk>t\<rbrakk> = E1\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>"
   996 proof (induct E1)
   989 proof (induct E1)
   997   case Hole
   990   case Hole
   998   show "\<box> \<cdot> E2\<lbrakk>t\<rbrakk> = \<box>\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" sorry
   991   show "(\<box> \<odot> E2)\<lbrakk>t\<rbrakk> = \<box>\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" sorry
   999 next
   992 next
  1000   case (CAppL E1 t')
   993   case (CAppL E1 t')
  1001   have ih: "(E1 \<cdot> E2)\<lbrakk>t\<rbrakk> = E1\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" by fact
   994   have ih: "(E1 \<odot> E2)\<lbrakk>t\<rbrakk> = E1\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" by fact
  1002   show "((CAppL E1 t') \<cdot> E2)\<lbrakk>t\<rbrakk> = (CAppL E1 t')\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" sorry
   995   show "((CAppL E1 t') \<odot> E2)\<lbrakk>t\<rbrakk> = (CAppL E1 t')\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" sorry
  1003 next
   996 next
  1004   case (CAppR t' E1)
   997   case (CAppR t' E1)
  1005   have ih: "(E1 \<cdot> E2)\<lbrakk>t\<rbrakk> = E1\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" by fact
   998   have ih: "(E1 \<odot> E2)\<lbrakk>t\<rbrakk> = E1\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" by fact
  1006   show "((CAppR t' E1) \<cdot> E2)\<lbrakk>t\<rbrakk> = (CAppR t' E1)\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" sorry
   999   show "((CAppR t' E1) \<odot> E2)\<lbrakk>t\<rbrakk> = (CAppR t' E1)\<lbrakk>E2\<lbrakk>t\<rbrakk>\<rbrakk>" sorry
  1007 qed
  1000 qed
  1008 
  1001 
  1009 lemma neut_hole:
  1002 lemma neut_hole:
  1010   shows "E \<cdot> \<box> = E"
  1003   shows "E \<odot> \<box> = E"
  1011 by (induct E) (simp_all)
  1004 by (induct E) (simp_all)
  1012 
  1005 
  1013 lemma circ_assoc:
  1006 lemma odot_assoc:
  1014   fixes E1 E2 E3::"ctx"
  1007   fixes E1 E2 E3::"ctx"
  1015   shows "(E1 \<cdot> E2) \<cdot> E3 = E1 \<cdot> (E2 \<cdot> E3)"
  1008   shows "(E1 \<odot> E2) \<odot> E3 = E1 \<odot> (E2 \<odot> E3)"
  1016 by (induct E1) (simp_all)
  1009 by (induct E1) (simp_all)
  1017 
  1010 
  1018 lemma
  1011 lemma
  1019   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<cdot> (Es1\<down>)"
  1012   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<odot> (Es1\<down>)"
  1020 proof (induct Es1)
  1013 proof (induct Es1)
  1021   case Nil
  1014   case Nil
  1022   show "([] @ Es2)\<down> = Es2\<down> \<cdot> []\<down>" sorry
  1015   show "([] @ Es2)\<down> = Es2\<down> \<odot> []\<down>" sorry
  1023 next
  1016 next
  1024   case (Cons E Es1)
  1017   case (Cons E Es1)
  1025   have ih: "(Es1 @ Es2)\<down> = Es2\<down> \<cdot> Es1\<down>" by fact
  1018   have ih: "(Es1 @ Es2)\<down> = Es2\<down> \<odot> Es1\<down>" by fact
  1026 
  1019 
  1027   show "((E # Es1) @ Es2)\<down> = Es2\<down> \<cdot> (E # Es1)\<down>" sorry
  1020   show "((E # Es1) @ Es2)\<down> = Es2\<down> \<odot> (E # Es1)\<down>" sorry
  1028 qed
  1021 qed
  1029 
  1022 
  1030 
  1023 
  1031 text {* 
  1024 text {* 
  1032   The last proof involves several steps of equational reasoning.
  1025   The last proof involves several steps of equational reasoning.
  1033   Isar provides some convenient means to express such equational 
  1026   Isar provides some convenient means to express such equational 
  1034   reasoning in a much cleaner fashion using the "also have" 
  1027   reasoning in a much cleaner fashion using the "also have" 
  1035   construction. *}
  1028   construction. 
       
  1029 *}
       
  1030 
  1036 
  1031 
  1037 lemma 
  1032 lemma 
  1038   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<cdot> (Es1\<down>)"
  1033   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<odot> (Es1\<down>)"
  1039 proof (induct Es1)
  1034 proof (induct Es1)
  1040   case Nil
  1035   case Nil
  1041   show "([] @ Es2)\<down> = Es2\<down> \<cdot> []\<down>" using neut_hole by simp
  1036   show "([] @ Es2)\<down> = Es2\<down> \<odot> []\<down>" using neut_hole by simp
  1042 next
  1037 next
  1043   case (Cons E Es1)
  1038   case (Cons E Es1)
  1044   have ih: "(Es1 @ Es2)\<down> = Es2\<down> \<cdot> Es1\<down>" by fact
  1039   have ih: "(Es1 @ Es2)\<down> = Es2\<down> \<odot> Es1\<down>" by fact
  1045   have "((E # Es1) @ Es2)\<down> = (Es1 @ Es2)\<down> \<cdot> E" by simp
  1040   have "((E # Es1) @ Es2)\<down> = (Es1 @ Es2)\<down> \<odot> E" by simp
  1046   also have "\<dots> = (Es2\<down> \<cdot> Es1\<down>) \<cdot> E" using ih by simp
  1041   also have "\<dots> = (Es2\<down> \<odot> Es1\<down>) \<odot> E" using ih by simp
  1047   also have "\<dots> = Es2\<down> \<cdot> (Es1\<down> \<cdot> E)" using circ_assoc by simp
  1042   also have "\<dots> = Es2\<down> \<odot> (Es1\<down> \<odot> E)" using odot_assoc by simp
  1048   also have "\<dots> = Es2\<down> \<cdot> (E # Es1)\<down>" by simp
  1043   also have "\<dots> = Es2\<down> \<odot> (E # Es1)\<down>" by simp
  1049   finally show "((E # Es1) @ Es2)\<down> = Es2\<down> \<cdot> (E # Es1)\<down>" by simp
  1044   finally show "((E # Es1) @ Es2)\<down> = Es2\<down> \<odot> (E # Es1)\<down>" by simp
  1050 qed
  1045 qed
  1051 
  1046 
  1052 text {******************************************************************
  1047 text {******************************************************************
  1053   
  1048   
  1054   Formalising Barendregt's Proof of the Substitution Lemma
  1049   Formalising Barendregt's Proof of the Substitution Lemma
  1075   of such a block to the 'outside' is the implication
  1070   of such a block to the 'outside' is the implication
  1076 
  1071 
  1077    \<lbrakk>A; B\<rbrakk> \<Longrightarrow> "C" 
  1072    \<lbrakk>A; B\<rbrakk> \<Longrightarrow> "C" 
  1078 
  1073 
  1079   Now if we want to prove a property "smth" using the case-distinctions
  1074   Now if we want to prove a property "smth" using the case-distinctions
  1080   P\<^isub>1, P\<^isub>2 and P\<^isub>3 then we can use the following reasoning:
  1075   P1, P2 and P3 then we can use the following reasoning:
  1081 
  1076 
  1082     { assume "P\<^isub>1"
  1077     { assume "P1"
  1083       \<dots>
  1078       \<dots>
  1084       have "smth"
  1079       have "smth"
  1085     }
  1080     }
  1086     moreover
  1081     moreover
  1087     { assume "P\<^isub>2"
  1082     { assume "P2"
  1088       \<dots>
  1083       \<dots>
  1089       have "smth"
  1084       have "smth"
  1090     }
  1085     }
  1091     moreover
  1086     moreover
  1092     { assume "P\<^isub>3"
  1087     { assume "P3"
  1093       \<dots>
  1088       \<dots>
  1094       have "smth"
  1089       have "smth"
  1095     }
  1090     }
  1096     ultimately have "smth" by blast
  1091     ultimately have "smth" by blast
  1097 
  1092 
  1098   The blocks establish the implications
  1093   The blocks establish the implications
  1099 
  1094 
  1100     P\<^isub>1 \<Longrightarrow> smth
  1095     P1 \<Longrightarrow> smth
  1101     P\<^isub>2 \<Longrightarrow> smth
  1096     P2 \<Longrightarrow> smth
  1102     P\<^isub>3 \<Longrightarrow> smth
  1097     P3 \<Longrightarrow> smth
  1103 
  1098 
  1104   If we know that P\<^isub>1, P\<^isub>2 and P\<^isub>3 cover all the cases, that is P\<^isub>1 \<or> P\<^isub>2 \<or> P\<^isub>3 is
  1099   If we know that P1, P2 and P3 cover all the cases, that is P1 \<or> P2 \<or> P3 is
  1105   true, then we have 'ultimately' established the property "smth" 
  1100   true, then we have 'ultimately' established the property "smth" 
  1106   
  1101   
  1107 *}
  1102 *}
  1108 
  1103 
  1109 text {******************************************************************
  1104 section {* EXERCISE 7 *}
  1110   
  1105 
  1111   7.) Exercise
  1106 text {*
  1112   ------------
       
  1113 
       
  1114   Fill in the cases 1.2 and 1.3 and the equational reasoning 
  1107   Fill in the cases 1.2 and 1.3 and the equational reasoning 
  1115   in the lambda-case.
  1108   in the lambda-case.
  1116 *}
  1109 *}
  1117 
  1110 
  1118 lemma forget:
  1111 lemma forget:
  1119   shows "atom x \<sharp> t \<Longrightarrow> t[x ::= s] = t"
  1112   shows "atom x \<sharp> t \<Longrightarrow> t[x ::= s] = t"
  1120 apply(nominal_induct t avoiding: x s rule: lam.strong_induct)
  1113 by (nominal_induct t avoiding: x s rule: lam.strong_induct)
  1121 apply(auto simp add: lam.fresh fresh_at_base)
  1114    (auto simp add: lam.fresh fresh_at_base)
  1122 done
       
  1123 
  1115 
  1124 lemma fresh_fact:
  1116 lemma fresh_fact:
  1125   fixes z::"name"
  1117   fixes z::"name"
  1126   assumes a: "atom z \<sharp> s"
  1118   assumes a: "atom z \<sharp> s"
  1127   and b: "z = y \<or> atom z \<sharp> t"
  1119   and b: "z = y \<or> atom z \<sharp> t"
  1128   shows "atom z \<sharp> t[y ::= s]"
  1120   shows "atom z \<sharp> t[y ::= s]"
  1129 using a b
  1121 using a b
  1130 apply (nominal_induct t avoiding: z y s rule: lam.strong_induct)
  1122 by (nominal_induct t avoiding: z y s rule: lam.strong_induct)
  1131 apply (auto simp add: lam.fresh fresh_at_base)
  1123    (auto simp add: lam.fresh fresh_at_base)
  1132 done
  1124 
  1133 
       
  1134 thm forget
       
  1135 thm fresh_fact
       
  1136 
  1125 
  1137 lemma 
  1126 lemma 
  1138   assumes a: "x \<noteq> y"
  1127   assumes a: "x \<noteq> y"
  1139   and     b: "atom x \<sharp> L"
  1128   and     b: "atom x \<sharp> L"
  1140   shows "M[x::=N][y::=L] = M[y::=L][x::=N[y::=L]]"
  1129   shows "M[x::=N][y::=L] = M[y::=L][x::=N[y::=L]]"
  1143   case (Var z)
  1132   case (Var z)
  1144   have a1: "x \<noteq> y" by fact
  1133   have a1: "x \<noteq> y" by fact
  1145   have a2: "atom x \<sharp> L" by fact
  1134   have a2: "atom x \<sharp> L" by fact
  1146   show "Var z[x::=N][y::=L] = Var z[y::=L][x::=N[y::=L]]" (is "?LHS = ?RHS")
  1135   show "Var z[x::=N][y::=L] = Var z[y::=L][x::=N[y::=L]]" (is "?LHS = ?RHS")
  1147   proof -
  1136   proof -
  1148     { (*Case 1.1*)
  1137     { -- {* Case 1.1 *}
  1149       assume c1: "z=x"
  1138       assume c1: "z = x"
  1150       have "(1)": "?LHS = N[y::=L]" using c1 by simp
  1139       have "(1)": "?LHS = N[y::=L]" using c1 by simp
  1151       have "(2)": "?RHS = N[y::=L]" using c1 a1 by simp
  1140       have "(2)": "?RHS = N[y::=L]" using c1 a1 by simp
  1152       have "?LHS = ?RHS" using "(1)" "(2)" by simp
  1141       have "?LHS = ?RHS" using "(1)" "(2)" by simp
  1153     }
  1142     }
  1154     moreover 
  1143     moreover 
  1155     { (*Case 1.2*)
  1144     { -- {* Case 1.2 *}
  1156       assume c2: "z = y" "z \<noteq> x" 
  1145       assume c2: "z = y" "z \<noteq> x" 
  1157       
  1146       
  1158       have "?LHS = ?RHS" sorry
  1147       have "?LHS = ?RHS" sorry
  1159     }
  1148     }
  1160     moreover 
  1149     moreover 
  1161     { (*Case 1.3*)
  1150     { -- {* Case 1.3 *}
  1162       assume c3: "z \<noteq> x" "z \<noteq> y"
  1151       assume c3: "z \<noteq> x" "z \<noteq> y"
  1163       
  1152       
  1164       have "?LHS = ?RHS" sorry
  1153       have "?LHS = ?RHS" sorry
  1165     }
  1154     }
  1166     ultimately show "?LHS = ?RHS" by blast
  1155     ultimately show "?LHS = ?RHS" by blast
  1167   qed
  1156   qed
  1168 next
  1157 next
  1169   case (Lam z M1) (* case 2: lambdas *)
  1158   case (Lam z M1) -- {* case 2: lambdas *}
  1170   have ih: "\<lbrakk>x \<noteq> y; atom x \<sharp> L\<rbrakk> \<Longrightarrow> M1[x::=N][y::=L] = M1[y::=L][x::=N[y::=L]]" by fact
  1159   have ih: "\<lbrakk>x \<noteq> y; atom x \<sharp> L\<rbrakk> \<Longrightarrow> M1[x::=N][y::=L] = M1[y::=L][x::=N[y::=L]]" by fact
  1171   have a1: "x \<noteq> y" by fact
  1160   have a1: "x \<noteq> y" by fact
  1172   have a2: "atom x \<sharp> L" by fact
  1161   have a2: "atom x \<sharp> L" by fact
  1173   have fs: "atom z \<sharp> x" "atom z \<sharp> y" "atom z \<sharp> N" "atom z \<sharp> L" by fact+
  1162   have fs: "atom z \<sharp> x" "atom z \<sharp> y" "atom z \<sharp> N" "atom z \<sharp> L" by fact+
  1174   then have b: "atom z \<sharp> N[y::=L]" by (simp add: fresh_fact)
  1163   then have b: "atom z \<sharp> N[y::=L]" by (simp add: fresh_fact)
  1178 
  1167 
  1179     also have "\<dots> = ?RHS" sorry
  1168     also have "\<dots> = ?RHS" sorry
  1180     finally show "?LHS = ?RHS" by simp
  1169     finally show "?LHS = ?RHS" by simp
  1181   qed
  1170   qed
  1182 next
  1171 next
  1183   case (App M1 M2) (* case 3: applications *)
  1172   case (App M1 M2) -- {* case 3: applications *}
  1184   then show "(App M1 M2)[x::=N][y::=L] = (App M1 M2)[y::=L][x::=N[y::=L]]" by simp
  1173   then show "(App M1 M2)[x::=N][y::=L] = (App M1 M2)[y::=L][x::=N[y::=L]]" by simp
  1185 qed
  1174 qed
  1186 
  1175 
  1187 text {* 
  1176 text {* 
  1188   Again the strong induction principle enables Isabelle to find
  1177   Again the strong induction principle enables Isabelle to find