Nominal/GPerm.thy
changeset 3173 9876d73adb2b
parent 3139 e05c033d69c1
child 3175 52730e5ec8cb
equal deleted inserted replaced
3172:4cf3a4d36799 3173:9876d73adb2b
   159   by (metis uminus_perm_raw_def)
   159   by (metis uminus_perm_raw_def)
   160 
   160 
   161 lemma uminus_perm_raw_rsp[simp]:
   161 lemma uminus_perm_raw_rsp[simp]:
   162   "x \<approx> y \<Longrightarrow> map swap_pair x \<approx> map swap_pair y"
   162   "x \<approx> y \<Longrightarrow> map swap_pair x \<approx> map swap_pair y"
   163   by (auto simp add: fun_eq_iff perm_apply_minus[symmetric] perm_eq_def)
   163   by (auto simp add: fun_eq_iff perm_apply_minus[symmetric] perm_eq_def)
   164 
       
   165 lemma [quot_respect]:
       
   166   "(op \<approx> ===> op \<approx>) uminus_perm_raw uminus_perm_raw"
       
   167   by (auto intro!: fun_relI simp add: fun_eq_iff perm_apply_minus[symmetric] perm_eq_def)
       
   168 
   164 
   169 lemma fst_snd_map_pair[simp]:
   165 lemma fst_snd_map_pair[simp]:
   170   "fst ` map_pair f g ` set l = f ` fst ` set l"
   166   "fst ` map_pair f g ` set l = f ` fst ` set l"
   171   "snd ` map_pair f g ` set l = g ` snd ` set l"
   167   "snd ` map_pair f g ` set l = g ` snd ` set l"
   172   by (induct l) auto
   168   by (induct l) auto
   238 
   234 
   239 lemma perm_add_raw_rsp[simp]:
   235 lemma perm_add_raw_rsp[simp]:
   240   "x \<approx> y \<Longrightarrow> xa \<approx> ya \<Longrightarrow> perm_add_raw x xa \<approx> perm_add_raw y ya"
   236   "x \<approx> y \<Longrightarrow> xa \<approx> ya \<Longrightarrow> perm_add_raw x xa \<approx> perm_add_raw y ya"
   241   by (simp add: fun_eq_iff perm_add_apply perm_eq_def)
   237   by (simp add: fun_eq_iff perm_add_apply perm_eq_def)
   242 
   238 
   243 lemma [quot_respect]:
       
   244   "(op \<approx> ===> op \<approx> ===> op \<approx>) perm_add_raw perm_add_raw"
       
   245   by (auto intro!: fun_relI simp add: perm_add_raw_rsp)
       
   246 
       
   247 lemma [simp]:
   239 lemma [simp]:
   248   "a \<approx> a \<longleftrightarrow> valid_perm a"
   240   "a \<approx> a \<longleftrightarrow> valid_perm a"
   249   by (simp_all add: perm_eq_def)
   241   by (simp_all add: perm_eq_def)
   250 
   242 
   251 lemma [quot_respect]: "[] \<approx> []"
       
   252   by auto
       
   253 
       
   254 lemmas [simp] = in_respects
       
   255 
       
   256 instantiation gperm :: (type) group_add
   243 instantiation gperm :: (type) group_add
   257 begin
   244 begin
   258 
   245 
   259 quotient_definition "0 :: 'a gperm" is "[] :: ('a \<times> 'a) list"
   246 lift_definition zero_gperm :: "'a gperm" is "[]" by simp
   260 
   247 
   261 quotient_definition "uminus :: 'a gperm \<Rightarrow> 'a gperm" is
   248 lift_definition uminus_gperm :: "'a gperm \<Rightarrow> 'a gperm" is uminus_perm_raw
   262   "uminus_perm_raw :: ('a \<times> 'a) list \<Rightarrow> ('a \<times> 'a) list"
   249   by (auto simp add: fun_eq_iff perm_apply_minus[symmetric] perm_eq_def)
   263 
   250 
   264 quotient_definition "(op +) :: 'a gperm \<Rightarrow> 'a gperm \<Rightarrow> 'a gperm" is
   251 lift_definition plus_gperm :: "'a gperm \<Rightarrow> 'a gperm \<Rightarrow> 'a gperm" is perm_add_raw
   265   "perm_add_raw :: ('a \<times> 'a) list \<Rightarrow> ('a \<times> 'a) list \<Rightarrow> ('a \<times> 'a) list"
   252   by simp
   266 
   253 
   267 definition
   254 definition
   268   minus_perm_def: "(p1::'a gperm) - p2 = p1 + - p2"
   255   minus_perm_def: "(p1::'a gperm) - p2 = p1 + - p2"
   269 
   256 
   270 instance
   257 instance
   271   apply default
   258   apply default
   272   unfolding minus_perm_def
   259   unfolding minus_perm_def
   273   by (partiality_descending, simp add: perm_add_apply perm_eq_def fun_eq_iff valid_perm_add_minus)+
   260   by (transfer,simp add: perm_add_apply perm_eq_def fun_eq_iff valid_perm_add_minus)+
   274 
   261 
   275 end
   262 end
   276 
   263 
   277 definition "mk_perm_raw l = (if valid_perm l then l else [])"
   264 definition "mk_perm_raw l = (if valid_perm l then l else [])"
   278 
   265 
   279 quotient_definition "mk_perm :: ('a \<times> 'a) list \<Rightarrow> 'a gperm"
   266 lift_definition mk_perm :: "('a \<times> 'a) list \<Rightarrow> 'a gperm" is "mk_perm_raw"
   280   is "mk_perm_raw"
   267   by (simp add: mk_perm_raw_def)
   281 
   268 
   282 definition "dest_perm_raw p = sort [x\<leftarrow>p. fst x \<noteq> snd x]"
   269 definition "dest_perm_raw p = sort [x\<leftarrow>p. fst x \<noteq> snd x]"
   283 
       
   284 quotient_definition "dest_perm :: ('a :: linorder) gperm \<Rightarrow> ('a \<times> 'a) list"
       
   285   is "dest_perm_raw"
       
   286 
       
   287 lemma [quot_respect]: "(op = ===> op \<approx>) mk_perm_raw mk_perm_raw"
       
   288   by (auto intro!: fun_relI simp add: mk_perm_raw_def)
       
   289 
   270 
   290 lemma distinct_fst_distinct[simp]: "distinct (map fst x) \<Longrightarrow> distinct x"
   271 lemma distinct_fst_distinct[simp]: "distinct (map fst x) \<Longrightarrow> distinct x"
   291   by (induct x) auto
   272   by (induct x) auto
   292 
   273 
   293 lemma perm_apply_in_set:
   274 lemma perm_apply_in_set:
   339   apply (metis in_set_in_dpr3 fun_eq_iff)
   320   apply (metis in_set_in_dpr3 fun_eq_iff)
   340   unfolding dest_perm_raw_def
   321   unfolding dest_perm_raw_def
   341   by (rule sorted_distinct_set_unique)
   322   by (rule sorted_distinct_set_unique)
   342      (simp_all add: distinct_filter valid_perm_def perm_eq_not_eq_same[simplified perm_eq_def, simplified])
   323      (simp_all add: distinct_filter valid_perm_def perm_eq_not_eq_same[simplified perm_eq_def, simplified])
   343 
   324 
   344 lemma [quot_respect]:
   325 lift_definition dest_perm :: "('a :: linorder) gperm \<Rightarrow> ('a \<times> 'a) list"
   345   "(op \<approx> ===> op =) dest_perm_raw dest_perm_raw"
   326   is "dest_perm_raw"
   346   by (auto intro!: fun_relI simp add: perm_eq_def)
   327   by (simp add: perm_eq_def)
   347 
   328 
   348 lemma dest_perm_mk_perm[simp]:
   329 lemma dest_perm_mk_perm[simp]:
   349   "dest_perm (mk_perm xs) = sort [x\<leftarrow>mk_perm_raw xs. fst x \<noteq> snd x]"
   330   "dest_perm (mk_perm xs) = sort [x\<leftarrow>mk_perm_raw xs. fst x \<noteq> snd x]"
   350   by (partiality_descending)
   331   by transfer (simp add: dest_perm_raw_def)
   351      (simp add: dest_perm_raw_def)
       
   352 
   332 
   353 lemma valid_perm_filter_id[simp]:
   333 lemma valid_perm_filter_id[simp]:
   354   "valid_perm p \<Longrightarrow> valid_perm [x\<leftarrow>p. fst x \<noteq> snd x]"
   334   "valid_perm p \<Longrightarrow> valid_perm [x\<leftarrow>p. fst x \<noteq> snd x]"
   355 proof (simp (no_asm) add: valid_perm_def, intro conjI)
   335 proof (simp (no_asm) add: valid_perm_def, intro conjI)
   356   show "valid_perm p \<Longrightarrow> distinct (map fst [x\<Colon>'a \<times> 'a\<leftarrow>p . fst x \<noteq> snd x])"
   336   show "valid_perm p \<Longrightarrow> distinct (map fst [x\<Colon>'a \<times> 'a\<leftarrow>p . fst x \<noteq> snd x])"
   395   "valid_perm p \<Longrightarrow> p \<approx> dest_perm_raw p"
   375   "valid_perm p \<Longrightarrow> p \<approx> dest_perm_raw p"
   396   by (simp_all add: dest_perm_raw_eq[symmetric])
   376   by (simp_all add: dest_perm_raw_eq[symmetric])
   397 
   377 
   398 lemma mk_perm_dest_perm[code abstype]:
   378 lemma mk_perm_dest_perm[code abstype]:
   399   "mk_perm (dest_perm p) = p"
   379   "mk_perm (dest_perm p) = p"
   400   by (partiality_descending)
   380   by transfer
   401      (auto simp add: mk_perm_raw_def)
   381      (auto simp add: mk_perm_raw_def)
   402 
   382 
   403 instantiation gperm :: (linorder) equal begin
   383 instantiation gperm :: (linorder) equal begin
   404 
   384 
   405 definition equal_gperm_def: "equal_gperm a b \<longleftrightarrow> dest_perm a = dest_perm b"
   385 definition equal_gperm_def: "equal_gperm a b \<longleftrightarrow> dest_perm a = dest_perm b"
   406 
   386 
   407 instance
   387 instance
   408   apply default
   388   apply default
   409   unfolding equal_gperm_def
   389   unfolding equal_gperm_def
   410   by partiality_descending simp
   390   by transfer simp
   411 
   391 
   412 end
   392 end
   413 
   393 
   414 lemma [code abstract]:
   394 lemma [code abstract]:
   415   "dest_perm 0 = []"
   395   "dest_perm 0 = []"
   416   by (partiality_descending) (simp add: dest_perm_raw_def)
   396   by transfer (simp add: dest_perm_raw_def)
   417 
   397 
   418 lemma [code abstract]:
   398 lemma [code abstract]:
   419   "dest_perm (-a) = dest_perm_raw (uminus_perm_raw (dest_perm a))"
   399   "dest_perm (-a) = dest_perm_raw (uminus_perm_raw (dest_perm a))"
   420   by (partiality_descending) (auto)
   400   by transfer auto
   421 
   401 
   422 lemma [code abstract]:
   402 lemma [code abstract]:
   423   "dest_perm (a + b) = dest_perm_raw (perm_add_raw (dest_perm a) (dest_perm b))"
   403   "dest_perm (a + b) = dest_perm_raw (perm_add_raw (dest_perm a) (dest_perm b))"
   424   by (partiality_descending) auto
   404   by transfer auto
   425 
   405 
   426 quotient_definition "gpermute :: 'a gperm \<Rightarrow> 'a \<Rightarrow> 'a"
   406 lift_definition gpermute :: "'a gperm \<Rightarrow> 'a \<Rightarrow> 'a"
   427 is perm_apply
   407   is perm_apply
   428 
   408   by (simp add: perm_eq_def)
   429 lemma [quot_respect]: "(op \<approx> ===> op =) perm_apply perm_apply"
       
   430   by (auto intro!: fun_relI simp add: perm_eq_def)
       
   431 
   409 
   432 lemma gpermute_zero[simp]:
   410 lemma gpermute_zero[simp]:
   433   "gpermute 0 x = x"
   411   "gpermute 0 x = x"
   434   by descending simp
   412   by transfer simp
   435 
   413 
   436 lemma gpermute_add[simp]:
   414 lemma gpermute_add[simp]:
   437   "gpermute (p + q) x = gpermute p (gpermute q x)"
   415   "gpermute (p + q) x = gpermute p (gpermute q x)"
   438   by descending (simp add: perm_add_apply)
   416   by transfer (simp add: perm_add_apply)
   439 
   417 
   440 definition [simp]:"swap_raw a b = (if a = b then [] else [(a, b), (b, a)])"
   418 definition [simp]: "swap_raw a b = (if a = b then [] else [(a, b), (b, a)])"
   441 
   419 
   442 lemma [quot_respect]: "(op = ===> op = ===> op \<approx>) swap_raw swap_raw"
   420 lift_definition gswap :: "'a \<Rightarrow> 'a \<Rightarrow> 'a gperm" is swap_raw
   443   by (auto intro!: fun_relI simp add: valid_perm_def)
   421   by (auto simp add: valid_perm_def)
   444 
       
   445 quotient_definition "gswap :: 'a \<Rightarrow> 'a \<Rightarrow> 'a gperm"
       
   446 is swap_raw
       
   447 
   422 
   448 lemma [code abstract]:
   423 lemma [code abstract]:
   449   "dest_perm (gswap a b) = (if (a, b) \<le> (b, a) then swap_raw a b else swap_raw b a)"
   424   "dest_perm (gswap a b) = (if (a, b) \<le> (b, a) then swap_raw a b else swap_raw b a)"
   450   by (partiality_descending) (auto simp add: dest_perm_raw_def)
   425   by transfer (auto simp add: dest_perm_raw_def)
   451 
   426 
   452 lemma swap_self [simp]:
   427 lemma swap_self [simp]:
   453   "gswap a a = 0"
   428   "gswap a a = 0"
   454   by (partiality_descending, auto)
   429   by transfer simp
   455 
   430 
   456 lemma [simp]: "a \<noteq> b \<Longrightarrow> valid_perm [(a, b), (b, a)]"
   431 lemma [simp]: "a \<noteq> b \<Longrightarrow> valid_perm [(a, b), (b, a)]"
   457   unfolding valid_perm_def by auto
   432   unfolding valid_perm_def by auto
   458 
   433 
   459 lemma swap_cancel [simp]:
   434 lemma swap_cancel [simp]:
   460   "gswap a b + gswap a b = 0"
   435   "gswap a b + gswap a b = 0"
   461   "gswap a b + gswap b a = 0"
   436   "gswap a b + gswap b a = 0"
   462   by (descending, auto simp add: perm_eq_def perm_add_apply)+
   437   by (transfer, auto simp add: perm_eq_def perm_add_apply)+
   463 
   438 
   464 lemma minus_swap [simp]:
   439 lemma minus_swap [simp]:
   465   "- gswap a b = gswap a b"
   440   "- gswap a b = gswap a b"
   466   by (partiality_descending, auto simp add: perm_eq_def)
   441   by transfer (auto simp add: perm_eq_def)
   467 
   442 
   468 lemma swap_commute:
   443 lemma swap_commute:
   469   "gswap a b = gswap b a"
   444   "gswap a b = gswap b a"
   470   by (partiality_descending, auto simp add: perm_eq_def)
   445   by transfer (auto simp add: perm_eq_def)
   471 
   446 
   472 lemma swap_triple:
   447 lemma swap_triple:
   473   assumes "a \<noteq> b" "c \<noteq> b"
   448   assumes "a \<noteq> b" "c \<noteq> b"
   474   shows "gswap a c + gswap b c + gswap a c = gswap a b"
   449   shows "gswap a c + gswap b c + gswap a c = gswap a b"
   475   using assms
   450   using assms
   476   by descending (auto simp add: perm_eq_def fun_eq_iff perm_add_apply)
   451   by transfer (auto simp add: perm_eq_def fun_eq_iff perm_add_apply)
   477 
   452 
   478 lemma gpermute_gswap[simp]:
   453 lemma gpermute_gswap[simp]:
   479   "b \<noteq> a \<Longrightarrow> gpermute (gswap a b) b = a"
   454   "b \<noteq> a \<Longrightarrow> gpermute (gswap a b) b = a"
   480   "a \<noteq> b \<Longrightarrow> gpermute (gswap a b) a = b"
   455   "a \<noteq> b \<Longrightarrow> gpermute (gswap a b) a = b"
   481   "c \<noteq> b \<Longrightarrow> c \<noteq> a \<Longrightarrow> gpermute (gswap a b) c = c"
   456   "c \<noteq> b \<Longrightarrow> c \<noteq> a \<Longrightarrow> gpermute (gswap a b) c = c"
   482   by (descending, auto)+
   457   by (transfer, auto)+
   483 
   458 
   484 lemma gperm_eq:
   459 lemma gperm_eq:
   485   "(p = q) = (\<forall>a. gpermute p a = gpermute q a)"
   460   "(p = q) = (\<forall>a. gpermute p a = gpermute q a)"
   486   by (partiality_descending) (auto simp add: perm_eq_def)
   461   by transfer (auto simp add: perm_eq_def)
   487 
   462 
   488 lemma finite_gpermute_neq:
   463 lemma finite_gpermute_neq:
   489   "finite {a. gpermute p a \<noteq> a}"
   464   "finite {a. gpermute p a \<noteq> a}"
   490   apply descending
   465   apply transfer
   491   apply (rule_tac B="fst ` set p" in finite_subset)
   466   apply (rule_tac B="fst ` set p" in finite_subset)
   492   apply auto
   467   apply auto
   493   by (metis perm_apply_outset)
   468   by (metis perm_apply_outset)
   494 
   469 
   495 end
   470 end