Tutorial/Tutorial1.thy
changeset 2689 ddc05a611005
parent 2688 87b735f86060
child 2690 f325eefe803e
equal deleted inserted replaced
2688:87b735f86060 2689:ddc05a611005
     3 
     3 
     4   Nominal Isabelle Tutorial at POPL'11
     4   Nominal Isabelle Tutorial at POPL'11
     5   ====================================
     5   ====================================
     6 
     6 
     7   Nominal Isabelle is a definitional extension of Isabelle/HOL, which
     7   Nominal Isabelle is a definitional extension of Isabelle/HOL, which
     8   means it does not add any new axioms to higher-order logic. It merely
     8   means it does not add any new axioms to higher-order logic. It just
     9   adds new definitions and an infrastructure for 'nominal resoning'.
     9   adds new definitions and an infrastructure for 'nominal resoning'.
    10 
    10 
    11 
    11 
    12   The jEdit Interface
    12   The jEdit Interface
    13   -------------------
    13   -------------------
    14 
    14 
    15   The Isabelle theorem prover comes with an interface for the jEdit. 
    15   The Isabelle theorem prover comes with an interface for jEdit. 
    16   Unlike many other theorem prover interfaces (e.g. ProofGeneral) where you 
    16   Unlike many other theorem prover interfaces (e.g. ProofGeneral) where you 
    17   try to advance a 'checked' region in a proof script, this interface immediately 
    17   advance a 'checked' region in a proof script, this interface immediately 
    18   checks the whole buffer. The text you type is also immediately checked
    18   checks the whole buffer. The text you type is also immediately checked. 
    19   as you type. Malformed text or unfinished proofs are highlighted in red 
    19   Malformed text or unfinished proofs are highlighted in red with a little 
    20   with a little red 'stop' signal on the left-hand side. If you drag the 
    20   red 'stop' signal on the left-hand side. If you drag the 'red-box' cursor 
    21   'red-box' cursor over a line, the Output window gives further feedback. 
    21   over a line, the Output window gives further feedback. 
    22 
    22 
    23   Note: If a section is not parsed correctly, the work-around is to cut it 
    23   Note: If a section is not parsed correctly, the work-around is to cut it 
    24   out and paste it back into the text (cut-out: Ctrl + X; paste in: Ctrl + V;
    24   out and paste it back into the text (cut-out: Ctrl + X; paste in: Ctrl + V;
    25   Cmd is Ctrl on the Mac)
    25   Cmd is Ctrl on the Mac)
    26 
    26 
    27   Nominal Isabelle and the interface can be started on the command line with
    27   Nominal Isabelle and jEdit can be started by typing on the command line
    28 
    28 
    29      isabelle jedit -l HOL-Nominal2
    29      isabelle jedit -l HOL-Nominal2
    30      isabelle jedit -l HOL-Nominal2 A.thy B.thy ...
    30      isabelle jedit -l HOL-Nominal2 A.thy B.thy ...
    31 
    31 
    32 
    32 
    53           ~       \<not>
    53           ~       \<not>
    54           ~=      \<noteq>
    54           ~=      \<noteq>
    55           :       \<in>
    55           :       \<in>
    56           ~:      \<notin>
    56           ~:      \<notin>
    57 
    57 
    58   For nominal two important symbols are
    58   For nominal the following two symbols have a special meaning
    59 
    59 
    60           \<sharp>       sharp     (freshness)
    60         \<sharp>    sharp     (freshness)
    61           \<bullet>       bullet    (permutations)
    61         \<bullet>    bullet    (permutation application)
    62 *}
    62 *}
    63 
    63 
    64 theory Tutorial1
    64 theory Tutorial1
    65 imports Lambda
    65 imports Lambda
    66 begin
    66 begin
    68 section {* Theories *}
    68 section {* Theories *}
    69 
    69 
    70 text {*
    70 text {*
    71   All formal developments in Isabelle are part of a theory. A theory 
    71   All formal developments in Isabelle are part of a theory. A theory 
    72   needs to have a name and must import some pre-existing theory. The 
    72   needs to have a name and must import some pre-existing theory. The 
    73   imported theory will normally be the theory Nominal2 (which  contains 
    73   imported theory will normally be Nominal2 (which provides many useful 
    74   many useful concepts like set-theory, lists, nominal theory etc).
    74   concepts like set-theory, lists, nominal things etc). For the purpose 
    75   For the purpose of the tutorial we import the theory Lambda.thy which
    75   of this tutorial we import the theory Lambda.thy, which contains 
    76   contains already some useful definitions for (alpha-equated) lambda 
    76   already some useful definitions for (alpha-equated) lambda terms.
    77   terms.
       
    78 *}
    77 *}
    79 
    78 
    80 
    79 
    81 
    80 
    82 section {* Types *}
    81 section {* Types *}
   133 term "App t1 t2"       -- {* another lambda-term *}
   132 term "App t1 t2"       -- {* another lambda-term *}
   134 term "x::name"         -- {* an (object) variable of type name *}
   133 term "x::name"         -- {* an (object) variable of type name *}
   135 term "atom (x::name)"  -- {* atom is an overloded function *}
   134 term "atom (x::name)"  -- {* atom is an overloded function *}
   136 
   135 
   137 text {* 
   136 text {* 
   138   Lam [x].Var is the syntax we made up for lambda abstractions. You can have
   137   Lam [x].Var is the syntax we made up for lambda abstractions. If you
   139   your own syntax, if you prefer (but \<lambda> is already taken up for Isabelle's
   138   prefer, you can have your own syntax (but \<lambda> is already taken up for 
   140   functions). We also came up with "name". If you prefer, you can call
   139   Isabelle's functions). We also came up with the type "name" for variables. 
   141   it "ident" or have more than one type for (object language) variables.
   140   You can introduce your own types of object variables using the 
   142 
   141   command atom_decl: 
       
   142 *}
       
   143 
       
   144 atom_decl ident
       
   145 atom_decl ty_var
       
   146 
       
   147 text {*
   143   Isabelle provides some useful colour feedback about its constants (black), 
   148   Isabelle provides some useful colour feedback about its constants (black), 
   144   free variables (blue) and bound variables (green).
   149   free variables (blue) and bound variables (green).
   145 *}
   150 *}
   146 
   151 
   147 term "True"    -- {* a constant that is defined in HOL...written in black *}
   152 term "True"    -- {* a constant defined somewhere...written in black *}
   148 term "true"    -- {* not recognised as a constant, therefore it is interpreted
   153 term "true"    -- {* not recognised as a constant, therefore it is interpreted
   149                      as a free variable, written in blue *}
   154                      as a free variable, written in blue *}
   150 term "\<forall>x. P x" -- {* x is bound (green), P is free (blue) *}
   155 term "\<forall>x. P x" -- {* x is bound (green), P is free (blue) *}
   151 
   156 
   152 
   157 
   260   Lemmas also need to have a proof, but ignore this 'detail' for the moment.
   265   Lemmas also need to have a proof, but ignore this 'detail' for the moment.
   261 
   266 
   262   Examples are
   267   Examples are
   263 *}
   268 *}
   264 
   269 
       
   270 
       
   271 
   265 lemma alpha_equ:
   272 lemma alpha_equ:
   266   shows "Lam [x].Var x = Lam [y].Var y"
   273   shows "Lam [x].Var x = Lam [y].Var y"
   267   by (simp add: lam.eq_iff Abs1_eq_iff lam.fresh fresh_at_base)
   274   by (simp add: lam.eq_iff Abs1_eq_iff lam.fresh fresh_at_base)
   268 
   275 
   269 lemma Lam_freshness:
   276 lemma Lam_freshness:
   270   assumes a: "x \<noteq> y"
   277   assumes a: "atom y \<sharp> Lam [x].t"
   271   and     b: "atom y \<sharp> Lam [x].t"
   278   shows "(y = x) \<or> (y \<noteq> x \<and> atom y \<sharp> t)"
   272   shows "atom y \<sharp> t"
   279   using a by (auto simp add: lam.fresh Abs_fresh_iff) 
   273   using a b by (simp add: lam.fresh Abs_fresh_iff) 
       
   274 
   280 
   275 lemma neutral_element:
   281 lemma neutral_element:
   276   fixes x::"nat"
   282   fixes x::"nat"
   277   shows "x + 0 = x"
   283   shows "x + 0 = x"
   278   by simp
   284   by simp
   498 
   504 
   499 lemma
   505 lemma
   500   assumes a: "t1 \<longrightarrow>b* t2" 
   506   assumes a: "t1 \<longrightarrow>b* t2" 
   501   shows "t1 \<longrightarrow>b** t2"
   507   shows "t1 \<longrightarrow>b** t2"
   502   using a
   508   using a
   503 by (induct) (auto intro: beta_star2.intros)
   509   by (induct) (auto intro: beta_star2.intros)
   504 
   510 
   505 lemma 
   511 lemma 
   506   assumes a: "t1 \<longrightarrow>b* t2"
   512   assumes a: "t1 \<longrightarrow>b* t2"
   507   and     b: "t2 \<longrightarrow>b* t3"
   513   and     b: "t2 \<longrightarrow>b* t3"
   508   shows "t1 \<longrightarrow>b* t3"
   514   shows "t1 \<longrightarrow>b* t3"
   509 using a b
   515   using a b
   510 by (induct) (auto intro: beta_star1.intros)
   516   by (induct) (auto intro: beta_star1.intros)
   511 
   517 
   512 lemma
   518 lemma
   513   assumes a: "t1 \<longrightarrow>b** t2"
   519   assumes a: "t1 \<longrightarrow>b** t2"
   514   shows "t1 \<longrightarrow>b* t2"
   520   shows "t1 \<longrightarrow>b* t2"
   515 using a
   521   using a
   516 by (induct) (auto intro: bs1_trans2 beta_star1.intros)
   522   by (induct) (auto intro: bs1_trans2 beta_star1.intros)
   517 
   523 
   518 inductive
   524 inductive
   519   eval :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<Down> _" [60, 60] 60) 
   525   eval :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<Down> _" [60, 60] 60) 
   520 where
   526 where
   521   e_Lam:  "Lam [x].t \<Down> Lam [x].t"
   527   e_Lam:  "Lam [x].t \<Down> Lam [x].t"
   554 typ ctx
   560 typ ctx
   555 term "\<box>"
   561 term "\<box>"
   556 term "CAppL"
   562 term "CAppL"
   557 term "CAppL \<box> (Var x)"
   563 term "CAppL \<box> (Var x)"
   558 
   564 
   559 text {* 
   565 subsection {* MINI EXERCISE *}
   560 
   566 
   561   1.) MINI EXERCISE
   567 text {*
   562   -----------------
       
   563 
       
   564   Try and see what happens if you apply a Hole to a Hole? 
   568   Try and see what happens if you apply a Hole to a Hole? 
   565 
       
   566 *}
   569 *}
   567 
   570 
   568 type_synonym ctxs = "ctx list"
   571 type_synonym ctxs = "ctx list"
   569 
   572 
   570 inductive
   573 inductive
   591   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   594   shows "<e1, Es1> \<mapsto>* <e3, Es3>"
   592 using a b
   595 using a b
   593 proof(induct)
   596 proof(induct)
   594   case (ms1 e1 Es1)
   597   case (ms1 e1 Es1)
   595   have c: "<e1, Es1> \<mapsto>* <e3, Es3>" by fact
   598   have c: "<e1, Es1> \<mapsto>* <e3, Es3>" by fact
   596   show "<e1, Es1> \<mapsto>* <e3, Es3>" sorry
   599   then show "<e1, Es1> \<mapsto>* <e3, Es3>" by simp
   597 next
   600 next
   598   case (ms2 e1 Es1 e2 Es2 e2' Es2') 
   601   case (ms2 e1 Es1 e2 Es2 e2' Es2') 
   599   have ih: "<e2', Es2'> \<mapsto>* <e3, Es3> \<Longrightarrow> <e2, Es2> \<mapsto>* <e3, Es3>" by fact
   602   have ih: "<e2', Es2'> \<mapsto>* <e3, Es3> \<Longrightarrow> <e2, Es2> \<mapsto>* <e3, Es3>" by fact
   600   have d1: "<e2', Es2'> \<mapsto>* <e3, Es3>" by fact
   603   have d1: "<e2', Es2'> \<mapsto>* <e3, Es3>" by fact
   601   have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact
   604   have d2: "<e1, Es1> \<mapsto> <e2, Es2>" by fact
   602   
   605   show "<e1, Es1> \<mapsto>* <e3, Es3>" using d1 d2 ih by blast
   603   show "<e1, Es1> \<mapsto>* <e3, Es3>" sorry
       
   604 qed
   606 qed
   605 
   607 
   606 text {* 
   608 text {* 
   607   Just like gotos in the Basic programming language, labels can reduce 
   609   Just like gotos in the Basic programming language, labels can reduce 
   608   the readability of proofs. Therefore one can use in Isar the notation
   610   the readability of proofs. Therefore one can use in Isar the notation
   656 lemma eval_to_val:
   658 lemma eval_to_val:
   657   assumes a: "t \<Down> t'"
   659   assumes a: "t \<Down> t'"
   658   shows "val t'"
   660   shows "val t'"
   659 using a by (induct) (auto)
   661 using a by (induct) (auto)
   660 
   662 
   661 
       
   662 theorem 
   663 theorem 
   663   assumes a: "t \<Down> t'"
   664   assumes a: "t \<Down> t'"
   664   shows "<t, []> \<mapsto>* <t', []>"
   665   shows "<t, []> \<mapsto>* <t', []>"
   665 using a 
   666 using a 
   666 proof (induct)
   667 proof (induct)
   667   case (e_Lam x t) 
   668   case (e_Lam x t) 
   668   -- {* no assumptions *}
   669   -- {* no assumptions *}
   669   show "<Lam [x].t, []> \<mapsto>* <Lam [x].t, []>" sorry
   670   show "<Lam [x].t, []> \<mapsto>* <Lam [x].t, []>" by auto
   670 next
   671 next
   671   case (e_App t1 x t t2 v' v) 
   672   case (e_App t1 x t t2 v' v) 
   672   -- {* all assumptions in this case *}
   673   -- {* all assumptions in this case *}
   673   have a1: "t1 \<Down> Lam [x].t" by fact
   674   have a1: "t1 \<Down> Lam [x].t" by fact
   674   have ih1: "<t1, []> \<mapsto>* <Lam [x].t, []>" by fact
   675   have ih1: "<t1, []> \<mapsto>* <Lam [x].t, []>" by fact
   695 corollary eval_implies_machines:
   696 corollary eval_implies_machines:
   696   assumes a: "t \<Down> t'"
   697   assumes a: "t \<Down> t'"
   697   shows "<t, []> \<mapsto>* <t', []>"
   698   shows "<t, []> \<mapsto>* <t', []>"
   698 using a eval_implies_machines_ctx by simp
   699 using a eval_implies_machines_ctx by simp
   699 
   700 
   700 section {* Types *}
       
   701 
       
   702 nominal_datatype ty =
       
   703   tVar "string"
       
   704 | tArr "ty" "ty" ("_ \<rightarrow> _" [100, 100] 100)
       
   705 
       
   706 
       
   707 text {* 
       
   708   Having defined them as nominal datatypes gives us additional
       
   709   definitions and theorems that come with types (see below).
       
   710  
       
   711   We next define the type of typing contexts, a predicate that
       
   712   defines valid contexts (i.e. lists that contain only unique
       
   713   variables) and the typing judgement.
       
   714 
       
   715 *}
       
   716 
       
   717 type_synonym ty_ctx = "(name \<times> ty) list"
       
   718 
       
   719 
       
   720 inductive
       
   721   valid :: "ty_ctx \<Rightarrow> bool"
       
   722 where
       
   723   v1[intro]: "valid []"
       
   724 | v2[intro]: "\<lbrakk>valid \<Gamma>; atom x \<sharp> \<Gamma>\<rbrakk>\<Longrightarrow> valid ((x, T) # \<Gamma>)"
       
   725 
       
   726 
       
   727 inductive
       
   728   typing :: "ty_ctx \<Rightarrow> lam \<Rightarrow> ty \<Rightarrow> bool" ("_ \<turnstile> _ : _" [60, 60, 60] 60) 
       
   729 where
       
   730   t_Var[intro]:  "\<lbrakk>valid \<Gamma>; (x, T) \<in> set \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Var x : T"
       
   731 | t_App[intro]:  "\<lbrakk>\<Gamma> \<turnstile> t1 : T1 \<rightarrow> T2; \<Gamma> \<turnstile> t2 : T1\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : 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"
       
   733 
       
   734 
       
   735 text {*
       
   736   The predicate atom x \<sharp> \<Gamma>, read as x fresh for \<Gamma>, is defined by 
       
   737   Nominal Isabelle. Freshness is defined for lambda-terms, products, 
       
   738   lists etc. For example we have:
       
   739   *}
       
   740 
       
   741 lemma
       
   742   fixes x::"name"
       
   743   shows "atom x \<sharp> Lam [x].t"
       
   744   and   "atom x \<sharp> (t1, t2) \<Longrightarrow> atom x \<sharp> App t1 t2"
       
   745   and   "atom x \<sharp> Var y \<Longrightarrow> atom x \<sharp> y" 
       
   746   and   "\<lbrakk>atom x \<sharp> t1; atom x \<sharp> t2\<rbrakk> \<Longrightarrow> atom x \<sharp> (t1, t2)"
       
   747   and   "\<lbrakk>atom x \<sharp> l1; atom x \<sharp> l2\<rbrakk> \<Longrightarrow> atom x \<sharp> (l1 @ l2)"
       
   748   and   "atom x \<sharp> y \<Longrightarrow> x \<noteq> y"
       
   749   by (simp_all add: lam.fresh fresh_append fresh_at_base) 
       
   750 
       
   751 text {* 
       
   752   We can also prove that every variable is fresh for a type. 
       
   753 *}
       
   754 
       
   755 lemma ty_fresh:
       
   756   fixes x::"name"
       
   757   and   T::"ty"
       
   758   shows "atom x \<sharp> T"
       
   759 by (induct T rule: ty.induct)
       
   760    (simp_all add: ty.fresh pure_fresh)
       
   761 
       
   762 text {* 
       
   763   In order to state the weakening lemma in a convenient form, we 
       
   764   using the following abbreviation. Abbreviations behave like 
       
   765   definitions, except that they are always automatically folded 
       
   766   and unfolded.
       
   767 *}
       
   768 
       
   769 abbreviation
       
   770   "sub_ty_ctx" :: "ty_ctx \<Rightarrow> ty_ctx \<Rightarrow> bool" ("_ \<sqsubseteq> _" [60, 60] 60) 
       
   771 where
       
   772   "\<Gamma>1 \<sqsubseteq> \<Gamma>2 \<equiv> \<forall>x. x \<in> set \<Gamma>1 \<longrightarrow> x \<in> set \<Gamma>2"
       
   773 
       
   774 
       
   775 subsection {* EXERCISE 4 *}
       
   776 
       
   777 text {*
       
   778   Fill in the details and give a proof of the weakening lemma. 
       
   779 *}
       
   780 
       
   781 lemma 
       
   782   assumes a: "\<Gamma>1 \<turnstile> t : T"
       
   783   and     b: "valid \<Gamma>2" 
       
   784   and     c: "\<Gamma>1 \<sqsubseteq> \<Gamma>2"
       
   785   shows "\<Gamma>2 \<turnstile> t : T"
       
   786 using a b c
       
   787 proof (induct arbitrary: \<Gamma>2)
       
   788   case (t_Var \<Gamma>1 x T)
       
   789   have a1: "valid \<Gamma>1" by fact
       
   790   have a2: "(x, T) \<in> set \<Gamma>1" by fact
       
   791   have a3: "valid \<Gamma>2" by fact
       
   792   have a4: "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
       
   793 
       
   794   show "\<Gamma>2 \<turnstile> Var x : T" sorry
       
   795 next
       
   796   case (t_Lam x \<Gamma>1 T1 t T2) 
       
   797   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
       
   798   have a0: "atom x \<sharp> \<Gamma>1" by fact
       
   799   have a1: "valid \<Gamma>2" by fact
       
   800   have a2: "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
       
   801 
       
   802   show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" sorry
       
   803 qed (auto) -- {* the application case *}
       
   804 
       
   805 
       
   806 text {* 
       
   807   Despite the frequent claim that the weakening lemma is trivial,
       
   808   routine or obvious, the proof in the lambda-case does not go 
       
   809   through smoothly. Painful variable renamings seem to be necessary. 
       
   810   But the proof using renamings is horribly complicated (see below). 
       
   811 *}
       
   812 
       
   813 equivariance valid
       
   814 equivariance typing
       
   815 
       
   816 lemma weakening_NOT_TO_BE_TRIED_AT_HOME: 
       
   817   assumes a: "\<Gamma>1 \<turnstile> t : T"
       
   818   and     b: "valid \<Gamma>2" 
       
   819   and     c: "\<Gamma>1 \<sqsubseteq> \<Gamma>2"
       
   820   shows "\<Gamma>2 \<turnstile> t : T"
       
   821 using a b c
       
   822 proof (induct arbitrary: \<Gamma>2)
       
   823   -- {* lambda case *}
       
   824   case (t_Lam x \<Gamma>1 T1 t T2) 
       
   825   have fc0: "atom x \<sharp> \<Gamma>1" 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 *}
       
   828   obtain c::"name" where fc1: "atom c \<sharp> (x, t, \<Gamma>1, \<Gamma>2)" by (rule obtain_fresh)
       
   829   -- {* we alpha-rename the abstraction *}
       
   830   have "Lam [c].((c \<leftrightarrow> x) \<bullet> t) = Lam [x].t" using fc1
       
   831     by (auto simp add: lam.eq_iff Abs1_eq_iff flip_def)
       
   832   moreover
       
   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 - 
       
   836     -- {* we need to establish 
       
   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)" 
       
   840     proof -
       
   841       have "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
       
   842       then have "(c \<leftrightarrow> x) \<bullet> ((x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2))" using fc0 fc1
       
   843         by (perm_simp) (simp add: flip_fresh_fresh)
       
   844       then show "(x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2)" by (rule permute_boolE)
       
   845     qed
       
   846     moreover 
       
   847     have **: "valid ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2))" 
       
   848     proof -
       
   849       have "valid \<Gamma>2" by fact
       
   850       then show "valid ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2))" using fc1
       
   851         by (auto simp add: fresh_permute_left atom_eqvt valid.eqvt)	
       
   852     qed
       
   853     -- {* these two facts give us by induction hypothesis the following *}
       
   854     ultimately have "(x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2) \<turnstile> t : T2" using ih by simp 
       
   855     -- {* we now apply renamings to get to our goal *}
       
   856     then have "(c \<leftrightarrow> x) \<bullet> ((x, T1) # ((c \<leftrightarrow> x) \<bullet> \<Gamma>2) \<turnstile> t : T2)" by (rule permute_boolI)
       
   857     then have "(c, T1) # \<Gamma>2 \<turnstile> ((c \<leftrightarrow> x) \<bullet> t) : T2" using fc1
       
   858       by (perm_simp) (simp add: flip_fresh_fresh ty_fresh)
       
   859     then show "\<Gamma>2 \<turnstile> Lam [c].((c \<leftrightarrow> x) \<bullet> t) : T1 \<rightarrow> T2" using fc1 by auto
       
   860   qed
       
   861   ultimately show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" by simp
       
   862 qed (auto) -- {* var and app cases, luckily, are automatic *}
       
   863 
       
   864 
       
   865 text {* 
       
   866   The remedy is to use a stronger induction principle that
       
   867   has the usual "variable convention" already build in. The
       
   868   following command derives this induction principle for us.
       
   869   (We shall explain what happens here later.)
       
   870 *}
       
   871 
       
   872 nominal_inductive typing
       
   873   avoids t_Lam: "x"
       
   874   unfolding fresh_star_def
       
   875   by (simp_all add: fresh_Pair lam.fresh ty_fresh)
       
   876 
       
   877 text {* Compare the two induction principles *}
       
   878 
       
   879 thm typing.induct
       
   880 thm typing.strong_induct -- {* has the additional assumption {atom x} \<sharp> c *}
       
   881 
       
   882 text {* 
       
   883   We can use the stronger induction principle by replacing
       
   884   the line
       
   885 
       
   886       proof (induct arbitrary: \<Gamma>2)
       
   887 
       
   888   with 
       
   889   
       
   890       proof (nominal_induct avoiding: \<Gamma>2 rule: typing.strong_induct)
       
   891 
       
   892   Try now the proof.
       
   893 *}
       
   894   
       
   895 
       
   896 lemma weakening: 
       
   897   assumes a: "\<Gamma>1 \<turnstile> t : T"
       
   898   and     b: "valid \<Gamma>2" 
       
   899   and     c: "\<Gamma>1 \<sqsubseteq> \<Gamma>2"
       
   900   shows "\<Gamma>2 \<turnstile> t : T"
       
   901 using a b c
       
   902 proof (nominal_induct avoiding: \<Gamma>2 rule: typing.strong_induct)
       
   903   case (t_Var \<Gamma>1 x T)  -- {* variable case is as before *}
       
   904   have "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact 
       
   905   moreover  
       
   906   have "valid \<Gamma>2" by fact 
       
   907   moreover 
       
   908   have "(x, T)\<in> set \<Gamma>1" by fact
       
   909   ultimately show "\<Gamma>2 \<turnstile> Var x : T" by auto
       
   910 next
       
   911   case (t_Lam x \<Gamma>1 T1 t T2) 
       
   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
       
   914   have a0: "atom x \<sharp> \<Gamma>1" by fact
       
   915   have a1: "valid \<Gamma>2" by fact
       
   916   have a2: "\<Gamma>1 \<sqsubseteq> \<Gamma>2" by fact
       
   917   have "valid ((x, T1) # \<Gamma>2)" using a1 vc by auto
       
   918   moreover
       
   919   have "(x, T1) # \<Gamma>1 \<sqsubseteq> (x, T1) # \<Gamma>2" using a2 by auto
       
   920   ultimately 
       
   921   have "(x, T1) # \<Gamma>2 \<turnstile> t : T2" using ih by simp 
       
   922   then show "\<Gamma>2 \<turnstile> Lam [x].t : T1 \<rightarrow> T2" using vc by auto
       
   923 qed (auto) -- {* app case *}
       
   924 
   701 
   925 
   702 
   926 section {* Function Definitions: Filling a Lambda-Term into a Context *}
   703 section {* Function Definitions: Filling a Lambda-Term into a Context *}
   927  
   704  
   928 text {*
   705 text {*
  1001 
   778 
  1002 lemma neut_hole:
   779 lemma neut_hole:
  1003   shows "E \<odot> \<box> = E"
   780   shows "E \<odot> \<box> = E"
  1004 by (induct E) (simp_all)
   781 by (induct E) (simp_all)
  1005 
   782 
  1006 lemma odot_assoc:
   783 lemma odot_assoc: (* fixme call compose *)
  1007   fixes E1 E2 E3::"ctx"
       
  1008   shows "(E1 \<odot> E2) \<odot> E3 = E1 \<odot> (E2 \<odot> E3)"
   784   shows "(E1 \<odot> E2) \<odot> E3 = E1 \<odot> (E2 \<odot> E3)"
  1009 by (induct E1) (simp_all)
   785 by (induct E1) (simp_all)
  1010 
   786 
  1011 lemma
   787 lemma
  1012   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<odot> (Es1\<down>)"
   788   shows "(Es1 @ Es2)\<down> = (Es2\<down>) \<odot> (Es1\<down>)"
  1112   shows "atom x \<sharp> t \<Longrightarrow> t[x ::= s] = t"
   888   shows "atom x \<sharp> t \<Longrightarrow> t[x ::= s] = t"
  1113 by (nominal_induct t avoiding: x s rule: lam.strong_induct)
   889 by (nominal_induct t avoiding: x s rule: lam.strong_induct)
  1114    (auto simp add: lam.fresh fresh_at_base)
   890    (auto simp add: lam.fresh fresh_at_base)
  1115 
   891 
  1116 lemma fresh_fact:
   892 lemma fresh_fact:
  1117   fixes z::"name"
       
  1118   assumes a: "atom z \<sharp> s"
   893   assumes a: "atom z \<sharp> s"
  1119   and b: "z = y \<or> atom z \<sharp> t"
   894   and b: "z = y \<or> atom z \<sharp> t"
  1120   shows "atom z \<sharp> t[y ::= s]"
   895   shows "atom z \<sharp> t[y ::= s]"
  1121 using a b
   896 using a b
  1122 by (nominal_induct t avoiding: z y s rule: lam.strong_induct)
   897 by (nominal_induct t avoiding: z y s rule: lam.strong_induct)