Nominal/Ex/Lambda.thy
changeset 2683 42c0d011a177
parent 2678 494b859bfc16
child 2685 1df873b63cb2
equal deleted inserted replaced
2682:2873b3230c44 2683:42c0d011a177
     5 atom_decl name
     5 atom_decl name
     6 
     6 
     7 nominal_datatype lam =
     7 nominal_datatype lam =
     8   Var "name"
     8   Var "name"
     9 | App "lam" "lam"
     9 | App "lam" "lam"
    10 | Lam x::"name" l::"lam"  bind x in l
    10 | Lam x::"name" l::"lam"  bind x in l ("Lam [_]. _" [100, 100] 100)
    11 
    11 
    12 thm lam.distinct
    12 text {* height function *}
    13 thm lam.induct
       
    14 thm lam.exhaust lam.strong_exhaust
       
    15 thm lam.fv_defs
       
    16 thm lam.bn_defs
       
    17 thm lam.perm_simps
       
    18 thm lam.eq_iff
       
    19 thm lam.fv_bn_eqvt
       
    20 thm lam.size_eqvt
       
    21 
    13 
    22 nominal_primrec
    14 nominal_primrec
    23   height :: "lam \<Rightarrow> int"
    15   height :: "lam \<Rightarrow> int"
    24 where
    16 where
    25   "height (Var x) = 1"
    17   "height (Var x) = 1"
    26 | "height (App t1 t2) = (max (height t1) (height t2)) + 1"
    18 | "height (App t1 t2) = max (height t1) (height t2) + 1"
    27 | "height (Lam x t) = (height t) + 1"
    19 | "height (Lam [x].t) = height t + 1"
       
    20 apply(rule_tac y="x" in lam.exhaust)
       
    21 apply(auto simp add: lam.distinct lam.eq_iff)
       
    22 apply(simp add: Abs_eq_iff alphas)
       
    23 apply(clarify)
       
    24 apply(subst (4) supp_perm_eq[where p="p", symmetric])
       
    25 apply(simp add: pure_supp fresh_star_def)
       
    26 apply(simp add: eqvt_at_def)
       
    27 done
       
    28 
       
    29 termination
       
    30   by (relation "measure size") (simp_all add: lam.size)
       
    31   
       
    32   
       
    33 text {* free name function - returns atom lists *}
       
    34 
       
    35 nominal_primrec 
       
    36   frees_lst :: "lam \<Rightarrow> atom list"
       
    37 where
       
    38   "frees_lst (Var x) = [atom x]"
       
    39 | "frees_lst (App t1 t2) = frees_lst t1 @ frees_lst t2"
       
    40 | "frees_lst (Lam [x]. t) = removeAll (atom x) (frees_lst t)"
    28 apply(rule_tac y="x" in lam.exhaust)
    41 apply(rule_tac y="x" in lam.exhaust)
    29 apply(simp_all)[3]
    42 apply(simp_all)[3]
    30 apply(simp_all only: lam.distinct)
    43 apply(simp_all only: lam.distinct)
    31 apply(simp add: lam.eq_iff)
    44 apply(simp add: lam.eq_iff)
    32 apply(simp add: lam.eq_iff)
    45 apply(simp add: lam.eq_iff)
    33 apply(subst (asm) Abs_eq_iff)
    46 apply(simp add: lam.eq_iff)
       
    47 apply(simp add: Abs_eq_iff)
    34 apply(erule exE)
    48 apply(erule exE)
    35 apply(simp add: alphas)
    49 apply(simp add: alphas)
       
    50 apply(simp add: atom_eqvt)
    36 apply(clarify)
    51 apply(clarify)
    37 apply(rule trans)
    52 apply(rule trans)
    38 apply(rule_tac p="p" in supp_perm_eq[symmetric])
    53 apply(rule_tac p="p" in supp_perm_eq[symmetric])
    39 apply(simp add: pure_supp)
    54 apply(simp (no_asm) add: supp_removeAll)
    40 apply(simp add: fresh_star_def)
    55 apply(drule supp_eqvt_at)
    41 apply(simp add: eqvt_at_def)
    56 apply(simp add: finite_supp)
       
    57 apply(auto simp add: fresh_star_def)[1]
       
    58 unfolding eqvt_at_def
       
    59 apply(simp only: removeAll_eqvt atom_eqvt)
    42 done
    60 done
    43 
    61 
    44 termination
    62 termination
    45   apply(relation "measure size")
    63   apply(relation "measure size")
    46   apply(simp_all add: lam.size)
    64   apply(simp_all add: lam.size)
    47   done
    65   done
    48   
    66 
    49 lemma removeAll_eqvt[eqvt]:
    67 text {* a small test lemma *}
    50   shows "p \<bullet> (removeAll x xs) = removeAll (p \<bullet> x) (p \<bullet> xs)"
       
    51 by (induct xs) (auto)
       
    52 
       
    53 lemma supp_removeAll:
       
    54   fixes x::"atom"
       
    55   shows "supp (removeAll x xs) = (supp xs - {x})"
       
    56 apply(induct xs)
       
    57 apply(simp_all add: supp_Nil supp_Cons)
       
    58 apply(rule conjI)
       
    59 apply(rule impI)
       
    60 apply(simp add: supp_atom)
       
    61 apply(rule impI)
       
    62 apply(simp add: supp_atom)
       
    63 apply(blast)
       
    64 done
       
    65 
       
    66 nominal_primrec 
       
    67   frees_lst :: "lam \<Rightarrow> atom list"
       
    68 where
       
    69   "frees_lst (Var x) = [atom x]"
       
    70 | "frees_lst (App t1 t2) = (frees_lst t1) @ (frees_lst t2)"
       
    71 | "frees_lst (Lam x t) = removeAll (atom x) (frees_lst t)"
       
    72 apply(rule_tac y="x" in lam.exhaust)
       
    73 apply(simp_all)[3]
       
    74 apply(simp_all only: lam.distinct)
       
    75 apply(simp add: lam.eq_iff)
       
    76 apply(simp add: lam.eq_iff)
       
    77 apply(simp add: lam.eq_iff)
       
    78 apply(simp add: Abs_eq_iff)
       
    79 apply(erule exE)
       
    80 apply(simp add: alphas)
       
    81 apply(simp add: atom_eqvt)
       
    82 apply(clarify)
       
    83 apply(rule trans)
       
    84 apply(rule_tac p="p" in supp_perm_eq[symmetric])
       
    85 apply(simp (no_asm) add: supp_removeAll)
       
    86 apply(drule supp_eqvt_at)
       
    87 apply(simp add: finite_supp)
       
    88 apply(auto simp add: fresh_star_def)[1]
       
    89 unfolding eqvt_at_def
       
    90 apply(simp only: removeAll_eqvt atom_eqvt)
       
    91 done
       
    92 
       
    93 termination
       
    94   apply(relation "measure size")
       
    95   apply(simp_all add: lam.size)
       
    96   done
       
    97 
       
    98 text {* a small lemma *}
       
    99 lemma
    68 lemma
   100   "supp t = set (frees_lst t)"
    69   shows "supp t = set (frees_lst t)"
   101 apply(induct t rule: lam.induct)
    70 apply(induct t rule: frees_lst.induct)
   102 apply(simp_all add: lam.supp supp_at_base)
    71 apply(simp_all add: lam.supp supp_at_base)
   103 done
    72 done
   104 
    73 
       
    74 text {* capture - avoiding substitution *}
       
    75 
   105 nominal_primrec
    76 nominal_primrec
   106   subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_ [_ ::= _]" [100,100,100] 100)
    77   subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_ [_ ::= _]" [90, 90, 90] 90)
   107 where
    78 where
   108   "(Var x)[y ::= s] = (if x=y then s else (Var x))"
    79   "(Var x)[y ::= s] = (if x = y then s else (Var x))"
   109 | "(App t\<^isub>1 t\<^isub>2)[y ::= s] = App (t\<^isub>1[y ::= s]) (t\<^isub>2[y ::= s])"
    80 | "(App t1 t2)[y ::= s] = App (t1[y ::= s]) (t2[y ::= s])"
   110 | "atom x \<sharp> (y, s) \<Longrightarrow> (Lam x t)[y ::= s] = Lam x (t[y ::= s])"
    81 | "atom x \<sharp> (y, s) \<Longrightarrow> (Lam [x]. t)[y ::= s] = Lam [x].(t[y ::= s])"
   111 apply(case_tac x)
    82 apply(auto simp add: lam.distinct lam.eq_iff)
   112 apply(simp)
    83 apply(rule_tac y="a" and c="(aa, b)" in lam.strong_exhaust)
   113 apply(rule_tac y="a" and c="(b, c)" in lam.strong_exhaust)
    84 apply(blast)+
   114 apply(simp add: lam.eq_iff lam.distinct)
    85 apply(simp add: fresh_star_def)
   115 apply(auto)[1]
       
   116 apply(simp add: lam.eq_iff lam.distinct)
       
   117 apply(auto)[1]
       
   118 apply(simp add: fresh_star_def lam.eq_iff lam.distinct)
       
   119 apply(simp_all add: lam.distinct)[5]
       
   120 apply(simp add: lam.eq_iff)
       
   121 apply(simp add: lam.eq_iff)
       
   122 apply(simp add: lam.eq_iff)
       
   123 apply(erule conjE)+
       
   124 apply(subgoal_tac "atom xa \<sharp> [[atom x]]lst. t \<and> atom x \<sharp> [[atom xa]]lst. ta")
    86 apply(subgoal_tac "atom xa \<sharp> [[atom x]]lst. t \<and> atom x \<sharp> [[atom xa]]lst. ta")
   125 prefer 2
       
   126 apply(rule conjI)
       
   127 apply(simp add: Abs_fresh_iff)
       
   128 apply(drule sym)
       
   129 apply(simp add: Abs_fresh_iff)
       
   130 apply(subst (asm) Abs_eq_iff2)
    87 apply(subst (asm) Abs_eq_iff2)
   131 apply(auto)
    88 apply(simp add: alphas atom_eqvt)
   132 apply(simp add: alphas)
       
   133 apply(simp add: atom_eqvt)
       
   134 apply(clarify)
    89 apply(clarify)
   135 apply(rule trans)
    90 apply(rule trans)
   136 apply(rule_tac p="p" in supp_perm_eq[symmetric])
    91 apply(rule_tac p="p" in supp_perm_eq[symmetric])
   137 apply(rule fresh_star_supp_conv)
    92 apply(rule fresh_star_supp_conv)
   138 apply(drule fresh_star_perm_set_conv)
    93 apply(drule fresh_star_perm_set_conv)
   149 apply(simp add: Abs_fresh_iff)
   104 apply(simp add: Abs_fresh_iff)
   150 apply(simp)
   105 apply(simp)
   151 apply(simp add: Abs_fresh_iff)
   106 apply(simp add: Abs_fresh_iff)
   152 apply(subgoal_tac "p \<bullet> ya = ya")
   107 apply(subgoal_tac "p \<bullet> ya = ya")
   153 apply(subgoal_tac "p \<bullet> sa = sa")
   108 apply(subgoal_tac "p \<bullet> sa = sa")
   154 unfolding eqvt_at_def
   109 apply(simp add: atom_eqvt eqvt_at_def)
   155 apply(simp add: atom_eqvt fresh_Pair)
       
   156 apply(rule perm_supp_eq)
   110 apply(rule perm_supp_eq)
   157 apply(auto simp add: fresh_star_def fresh_Pair)[1]
   111 apply(auto simp add: fresh_star_def fresh_Pair)[1]
   158 apply(rule perm_supp_eq)
   112 apply(rule perm_supp_eq)
   159 apply(auto simp add: fresh_star_def fresh_Pair)[1]
   113 apply(auto simp add: fresh_star_def fresh_Pair)[1]
       
   114 apply(rule conjI)
       
   115 apply(simp add: Abs_fresh_iff)
       
   116 apply(drule sym)
       
   117 apply(simp add: Abs_fresh_iff)
   160 done
   118 done
   161 
   119 
   162 termination
   120 termination
   163   apply(relation "measure (\<lambda>(t,_,_). size t)")
   121   by (relation "measure (\<lambda>(t,_,_). size t)")
   164   apply(simp_all add: lam.size)
   122      (simp_all add: lam.size)
   165   done
   123 
       
   124 lemma subst_eqvt[eqvt]:
       
   125   shows "(p \<bullet> t[x ::= s]) = (p \<bullet> t)[(p \<bullet> x) ::= (p \<bullet> s)]"
       
   126 by (induct t x s rule: subst.induct) (simp_all)
       
   127 
       
   128 lemma forget:
       
   129   shows "atom x \<sharp> t \<Longrightarrow> t[x ::= s] = t"
       
   130 apply(nominal_induct t avoiding: x s rule: lam.strong_induct)
       
   131 apply(auto simp add: lam.fresh fresh_at_base)
       
   132 done
       
   133 
       
   134 text {* same lemma but with subst.induction *}
       
   135 lemma forget2:
       
   136   shows "atom x \<sharp> t \<Longrightarrow> t[x ::= s] = t"
       
   137 apply(induct t x s rule: subst.induct)
       
   138 apply(auto simp add: lam.fresh fresh_at_base fresh_Pair)
       
   139 done
       
   140 
       
   141 lemma fresh_fact:
       
   142   fixes z::"name"
       
   143   assumes a: "atom z \<sharp> s"
       
   144   and b: "z = y \<or> atom z \<sharp> t"
       
   145   shows "atom z \<sharp> t[y ::= s]"
       
   146 using a b
       
   147 apply (nominal_induct t avoiding: z y s rule: lam.strong_induct)
       
   148 apply (auto simp add: lam.fresh fresh_at_base)
       
   149 done
       
   150 
       
   151 lemma substitution_lemma:  
       
   152   assumes a: "x \<noteq> y" "atom x \<sharp> u"
       
   153   shows "t[x ::= s][y ::= u] = t[y ::= u][x ::= s[y ::= u]]"
       
   154 using a 
       
   155 by (nominal_induct t avoiding: x y s u rule: lam.strong_induct)
       
   156    (auto simp add: fresh_fact forget)
       
   157 
       
   158 lemma subst_rename: 
       
   159   assumes a: "atom y \<sharp> t"
       
   160   shows "t[x ::= s] = ((y \<leftrightarrow> x) \<bullet>t)[y ::= s]"
       
   161 using a 
       
   162 apply (nominal_induct t avoiding: x y s rule: lam.strong_induct)
       
   163 apply (auto simp add: lam.fresh fresh_at_base)
       
   164 done
       
   165 
       
   166 
       
   167 subsection {* single-step beta-reduction *}
       
   168 
       
   169 inductive 
       
   170   beta :: "lam \<Rightarrow> lam \<Rightarrow> bool" (" _ \<longrightarrow>b _" [80,80] 80)
       
   171 where
       
   172   b1[intro]: "t1 \<longrightarrow>b t2 \<Longrightarrow> App t1 s \<longrightarrow>b App t2 s"
       
   173 | b2[intro]: "s1 \<longrightarrow>b s2 \<Longrightarrow> App t s1 \<longrightarrow>b App t s2"
       
   174 | b3[intro]: "t1 \<longrightarrow>b t2 \<Longrightarrow> Lam [x]. t1 \<longrightarrow>b Lam [x]. t2"
       
   175 | b4[intro]: "atom x \<sharp> s \<Longrightarrow> App (Lam [x]. t) s \<longrightarrow>b t[x ::= s]"
       
   176 
       
   177 equivariance beta
       
   178 
       
   179 nominal_inductive beta
       
   180   avoids b4: "x"
       
   181   by (simp_all add: fresh_star_def fresh_Pair lam.fresh fresh_fact)
       
   182 
       
   183 text {* One-Reduction *}
       
   184 
       
   185 inductive 
       
   186   One :: "lam \<Rightarrow> lam \<Rightarrow> bool" (" _ \<longrightarrow>1 _" [80,80] 80)
       
   187 where
       
   188   o1[intro]: "Var x \<longrightarrow>1 Var x"
       
   189 | o2[intro]: "\<lbrakk>t1 \<longrightarrow>1 t2; s1 \<longrightarrow>1 s2\<rbrakk> \<Longrightarrow> App t1 s1 \<longrightarrow>1 App t2 s2"
       
   190 | o3[intro]: "t1 \<longrightarrow>1 t2 \<Longrightarrow> Lam [x].t1 \<longrightarrow>1 Lam [x].t2"
       
   191 | o4[intro]: "\<lbrakk>atom x \<sharp> (s1, s2); t1 \<longrightarrow>1 t2; s1 \<longrightarrow>1 s2\<rbrakk> \<Longrightarrow> App (Lam [x].t1) s1 \<longrightarrow>1 t2[x ::= s2]"
       
   192 
       
   193 equivariance One
       
   194 
       
   195 nominal_inductive One 
       
   196   avoids o3: "x"
       
   197       |  o4: "x"
       
   198   by (simp_all add: fresh_star_def fresh_Pair lam.fresh fresh_fact)
       
   199 
       
   200 lemma One_refl:
       
   201   shows "t \<longrightarrow>1 t"
       
   202 by (nominal_induct t rule: lam.strong_induct) (auto)
       
   203 
       
   204 lemma One_subst: 
       
   205   assumes a: "t1 \<longrightarrow>1 t2" "s1 \<longrightarrow>1 s2"
       
   206   shows "t1[x ::= s1] \<longrightarrow>1 t2[x ::= s2]" 
       
   207 using a 
       
   208 apply(nominal_induct t1 t2 avoiding: s1 s2 x rule: One.strong_induct)
       
   209 apply(auto simp add: substitution_lemma fresh_at_base fresh_fact fresh_Pair)
       
   210 done
       
   211 
       
   212 lemma better_o4_intro:
       
   213   assumes a: "t1 \<longrightarrow>1 t2" "s1 \<longrightarrow>1 s2"
       
   214   shows "App (Lam [x]. t1) s1 \<longrightarrow>1 t2[ x ::= s2]"
       
   215 proof -
       
   216   obtain y::"name" where fs: "atom y \<sharp> (x, t1, s1, t2, s2)" sorry
       
   217   have "App (Lam [x]. t1) s1 = App (Lam [y]. ((y \<leftrightarrow> x) \<bullet> t1)) s1" using fs
       
   218     by (auto simp add: lam.eq_iff Abs1_eq_iff' flip_def fresh_Pair fresh_at_base)
       
   219   also have "\<dots> \<longrightarrow>1 ((y \<leftrightarrow> x) \<bullet> t2)[y ::= s2]" using fs a by (auto simp add: One.eqvt)
       
   220   also have "\<dots> = t2[x ::= s2]" using fs by (simp add: subst_rename[symmetric])
       
   221   finally show "App (Lam [x].t1) s1 \<longrightarrow>1 t2[x ::= s2]" by simp
       
   222 qed
       
   223 
       
   224 
       
   225 
       
   226 
       
   227 
       
   228 section {* Locally Nameless Terms *}
   166 
   229 
   167 nominal_datatype ln = 
   230 nominal_datatype ln = 
   168   LNBnd nat
   231   LNBnd nat
   169 | LNVar name
   232 | LNVar name
   170 | LNApp ln ln
   233 | LNApp ln ln