Nominal/Ex/BetaCR.thy
changeset 3078 abf147627b4b
child 3079 a303ef51cd97
equal deleted inserted replaced
3077:df1055004f52 3078:abf147627b4b
       
     1 theory BetaCR
       
     2 imports 
       
     3   "../Nominal2"
       
     4 begin
       
     5 
       
     6 atom_decl name
       
     7 
       
     8 nominal_datatype lam =
       
     9   Var "name"
       
    10 | App "lam" "lam"
       
    11 | Lam x::"name" l::"lam"  binds x in l ("Lam [_]. _" [100, 100] 100)
       
    12 
       
    13 nominal_primrec
       
    14   subst :: "lam \<Rightarrow> name \<Rightarrow> lam \<Rightarrow> lam"  ("_ [_ ::= _]" [90, 90, 90] 90)
       
    15 where
       
    16   "(Var x)[y ::= s] = (if x = y then s else (Var x))"
       
    17 | "(App t1 t2)[y ::= s] = App (t1[y ::= s]) (t2[y ::= s])"
       
    18 | "atom x \<sharp> (y, s) \<Longrightarrow> (Lam [x]. t)[y ::= s] = Lam [x].(t[y ::= s])"
       
    19   unfolding eqvt_def subst_graph_def
       
    20   apply (rule, perm_simp, rule)
       
    21   apply(rule TrueI)
       
    22   apply(auto simp add: lam.distinct lam.eq_iff)
       
    23   apply(rule_tac y="a" and c="(aa, b)" in lam.strong_exhaust)
       
    24   apply(blast)+
       
    25   apply(simp_all add: fresh_star_def fresh_Pair_elim)
       
    26   apply (erule_tac c="(ya,sa)" in Abs_lst1_fcb2)
       
    27   apply(simp_all add: Abs_fresh_iff)
       
    28   apply(simp add: fresh_star_def fresh_Pair)
       
    29   apply(simp add: eqvt_at_def atom_eqvt fresh_star_Pair perm_supp_eq)
       
    30   apply(simp add: eqvt_at_def atom_eqvt fresh_star_Pair perm_supp_eq)
       
    31 done
       
    32 
       
    33 termination (eqvt)
       
    34   by lexicographic_order
       
    35 
       
    36 lemma fresh_fact:
       
    37   fixes z::"name"
       
    38   assumes a: "atom z \<sharp> s"
       
    39       and b: "z = y \<or> atom z \<sharp> t"
       
    40   shows "atom z \<sharp> t[y ::= s]"
       
    41   using a b
       
    42   by (nominal_induct t avoiding: z y s rule: lam.strong_induct)
       
    43       (auto simp add: lam.fresh fresh_at_base)
       
    44 
       
    45 inductive 
       
    46   beta :: "lam \<Rightarrow> lam \<Rightarrow> bool" (" _ \<longrightarrow>b _" [80,80] 80)
       
    47 where
       
    48   b1[intro]: "t1 \<longrightarrow>b t2 \<Longrightarrow> App t1 s \<longrightarrow>b App t2 s"
       
    49 | b2[intro]: "s1 \<longrightarrow>b s2 \<Longrightarrow> App t s1 \<longrightarrow>b App t s2"
       
    50 | b3[intro]: "t1 \<longrightarrow>b t2 \<Longrightarrow> Lam [x]. t1 \<longrightarrow>b Lam [x]. t2"
       
    51 | b4[intro]: "atom x \<sharp> s \<Longrightarrow> App (Lam [x]. t) s \<longrightarrow>b t[x ::= s]"
       
    52 
       
    53 equivariance beta
       
    54 
       
    55 (* HERE 1 *)
       
    56 nominal_inductive beta
       
    57   avoids b3: x
       
    58   by (simp_all add: fresh_star_def fresh_Pair lam.fresh fresh_fact)
       
    59 
       
    60 (* This also works, but we cannot have them together: *)
       
    61 (*nominal_inductive beta
       
    62   avoids b4: x
       
    63   by (simp_all add: fresh_star_def fresh_Pair lam.fresh fresh_fact)*)
       
    64 
       
    65 (* But I need a combination, possibly with an 'and' syntax:
       
    66 nominal_inductive beta
       
    67   avoids b3: x and b4: x
       
    68   by (simp_all add: fresh_star_def fresh_Pair lam.fresh fresh_fact)
       
    69 *)
       
    70 
       
    71 (* The combination should look like this: *)
       
    72 lemma beta_strong_induct:
       
    73   assumes "x1 \<longrightarrow>b x2"
       
    74   and "\<And>t1 t2 s c. \<lbrakk> t1 \<longrightarrow>b t2; \<And>c. P c t1 t2\<rbrakk> \<Longrightarrow> P c (App t1 s) (App t2 s)"
       
    75   and "\<And>s1 s2 t c. \<lbrakk> s1 \<longrightarrow>b s2; \<And>c. P c s1 s2\<rbrakk> \<Longrightarrow> P c (App t s1) (App t s2)"
       
    76   and "\<And>t1 t2 x c. \<lbrakk>{atom x} \<sharp>* c;  t1 \<longrightarrow>b t2; \<And>c. P c t1 t2\<rbrakk> \<Longrightarrow> P c (Lam [x]. t1) (Lam [x]. t2)"
       
    77   and "\<And>x s t c. \<lbrakk>{atom x} \<sharp>* c; atom x \<sharp> s\<rbrakk> \<Longrightarrow> P c (App (Lam [x]. t) s) (t [x ::= s])"
       
    78   shows "P (c\<Colon>'a\<Colon>fs) x1 x2"
       
    79   sorry
       
    80 
       
    81 inductive
       
    82   beta_star :: "lam \<Rightarrow> lam \<Rightarrow> bool" (" _ \<longrightarrow>b* _" [80,80] 80)
       
    83 where
       
    84   bs1[intro, simp]: "M \<longrightarrow>b* M"
       
    85 | bs2[intro]: "\<lbrakk>M1\<longrightarrow>b* M2; M2 \<longrightarrow>b M3\<rbrakk> \<Longrightarrow> M1 \<longrightarrow>b* M3"
       
    86 
       
    87 lemma beta_star_trans:
       
    88   assumes "A \<longrightarrow>b* B"
       
    89   and     "B \<longrightarrow>b* C"
       
    90   shows   "A \<longrightarrow>b* C"
       
    91   using assms(2) assms(1)
       
    92   by induct auto
       
    93 
       
    94 (* HERE 2: Does not work:*)
       
    95 
       
    96 (* equivariance beta_star *)
       
    97 
       
    98 (* proved manually below. *)
       
    99 
       
   100 lemma eqvt_helper: "x1 \<longrightarrow>b* x2 \<Longrightarrow>  (p \<bullet> x1) \<longrightarrow>b* (p \<bullet> x2)"
       
   101   apply (erule beta_star.induct)
       
   102   apply auto
       
   103   using eqvt(1) bs2
       
   104   by blast
       
   105 
       
   106 lemma [eqvt]: "p \<bullet> (x1 \<longrightarrow>b* x2) = ((p \<bullet> x1) \<longrightarrow>b* (p \<bullet> x2))"
       
   107   apply rule
       
   108   apply (drule permute_boolE)
       
   109   apply (erule eqvt_helper)
       
   110   apply (intro permute_boolI)
       
   111   apply (drule_tac p="-p" in eqvt_helper)
       
   112   by simp
       
   113 
       
   114 definition
       
   115   equ :: "lam \<Rightarrow> lam \<Rightarrow> bool" ("_ \<approx> _")
       
   116 where
       
   117   "t \<approx> s \<longleftrightarrow> (\<exists>r. t \<longrightarrow>b* r \<and> s \<longrightarrow>b* r)"
       
   118 
       
   119 lemma equ_refl:
       
   120   shows "t \<approx> t"
       
   121   unfolding equ_def by auto
       
   122 
       
   123 lemma equ_sym:
       
   124   assumes "t \<approx> s"
       
   125   shows "s \<approx> t"
       
   126   using assms unfolding equ_def
       
   127   by auto
       
   128 
       
   129 (* can be ported from nominal1 *)
       
   130 lemma cr:
       
   131   assumes "t \<longrightarrow>b* t1" and "t \<longrightarrow>b* t2" shows "\<exists>t3. t1 \<longrightarrow>b* t3 \<and> t2 \<longrightarrow>b* t3"
       
   132   sorry
       
   133 
       
   134 lemma equ_trans:
       
   135   assumes "A \<approx> B" "B \<approx> C"
       
   136   shows "A \<approx> C"
       
   137   using assms unfolding equ_def
       
   138 proof (elim exE conjE)
       
   139   fix D E
       
   140   assume a: "A \<longrightarrow>b* D" "B \<longrightarrow>b* D" "B \<longrightarrow>b* E" "C \<longrightarrow>b* E"
       
   141   then obtain F where "D \<longrightarrow>b* F" "E \<longrightarrow>b* F" using cr by blast
       
   142   then have "A \<longrightarrow>b* F \<and> C \<longrightarrow>b* F" using a beta_star_trans by blast
       
   143   then show "\<exists>F. A \<longrightarrow>b* F \<and> C \<longrightarrow>b* F" by blast
       
   144 qed
       
   145 
       
   146 lemma App_beta: "A \<longrightarrow>b* B \<Longrightarrow> C \<longrightarrow>b* D \<Longrightarrow> App A C \<longrightarrow>b* App B D"
       
   147   apply (erule beta_star.induct)
       
   148   apply auto
       
   149   apply (erule beta_star.induct)
       
   150   apply auto
       
   151   done
       
   152 
       
   153 lemma Lam_beta: "A \<longrightarrow>b* B \<Longrightarrow> Lam [x]. A \<longrightarrow>b* Lam [x]. B"
       
   154   by (erule beta_star.induct) auto
       
   155 
       
   156 lemma [quot_respect]:
       
   157   shows "(op = ===> equ) Var Var"
       
   158   and   "(equ ===> equ ===> equ) App App"
       
   159   and   "(op = ===> equ ===> equ) BetaCR.Lam BetaCR.Lam"
       
   160   unfolding fun_rel_def equ_def
       
   161   apply auto
       
   162   apply (rule_tac x="App r ra" in exI)
       
   163   apply (auto simp add: App_beta)
       
   164   apply (rule_tac x="Lam [x]. r" in exI)
       
   165   apply (auto simp add: Lam_beta)
       
   166   done
       
   167 
       
   168 lemma beta_subst1_pre: "B \<longrightarrow>b C \<Longrightarrow> A [x ::= B] \<longrightarrow>b* A [x ::= C]"
       
   169   by (nominal_induct A avoiding: x B C rule: lam.strong_induct)
       
   170      (auto simp add: App_beta Lam_beta)
       
   171 
       
   172 lemma beta_subst1: "B \<longrightarrow>b* C \<Longrightarrow> A [x ::= B] \<longrightarrow>b* A [x ::= C]"
       
   173   apply (erule beta_star.induct)
       
   174   apply auto
       
   175   apply (subgoal_tac "A [x ::= M2] \<longrightarrow>b* A [x ::= M3]")
       
   176   apply (rotate_tac 1)
       
   177   apply (erule beta_star_trans)
       
   178   apply assumption
       
   179   apply (simp add: beta_subst1_pre)
       
   180   done
       
   181 
       
   182 lemma forget:
       
   183   shows "atom x \<sharp> t \<Longrightarrow> t[x ::= s] = t"
       
   184   by (nominal_induct t avoiding: x s rule: lam.strong_induct)
       
   185      (auto simp add: lam.fresh fresh_at_base)
       
   186 
       
   187 lemma substitution_lemma:
       
   188   assumes a: "x \<noteq> y" "atom x \<sharp> u"
       
   189   shows "t[x ::= s][y ::= u] = t[y ::= u][x ::= s[y ::= u]]"
       
   190   using a
       
   191   by (nominal_induct t avoiding: x y s u rule: lam.strong_induct)
       
   192      (auto simp add: fresh_fact forget)
       
   193 
       
   194 lemma beta_subst2_pre:
       
   195   assumes "A \<longrightarrow>b B" shows "A [x ::= C] \<longrightarrow>b* B [x ::= C]"
       
   196   using assms
       
   197 (* HERE 3: nominal_induct doesn't work - leaves the assumption *)
       
   198 (*  apply (nominal_induct avoiding: x C rule: beta_strong_induct)*)
       
   199   apply -
       
   200   apply (erule beta_strong_induct[of A B "\<lambda>c A B. A [(fst c) ::= (snd c)] \<longrightarrow>b* B [(fst c) ::= (snd c)]" "(x, C)", simplified])
       
   201   apply (auto simp add: App_beta fresh_star_def fresh_Pair Lam_beta)[3]
       
   202   apply (subst substitution_lemma)
       
   203   apply (auto simp add: fresh_star_def fresh_Pair fresh_at_base)[2]
       
   204   apply (auto simp add: fresh_star_def fresh_Pair)
       
   205   apply (rule beta_star.intros)
       
   206   defer
       
   207   apply (subst beta.intros)
       
   208   apply (auto simp add: fresh_fact)
       
   209   done
       
   210 
       
   211 lemma beta_subst2: "A \<longrightarrow>b* B \<Longrightarrow> A [x ::= C] \<longrightarrow>b* B [x ::= C]"
       
   212   apply (erule beta_star.induct)
       
   213   apply auto
       
   214   apply (subgoal_tac "M2[x ::= C] \<longrightarrow>b* M3[x ::= C]")
       
   215   apply (rotate_tac 1)
       
   216   apply (erule beta_star_trans)
       
   217   apply assumption
       
   218   apply (simp add: beta_subst2_pre)
       
   219   done
       
   220 
       
   221 lemma beta_subst: "A \<longrightarrow>b* B \<Longrightarrow> C \<longrightarrow>b* D \<Longrightarrow> A [x ::= C] \<longrightarrow>b* B [x ::= D]"
       
   222   using beta_subst1 beta_subst2 beta_star_trans by metis
       
   223 
       
   224 lemma [quot_respect]:
       
   225   shows "(equ ===> op = ===> equ ===> equ) subst subst"
       
   226 unfolding fun_rel_def equ_def
       
   227 apply auto
       
   228 apply (rule_tac x="r [xa ::= ra]" in exI)
       
   229 apply (simp add: beta_subst)
       
   230 done
       
   231 
       
   232 lemma [quot_respect]:
       
   233   shows "(op = ===> equ ===> equ) permute permute"
       
   234   unfolding fun_rel_def equ_def
       
   235   apply (auto intro: eqvts)
       
   236   apply (rule_tac x="x \<bullet> r" in exI)
       
   237   using eqvts(1) permute_boolI by metis
       
   238 
       
   239 quotient_type qlam = lam / equ
       
   240   by (auto intro!: equivpI reflpI sympI transpI simp add: equ_refl equ_sym)
       
   241      (erule equ_trans, assumption)
       
   242 
       
   243 quotient_definition "QVar::name \<Rightarrow> qlam" is Var
       
   244 quotient_definition "QApp::qlam \<Rightarrow> qlam \<Rightarrow> qlam" is App
       
   245 quotient_definition QLam ("QLam [_]._")
       
   246   where "QLam::name \<Rightarrow> qlam \<Rightarrow> qlam" is Beta.Lam
       
   247 
       
   248 lemmas qlam_strong_induct = lam.strong_induct[quot_lifted]
       
   249 lemmas qlam_induct = lam.induct[quot_lifted]
       
   250 
       
   251 instantiation qlam :: pt
       
   252 begin
       
   253 
       
   254 quotient_definition "permute_qlam::perm \<Rightarrow> qlam \<Rightarrow> qlam" 
       
   255   is "permute::perm \<Rightarrow> lam \<Rightarrow> lam"
       
   256 
       
   257 instance
       
   258 apply default
       
   259 apply(descending)
       
   260 apply(simp)
       
   261 apply(rule equ_refl)
       
   262 apply(descending)
       
   263 apply(simp)
       
   264 apply(rule equ_refl)
       
   265 done
       
   266 
       
   267 end
       
   268 
       
   269 lemma qlam_perm[simp, eqvt]:
       
   270   shows "p \<bullet> (QVar x) = QVar (p \<bullet> x)"
       
   271   and "p \<bullet> (QApp t s) = QApp (p \<bullet> t) (p \<bullet> s)"
       
   272   and "p \<bullet> (QLam [x].t) = QLam [p \<bullet> x].(p \<bullet> t)"
       
   273   by(descending, simp add: equ_refl)+
       
   274 
       
   275 lemma qlam_supports:
       
   276   shows "{atom x} supports (QVar x)"
       
   277   and   "supp (t, s) supports (QApp t s)"
       
   278   and   "supp (x, t) supports (QLam [x].t)"
       
   279 unfolding supports_def fresh_def[symmetric]
       
   280 by (auto simp add: swap_fresh_fresh)
       
   281 
       
   282 lemma qlam_fs:
       
   283   fixes t::"qlam"
       
   284   shows "finite (supp t)"
       
   285 apply(induct t rule: qlam_induct)
       
   286 apply(rule supports_finite)
       
   287 apply(rule qlam_supports)
       
   288 apply(simp)
       
   289 apply(rule supports_finite)
       
   290 apply(rule qlam_supports)
       
   291 apply(simp add: supp_Pair)
       
   292 apply(rule supports_finite)
       
   293 apply(rule qlam_supports)
       
   294 apply(simp add: supp_Pair finite_supp)
       
   295 done
       
   296 
       
   297 instantiation qlam :: fs
       
   298 begin
       
   299 
       
   300 instance
       
   301 apply(default)
       
   302 apply(rule qlam_fs)
       
   303 done
       
   304 
       
   305 end
       
   306 
       
   307 quotient_definition subst_qlam ("_[_ ::q= _]")
       
   308   where "subst_qlam::qlam \<Rightarrow> name \<Rightarrow> qlam \<Rightarrow> qlam" is subst  
       
   309 
       
   310 lemmas qsubst = subst.simps(1-2)[quot_lifted]
       
   311 
       
   312 definition
       
   313   "Supp t = \<Inter>{supp s | s. s \<approx> t}"
       
   314 
       
   315 lemma [quot_respect]:
       
   316   shows "(equ ===> op=) Supp Supp"
       
   317   unfolding fun_rel_def Supp_def
       
   318   apply(intro allI impI)
       
   319   apply(rule_tac f="Inter" in arg_cong)
       
   320   apply(auto)
       
   321   apply (metis equ_trans)
       
   322   by (metis equivp_def qlam_equivp)
       
   323 
       
   324 quotient_definition "supp_qlam::qlam \<Rightarrow> atom set" 
       
   325   is "Supp::lam \<Rightarrow> atom set"
       
   326 
       
   327 lemma Supp_supp:
       
   328   "Supp t \<subseteq> supp t"
       
   329 unfolding Supp_def
       
   330 apply(auto)
       
   331 apply(drule_tac x="supp t" in spec)
       
   332 apply(auto simp add: equ_refl)
       
   333 done
       
   334 
       
   335 lemma Supp_Lam:
       
   336   "atom a \<notin> Supp (Lam [a].t)"
       
   337 proof -
       
   338   have "atom a \<notin> supp (Lam [a].t)" by (simp add: lam.supp)
       
   339   then show ?thesis using Supp_supp
       
   340     by blast
       
   341 qed
       
   342 
       
   343 lemma [eqvt]: "(p \<bullet> (a \<approx> b)) = ((p \<bullet> a) \<approx> (p \<bullet> b))"
       
   344   unfolding equ_def
       
   345   by perm_simp rule
       
   346 
       
   347 lemma [eqvt]: "p \<bullet> (Supp x) = Supp (p \<bullet> x)"
       
   348   unfolding Supp_def
       
   349   by perm_simp rule
       
   350 
       
   351 lemmas s = Supp_Lam[quot_lifted]
       
   352 
       
   353 lemma var_beta_pre: "s \<longrightarrow>b* r \<Longrightarrow> s = Var name \<Longrightarrow> r = Var name"
       
   354   apply (induct rule: beta_star.induct)
       
   355   apply simp
       
   356   apply (subgoal_tac "M2 = Var name")
       
   357   apply (thin_tac "M1 \<longrightarrow>b* M2")
       
   358   apply (thin_tac "M1 = Var name")
       
   359   apply (thin_tac "M1 = Var name \<Longrightarrow> M2 = Var name")
       
   360   defer
       
   361   apply simp
       
   362   apply (erule_tac beta.cases)
       
   363   apply simp_all
       
   364   done
       
   365 
       
   366 lemma var_beta: "Var name \<longrightarrow>b* r \<longleftrightarrow> r = Var name"
       
   367   by (auto simp add: var_beta_pre)
       
   368 
       
   369 lemma qlam_eq_iff:
       
   370   "(QVar n = QVar m) = (n = m)"
       
   371   apply descending unfolding equ_def var_beta by auto
       
   372 
       
   373 lemma "supp (QVar n) = {atom n}"
       
   374   unfolding supp_def
       
   375   apply simp
       
   376   unfolding qlam_eq_iff
       
   377   apply (fold supp_def)
       
   378   apply (simp add: supp_at_base)
       
   379   done
       
   380 
       
   381 end
       
   382 
       
   383 
       
   384