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 |
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)" |