src/HOL/Algebra/Divisibility.thy
changeset 73350 649316106b08
parent 73297 beaff25452d2
child 73393 716d256259d5
equal deleted inserted replaced
73349:6c2da22c9631 73350:649316106b08
   813 
   813 
   814 subsection \<open>Factorization and Factorial Monoids\<close>
   814 subsection \<open>Factorization and Factorial Monoids\<close>
   815 
   815 
   816 subsubsection \<open>Function definitions\<close>
   816 subsubsection \<open>Function definitions\<close>
   817 
   817 
   818 definition factors :: "[_, 'a list, 'a] \<Rightarrow> bool"
   818 definition factors :: "('a, _) monoid_scheme \<Rightarrow> 'a list \<Rightarrow> 'a \<Rightarrow> bool"
   819   where "factors G fs a \<longleftrightarrow> (\<forall>x \<in> (set fs). irreducible G x) \<and> foldr (\<otimes>\<^bsub>G\<^esub>) fs \<one>\<^bsub>G\<^esub> = a"
   819   where "factors G fs a \<longleftrightarrow> (\<forall>x \<in> (set fs). irreducible G x) \<and> foldr (\<otimes>\<^bsub>G\<^esub>) fs \<one>\<^bsub>G\<^esub> = a"
   820 
   820 
   821 definition wfactors ::"[_, 'a list, 'a] \<Rightarrow> bool"
   821 definition wfactors ::"('a, _) monoid_scheme \<Rightarrow> 'a list \<Rightarrow> 'a \<Rightarrow> bool"
   822   where "wfactors G fs a \<longleftrightarrow> (\<forall>x \<in> (set fs). irreducible G x) \<and> foldr (\<otimes>\<^bsub>G\<^esub>) fs \<one>\<^bsub>G\<^esub> \<sim>\<^bsub>G\<^esub> a"
   822   where "wfactors G fs a \<longleftrightarrow> (\<forall>x \<in> (set fs). irreducible G x) \<and> foldr (\<otimes>\<^bsub>G\<^esub>) fs \<one>\<^bsub>G\<^esub> \<sim>\<^bsub>G\<^esub> a"
   823 
   823 
   824 abbreviation list_assoc :: "('a,_) monoid_scheme \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "[\<sim>]\<index>" 44)
   824 abbreviation list_assoc :: "('a, _) monoid_scheme \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool" (infix "[\<sim>]\<index>" 44)
   825   where "list_assoc G \<equiv> list_all2 (\<sim>\<^bsub>G\<^esub>)"
   825   where "list_assoc G \<equiv> list_all2 (\<sim>\<^bsub>G\<^esub>)"
   826 
   826 
   827 definition essentially_equal :: "[_, 'a list, 'a list] \<Rightarrow> bool"
   827 definition essentially_equal :: "('a, _) monoid_scheme \<Rightarrow> 'a list \<Rightarrow> 'a list \<Rightarrow> bool"
   828   where "essentially_equal G fs1 fs2 \<longleftrightarrow> (\<exists>fs1'. fs1 <~~> fs1' \<and> fs1' [\<sim>]\<^bsub>G\<^esub> fs2)"
   828   where "essentially_equal G fs1 fs2 \<longleftrightarrow> (\<exists>fs1'. fs1 <~~> fs1' \<and> fs1' [\<sim>]\<^bsub>G\<^esub> fs2)"
   829 
   829 
   830 
   830 
   831 locale factorial_monoid = comm_monoid_cancel +
   831 locale factorial_monoid = comm_monoid_cancel +
   832   assumes factors_exist: "\<lbrakk>a \<in> carrier G; a \<notin> Units G\<rbrakk> \<Longrightarrow> \<exists>fs. set fs \<subseteq> carrier G \<and> factors G fs a"
   832   assumes factors_exist: "\<lbrakk>a \<in> carrier G; a \<notin> Units G\<rbrakk> \<Longrightarrow> \<exists>fs. set fs \<subseteq> carrier G \<and> factors G fs a"
   876 text \<open>Permutations\<close>
   876 text \<open>Permutations\<close>
   877 
   877 
   878 lemma perm_map [intro]:
   878 lemma perm_map [intro]:
   879   assumes p: "a <~~> b"
   879   assumes p: "a <~~> b"
   880   shows "map f a <~~> map f b"
   880   shows "map f a <~~> map f b"
   881   using p by induct auto
   881   using p by (simp add: perm_iff_eq_mset)
   882 
   882 
   883 lemma perm_map_switch:
   883 lemma perm_map_switch:
   884   assumes m: "map f a = map f b" and p: "b <~~> c"
   884   assumes m: "map f a = map f b" and p: "b <~~> c"
   885   shows "\<exists>d. a <~~> d \<and> map f d = map f c"
   885   shows "\<exists>d. a <~~> d \<and> map f d = map f c"
   886   using p m by (induct arbitrary: a) (simp, force, force, blast)
   886 proof -
       
   887   from m have \<open>length a = length b\<close>
       
   888     by (rule map_eq_imp_length_eq)
       
   889   from p have \<open>mset c = mset b\<close>
       
   890     by (simp add: perm_iff_eq_mset)
       
   891   then obtain p where \<open>p permutes {..<length b}\<close> \<open>permute_list p b = c\<close>
       
   892     by (rule mset_eq_permutation)
       
   893   with \<open>length a = length b\<close> have \<open>p permutes {..<length a}\<close>
       
   894     by simp
       
   895   moreover define d where \<open>d = permute_list p a\<close>
       
   896   ultimately have \<open>mset a = mset d\<close> \<open>map f d = map f c\<close>
       
   897     using m \<open>p permutes {..<length b}\<close> \<open>permute_list p b = c\<close>
       
   898     by (auto simp flip: permute_list_map)
       
   899   then show ?thesis
       
   900     by (auto simp add: perm_iff_eq_mset)
       
   901 qed
   887 
   902 
   888 lemma (in monoid) perm_assoc_switch:
   903 lemma (in monoid) perm_assoc_switch:
   889   assumes a:"as [\<sim>] bs" and p: "bs <~~> cs"
   904   assumes a:"as [\<sim>] bs" and p: "bs <~~> cs"
   890   shows "\<exists>bs'. as <~~> bs' \<and> bs' [\<sim>] cs"
   905   shows "\<exists>bs'. as <~~> bs' \<and> bs' [\<sim>] cs"
   891   using p a
   906   using p a
  1570 
  1585 
  1571 (* FIXME: use class_of x instead of closure_of {x} *)
  1586 (* FIXME: use class_of x instead of closure_of {x} *)
  1572 
  1587 
  1573 abbreviation "assocs G x \<equiv> eq_closure_of (division_rel G) {x}"
  1588 abbreviation "assocs G x \<equiv> eq_closure_of (division_rel G) {x}"
  1574 
  1589 
  1575 definition "fmset G as = mset (map (\<lambda>a. assocs G a) as)"
  1590 definition "fmset G as = mset (map (assocs G) as)"
  1576 
  1591 
  1577 
  1592 
  1578 text \<open>Helper lemmas\<close>
  1593 text \<open>Helper lemmas\<close>
  1579 
  1594 
  1580 lemma (in monoid) assocs_repr_independence:
  1595 lemma (in monoid) assocs_repr_independence:
  1637 lemma (in comm_monoid_cancel) ee_fmset:
  1652 lemma (in comm_monoid_cancel) ee_fmset:
  1638   assumes ee: "essentially_equal G as bs"
  1653   assumes ee: "essentially_equal G as bs"
  1639     and ascarr: "set as \<subseteq> carrier G" and bscarr: "set bs \<subseteq> carrier G"
  1654     and ascarr: "set as \<subseteq> carrier G" and bscarr: "set bs \<subseteq> carrier G"
  1640   shows "fmset G as = fmset G bs"
  1655   shows "fmset G as = fmset G bs"
  1641   using ee
  1656   using ee
       
  1657   thm essentially_equal_def
  1642 proof (elim essentially_equalE)
  1658 proof (elim essentially_equalE)
  1643   fix as'
  1659   fix as'
  1644   assume prm: "as <~~> as'"
  1660   assume prm: "as <~~> as'"
  1645   from prm ascarr have as'carr: "set as' \<subseteq> carrier G"
  1661   from prm ascarr have as'carr: "set as' \<subseteq> carrier G"
  1646     by (rule perm_closed)
  1662     by (rule perm_closed)
  1650   with as'carr bscarr have "fmset G as' = fmset G bs"
  1666   with as'carr bscarr have "fmset G as' = fmset G bs"
  1651     by (simp add: fmset_listassoc_cong)
  1667     by (simp add: fmset_listassoc_cong)
  1652   finally show "fmset G as = fmset G bs" .
  1668   finally show "fmset G as = fmset G bs" .
  1653 qed
  1669 qed
  1654 
  1670 
  1655 lemma (in monoid_cancel) fmset_ee_aux:
       
  1656   assumes "cas <~~> cbs" "cas = map (assocs G) as" "cbs = map (assocs G) bs"
       
  1657   shows "\<exists>as'. as <~~> as' \<and> map (assocs G) as' = cbs"
       
  1658   using assms
       
  1659 proof (induction cas cbs arbitrary: as bs rule: perm.induct)
       
  1660   case (Cons xs ys z)
       
  1661   then show ?case
       
  1662     by (clarsimp simp add: map_eq_Cons_conv) blast
       
  1663 next
       
  1664   case (trans xs ys zs)
       
  1665   then obtain as' where " as <~~> as' \<and> map (assocs G) as' = ys"
       
  1666     by (metis (no_types, lifting) ex_map_conv mset_eq_perm set_mset_mset)
       
  1667   then show ?case
       
  1668     using trans.IH(2) trans.prems(2) by blast
       
  1669 qed auto
       
  1670 
       
  1671 lemma (in comm_monoid_cancel) fmset_ee:
  1671 lemma (in comm_monoid_cancel) fmset_ee:
  1672   assumes mset: "fmset G as = fmset G bs"
  1672   assumes mset: "fmset G as = fmset G bs"
  1673     and ascarr: "set as \<subseteq> carrier G" and bscarr: "set bs \<subseteq> carrier G"
  1673     and ascarr: "set as \<subseteq> carrier G" and bscarr: "set bs \<subseteq> carrier G"
  1674   shows "essentially_equal G as bs"
  1674   shows "essentially_equal G as bs"
  1675 proof -
  1675 proof -
  1676   from mset have "map (assocs G) as <~~> map (assocs G) bs"
  1676   from mset have "mset (map (assocs G) bs) = mset (map (assocs G) as)"
  1677     by (simp add: fmset_def mset_eq_perm del: mset_map)
  1677     by (simp add: fmset_def)
  1678   then obtain as' where tp: "as <~~> as'" and tm: "map (assocs G) as' = map (assocs G) bs"
  1678   then obtain p where \<open>p permutes {..<length (map (assocs G) as)}\<close>
  1679     using fmset_ee_aux by blast
  1679     \<open>permute_list p (map (assocs G) as) = map (assocs G) bs\<close>
  1680   with ascarr have as'carr: "set as' \<subseteq> carrier G"
  1680     by (rule mset_eq_permutation)
  1681     using perm_closed by blast
  1681   then have \<open>p permutes {..<length as}\<close>
  1682   from tm as'carr[THEN subsetD] bscarr[THEN subsetD] have "as' [\<sim>] bs"
  1682     \<open>map (assocs G) (permute_list p as) = map (assocs G) bs\<close>
  1683     by (induct as' arbitrary: bs) (simp, fastforce dest: assocs_eqD[THEN associated_sym])
  1683     by (simp_all add: permute_list_map) 
  1684   with tp show "essentially_equal G as bs"
  1684   moreover define as' where \<open>as' = permute_list p as\<close>
  1685     by (fast intro: essentially_equalI)
  1685   ultimately have tp: "as <~~> as'" and tm: "map (assocs G) as' = map (assocs G) bs"
       
  1686     by (simp_all add: perm_iff_eq_mset)
       
  1687   from tp show ?thesis
       
  1688   proof (rule essentially_equalI)
       
  1689     from tm tp ascarr have as'carr: "set as' \<subseteq> carrier G"
       
  1690       using perm_closed by blast
       
  1691     from tm as'carr[THEN subsetD] bscarr[THEN subsetD] show "as' [\<sim>] bs"
       
  1692       by (induct as' arbitrary: bs) (simp, fastforce dest: assocs_eqD[THEN associated_sym])
       
  1693   qed
  1686 qed
  1694 qed
  1687 
  1695 
  1688 lemma (in comm_monoid_cancel) ee_is_fmset:
  1696 lemma (in comm_monoid_cancel) ee_is_fmset:
  1689   assumes "set as \<subseteq> carrier G" and "set bs \<subseteq> carrier G"
  1697   assumes "set as \<subseteq> carrier G" and "set bs \<subseteq> carrier G"
  1690   shows "essentially_equal G as bs = (fmset G as = fmset G bs)"
  1698   shows "essentially_equal G as bs = (fmset G as = fmset G bs)"