Nominal/Nominal2_Eqvt.thy
changeset 2568 8193bbaa07fe
parent 2565 6bf332360510
child 2591 35c570891a3a
equal deleted inserted replaced
2567:41137dc935ff 2568:8193bbaa07fe
       
     1 (*  Title:      Nominal2_Eqvt
       
     2     Author:     Brian Huffman, 
       
     3     Author:     Christian Urban
       
     4 
       
     5     Equivariance, supp and freshness lemmas for various operators 
       
     6     (contains many, but not all such lemmas).
       
     7 *)
       
     8 theory Nominal2_Eqvt
       
     9 imports Nominal2_Base 
       
    10 uses ("nominal_thmdecls.ML")
       
    11      ("nominal_permeq.ML")
       
    12      ("nominal_eqvt.ML")
       
    13 begin
       
    14 
       
    15 
       
    16 section {* Permsimp and Eqvt infrastructure *}
       
    17 
       
    18 text {* Setup of the theorem attributes @{text eqvt} and @{text eqvt_raw} *}
       
    19 
       
    20 use "nominal_thmdecls.ML"
       
    21 setup "Nominal_ThmDecls.setup"
       
    22 
       
    23 
       
    24 section {* eqvt lemmas *}
       
    25 
       
    26 lemmas [eqvt] =
       
    27   conj_eqvt Not_eqvt ex_eqvt all_eqvt imp_eqvt
       
    28   imp_eqvt[folded induct_implies_def]
       
    29   uminus_eqvt
       
    30 
       
    31   (* nominal *)
       
    32   supp_eqvt fresh_eqvt fresh_star_eqvt add_perm_eqvt atom_eqvt 
       
    33   swap_eqvt flip_eqvt
       
    34 
       
    35   (* datatypes *)
       
    36   Pair_eqvt permute_list.simps 
       
    37 
       
    38   (* sets *)
       
    39   mem_eqvt empty_eqvt insert_eqvt set_eqvt
       
    40 
       
    41   (* fsets *)
       
    42   permute_fset fset_eqvt
       
    43 
       
    44 text {* helper lemmas for the perm_simp *}
       
    45 
       
    46 definition
       
    47   "unpermute p = permute (- p)"
       
    48 
       
    49 lemma eqvt_apply:
       
    50   fixes f :: "'a::pt \<Rightarrow> 'b::pt" 
       
    51   and x :: "'a::pt"
       
    52   shows "p \<bullet> (f x) \<equiv> (p \<bullet> f) (p \<bullet> x)"
       
    53   unfolding permute_fun_def by simp
       
    54 
       
    55 lemma eqvt_lambda:
       
    56   fixes f :: "'a::pt \<Rightarrow> 'b::pt"
       
    57   shows "p \<bullet> (\<lambda>x. f x) \<equiv> (\<lambda>x. p \<bullet> (f (unpermute p x)))"
       
    58   unfolding permute_fun_def unpermute_def by simp
       
    59 
       
    60 lemma eqvt_bound:
       
    61   shows "p \<bullet> unpermute p x \<equiv> x"
       
    62   unfolding unpermute_def by simp
       
    63 
       
    64 text {* provides perm_simp methods *}
       
    65 
       
    66 use "nominal_permeq.ML"
       
    67 setup Nominal_Permeq.setup
       
    68 
       
    69 method_setup perm_simp =
       
    70  {* Nominal_Permeq.args_parser >> Nominal_Permeq.perm_simp_meth *}
       
    71  {* pushes permutations inside. *}
       
    72 
       
    73 method_setup perm_strict_simp =
       
    74  {* Nominal_Permeq.args_parser >> Nominal_Permeq.perm_strict_simp_meth *}
       
    75  {* pushes permutations inside, raises an error if it cannot solve all permutations. *}
       
    76 
       
    77 (* the normal version of this lemma would cause loops *)
       
    78 lemma permute_eqvt_raw[eqvt_raw]:
       
    79   shows "p \<bullet> permute \<equiv> permute"
       
    80 apply(simp add: fun_eq_iff permute_fun_def)
       
    81 apply(subst permute_eqvt)
       
    82 apply(simp)
       
    83 done
       
    84 
       
    85 subsection {* Equivariance of Logical Operators *}
       
    86 
       
    87 lemma eq_eqvt[eqvt]:
       
    88   shows "p \<bullet> (x = y) \<longleftrightarrow> (p \<bullet> x) = (p \<bullet> y)"
       
    89   unfolding permute_eq_iff permute_bool_def ..
       
    90 
       
    91 lemma if_eqvt[eqvt]:
       
    92   shows "p \<bullet> (if b then x else y) = (if p \<bullet> b then p \<bullet> x else p \<bullet> y)"
       
    93   by (simp add: permute_fun_def permute_bool_def)
       
    94 
       
    95 lemma True_eqvt[eqvt]:
       
    96   shows "p \<bullet> True = True"
       
    97   unfolding permute_bool_def ..
       
    98 
       
    99 lemma False_eqvt[eqvt]:
       
   100   shows "p \<bullet> False = False"
       
   101   unfolding permute_bool_def ..
       
   102 
       
   103 lemma disj_eqvt[eqvt]:
       
   104   shows "p \<bullet> (A \<or> B) = ((p \<bullet> A) \<or> (p \<bullet> B))"
       
   105   by (simp add: permute_bool_def)
       
   106 
       
   107 lemma all_eqvt2:
       
   108   shows "p \<bullet> (\<forall>x. P x) = (\<forall>x. p \<bullet> P (- p \<bullet> x))"
       
   109   by (perm_simp add: permute_minus_cancel) (rule refl)
       
   110 
       
   111 lemma ex_eqvt2:
       
   112   shows "p \<bullet> (\<exists>x. P x) = (\<exists>x. p \<bullet> P (- p \<bullet> x))"
       
   113   by (perm_simp add: permute_minus_cancel) (rule refl)
       
   114 
       
   115 lemma ex1_eqvt[eqvt]:
       
   116   shows "p \<bullet> (\<exists>!x. P x) = (\<exists>!x. (p \<bullet> P) x)"
       
   117   unfolding Ex1_def
       
   118   by (perm_simp) (rule refl)
       
   119 
       
   120 lemma ex1_eqvt2:
       
   121   shows "p \<bullet> (\<exists>!x. P x) = (\<exists>!x. p \<bullet> P (- p \<bullet> x))"
       
   122   by (perm_simp add: permute_minus_cancel) (rule refl)
       
   123 
       
   124 lemma the_eqvt:
       
   125   assumes unique: "\<exists>!x. P x"
       
   126   shows "(p \<bullet> (THE x. P x)) = (THE x. p \<bullet> P (- p \<bullet> x))"
       
   127   apply(rule the1_equality [symmetric])
       
   128   apply(simp add: ex1_eqvt2[symmetric])
       
   129   apply(simp add: permute_bool_def unique)
       
   130   apply(simp add: permute_bool_def)
       
   131   apply(rule theI'[OF unique])
       
   132   done
       
   133 
       
   134 subsection {* Equivariance Set Operations *}
       
   135 
       
   136 lemma not_mem_eqvt:
       
   137   shows "p \<bullet> (x \<notin> A) \<longleftrightarrow> (p \<bullet> x) \<notin> (p \<bullet> A)"
       
   138   by (perm_simp) (rule refl)
       
   139 
       
   140 lemma Collect_eqvt[eqvt]:
       
   141   shows "p \<bullet> {x. P x} = {x. (p \<bullet> P) x}"
       
   142   unfolding Collect_def permute_fun_def ..
       
   143 
       
   144 lemma Collect_eqvt2:
       
   145   shows "p \<bullet> {x. P x} = {x. p \<bullet> (P (-p \<bullet> x))}"
       
   146   by (perm_simp add: permute_minus_cancel) (rule refl)
       
   147 
       
   148 lemma Bex_eqvt[eqvt]:
       
   149   shows "p \<bullet> (\<exists>x \<in> S. P x) = (\<exists>x \<in> (p \<bullet> S). (p \<bullet> P) x)"
       
   150   unfolding Bex_def
       
   151   by (perm_simp) (rule refl)
       
   152 
       
   153 lemma Ball_eqvt[eqvt]:
       
   154   shows "p \<bullet> (\<forall>x \<in> S. P x) = (\<forall>x \<in> (p \<bullet> S). (p \<bullet> P) x)"
       
   155   unfolding Ball_def
       
   156   by (perm_simp) (rule refl)
       
   157 
       
   158 lemma supp_set_empty:
       
   159   shows "supp {} = {}"
       
   160   unfolding supp_def
       
   161   by (simp add: empty_eqvt)
       
   162 
       
   163 lemma fresh_set_empty:
       
   164   shows "a \<sharp> {}"
       
   165   by (simp add: fresh_def supp_set_empty)
       
   166 
       
   167 lemma UNIV_eqvt[eqvt]:
       
   168   shows "p \<bullet> UNIV = UNIV"
       
   169   unfolding UNIV_def
       
   170   by (perm_simp) (rule refl)
       
   171 
       
   172 lemma union_eqvt[eqvt]:
       
   173   shows "p \<bullet> (A \<union> B) = (p \<bullet> A) \<union> (p \<bullet> B)"
       
   174   unfolding Un_def
       
   175   by (perm_simp) (rule refl)
       
   176 
       
   177 lemma inter_eqvt[eqvt]:
       
   178   shows "p \<bullet> (A \<inter> B) = (p \<bullet> A) \<inter> (p \<bullet> B)"
       
   179   unfolding Int_def 
       
   180   by (perm_simp) (rule refl)
       
   181 
       
   182 lemma Diff_eqvt[eqvt]:
       
   183   fixes A B :: "'a::pt set"
       
   184   shows "p \<bullet> (A - B) = p \<bullet> A - p \<bullet> B"
       
   185   unfolding set_diff_eq
       
   186   by (perm_simp) (rule refl)
       
   187 
       
   188 lemma Compl_eqvt[eqvt]:
       
   189   fixes A :: "'a::pt set"
       
   190   shows "p \<bullet> (- A) = - (p \<bullet> A)"
       
   191   unfolding Compl_eq_Diff_UNIV
       
   192   by (perm_simp) (rule refl)
       
   193 
       
   194 lemma image_eqvt:
       
   195   shows "p \<bullet> (f ` A) = (p \<bullet> f) ` (p \<bullet> A)"
       
   196   unfolding permute_set_eq_image
       
   197   unfolding permute_fun_def [where f=f]
       
   198   by (simp add: image_image)
       
   199 
       
   200 lemma vimage_eqvt[eqvt]:
       
   201   shows "p \<bullet> (f -` A) = (p \<bullet> f) -` (p \<bullet> A)"
       
   202   unfolding vimage_def
       
   203   by (perm_simp) (rule refl)
       
   204 
       
   205 lemma Union_eqvt[eqvt]:
       
   206   shows "p \<bullet> (\<Union> S) = \<Union> (p \<bullet> S)"
       
   207   unfolding Union_eq 
       
   208   by (perm_simp) (rule refl)
       
   209 
       
   210 lemma finite_permute_iff:
       
   211   shows "finite (p \<bullet> A) \<longleftrightarrow> finite A"
       
   212   unfolding permute_set_eq_vimage
       
   213   using bij_permute by (rule finite_vimage_iff)
       
   214 
       
   215 lemma finite_eqvt[eqvt]:
       
   216   shows "p \<bullet> finite A = finite (p \<bullet> A)"
       
   217   unfolding finite_permute_iff permute_bool_def ..
       
   218 
       
   219 lemma supp_set:
       
   220   fixes xs :: "('a::fs) list"
       
   221   shows "supp (set xs) = supp xs"
       
   222 apply(induct xs)
       
   223 apply(simp add: supp_set_empty supp_Nil)
       
   224 apply(simp add: supp_Cons supp_of_finite_insert)
       
   225 done
       
   226 
       
   227 
       
   228 section {* List Operations *}
       
   229 
       
   230 lemma append_eqvt[eqvt]:
       
   231   shows "p \<bullet> (xs @ ys) = (p \<bullet> xs) @ (p \<bullet> ys)"
       
   232   by (induct xs) auto
       
   233 
       
   234 lemma supp_append:
       
   235   shows "supp (xs @ ys) = supp xs \<union> supp ys"
       
   236   by (induct xs) (auto simp add: supp_Nil supp_Cons)
       
   237 
       
   238 lemma fresh_append:
       
   239   shows "a \<sharp> (xs @ ys) \<longleftrightarrow> a \<sharp> xs \<and> a \<sharp> ys"
       
   240   by (induct xs) (simp_all add: fresh_Nil fresh_Cons)
       
   241 
       
   242 lemma rev_eqvt[eqvt]:
       
   243   shows "p \<bullet> (rev xs) = rev (p \<bullet> xs)"
       
   244   by (induct xs) (simp_all add: append_eqvt)
       
   245 
       
   246 lemma supp_rev:
       
   247   shows "supp (rev xs) = supp xs"
       
   248   by (induct xs) (auto simp add: supp_append supp_Cons supp_Nil)
       
   249 
       
   250 lemma fresh_rev:
       
   251   shows "a \<sharp> rev xs \<longleftrightarrow> a \<sharp> xs"
       
   252   by (induct xs) (auto simp add: fresh_append fresh_Cons fresh_Nil)
       
   253 
       
   254 lemma map_eqvt[eqvt]: 
       
   255   shows "p \<bullet> (map f xs) = map (p \<bullet> f) (p \<bullet> xs)"
       
   256   by (induct xs) (simp_all, simp only: permute_fun_app_eq)
       
   257 
       
   258 
       
   259 subsection {* Equivariance for fsets *} 
       
   260 
       
   261 lemma map_fset_eqvt[eqvt]: 
       
   262   shows "p \<bullet> (map_fset f S) = map_fset (p \<bullet> f) (p \<bullet> S)"
       
   263   by (lifting map_eqvt)
       
   264 
       
   265 
       
   266 subsection {* Product Operations *}
       
   267 
       
   268 lemma fst_eqvt[eqvt]:
       
   269   "p \<bullet> (fst x) = fst (p \<bullet> x)"
       
   270  by (cases x) simp
       
   271 
       
   272 lemma snd_eqvt[eqvt]:
       
   273   "p \<bullet> (snd x) = snd (p \<bullet> x)"
       
   274  by (cases x) simp
       
   275 
       
   276 lemma split_eqvt[eqvt]: 
       
   277   shows "p \<bullet> (split P x) = split (p \<bullet> P) (p \<bullet> x)"
       
   278   unfolding split_def
       
   279   by (perm_simp) (rule refl)
       
   280 
       
   281 
       
   282 section {* Test cases *}
       
   283 
       
   284 
       
   285 declare [[trace_eqvt = false]]
       
   286 (* declare [[trace_eqvt = true]] *)
       
   287 
       
   288 lemma 
       
   289   fixes B::"'a::pt"
       
   290   shows "p \<bullet> (B = C)"
       
   291 apply(perm_simp)
       
   292 oops
       
   293 
       
   294 lemma 
       
   295   fixes B::"bool"
       
   296   shows "p \<bullet> (B = C)"
       
   297 apply(perm_simp)
       
   298 oops
       
   299 
       
   300 lemma 
       
   301   fixes B::"bool"
       
   302   shows "p \<bullet> (A \<longrightarrow> B = C)"
       
   303 apply (perm_simp) 
       
   304 oops
       
   305 
       
   306 lemma 
       
   307   shows "p \<bullet> (\<lambda>(x::'a::pt). A \<longrightarrow> (B::'a \<Rightarrow> bool) x = C) = foo"
       
   308 apply(perm_simp)
       
   309 oops
       
   310 
       
   311 lemma 
       
   312   shows "p \<bullet> (\<lambda>B::bool. A \<longrightarrow> (B = C)) = foo"
       
   313 apply (perm_simp)
       
   314 oops
       
   315 
       
   316 lemma 
       
   317   shows "p \<bullet> (\<lambda>x y. \<exists>z. x = z \<and> x = y \<longrightarrow> z \<noteq> x) = foo"
       
   318 apply (perm_simp)
       
   319 oops
       
   320 
       
   321 lemma 
       
   322   shows "p \<bullet> (\<lambda>f x. f (g (f x))) = foo"
       
   323 apply (perm_simp)
       
   324 oops
       
   325 
       
   326 lemma 
       
   327   fixes p q::"perm"
       
   328   and   x::"'a::pt"
       
   329   shows "p \<bullet> (q \<bullet> x) = foo"
       
   330 apply(perm_simp)
       
   331 oops
       
   332 
       
   333 lemma 
       
   334   fixes p q r::"perm"
       
   335   and   x::"'a::pt"
       
   336   shows "p \<bullet> (q \<bullet> r \<bullet> x) = foo"
       
   337 apply(perm_simp)
       
   338 oops
       
   339 
       
   340 lemma 
       
   341   fixes p r::"perm"
       
   342   shows "p \<bullet> (\<lambda>q::perm. q \<bullet> (r \<bullet> x)) = foo"
       
   343 apply (perm_simp)
       
   344 oops
       
   345 
       
   346 lemma 
       
   347   fixes C D::"bool"
       
   348   shows "B (p \<bullet> (C = D))"
       
   349 apply(perm_simp)
       
   350 oops
       
   351 
       
   352 declare [[trace_eqvt = false]]
       
   353 
       
   354 text {* there is no raw eqvt-rule for The *}
       
   355 lemma "p \<bullet> (THE x. P x) = foo"
       
   356 apply(perm_strict_simp exclude: The)
       
   357 apply(perm_simp exclude: The)
       
   358 oops
       
   359 
       
   360 lemma 
       
   361   fixes P :: "(('b \<Rightarrow> bool) \<Rightarrow> ('b::pt)) \<Rightarrow> ('a::pt)"
       
   362   shows "p \<bullet> (P The) = foo"
       
   363 apply(perm_simp exclude: The)
       
   364 oops
       
   365 
       
   366 lemma
       
   367   fixes  P :: "('a::pt) \<Rightarrow> ('b::pt) \<Rightarrow> bool"
       
   368   shows "p \<bullet> (\<lambda>(a, b). P a b) = (\<lambda>(a, b). (p \<bullet> P) a b)"
       
   369 apply(perm_simp)
       
   370 oops
       
   371 
       
   372 thm eqvts
       
   373 thm eqvts_raw
       
   374 
       
   375 ML {* Nominal_ThmDecls.is_eqvt @{context} @{term "supp"} *}
       
   376 
       
   377 
       
   378 section {* automatic equivariance procedure for inductive definitions *}
       
   379 
       
   380 use "nominal_eqvt.ML"
       
   381 
       
   382 end