diff -r f75d765a281f -r 43055b016688 src/HOL/Algebra/Coset.thy --- a/src/HOL/Algebra/Coset.thy Tue Jun 12 11:18:35 2018 +0100 +++ b/src/HOL/Algebra/Coset.thy Tue Jun 12 16:08:57 2018 +0100 @@ -38,346 +38,325 @@ normal_rel :: "['a set, ('a, 'b) monoid_scheme] \ bool" (infixl "\" 60) where "H \ G \ normal H G" +(* ************************************************************************** *) +(* Next two lemmas contributed by Martin Baillon. *) + +lemma l_coset_eq_set_mult: + fixes G (structure) + shows "x <# H = {x} <#> H" + unfolding l_coset_def set_mult_def by simp + +lemma r_coset_eq_set_mult: + fixes G (structure) + shows "H #> x = H <#> {x}" + unfolding r_coset_def set_mult_def by simp + +(* ************************************************************************** *) + + +(* ************************************************************************** *) +(* Next five lemmas contributed by Paulo Emílio de Vilhena. *) + +lemma (in subgroup) rcosets_not_empty: + assumes "R \ rcosets H" + shows "R \ {}" +proof - + obtain g where "g \ carrier G" "R = H #> g" + using assms unfolding RCOSETS_def by blast + hence "\ \ g \ R" + using one_closed unfolding r_coset_def by blast + thus ?thesis by blast +qed + +lemma (in group) diff_neutralizes: + assumes "subgroup H G" "R \ rcosets H" + shows "\r1 r2. \ r1 \ R; r2 \ R \ \ r1 \ (inv r2) \ H" +proof - + fix r1 r2 assume r1: "r1 \ R" and r2: "r2 \ R" + obtain g where g: "g \ carrier G" "R = H #> g" + using assms unfolding RCOSETS_def by blast + then obtain h1 h2 where h1: "h1 \ H" "r1 = h1 \ g" + and h2: "h2 \ H" "r2 = h2 \ g" + using r1 r2 unfolding r_coset_def by blast + hence "r1 \ (inv r2) = (h1 \ g) \ ((inv g) \ (inv h2))" + using inv_mult_group is_group assms(1) g(1) subgroup.mem_carrier by fastforce + also have " ... = (h1 \ (g \ inv g) \ inv h2)" + using h1 h2 assms(1) g(1) inv_closed m_closed monoid.m_assoc + monoid_axioms subgroup.mem_carrier by smt + finally have "r1 \ inv r2 = h1 \ inv h2" + using assms(1) g(1) h1(1) subgroup.mem_carrier by fastforce + thus "r1 \ inv r2 \ H" by (metis assms(1) h1(1) h2(1) subgroup_def) +qed + + +subsection \Stable Operations for Subgroups\ + +lemma (in group) subgroup_set_mult_equality[simp]: + assumes "subgroup H G" "I \ H" "J \ H" + shows "I <#>\<^bsub>G \ carrier := H \\<^esub> J = I <#> J" + unfolding set_mult_def subgroup_mult_equality[OF assms(1)] by auto + +lemma (in group) subgroup_rcos_equality[simp]: + assumes "subgroup H G" "I \ H" "h \ H" + shows "I #>\<^bsub>G \ carrier := H \\<^esub> h = I #> h" + using subgroup_set_mult_equality by (simp add: r_coset_eq_set_mult assms) + +lemma (in group) subgroup_lcos_equality[simp]: + assumes "subgroup H G" "I \ H" "h \ H" + shows "h <#\<^bsub>G \ carrier := H \\<^esub> I = h <# I" + using subgroup_set_mult_equality by (simp add: l_coset_eq_set_mult assms) + +(* ************************************************************************** *) + + +subsection \Basic Properties of set_mult\ + +lemma (in group) setmult_subset_G: + assumes "H \ carrier G" "K \ carrier G" + shows "H <#> K \ carrier G" using assms + by (auto simp add: set_mult_def subsetD) + +lemma (in monoid) set_mult_closed: + assumes "H \ carrier G" "K \ carrier G" + shows "H <#> K \ carrier G" + using assms by (auto simp add: set_mult_def subsetD) + +(* ************************************************************************** *) +(* Next lemma contributed by Martin Baillon. *) + +lemma (in group) set_mult_assoc: + assumes "M \ carrier G" "H \ carrier G" "K \ carrier G" + shows "(M <#> H) <#> K = M <#> (H <#> K)" +proof + show "(M <#> H) <#> K \ M <#> (H <#> K)" + proof + fix x assume "x \ (M <#> H) <#> K" + then obtain m h k where x: "m \ M" "h \ H" "k \ K" "x = (m \ h) \ k" + unfolding set_mult_def by blast + hence "x = m \ (h \ k)" + using assms m_assoc by blast + thus "x \ M <#> (H <#> K)" + unfolding set_mult_def using x by blast + qed +next + show "M <#> (H <#> K) \ (M <#> H) <#> K" + proof + fix x assume "x \ M <#> (H <#> K)" + then obtain m h k where x: "m \ M" "h \ H" "k \ K" "x = m \ (h \ k)" + unfolding set_mult_def by blast + hence "x = (m \ h) \ k" + using assms m_assoc rev_subsetD by metis + thus "x \ (M <#> H) <#> K" + unfolding set_mult_def using x by blast + qed +qed + +(* ************************************************************************** *) + subsection \Basic Properties of Cosets\ lemma (in group) coset_mult_assoc: - "[| M \ carrier G; g \ carrier G; h \ carrier G |] - ==> (M #> g) #> h = M #> (g \ h)" -by (force simp add: r_coset_def m_assoc) + assumes "M \ carrier G" "g \ carrier G" "h \ carrier G" + shows "(M #> g) #> h = M #> (g \ h)" + using assms by (force simp add: r_coset_def m_assoc) + +lemma (in group) coset_assoc: + assumes "x \ carrier G" "y \ carrier G" "H \ carrier G" + shows "x <# (H #> y) = (x <# H) #> y" + using set_mult_assoc[of "{x}" H "{y}"] + by (simp add: l_coset_eq_set_mult r_coset_eq_set_mult assms) lemma (in group) coset_mult_one [simp]: "M \ carrier G ==> M #> \ = M" by (force simp add: r_coset_def) lemma (in group) coset_mult_inv1: - "[| M #> (x \ (inv y)) = M; x \ carrier G ; y \ carrier G; - M \ carrier G |] ==> M #> x = M #> y" -apply (erule subst [of concl: "%z. M #> x = z #> y"]) -apply (simp add: coset_mult_assoc m_assoc) -done + assumes "M #> (x \ (inv y)) = M" + and "x \ carrier G" "y \ carrier G" "M \ carrier G" + shows "M #> x = M #> y" using assms + by (metis coset_mult_assoc group.inv_solve_right is_group subgroup_def subgroup_self) lemma (in group) coset_mult_inv2: - "[| M #> x = M #> y; x \ carrier G; y \ carrier G; M \ carrier G |] - ==> M #> (x \ (inv y)) = M " -apply (simp add: coset_mult_assoc [symmetric]) -apply (simp add: coset_mult_assoc) -done + assumes "M #> x = M #> y" + and "x \ carrier G" "y \ carrier G" "M \ carrier G" + shows "M #> (x \ (inv y)) = M " using assms + by (metis group.coset_mult_assoc group.coset_mult_one inv_closed is_group r_inv) lemma (in group) coset_join1: - "[| H #> x = H; x \ carrier G; subgroup H G |] ==> x \ H" -apply (erule subst) -apply (simp add: r_coset_def) -apply (blast intro: l_one subgroup.one_closed sym) -done + assumes "H #> x = H" + and "x \ carrier G" "subgroup H G" + shows "x \ H" + using assms r_coset_def l_one subgroup.one_closed sym by fastforce lemma (in group) solve_equation: - "\subgroup H G; x \ H; y \ H\ \ \h\H. y = h \ x" -apply (rule bexI [of _ "y \ (inv x)"]) -apply (auto simp add: subgroup.m_closed subgroup.m_inv_closed m_assoc - subgroup.subset [THEN subsetD]) -done + assumes "subgroup H G" "x \ H" "y \ H" + shows "\h \ H. y = h \ x" +proof - + have "y = (y \ (inv x)) \ x" using assms + by (simp add: m_assoc subgroup.mem_carrier) + moreover have "y \ (inv x) \ H" using assms + by (simp add: subgroup_def) + ultimately show ?thesis by blast +qed lemma (in group) repr_independence: - "\y \ H #> x; x \ carrier G; subgroup H G\ \ H #> x = H #> y" + assumes "y \ H #> x" "x \ carrier G" "subgroup H G" + shows "H #> x = H #> y" using assms by (auto simp add: r_coset_def m_assoc [symmetric] subgroup.subset [THEN subsetD] subgroup.m_closed solve_equation) lemma (in group) coset_join2: - "\x \ carrier G; subgroup H G; x\H\ \ H #> x = H" + assumes "x \ carrier G" "subgroup H G" "x \ H" + shows "H #> x = H" using assms \ \Alternative proof is to put @{term "x=\"} in \repr_independence\.\ by (force simp add: subgroup.m_closed r_coset_def solve_equation) +lemma (in group) coset_join3: + assumes "x \ carrier G" "subgroup H G" "x \ H" + shows "x <# H = H" +proof + have "\h. h \ H \ x \ h \ H" using assms + by (simp add: subgroup.m_closed) + thus "x <# H \ H" unfolding l_coset_def by blast +next + have "\h. h \ H \ x \ ((inv x) \ h) = h" + by (smt assms inv_closed l_one m_assoc r_inv subgroup.mem_carrier) + moreover have "\h. h \ H \ (inv x) \ h \ H" + by (simp add: assms subgroup.m_closed subgroup.m_inv_closed) + ultimately show "H \ x <# H" unfolding l_coset_def by blast +qed + lemma (in monoid) r_coset_subset_G: - "[| H \ carrier G; x \ carrier G |] ==> H #> x \ carrier G" + "\ H \ carrier G; x \ carrier G \ \ H #> x \ carrier G" by (auto simp add: r_coset_def) lemma (in group) rcosI: - "[| h \ H; H \ carrier G; x \ carrier G|] ==> h \ x \ H #> x" + "\ h \ H; H \ carrier G; x \ carrier G \ \ h \ x \ H #> x" by (auto simp add: r_coset_def) lemma (in group) rcosetsI: "\H \ carrier G; x \ carrier G\ \ H #> x \ rcosets H" by (auto simp add: RCOSETS_def) -text\Really needed?\ -lemma (in group) transpose_inv: - "[| x \ y = z; x \ carrier G; y \ carrier G; z \ carrier G |] - ==> (inv x) \ z = y" -by (force simp add: m_assoc [symmetric]) - -lemma (in group) rcos_self: "[| x \ carrier G; subgroup H G |] ==> x \ H #> x" -apply (simp add: r_coset_def) -apply (blast intro: sym l_one subgroup.subset [THEN subsetD] - subgroup.one_closed) -done +lemma (in group) rcos_self: + "\ x \ carrier G; subgroup H G \ \ x \ H #> x" + by (metis l_one rcosI subgroup_def) text (in group) \Opposite of @{thm [source] "repr_independence"}\ lemma (in group) repr_independenceD: - assumes "subgroup H G" - assumes ycarr: "y \ carrier G" - and repr: "H #> x = H #> y" + assumes "subgroup H G" "y \ carrier G" + and "H #> x = H #> y" shows "y \ H #> x" -proof - - interpret subgroup H G by fact - show ?thesis apply (subst repr) - apply (intro rcos_self) - apply (rule ycarr) - apply (rule is_subgroup) - done -qed + using assms by (simp add: rcos_self) text \Elements of a right coset are in the carrier\ lemma (in subgroup) elemrcos_carrier: - assumes "group G" - assumes acarr: "a \ carrier G" - and a': "a' \ H #> a" + assumes "group G" "a \ carrier G" + and "a' \ H #> a" shows "a' \ carrier G" -proof - - interpret group G by fact - from subset and acarr - have "H #> a \ carrier G" by (rule r_coset_subset_G) - from this and a' - show "a' \ carrier G" - by fast -qed + by (meson assms group.is_monoid monoid.r_coset_subset_G subset subsetCE) lemma (in subgroup) rcos_const: - assumes "group G" - assumes hH: "h \ H" + assumes "group G" "h \ H" shows "H #> h = H" -proof - - interpret group G by fact - show ?thesis apply (unfold r_coset_def) - apply rule - apply rule - apply clarsimp - apply (intro subgroup.m_closed) - apply (rule is_subgroup) - apply assumption - apply (rule hH) - apply rule - apply simp - proof - - fix h' - assume h'H: "h' \ H" - note carr = hH[THEN mem_carrier] h'H[THEN mem_carrier] - from carr - have a: "h' = (h' \ inv h) \ h" by (simp add: m_assoc) - from h'H hH - have "h' \ inv h \ H" by simp - from this and a - show "\x\H. h' = x \ h" by fast - qed -qed + using group.coset_join2[OF assms(1), of h H] + by (simp add: assms(2) subgroup_axioms) -text \Step one for lemma \rcos_module\\ lemma (in subgroup) rcos_module_imp: - assumes "group G" - assumes xcarr: "x \ carrier G" - and x'cos: "x' \ H #> x" + assumes "group G" "x \ carrier G" + and "x' \ H #> x" shows "(x' \ inv x) \ H" proof - - interpret group G by fact - from xcarr x'cos - have x'carr: "x' \ carrier G" - by (rule elemrcos_carrier[OF is_group]) - from xcarr - have ixcarr: "inv x \ carrier G" - by simp - from x'cos - have "\h\H. x' = h \ x" - unfolding r_coset_def - by fast - from this - obtain h - where hH: "h \ H" - and x': "x' = h \ x" - by auto - from hH and subset - have hcarr: "h \ carrier G" by fast - note carr = xcarr x'carr hcarr - from x' and carr - have "x' \ (inv x) = (h \ x) \ (inv x)" by fast - also from carr - have "\ = h \ (x \ inv x)" by (simp add: m_assoc) - also from carr - have "\ = h \ \" by simp - also from carr - have "\ = h" by simp - finally - have "x' \ (inv x) = h" by simp - from hH this - show "x' \ (inv x) \ H" by simp + obtain h where h: "h \ H" "x' = h \ x" + using assms(3) unfolding r_coset_def by blast + hence "x' \ inv x = h" + by (metis assms elemrcos_carrier group.inv_solve_right mem_carrier) + thus ?thesis using h by blast qed -text \Step two for lemma \rcos_module\\ lemma (in subgroup) rcos_module_rev: - assumes "group G" - assumes carr: "x \ carrier G" "x' \ carrier G" - and xixH: "(x' \ inv x) \ H" + assumes "group G" "x \ carrier G" "x' \ carrier G" + and "(x' \ inv x) \ H" shows "x' \ H #> x" proof - - interpret group G by fact - from xixH - have "\h\H. x' \ (inv x) = h" by fast - from this - obtain h - where hH: "h \ H" - and hsym: "x' \ (inv x) = h" - by fast - from hH subset have hcarr: "h \ carrier G" by simp - note carr = carr hcarr - from hsym[symmetric] have "h \ x = x' \ (inv x) \ x" by fast - also from carr - have "\ = x' \ ((inv x) \ x)" by (simp add: m_assoc) - also from carr - have "\ = x' \ \" by simp - also from carr - have "\ = x'" by simp - finally - have "h \ x = x'" by simp - from this[symmetric] and hH - show "x' \ H #> x" - unfolding r_coset_def - by fast + obtain h where h: "h \ H" "x' \ inv x = h" + using assms(4) unfolding r_coset_def by blast + hence "x' = h \ x" + by (metis assms group.inv_solve_right mem_carrier) + thus ?thesis using h unfolding r_coset_def by blast qed text \Module property of right cosets\ lemma (in subgroup) rcos_module: - assumes "group G" - assumes carr: "x \ carrier G" "x' \ carrier G" + assumes "group G" "x \ carrier G" "x' \ carrier G" shows "(x' \ H #> x) = (x' \ inv x \ H)" -proof - - interpret group G by fact - show ?thesis proof assume "x' \ H #> x" - from this and carr - show "x' \ inv x \ H" - by (intro rcos_module_imp[OF is_group]) - next - assume "x' \ inv x \ H" - from this and carr - show "x' \ H #> x" - by (intro rcos_module_rev[OF is_group]) - qed -qed + using rcos_module_rev rcos_module_imp assms by blast text \Right cosets are subsets of the carrier.\ lemma (in subgroup) rcosets_carrier: - assumes "group G" - assumes XH: "X \ rcosets H" + assumes "group G" "X \ rcosets H" shows "X \ carrier G" -proof - - interpret group G by fact - from XH have "\x\ carrier G. X = H #> x" - unfolding RCOSETS_def - by fast - from this - obtain x - where xcarr: "x\ carrier G" - and X: "X = H #> x" - by fast - from subset and xcarr - show "X \ carrier G" - unfolding X - by (rule r_coset_subset_G) -qed + using assms elemrcos_carrier singletonD + subset_eq unfolding RCOSETS_def by force + text \Multiplication of general subsets\ -lemma (in monoid) set_mult_closed: - assumes Acarr: "A \ carrier G" - and Bcarr: "B \ carrier G" - shows "A <#> B \ carrier G" -apply rule apply (simp add: set_mult_def, clarsimp) -proof - - fix a b - assume "a \ A" - from this and Acarr - have acarr: "a \ carrier G" by fast - - assume "b \ B" - from this and Bcarr - have bcarr: "b \ carrier G" by fast - - from acarr bcarr - show "a \ b \ carrier G" by (rule m_closed) -qed lemma (in comm_group) mult_subgroups: - assumes subH: "subgroup H G" - and subK: "subgroup K G" + assumes "subgroup H G" and "subgroup K G" shows "subgroup (H <#> K) G" -apply (rule subgroup.intro) - apply (intro set_mult_closed subgroup.subset[OF subH] subgroup.subset[OF subK]) - apply (simp add: set_mult_def) apply clarsimp defer 1 - apply (simp add: set_mult_def) defer 1 - apply (simp add: set_mult_def, clarsimp) defer 1 -proof - - fix ha hb ka kb - assume haH: "ha \ H" and hbH: "hb \ H" and kaK: "ka \ K" and kbK: "kb \ K" - note carr = haH[THEN subgroup.mem_carrier[OF subH]] hbH[THEN subgroup.mem_carrier[OF subH]] - kaK[THEN subgroup.mem_carrier[OF subK]] kbK[THEN subgroup.mem_carrier[OF subK]] - from carr - have "(ha \ ka) \ (hb \ kb) = ha \ (ka \ hb) \ kb" by (simp add: m_assoc) - also from carr - have "\ = ha \ (hb \ ka) \ kb" by (simp add: m_comm) - also from carr - have "\ = (ha \ hb) \ (ka \ kb)" by (simp add: m_assoc) - finally - have eq: "(ha \ ka) \ (hb \ kb) = (ha \ hb) \ (ka \ kb)" . - - from haH hbH have hH: "ha \ hb \ H" by (simp add: subgroup.m_closed[OF subH]) - from kaK kbK have kK: "ka \ kb \ K" by (simp add: subgroup.m_closed[OF subK]) - - from hH and kK and eq - show "\h'\H. \k'\K. (ha \ ka) \ (hb \ kb) = h' \ k'" by fast +proof (rule subgroup.intro) + show "H <#> K \ carrier G" + by (simp add: setmult_subset_G assms subgroup_imp_subset) +next + have "\ \ \ \ H <#> K" + unfolding set_mult_def using assms subgroup.one_closed by blast + thus "\ \ H <#> K" by simp next - have "\ = \ \ \" by simp - from subgroup.one_closed[OF subH] subgroup.one_closed[OF subK] this - show "\h\H. \k\K. \ = h \ k" by fast + show "\x. x \ H <#> K \ inv x \ H <#> K" + proof - + fix x assume "x \ H <#> K" + then obtain h k where hk: "h \ H" "k \ K" "x = h \ k" + unfolding set_mult_def by blast + hence "inv x = (inv k) \ (inv h)" + by (meson inv_mult_group assms subgroup.mem_carrier) + hence "inv x = (inv h) \ (inv k)" + by (metis hk inv_mult assms subgroup.mem_carrier) + thus "inv x \ H <#> K" + unfolding set_mult_def using hk assms + by (metis (no_types, lifting) UN_iff singletonI subgroup_def) + qed next - fix h k - assume hH: "h \ H" - and kK: "k \ K" - - from hH[THEN subgroup.mem_carrier[OF subH]] kK[THEN subgroup.mem_carrier[OF subK]] - have "inv (h \ k) = inv h \ inv k" by (simp add: inv_mult_group m_comm) - - from subgroup.m_inv_closed[OF subH hH] and subgroup.m_inv_closed[OF subK kK] and this - show "\ha\H. \ka\K. inv (h \ k) = ha \ ka" by fast + show "\x y. x \ H <#> K \ y \ H <#> K \ x \ y \ H <#> K" + proof - + fix x y assume "x \ H <#> K" "y \ H <#> K" + then obtain h1 k1 h2 k2 where h1k1: "h1 \ H" "k1 \ K" "x = h1 \ k1" + and h2k2: "h2 \ H" "k2 \ K" "y = h2 \ k2" + unfolding set_mult_def by blast + hence "x \ y = (h1 \ k1) \ (h2 \ k2)" by simp + also have " ... = h1 \ (k1 \ h2) \ k2" + by (smt h1k1 h2k2 m_assoc m_closed assms subgroup.mem_carrier) + also have " ... = h1 \ (h2 \ k1) \ k2" + by (metis (no_types, hide_lams) assms m_comm h1k1(2) h2k2(1) subgroup.mem_carrier) + finally have "x \ y = (h1 \ h2) \ (k1 \ k2)" + by (smt assms h1k1 h2k2 m_assoc monoid.m_closed monoid_axioms subgroup.mem_carrier) + thus "x \ y \ H <#> K" unfolding set_mult_def + using subgroup.m_closed[OF assms(1) h1k1(1) h2k2(1)] + subgroup.m_closed[OF assms(2) h1k1(2) h2k2(2)] by blast + qed qed lemma (in subgroup) lcos_module_rev: - assumes "group G" - assumes carr: "x \ carrier G" "x' \ carrier G" - and xixH: "(inv x \ x') \ H" + assumes "group G" "x \ carrier G" "x' \ carrier G" + and "(inv x \ x') \ H" shows "x' \ x <# H" proof - - interpret group G by fact - from xixH - have "\h\H. (inv x) \ x' = h" by fast - from this - obtain h - where hH: "h \ H" - and hsym: "(inv x) \ x' = h" - by fast - - from hH subset have hcarr: "h \ carrier G" by simp - note carr = carr hcarr - from hsym[symmetric] have "x \ h = x \ ((inv x) \ x')" by fast - also from carr - have "\ = (x \ (inv x)) \ x'" by (simp add: m_assoc[symmetric]) - also from carr - have "\ = \ \ x'" by simp - also from carr - have "\ = x'" by simp - finally - have "x \ h = x'" by simp - - from this[symmetric] and hH - show "x' \ x <# H" - unfolding l_coset_def - by fast + obtain h where h: "h \ H" "inv x \ x' = h" + using assms(4) unfolding l_coset_def by blast + hence "x' = x \ h" + by (metis assms group.inv_solve_left mem_carrier) + thus ?thesis using h unfolding l_coset_def by blast qed @@ -391,21 +370,21 @@ by (simp add: normal_def normal_axioms_def is_group) lemma (in normal) inv_op_closed1: - "\x \ carrier G; h \ H\ \ (inv x) \ h \ x \ H" -apply (insert coset_eq) -apply (auto simp add: l_coset_def r_coset_def) -apply (drule bspec, assumption) -apply (drule equalityD1 [THEN subsetD], blast, clarify) -apply (simp add: m_assoc) -apply (simp add: m_assoc [symmetric]) -done + assumes "x \ carrier G" and "h \ H" + shows "(inv x) \ h \ x \ H" +proof - + have "h \ x \ x <# H" + using assms coset_eq assms(1) unfolding r_coset_def by blast + then obtain h' where "h' \ H" "h \ x = x \ h'" + unfolding l_coset_def by blast + thus ?thesis by (metis assms inv_closed l_inv l_one m_assoc mem_carrier) +qed lemma (in normal) inv_op_closed2: - "\x \ carrier G; h \ H\ \ x \ h \ (inv x) \ H" -apply (subgoal_tac "inv (inv x) \ h \ (inv x) \ H") -apply (simp add: ) -apply (blast intro: inv_op_closed1) -done + assumes "x \ carrier G" and "h \ H" + shows "x \ h \ (inv x) \ H" + using assms inv_op_closed1 by (metis inv_closed inv_inv) + text\Alternative characterization of normal subgroups\ lemma (in group) normal_inv_iff: @@ -455,74 +434,81 @@ qed qed +corollary (in group) normal_invI: + assumes "subgroup N G" and "\x h. \ x \ carrier G; h \ N \ \ x \ h \ inv x \ N" + shows "N \ G" + using assms normal_inv_iff by blast -subsection\More Properties of Cosets\ +corollary (in group) normal_invE: + assumes "N \ G" + shows "subgroup N G" and "\x h. \ x \ carrier G; h \ N \ \ x \ h \ inv x \ N" + using assms normal_inv_iff apply blast + by (simp add: assms normal.inv_op_closed2) + + +lemma (in group) one_is_normal : + "{\} \ G" +proof(intro normal_invI ) + show "subgroup {\} G" + by (simp add: subgroup_def) + show "\x h. x \ carrier G \ h \ {\} \ x \ h \ inv x \ {\}" by simp +qed + + +subsection\More Properties of Left Cosets\ + +lemma (in group) l_repr_independence: + assumes "y \ x <# H" "x \ carrier G" "subgroup H G" + shows "x <# H = y <# H" +proof - + obtain h' where h': "h' \ H" "y = x \ h'" + using assms(1) unfolding l_coset_def by blast + hence "\ h. h \ H \ x \ h = y \ ((inv h') \ h)" + by (smt assms(2-3) inv_closed inv_solve_right m_assoc m_closed subgroup.mem_carrier) + hence "\ xh. xh \ x <# H \ xh \ y <# H" + unfolding l_coset_def by (metis (no_types, lifting) UN_iff assms(3) h'(1) subgroup_def) + moreover have "\ h. h \ H \ y \ h = x \ (h' \ h)" + using h' by (meson assms(2) assms(3) m_assoc subgroup.mem_carrier) + hence "\ yh. yh \ y <# H \ yh \ x <# H" + unfolding l_coset_def using subgroup.m_closed[OF assms(3) h'(1)] by blast + ultimately show ?thesis by blast +qed lemma (in group) lcos_m_assoc: - "[| M \ carrier G; g \ carrier G; h \ carrier G |] - ==> g <# (h <# M) = (g \ h) <# M" + "\ M \ carrier G; g \ carrier G; h \ carrier G \ \ g <# (h <# M) = (g \ h) <# M" by (force simp add: l_coset_def m_assoc) -lemma (in group) lcos_mult_one: "M \ carrier G ==> \ <# M = M" +lemma (in group) lcos_mult_one: "M \ carrier G \ \ <# M = M" by (force simp add: l_coset_def) lemma (in group) l_coset_subset_G: - "[| H \ carrier G; x \ carrier G |] ==> x <# H \ carrier G" + "\ H \ carrier G; x \ carrier G \ \ x <# H \ carrier G" by (auto simp add: l_coset_def subsetD) -lemma (in group) l_coset_swap: - "\y \ x <# H; x \ carrier G; subgroup H G\ \ x \ y <# H" -proof (simp add: l_coset_def) - assume "\h\H. y = x \ h" - and x: "x \ carrier G" - and sb: "subgroup H G" - then obtain h' where h': "h' \ H \ x \ h' = y" by blast - show "\h\H. x = y \ h" - proof - show "x = y \ inv h'" using h' x sb - by (auto simp add: m_assoc subgroup.subset [THEN subsetD]) - show "inv h' \ H" using h' sb - by (auto simp add: subgroup.subset [THEN subsetD] subgroup.m_inv_closed) - qed -qed - lemma (in group) l_coset_carrier: - "[| y \ x <# H; x \ carrier G; subgroup H G |] ==> y \ carrier G" -by (auto simp add: l_coset_def m_assoc - subgroup.subset [THEN subsetD] subgroup.m_closed) + "\ y \ x <# H; x \ carrier G; subgroup H G \ \ y \ carrier G" + by (auto simp add: l_coset_def m_assoc subgroup.subset [THEN subsetD] subgroup.m_closed) -lemma (in group) l_repr_imp_subset: - assumes y: "y \ x <# H" and x: "x \ carrier G" and sb: "subgroup H G" - shows "y <# H \ x <# H" -proof - - from y - obtain h' where "h' \ H" "x \ h' = y" by (auto simp add: l_coset_def) - thus ?thesis using x sb - by (auto simp add: l_coset_def m_assoc - subgroup.subset [THEN subsetD] subgroup.m_closed) -qed +lemma (in group) l_coset_swap: + assumes "y \ x <# H" "x \ carrier G" "subgroup H G" + shows "x \ y <# H" + using assms(2) l_repr_independence[OF assms] subgroup.one_closed[OF assms(3)] + unfolding l_coset_def by fastforce -lemma (in group) l_repr_independence: - assumes y: "y \ x <# H" and x: "x \ carrier G" and sb: "subgroup H G" - shows "x <# H = y <# H" +lemma (in group) subgroup_mult_id: + assumes "subgroup H G" + shows "H <#> H = H" proof - show "x <# H \ y <# H" - by (rule l_repr_imp_subset, - (blast intro: l_coset_swap l_coset_carrier y x sb)+) - show "y <# H \ x <# H" by (rule l_repr_imp_subset [OF y x sb]) + show "H <#> H \ H" + unfolding set_mult_def using subgroup.m_closed[OF assms] by (simp add: UN_subset_iff) + show "H \ H <#> H" + proof + fix x assume x: "x \ H" thus "x \ H <#> H" unfolding set_mult_def + using subgroup.m_closed[OF assms subgroup.one_closed[OF assms] x] subgroup.one_closed[OF assms] + by (smt UN_iff assms coset_join3 l_coset_def subgroup.mem_carrier) + qed qed -lemma (in group) setmult_subset_G: - "\H \ carrier G; K \ carrier G\ \ H <#> K \ carrier G" -by (auto simp add: set_mult_def subsetD) - -lemma (in group) subgroup_mult_id: "subgroup H G \ H <#> H = H" -apply (auto simp add: subgroup.m_closed set_mult_def Sigma_def) -apply (rule_tac x = x in bexI) -apply (rule bexI [of _ "\"]) -apply (auto simp add: subgroup.one_closed subgroup.subset [THEN subsetD]) -done - subsubsection \Set of Inverses of an \r_coset\.\ @@ -552,20 +538,21 @@ subsubsection \Theorems for \<#>\ with \#>\ or \<#\.\ lemma (in group) setmult_rcos_assoc: - "\H \ carrier G; K \ carrier G; x \ carrier G\ - \ H <#> (K #> x) = (H <#> K) #> x" -by (force simp add: r_coset_def set_mult_def m_assoc) + "\H \ carrier G; K \ carrier G; x \ carrier G\ \ + H <#> (K #> x) = (H <#> K) #> x" + using set_mult_assoc[of H K "{x}"] by (simp add: r_coset_eq_set_mult) lemma (in group) rcos_assoc_lcos: - "\H \ carrier G; K \ carrier G; x \ carrier G\ - \ (H #> x) <#> K = H <#> (x <# K)" -by (force simp add: r_coset_def l_coset_def set_mult_def m_assoc) + "\H \ carrier G; K \ carrier G; x \ carrier G\ \ + (H #> x) <#> K = H <#> (x <# K)" + using set_mult_assoc[of H "{x}" K] + by (simp add: l_coset_eq_set_mult r_coset_eq_set_mult) lemma (in normal) rcos_mult_step1: - "\x \ carrier G; y \ carrier G\ - \ (H #> x) <#> (H #> y) = (H <#> (x <# H)) #> y" -by (simp add: setmult_rcos_assoc subset - r_coset_subset_G l_coset_subset_G rcos_assoc_lcos) + "\x \ carrier G; y \ carrier G\ \ + (H #> x) <#> (H #> y) = (H <#> (x <# H)) #> y" + by (simp add: setmult_rcos_assoc r_coset_subset_G + subset l_coset_subset_G rcos_assoc_lcos) lemma (in normal) rcos_mult_step2: "\x \ carrier G; y \ carrier G\ @@ -645,7 +632,7 @@ lemma (in subgroup) l_coset_eq_rcong: assumes "group G" assumes a: "a \ carrier G" - shows "a <# H = rcong H `` {a}" + shows "a <# H = (rcong H) `` {a}" proof - interpret group G by fact show ?thesis by (force simp add: r_congruent_def l_coset_def m_assoc [symmetric] a ) @@ -661,9 +648,7 @@ proof - interpret subgroup H G by fact from p show ?thesis apply (rule_tac UN_I [of "hb \ ((inv ha) \ h)"]) - apply (simp add: ) - apply (simp add: m_assoc transpose_inv) - done + apply blast by (simp add: inv_solve_left m_assoc) qed lemma (in group) rcos_disjoint: @@ -793,28 +778,47 @@ "\H \ carrier G; a \ carrier G\ \ inj_on (\y. y \ a) H" by (force simp add: inj_on_def subsetD) +(* ************************************************************************** *) + lemma (in group) card_cosets_equal: - "\c \ rcosets H; H \ carrier G; finite(carrier G)\ - \ card c = card H" -apply (auto simp add: RCOSETS_def) -apply (rule card_bij_eq) - apply (rule inj_on_f, assumption+) - apply (force simp add: m_assoc subsetD r_coset_def) - apply (rule inj_on_g, assumption+) - apply (force simp add: m_assoc subsetD r_coset_def) - txt\The sets @{term "H #> a"} and @{term "H"} are finite.\ - apply (simp add: r_coset_subset_G [THEN finite_subset]) -apply (blast intro: finite_subset) -done + assumes "R \ rcosets H" "H \ carrier G" + shows "\f. bij_betw f H R" +proof - + obtain g where g: "g \ carrier G" "R = H #> g" + using assms(1) unfolding RCOSETS_def by blast + + let ?f = "\h. h \ g" + have "\r. r \ R \ \h \ H. ?f h = r" + proof - + fix r assume "r \ R" + then obtain h where "h \ H" "r = h \ g" + using g unfolding r_coset_def by blast + thus "\h \ H. ?f h = r" by blast + qed + hence "R \ ?f ` H" by blast + moreover have "?f ` H \ R" + using g unfolding r_coset_def by blast + ultimately show ?thesis using inj_on_g unfolding bij_betw_def + using assms(2) g(1) by auto +qed + +corollary (in group) card_rcosets_equal: + assumes "R \ rcosets H" "H \ carrier G" + shows "card H = card R" + using card_cosets_equal assms bij_betw_same_card by blast + +corollary (in group) rcosets_finite: + assumes "R \ rcosets H" "H \ carrier G" "finite H" + shows "finite R" + using card_cosets_equal assms bij_betw_finite is_group by blast + +(* ************************************************************************** *) lemma (in group) rcosets_subset_PowG: "subgroup H G \ rcosets H \ Pow(carrier G)" -apply (simp add: RCOSETS_def) -apply (blast dest: r_coset_subset_G subgroup.subset) -done + using rcosets_part_G by auto - -theorem (in group) lagrange: +proposition (in group) lagrange_finite: "\finite(carrier G); subgroup H G\ \ card(rcosets H) * card(H) = order(G)" apply (simp (no_asm_simp) add: order_def rcosets_part_G [symmetric]) @@ -822,10 +826,42 @@ apply (rule card_partition) apply (simp add: rcosets_subset_PowG [THEN finite_subset]) apply (simp add: rcosets_part_G) - apply (simp add: card_cosets_equal subgroup.subset) + apply (simp add: card_rcosets_equal subgroup_imp_subset) apply (simp add: rcos_disjoint) done +theorem (in group) lagrange: + assumes "subgroup H G" + shows "card (rcosets H) * card H = order G" +proof (cases "finite (carrier G)") + case True thus ?thesis using lagrange_finite assms by simp +next + case False note inf_G = this + thus ?thesis + proof (cases "finite H") + case False thus ?thesis using inf_G by (simp add: order_def) + next + case True note finite_H = this + have "infinite (rcosets H)" + proof (rule ccontr) + assume "\ infinite (rcosets H)" + hence finite_rcos: "finite (rcosets H)" by simp + hence "card (\(rcosets H)) = (\R\(rcosets H). card R)" + using card_Union_disjoint[of "rcosets H"] finite_H rcos_disjoint[OF assms(1)] + rcosets_finite[where ?H = H] by (simp add: assms subgroup_imp_subset) + hence "order G = (\R\(rcosets H). card R)" + by (simp add: assms order_def rcosets_part_G) + hence "order G = (\R\(rcosets H). card H)" + using card_rcosets_equal by (simp add: assms subgroup_imp_subset) + hence "order G = (card H) * (card (rcosets H))" by simp + hence "order G \ 0" using finite_rcos finite_H assms ex_in_conv + rcosets_part_G subgroup.one_closed by fastforce + thus False using inf_G order_gt_0_iff_finite by blast + qed + thus ?thesis using inf_G by (simp add: order_def) + qed +qed + subsection \Quotient Groups: Factorization of a Group\ @@ -845,7 +881,7 @@ lemma (in normal) rcosets_assoc: "\M1 \ rcosets H; M2 \ rcosets H; M3 \ rcosets H\ \ M1 <#> M2 <#> M3 = M1 <#> (M2 <#> M3)" -by (auto simp add: RCOSETS_def rcos_sum m_assoc) + by (simp add: group.set_mult_assoc is_group rcosets_carrier) lemma (in subgroup) subgroup_in_rcosets: assumes "group G" @@ -1016,10 +1052,111 @@ text\If @{term h} is a homomorphism from @{term G} onto @{term H}, then the quotient group @{term "G Mod (kernel G H h)"} is isomorphic to @{term H}.\ -theorem (in group_hom) FactGroup_iso: +theorem (in group_hom) FactGroup_iso_set: "h ` carrier G = carrier H - \ (\X. the_elem (h`X)) \ (G Mod (kernel G H h)) \ H" + \ (\X. the_elem (h`X)) \ iso (G Mod (kernel G H h)) H" by (simp add: iso_def FactGroup_hom FactGroup_inj_on bij_betw_def FactGroup_onto) +corollary (in group_hom) FactGroup_iso : + "h ` carrier G = carrier H + \ (G Mod (kernel G H h))\ H" + using FactGroup_iso_set unfolding is_iso_def by auto + + +(* Next two lemmas contributed by Paulo Emílio de Vilhena. *) + +lemma (in group_hom) trivial_hom_iff: + "(h ` (carrier G) = { \\<^bsub>H\<^esub> }) = (kernel G H h = carrier G)" + unfolding kernel_def using one_closed by force + +lemma (in group_hom) trivial_ker_imp_inj: + assumes "kernel G H h = { \ }" + shows "inj_on h (carrier G)" +proof (rule inj_onI) + fix g1 g2 assume A: "g1 \ carrier G" "g2 \ carrier G" "h g1 = h g2" + hence "h (g1 \ (inv g2)) = \\<^bsub>H\<^esub>" by simp + hence "g1 \ (inv g2) = \" + using A assms unfolding kernel_def by blast + thus "g1 = g2" + using A G.inv_equality G.inv_inv by blast +qed + + +(* Next subsection contributed by Martin Baillon. *) + +subsection \Theorems about Factor Groups and Direct product\ + + +lemma (in group) DirProd_normal : + assumes "group K" + and "H \ G" + and "N \ K" + shows "H \ N \ G \\ K" +proof (intro group.normal_invI[OF DirProd_group[OF group_axioms assms(1)]]) + show sub : "subgroup (H \ N) (G \\ K)" + using DirProd_subgroups[OF group_axioms normal_imp_subgroup[OF assms(2)]assms(1) + normal_imp_subgroup[OF assms(3)]]. + show "\x h. x \ carrier (G\\K) \ h \ H\N \ x \\<^bsub>G\\K\<^esub> h \\<^bsub>G\\K\<^esub> inv\<^bsub>G\\K\<^esub> x \ H\N" + proof- + fix x h assume xGK : "x \ carrier (G \\ K)" and hHN : " h \ H \ N" + hence hGK : "h \ carrier (G \\ K)" using subgroup_imp_subset[OF sub] by auto + from xGK obtain x1 x2 where x1x2 :"x1 \ carrier G" "x2 \ carrier K" "x = (x1,x2)" + unfolding DirProd_def by fastforce + from hHN obtain h1 h2 where h1h2 : "h1 \ H" "h2 \ N" "h = (h1,h2)" + unfolding DirProd_def by fastforce + hence h1h2GK : "h1 \ carrier G" "h2 \ carrier K" + using normal_imp_subgroup subgroup_imp_subset assms apply blast+. + have "inv\<^bsub>G \\ K\<^esub> x = (inv\<^bsub>G\<^esub> x1,inv\<^bsub>K\<^esub> x2)" + using inv_DirProd[OF group_axioms assms(1) x1x2(1)x1x2(2)] x1x2 by auto + hence "x \\<^bsub>G \\ K\<^esub> h \\<^bsub>G \\ K\<^esub> inv\<^bsub>G \\ K\<^esub> x = (x1 \ h1 \ inv x1,x2 \\<^bsub>K\<^esub> h2 \\<^bsub>K\<^esub> inv\<^bsub>K\<^esub> x2)" + using h1h2 x1x2 h1h2GK by auto + moreover have "x1 \ h1 \ inv x1 \ H" "x2 \\<^bsub>K\<^esub> h2 \\<^bsub>K\<^esub> inv\<^bsub>K\<^esub> x2 \ N" + using normal_invE group.normal_invE[OF assms(1)] assms x1x2 h1h2 apply auto. + hence "(x1 \ h1 \ inv x1, x2 \\<^bsub>K\<^esub> h2 \\<^bsub>K\<^esub> inv\<^bsub>K\<^esub> x2)\ H \ N" by auto + ultimately show " x \\<^bsub>G \\ K\<^esub> h \\<^bsub>G \\ K\<^esub> inv\<^bsub>G \\ K\<^esub> x \ H \ N" by auto + qed +qed + +lemma (in group) FactGroup_DirProd_multiplication_iso_set : + assumes "group K" + and "H \ G" + and "N \ K" + shows "(\ (X, Y). X \ Y) \ iso ((G Mod H) \\ (K Mod N)) (G \\ K Mod H \ N)" + +proof- + have R :"(\(X, Y). X \ Y) \ carrier (G Mod H) \ carrier (K Mod N) \ carrier (G \\ K Mod H \ N)" + unfolding r_coset_def Sigma_def DirProd_def FactGroup_def RCOSETS_def apply simp by blast + moreover have "(\x\carrier (G Mod H). \y\carrier (K Mod N). \xa\carrier (G Mod H). + \ya\carrier (K Mod N). (x <#> xa) \ (y <#>\<^bsub>K\<^esub> ya) = x \ y <#>\<^bsub>G \\ K\<^esub> xa \ ya)" + unfolding set_mult_def apply auto apply blast+. + moreover have "(\x\carrier (G Mod H). \y\carrier (K Mod N). \xa\carrier (G Mod H). + \ya\carrier (K Mod N). x \ y = xa \ ya \ x = xa \ y = ya)" + unfolding FactGroup_def using times_eq_iff subgroup.rcosets_not_empty + by (metis assms(2) assms(3) normal_def partial_object.select_convs(1)) + moreover have "(\(X, Y). X \ Y) ` (carrier (G Mod H) \ carrier (K Mod N)) = + carrier (G \\ K Mod H \ N)" + unfolding image_def apply auto using R apply force + unfolding DirProd_def FactGroup_def RCOSETS_def r_coset_def apply auto apply force. + ultimately show ?thesis + unfolding iso_def hom_def bij_betw_def inj_on_def by simp +qed + +corollary (in group) FactGroup_DirProd_multiplication_iso_1 : + assumes "group K" + and "H \ G" + and "N \ K" + shows " ((G Mod H) \\ (K Mod N)) \ (G \\ K Mod H \ N)" + unfolding is_iso_def using FactGroup_DirProd_multiplication_iso_set assms by auto + +corollary (in group) FactGroup_DirProd_multiplication_iso_2 : + assumes "group K" + and "H \ G" + and "N \ K" + shows "(G \\ K Mod H \ N) \ ((G Mod H) \\ (K Mod N))" + using FactGroup_DirProd_multiplication_iso_1 group.iso_sym assms + DirProd_group[OF normal.factorgroup_is_group normal.factorgroup_is_group] + by blast + + end