Nominal/Ex/Weakening.thy
changeset 2643 0579d3a48304
parent 2639 a8fc346deda3
child 2645 09cf78bb53d4
equal deleted inserted replaced
2642:f338b455314c 2643:0579d3a48304
       
     1 theory Lambda
       
     2 imports "../Nominal2" 
       
     3 begin
       
     4 
       
     5 section {* The Weakening property in the simply-typed lambda-calculus *}
       
     6 
       
     7 atom_decl name
       
     8 
       
     9 nominal_datatype lam =
       
    10   Var "name"
       
    11 | App "lam" "lam"
       
    12 | Lam x::"name" l::"lam" bind x in l ("Lam [_]. _" [100,100] 100)
       
    13 
       
    14 text {* Typing *}
       
    15 
       
    16 nominal_datatype ty =
       
    17   TVar string
       
    18 | TFun ty ty ("_ \<rightarrow> _" [100,100] 100) 
       
    19 
       
    20 lemma fresh_ty:
       
    21   fixes x::"name"
       
    22   and   T::"ty"
       
    23   shows "atom x \<sharp> T"
       
    24   by (nominal_induct T rule: ty.strong_induct)
       
    25      (simp_all add: ty.fresh pure_fresh)
       
    26 
       
    27 text {* Valid typing contexts *}
       
    28 
       
    29 inductive
       
    30   valid :: "(name \<times> ty) list \<Rightarrow> bool"
       
    31 where
       
    32   v_Nil[intro]: "valid []"
       
    33 | v_Cons[intro]: "\<lbrakk>atom x \<sharp> Gamma; valid Gamma\<rbrakk> \<Longrightarrow> valid ((x, T) # Gamma)"
       
    34 
       
    35 equivariance valid
       
    36 
       
    37 text {* Typing judgements *}
       
    38 
       
    39 inductive
       
    40   typing :: "(name \<times> ty) list \<Rightarrow> lam \<Rightarrow> ty \<Rightarrow> bool" ("_ \<turnstile> _ : _" [60,60,60] 60) 
       
    41 where
       
    42     t_Var[intro]: "\<lbrakk>valid \<Gamma>; (x, T) \<in> set \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Var x : T"
       
    43   | t_App[intro]: "\<lbrakk>\<Gamma> \<turnstile> t1 : T1 \<rightarrow> T2; \<Gamma> \<turnstile> t2 : T1\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> App t1 t2 : T2"
       
    44   | t_Lam[intro]: "\<lbrakk>atom x \<sharp> \<Gamma>; (x, T1) # \<Gamma> \<turnstile> t : T2\<rbrakk> \<Longrightarrow> \<Gamma> \<turnstile> Lam [x]. t : T1 \<rightarrow> T2"
       
    45 
       
    46 equivariance typing
       
    47 
       
    48 text {* Strong induction principle for typing judgements *}
       
    49 
       
    50 nominal_inductive typing
       
    51   avoids t_Lam: "x"
       
    52   by (simp_all add: fresh_star_def fresh_ty lam.fresh)
       
    53 
       
    54 
       
    55 abbreviation
       
    56   "sub_context" :: "(name \<times> ty) list \<Rightarrow> (name \<times> ty) list \<Rightarrow> bool" (infixr "\<subseteq>" 60) 
       
    57 where
       
    58   "\<Gamma>1 \<subseteq> \<Gamma>2 \<equiv> \<forall>x T. (x, T) \<in> set \<Gamma>1 \<longrightarrow> (x, T) \<in> set \<Gamma>2"
       
    59 
       
    60 
       
    61 text {* The proof *}
       
    62 
       
    63 lemma weakening_version1: 
       
    64   fixes \<Gamma>1 \<Gamma>2::"(name \<times> ty) list"
       
    65   and   t ::"lam"
       
    66   and   \<tau> ::"ty"
       
    67   assumes a: "\<Gamma>1 \<turnstile> t : T"
       
    68   and     b: "valid \<Gamma>2" 
       
    69   and     c: "\<Gamma>1 \<subseteq> \<Gamma>2"
       
    70   shows "\<Gamma>2 \<turnstile> t : T"
       
    71 using a b c
       
    72 proof (nominal_induct \<Gamma>1 t T avoiding: \<Gamma>2 rule: typing.strong_induct)
       
    73   case (t_Var \<Gamma>1 x T)  (* variable case *)
       
    74   have "\<Gamma>1 \<subseteq> \<Gamma>2" by fact 
       
    75   moreover  
       
    76   have "valid \<Gamma>2" by fact 
       
    77   moreover 
       
    78   have "(x, T) \<in> set \<Gamma>1" by fact
       
    79   ultimately show "\<Gamma>2 \<turnstile> Var x : T" by auto
       
    80 next
       
    81   case (t_Lam x \<Gamma>1 T1 t T2) (* lambda case *)
       
    82   have vc: "atom x \<sharp> \<Gamma>2" by fact   (* variable convention *)
       
    83   have ih: "\<lbrakk>valid ((x, T1) # \<Gamma>2); (x, T1) # \<Gamma>1 \<subseteq> (x, T1) # \<Gamma>2\<rbrakk> \<Longrightarrow> (x, T1) # \<Gamma>2 \<turnstile> t : T2" by fact
       
    84   have "\<Gamma>1 \<subseteq> \<Gamma>2" by fact
       
    85   then have "(x, T1) # \<Gamma>1 \<subseteq> (x, T1) # \<Gamma>2" by simp
       
    86   moreover
       
    87   have "valid \<Gamma>2" by fact
       
    88   then have "valid ((x, T1) # \<Gamma>2)" using vc by auto
       
    89   ultimately have "(x, T1) # \<Gamma>2 \<turnstile> t : T2" using ih by simp
       
    90   with vc show "\<Gamma>2 \<turnstile> Lam [x]. t : T1 \<rightarrow> T2" by auto
       
    91 qed (auto) (* app case *)
       
    92 
       
    93 lemma weakening_version2: 
       
    94   fixes \<Gamma>1 \<Gamma>2::"(name \<times> ty) list"
       
    95   assumes a: "\<Gamma>1 \<turnstile> t : T" 
       
    96   and     b: "valid \<Gamma>2" 
       
    97   and     c: "\<Gamma>1 \<subseteq> \<Gamma>2"
       
    98   shows "\<Gamma>2 \<turnstile> t : T"
       
    99 using a b c
       
   100 by (nominal_induct \<Gamma>1 t T avoiding: \<Gamma>2 rule: typing.strong_induct)
       
   101    (auto | atomize)+
       
   102 
       
   103 
       
   104 text {* A version with finite sets as typing contexts *}
       
   105 
       
   106 inductive
       
   107   valid2 :: "(name \<times> ty) fset \<Rightarrow> bool"
       
   108 where
       
   109   v2_Empty[intro]: "valid2 {||}"
       
   110 | v2_Insert[intro]: "\<lbrakk>(x, T) |\<notin>| Gamma; valid2 Gamma\<rbrakk> \<Longrightarrow> valid2 (insert_fset (x, T) Gamma)"
       
   111 
       
   112 equivariance valid2
       
   113 
       
   114 inductive
       
   115   typing2 :: "(name \<times> ty) fset \<Rightarrow> lam \<Rightarrow> ty \<Rightarrow> bool" ("_ 2\<turnstile> _ : _" [60,60,60] 60) 
       
   116 where
       
   117     t2_Var[intro]: "\<lbrakk>valid2 \<Gamma>; (x, T) |\<in>| \<Gamma>\<rbrakk> \<Longrightarrow> \<Gamma> 2\<turnstile> Var x : T"
       
   118   | t2_App[intro]: "\<lbrakk>\<Gamma> 2\<turnstile> t1 : T1 \<rightarrow> T2; \<Gamma> 2\<turnstile> t2 : T1\<rbrakk> \<Longrightarrow> \<Gamma> 2\<turnstile> App t1 t2 : T2"
       
   119   | t2_Lam[intro]: "\<lbrakk>atom x \<sharp> \<Gamma>; insert_fset (x, T1) \<Gamma> 2\<turnstile> t : T2\<rbrakk> \<Longrightarrow> \<Gamma> 2\<turnstile> Lam [x]. t : T1 \<rightarrow> T2"
       
   120 
       
   121 equivariance typing2
       
   122 
       
   123 nominal_inductive typing2
       
   124   avoids t2_Lam: "x"
       
   125   by (simp_all add: fresh_star_def fresh_ty lam.fresh)
       
   126 
       
   127 lemma weakening_version3: 
       
   128   fixes \<Gamma>::"(name \<times> ty) fset"
       
   129   assumes a: "\<Gamma> 2\<turnstile> t : T" 
       
   130   and     b: "(x, T') |\<notin>| \<Gamma>"
       
   131   shows "{|(x, T')|} |\<union>| \<Gamma> 2\<turnstile> t : T"
       
   132 using a b
       
   133 apply(nominal_induct \<Gamma> t T avoiding: x rule: typing2.strong_induct)
       
   134 apply(auto)[2]
       
   135 apply(rule t2_Lam)
       
   136 apply(simp add: fresh_insert_fset fresh_Pair fresh_ty)
       
   137 apply(simp)
       
   138 apply(drule_tac x="xa" in meta_spec)
       
   139 apply(drule meta_mp)
       
   140 apply(simp add: fresh_at_base)
       
   141 apply(simp add: insert_fset_left_comm)
       
   142 done
       
   143 
       
   144 lemma weakening_version4: 
       
   145   fixes \<Gamma>::"(name \<times> ty) fset"
       
   146   assumes a: "\<Gamma> 2\<turnstile> t : T" 
       
   147   and     b: "(x, T') |\<notin>| \<Gamma>"
       
   148   shows "{|(x, T')|} |\<union>| \<Gamma> 2\<turnstile> t : T"
       
   149 using a b
       
   150 apply(induct \<Gamma> t T arbitrary: x)
       
   151 apply(auto)[2]
       
   152 apply(rule t2_Lam)
       
   153 oops
       
   154 
       
   155 end
       
   156 
       
   157 
       
   158