# HG changeset patch # User paulson # Date 1554292527 -3600 # Node ID 733e256ecdf3654f97462c059fc04c96cedc57dd # Parent 3374d16efc61156c9ea7d9aed08dd6c5e54e50e5 new group theory material, mostly ported from HOL Light diff -r 3374d16efc61 -r 733e256ecdf3 src/HOL/Algebra/Coset.thy --- a/src/HOL/Algebra/Coset.thy Wed Apr 03 00:07:26 2019 +0200 +++ b/src/HOL/Algebra/Coset.thy Wed Apr 03 12:55:27 2019 +0100 @@ -1061,6 +1061,26 @@ apply (simp add: kernel_def) done +lemma iso_kernel_image: + assumes "group G" "group H" + shows "f \ iso G H \ f \ hom G H \ kernel G H f = {\\<^bsub>G\<^esub>} \ f ` carrier G = carrier H" + (is "?lhs = ?rhs") +proof (intro iffI conjI) + assume f: ?lhs + show "f \ hom G H" + using Group.iso_iff f by blast + show "kernel G H f = {\\<^bsub>G\<^esub>}" + using assms f Group.group_def hom_one + by (fastforce simp add: kernel_def iso_iff_mon_epi mon_iff_hom_one set_eq_iff) + show "f ` carrier G = carrier H" + by (meson Group.iso_iff f) +next + assume ?rhs + with assms show ?lhs + by (auto simp: kernel_def iso_def bij_betw_def inj_on_one_iff') +qed + + lemma (in group_hom) FactGroup_nonempty: assumes X: "X \ carrier (G Mod kernel G H h)" shows "X \ {}" @@ -1083,7 +1103,7 @@ proof - have "x \\<^bsub>G\<^esub> inv\<^bsub>G\<^esub> y \ N" using \N \ G\ group.rcos_self normal.axioms(2) normal_imp_subgroup - subgroup.rcos_module_imp that by fastforce + subgroup.rcos_module_imp that by metis with h have xy: "x \\<^bsub>G\<^esub> inv\<^bsub>G\<^esub> y \ kernel G H h" by blast have "h x \\<^bsub>H\<^esub> inv\<^bsub>H\<^esub>(h y) = h (x \\<^bsub>G\<^esub> inv\<^bsub>G\<^esub> y)" @@ -1221,7 +1241,6 @@ using A G.inv_equality G.inv_inv by blast qed -(* NEW ========================================================================== *) lemma (in group_hom) inj_iff_trivial_ker: shows "inj_on h (carrier G) \ kernel G H h = { \ }" proof @@ -1236,7 +1255,6 @@ using trivial_ker_imp_inj by simp qed -(* NEW ========================================================================== *) lemma (in group_hom) induced_group_hom': assumes "subgroup I G" shows "group_hom (G \ carrier := I \) H h" proof - @@ -1247,13 +1265,11 @@ unfolding group_hom_def group_hom_axioms_def by auto qed -(* NEW ========================================================================== *) lemma (in group_hom) inj_on_subgroup_iff_trivial_ker: assumes "subgroup I G" shows "inj_on h I \ kernel (G \ carrier := I \) H h = { \ }" using group_hom.inj_iff_trivial_ker[OF induced_group_hom'[OF assms]] by simp -(* NEW ========================================================================== *) lemma set_mult_hom: assumes "h \ hom G H" "I \ carrier G" and "J \ carrier G" shows "h ` (I <#>\<^bsub>G\<^esub> J) = (h ` I) <#>\<^bsub>H\<^esub> (h ` J)" @@ -1281,13 +1297,11 @@ qed qed -(* NEW ========================================================================== *) corollary coset_hom: assumes "h \ hom G H" "I \ carrier G" "a \ carrier G" shows "h ` (a <#\<^bsub>G\<^esub> I) = h a <#\<^bsub>H\<^esub> (h ` I)" and "h ` (I #>\<^bsub>G\<^esub> a) = (h ` I) #>\<^bsub>H\<^esub> h a" unfolding l_coset_eq_set_mult r_coset_eq_set_mult using assms set_mult_hom[OF assms(1)] by auto -(* NEW ========================================================================== *) corollary (in group_hom) set_mult_ker_hom: assumes "I \ carrier G" shows "h ` (I <#> (kernel G H h)) = h ` I" and "h ` ((kernel G H h) <#> I) = h ` I" @@ -1305,8 +1319,145 @@ using set_mult_hom[OF homh assms ker_in_carrier] set_mult_hom[OF homh ker_in_carrier assms] by simp+ qed +subsubsection\Trivial homomorphisms\ -subsection \Theorems about Factor Groups and Direct product\ +definition trivial_homomorphism where + "trivial_homomorphism G H f \ f \ hom G H \ (\x \ carrier G. f x = one H)" + +lemma trivial_homomorphism_kernel: + "trivial_homomorphism G H f \ f \ hom G H \ kernel G H f = carrier G" + by (auto simp: trivial_homomorphism_def kernel_def) + +lemma (in group) trivial_homomorphism_image: + "trivial_homomorphism G H f \ f \ hom G H \ f ` carrier G = {one H}" + by (auto simp: trivial_homomorphism_def) (metis one_closed rev_image_eqI) + + +subsection \Image kernel theorems\ + +lemma group_Int_image_ker: + assumes f: "f \ hom G H" and g: "g \ hom H K" and "inj_on (g \ f) (carrier G)" "group G" "group H" "group K" + shows "(f ` carrier G) \ (kernel H K g) = {\\<^bsub>H\<^esub>}" +proof - + have "(f ` carrier G) \ (kernel H K g) \ {\\<^bsub>H\<^esub>}" + using assms + apply (clarsimp simp: kernel_def o_def) + by (metis group.is_monoid hom_one inj_on_eq_iff monoid.one_closed) + moreover have "one H \ f ` carrier G" + by (metis f \group G\ \group H\ group.is_monoid hom_one image_iff monoid.one_closed) + moreover have "one H \ kernel H K g" + apply (simp add: kernel_def) + using g group.is_monoid hom_one \group H\ \group K\ by blast + ultimately show ?thesis + by blast +qed + + +lemma group_sum_image_ker: + assumes f: "f \ hom G H" and g: "g \ hom H K" and eq: "(g \ f) ` (carrier G) = carrier K" + and "group G" "group H" "group K" + shows "set_mult H (f ` carrier G) (kernel H K g) = carrier H" (is "?lhs = ?rhs") +proof + show "?lhs \ ?rhs" + apply (auto simp: kernel_def set_mult_def) + by (meson Group.group_def assms(5) f hom_carrier image_eqI monoid.m_closed subset_iff) + have "\x\carrier G. \z. z \ carrier H \ g z = \\<^bsub>K\<^esub> \ y = f x \\<^bsub>H\<^esub> z" + if y: "y \ carrier H" for y + proof - + have "g y \ carrier K" + using g hom_carrier that by blast + with assms obtain x where x: "x \ carrier G" "(g \ f) x = g y" + by (metis image_iff) + with assms have "inv\<^bsub>H\<^esub> f x \\<^bsub>H\<^esub> y \ carrier H" + by (metis group.subgroup_self hom_carrier image_subset_iff subgroup_def y) + moreover + have "g (inv\<^bsub>H\<^esub> f x \\<^bsub>H\<^esub> y) = \\<^bsub>K\<^esub>" + proof - + have "inv\<^bsub>H\<^esub> f x \ carrier H" + by (meson \group H\ f group.inv_closed hom_carrier image_subset_iff x(1)) + then have "g (inv\<^bsub>H\<^esub> f x \\<^bsub>H\<^esub> y) = g (inv\<^bsub>H\<^esub> f x) \\<^bsub>K\<^esub> g y" + by (simp add: hom_mult [OF g] y) + also have "\ = inv\<^bsub>K\<^esub> (g (f x)) \\<^bsub>K\<^esub> g y" + using assms x(1) + by (metis (mono_tags, lifting) group_hom.hom_inv group_hom.intro group_hom_axioms.intro hom_carrier image_subset_iff) + also have "\ = \\<^bsub>K\<^esub>" + using \g y \ carrier K\ assms(6) group.l_inv x(2) by fastforce + finally show ?thesis . + qed + moreover + have "y = f x \\<^bsub>H\<^esub> (inv\<^bsub>H\<^esub> f x \\<^bsub>H\<^esub> y)" + using x y + by (metis (no_types, hide_lams) assms(5) f group.inv_solve_left group.subgroup_self hom_carrier image_subset_iff subgroup_def that) + ultimately + show ?thesis + using x y by force + qed + then show "?rhs \ ?lhs" + by (auto simp: kernel_def set_mult_def) +qed + + +lemma group_sum_ker_image: + assumes f: "f \ hom G H" and g: "g \ hom H K" and eq: "(g \ f) ` (carrier G) = carrier K" + and "group G" "group H" "group K" + shows "set_mult H (kernel H K g) (f ` carrier G) = carrier H" (is "?lhs = ?rhs") +proof + show "?lhs \ ?rhs" + apply (auto simp: kernel_def set_mult_def) + by (meson Group.group_def \group H\ f hom_carrier image_eqI monoid.m_closed subset_iff) + have "\w\carrier H. \x \ carrier G. g w = \\<^bsub>K\<^esub> \ y = w \\<^bsub>H\<^esub> f x" + if y: "y \ carrier H" for y + proof - + have "g y \ carrier K" + using g hom_carrier that by blast + with assms obtain x where x: "x \ carrier G" "(g \ f) x = g y" + by (metis image_iff) + with assms have carr: "(y \\<^bsub>H\<^esub> inv\<^bsub>H\<^esub> f x) \ carrier H" + by (metis group.subgroup_self hom_carrier image_subset_iff subgroup_def y) + moreover + have "g (y \\<^bsub>H\<^esub> inv\<^bsub>H\<^esub> f x) = \\<^bsub>K\<^esub>" + proof - + have "inv\<^bsub>H\<^esub> f x \ carrier H" + by (meson \group H\ f group.inv_closed hom_carrier image_subset_iff x(1)) + then have "g (y \\<^bsub>H\<^esub> inv\<^bsub>H\<^esub> f x) = g y \\<^bsub>K\<^esub> g (inv\<^bsub>H\<^esub> f x)" + by (simp add: hom_mult [OF g] y) + also have "\ = g y \\<^bsub>K\<^esub> inv\<^bsub>K\<^esub> (g (f x))" + using assms x(1) + by (metis (mono_tags, lifting) group_hom.hom_inv group_hom.intro group_hom_axioms.intro hom_carrier image_subset_iff) + also have "\ = \\<^bsub>K\<^esub>" + using \g y \ carrier K\ assms(6) group.l_inv x(2) + by (simp add: group.r_inv) + finally show ?thesis . + qed + moreover + have "y = (y \\<^bsub>H\<^esub> inv\<^bsub>H\<^esub> f x) \\<^bsub>H\<^esub> f x" + using x y by (meson \group H\ carr f group.inv_solve_right hom_carrier image_subset_iff) + ultimately + show ?thesis + using x y by force + qed + then show "?rhs \ ?lhs" + by (force simp: kernel_def set_mult_def) +qed + +lemma group_semidirect_sum_ker_image: + assumes "(g \ f) \ iso G K" "f \ hom G H" "g \ hom H K" "group G" "group H" "group K" + shows "(kernel H K g) \ (f ` carrier G) = {\\<^bsub>H\<^esub>}" + "kernel H K g <#>\<^bsub>H\<^esub> (f ` carrier G) = carrier H" + using assms + by (simp_all add: iso_iff_mon_epi group_Int_image_ker group_sum_ker_image epi_def mon_def Int_commute [of "kernel H K g"]) + +lemma group_semidirect_sum_image_ker: + assumes f: "f \ hom G H" and g: "g \ hom H K" and iso: "(g \ f) \ iso G K" + and "group G" "group H" "group K" + shows "(f ` carrier G) \ (kernel H K g) = {\\<^bsub>H\<^esub>}" + "f ` carrier G <#>\<^bsub>H\<^esub> (kernel H K g) = carrier H" + using group_Int_image_ker [OF f g] group_sum_image_ker [OF f g] assms + by (simp_all add: iso_def bij_betw_def) + + + +subsection \Factor Groups and Direct product\ lemma (in group) DirProd_normal : \<^marker>\contributor \Martin Baillon\\ assumes "group K" diff -r 3374d16efc61 -r 733e256ecdf3 src/HOL/Algebra/Elementary_Groups.thy --- a/src/HOL/Algebra/Elementary_Groups.thy Wed Apr 03 00:07:26 2019 +0200 +++ b/src/HOL/Algebra/Elementary_Groups.thy Wed Apr 03 12:55:27 2019 +0100 @@ -5,7 +5,7 @@ *) theory Elementary_Groups -imports Generated_Groups +imports Generated_Groups Multiplicative_Group "HOL-Library.Infinite_Set" begin subsection\Direct sum/product lemmas\ @@ -379,4 +379,289 @@ "x \ carrier G \ pow G x \ hom integer_group G" by (rule homI) (auto simp: int_pow_mult) +subsection\Additive group of integers modulo n (n = 0 gives just the integers)\ + +definition integer_mod_group :: "nat \ int monoid" + where + "integer_mod_group n \ + if n = 0 then integer_group + else \carrier = {0..x y. (x+y) mod int n), one = 0\" + +lemma carrier_integer_mod_group: + "carrier(integer_mod_group n) = (if n=0 then UNIV else {0..x y. (x + y) mod int n)" + by (simp add: integer_mod_group_def integer_group_def) + +lemma group_integer_mod_group [simp]: "group (integer_mod_group n)" +proof - + have *: "\y\0. y < int n \ (y + x) mod int n = 0" if "x < int n" "0 \ x" for x + proof (cases "x=0") + case False + with that show ?thesis + by (rule_tac x="int n - x" in exI) auto + qed (use that in auto) + show ?thesis + apply (rule groupI) + apply (auto simp: integer_mod_group_def Bex_def *, presburger+) + done +qed + +lemma inv_integer_mod_group[simp]: + "x \ carrier (integer_mod_group n) \ m_inv(integer_mod_group n) x = (-x) mod int n" + by (rule group.inv_equality [OF group_integer_mod_group]) (auto simp: integer_mod_group_def add.commute mod_add_right_eq) + + +lemma pow_integer_mod_group [simp]: + fixes m::nat + shows "pow (integer_mod_group n) x m = (int m * x) mod int n" +proof (cases "n=0") + case False + show ?thesis + by (induction m) (auto simp: add.commute mod_add_right_eq distrib_left mult.commute) +qed (simp add: integer_mod_group_def) + +lemma int_pow_integer_mod_group: + "pow (integer_mod_group n) x m = (m * x) mod int n" +proof - + have "inv\<^bsub>integer_mod_group n\<^esub> (- (m * x) mod int n) = m * x mod int n" + by (simp add: carrier_integer_mod_group mod_minus_eq) + then show ?thesis + by (simp add: int_pow_def2) +qed + +lemma abelian_integer_mod_group [simp]: "comm_group(integer_mod_group n)" + by (simp add: add.commute group.group_comm_groupI) + +lemma integer_mod_group_0 [simp]: "0 \ carrier(integer_mod_group n)" + by (simp add: integer_mod_group_def) + +lemma integer_mod_group_1 [simp]: "1 \ carrier(integer_mod_group n) \ (n \ 1)" + by (auto simp: integer_mod_group_def) + +lemma trivial_integer_mod_group: "trivial_group(integer_mod_group n) \ n = 1" + (is "?lhs = ?rhs") +proof + assume ?lhs + then show ?rhs + by (simp add: trivial_group_def carrier_integer_mod_group set_eq_iff split: if_split_asm) (presburger+) +next + assume ?rhs + then show ?lhs + by (force simp: trivial_group_def carrier_integer_mod_group) +qed + + +subsection\Cyclic groups\ + +lemma (in group) subgroup_of_powers: + "x \ carrier G \ subgroup (range (\n::int. x [^] n)) G" + apply (auto simp: subgroup_def image_iff simp flip: int_pow_mult int_pow_neg) + apply (metis group.int_pow_diff int_pow_closed is_group r_inv) + done + +lemma (in group) carrier_subgroup_generated_by_singleton: + assumes "x \ carrier G" + shows "carrier(subgroup_generated G {x}) = (range (\n::int. x [^] n))" +proof + show "carrier (subgroup_generated G {x}) \ range (\n::int. x [^] n)" + proof (rule subgroup_generated_minimal) + show "subgroup (range (\n::int. x [^] n)) G" + using assms subgroup_of_powers by blast + show "{x} \ range (\n::int. x [^] n)" + by clarify (metis assms int_pow_1 range_eqI) + qed + have x: "x \ carrier (subgroup_generated G {x})" + using assms subgroup_generated_subset_carrier_subset by auto + show "range (\n::int. x [^] n) \ carrier (subgroup_generated G {x})" + proof clarify + fix n :: "int" + show "x [^] n \ carrier (subgroup_generated G {x})" + by (simp add: x subgroup_int_pow_closed subgroup_subgroup_generated) + qed +qed + + +definition cyclic_group + where "cyclic_group G \ \x \ carrier G. subgroup_generated G {x} = G" + +lemma (in group) cyclic_group: + "cyclic_group G \ (\x \ carrier G. carrier G = range (\n::int. x [^] n))" +proof - + have "\x. \x \ carrier G; carrier G = range (\n::int. x [^] n)\ + \ \x\carrier G. subgroup_generated G {x} = G" + by (rule_tac x=x in bexI) (auto simp: generate_pow subgroup_generated_def intro!: monoid.equality) + then show ?thesis + unfolding cyclic_group_def + using carrier_subgroup_generated_by_singleton by fastforce +qed + +lemma cyclic_integer_group [simp]: "cyclic_group integer_group" +proof - + have *: "int n \ generate integer_group {1}" for n + proof (induction n) + case 0 + then show ?case + using generate.simps by force + next + case (Suc n) + then show ?case + by simp (metis generate.simps insert_subset integer_group_def monoid.simps(1) subsetI) + qed + have **: "i \ generate integer_group {1}" for i + proof (cases i rule: int_cases) + case (nonneg n) + then show ?thesis + by (simp add: *) + next + case (neg n) + then have "-i \ generate integer_group {1}" + by (metis "*" add.inverse_inverse) + then have "- (-i) \ generate integer_group {1}" + by (metis UNIV_I group.generate_m_inv_closed group_integer_group integer_group_def inv_integer_group partial_object.select_convs(1) subsetI) + then show ?thesis + by simp + qed + show ?thesis + unfolding cyclic_group_def + by (rule_tac x=1 in bexI) + (auto simp: carrier_subgroup_generated ** intro: monoid.equality) +qed + +lemma nontrivial_integer_group [simp]: "\ trivial_group integer_group" + using integer_mod_group_def trivial_integer_mod_group by presburger + + +lemma (in group) cyclic_imp_abelian_group: + "cyclic_group G \ comm_group G" + apply (auto simp: cyclic_group comm_group_def is_group intro!: monoid_comm_monoidI) + apply (metis add.commute int_pow_mult rangeI) + done + +lemma trivial_imp_cyclic_group: + "trivial_group G \ cyclic_group G" + by (metis cyclic_group_def group.subgroup_generated_group_carrier insertI1 trivial_group_def) + +lemma (in group) cyclic_group_alt: + "cyclic_group G \ (\x. subgroup_generated G {x} = G)" +proof safe + fix x + assume *: "subgroup_generated G {x} = G" + show "cyclic_group G" + proof (cases "x \ carrier G") + case True + then show ?thesis + using \subgroup_generated G {x} = G\ cyclic_group_def by blast + next + case False + then show ?thesis + by (metis "*" Int_empty_right Int_insert_right_if0 carrier_subgroup_generated generate_empty trivial_group trivial_imp_cyclic_group) + qed +qed (auto simp: cyclic_group_def) + +lemma (in group) cyclic_group_generated: + "cyclic_group (subgroup_generated G {x})" + using group.cyclic_group_alt group_subgroup_generated subgroup_generated2 by blast + +lemma (in group) cyclic_group_epimorphic_image: + assumes "h \ epi G H" "cyclic_group G" "group H" + shows "cyclic_group H" +proof - + interpret h: group_hom + using assms + by (simp add: group_hom_def group_hom_axioms_def is_group epi_def) + obtain x where "x \ carrier G" and x: "carrier G = range (\n::int. x [^] n)" and eq: "carrier H = h ` carrier G" + using assms by (auto simp: cyclic_group epi_def) + have "h ` carrier G = range (\n::int. h x [^]\<^bsub>H\<^esub> n)" + by (metis (no_types, lifting) \x \ carrier G\ h.hom_int_pow image_cong image_image x) + then show ?thesis + using \x \ carrier G\ eq h.cyclic_group by blast +qed + +lemma isomorphic_group_cyclicity: + "\G \ H; group G; group H\ \ cyclic_group G \ cyclic_group H" + by (meson ex_in_conv group.cyclic_group_epimorphic_image group.iso_sym is_iso_def iso_iff_mon_epi) + + +lemma (in group) + assumes "x \ carrier G" + shows finite_cyclic_subgroup: + "finite(carrier(subgroup_generated G {x})) \ (\n::nat. n \ 0 \ x [^] n = \)" (is "?fin \ ?nat1") + and infinite_cyclic_subgroup: + "infinite(carrier(subgroup_generated G {x})) \ (\m n::nat. x [^] m = x [^] n \ m = n)" (is "\ ?fin \ ?nateq") + and finite_cyclic_subgroup_int: + "finite(carrier(subgroup_generated G {x})) \ (\i::int. i \ 0 \ x [^] i = \)" (is "?fin \ ?int1") + and infinite_cyclic_subgroup_int: + "infinite(carrier(subgroup_generated G {x})) \ (\i j::int. x [^] i = x [^] j \ i = j)" (is "\ ?fin \ ?inteq") +proof - + have 1: "\ ?fin" if ?nateq + proof - + have "infinite (range (\n::nat. x [^] n))" + using that range_inj_infinite [of "(\n::nat. x [^] n)"] by (auto simp: inj_on_def) + moreover have "range (\n::nat. x [^] n) \ range (\i::int. x [^] i)" + apply clarify + by (metis assms group.int_pow_neg int_pow_closed int_pow_neg_int is_group local.inv_equality nat_pow_closed r_inv rangeI) + ultimately show ?thesis + using carrier_subgroup_generated_by_singleton [OF assms] finite_subset by auto + qed + have 2: "m = n" if mn: "x [^] m = x [^] n" and eq [rule_format]: "?inteq" for m n::nat + using eq [of "int m" "int n"] + by (simp add: int_pow_int mn) + have 3: ?nat1 if non: "\ ?inteq" + proof - + obtain i j::int where eq: "x [^] i = x [^] j" and "i \ j" + using non by auto + show ?thesis + proof (cases i j rule: linorder_cases) + case less + then have [simp]: "x [^] (j - i) = \" + by (simp add: eq assms int_pow_diff) + show ?thesis + using less by (rule_tac x="nat (j-i)" in exI) auto + next + case greater + then have [simp]: "x [^] (i - j) = \" + by (simp add: eq assms int_pow_diff) + then show ?thesis + using greater by (rule_tac x="nat (i-j)" in exI) auto + qed (use \i \ j\ in auto) + qed + have 4: "\i::int. (i \ 0) \ x [^] i = \" if "n \ 0" "x [^] n = \" for n::nat + apply (rule_tac x="int n" in exI) + by (simp add: int_pow_int that) + have 5: "finite (carrier (subgroup_generated G {x}))" if "i \ 0" and 1: "x [^] i = \" for i::int + proof - + obtain n::nat where n: "n > 0" "x [^] n = \" + using "1" "3" \i \ 0\ by fastforce + have "x [^] a \ ([^]) x ` {0.. {0.. ([^]) x ` {0.. ?nat1" "\ ?fin \ ?nateq" "?fin \ ?int1" "\ ?fin \ ?inteq" + using 1 2 3 4 5 by meson+ +qed + +lemma (in group) finite_cyclic_subgroup_order: + "x \ carrier G \ finite(carrier(subgroup_generated G {x})) \ ord x \ 0" + by (simp add: finite_cyclic_subgroup ord_eq_0) + +lemma (in group) infinite_cyclic_subgroup_order: + "x \ carrier G \ infinite (carrier(subgroup_generated G {x})) \ ord x = 0" + by (simp add: finite_cyclic_subgroup_order) + + end diff -r 3374d16efc61 -r 733e256ecdf3 src/HOL/Algebra/Generated_Groups.thy --- a/src/HOL/Algebra/Generated_Groups.thy Wed Apr 03 00:07:26 2019 +0200 +++ b/src/HOL/Algebra/Generated_Groups.thy Wed Apr 03 12:55:27 2019 +0100 @@ -2,12 +2,14 @@ Author: Paulo Emílio de Vilhena *) +section \Generated Groups\ + theory Generated_Groups imports Group Coset begin -section \Generated Groups\ +subsection \Generated Groups\ inductive_set generate :: "('a, 'b) monoid_scheme \ 'a set \ 'a set" for G and H where @@ -17,7 +19,7 @@ | eng: "h1 \ generate G H \ h2 \ generate G H \ h1 \\<^bsub>G\<^esub> h2 \ generate G H" -subsection \Basic Properties\ +subsubsection \Basic Properties\ lemma (in group) generate_consistent: assumes "K \ H" "subgroup H G" shows "generate (G \ carrier := H \) K = generate G K" @@ -195,9 +197,9 @@ qed -section \Derived Subgroup\ +subsection \Derived Subgroup\ -subsection \Definitions\ +subsubsection \Definitions\ abbreviation derived_set :: "('a, 'b) monoid_scheme \ 'a set \ 'a set" where "derived_set G H \ @@ -207,7 +209,7 @@ "derived G H = generate G (derived_set G H)" -subsection \Basic Properties\ +subsubsection \Basic Properties\ lemma (in group) derived_set_incl: assumes "K \ H" "subgroup H G" shows "derived_set G K \ H" @@ -444,7 +446,7 @@ using derived_img[OF G.exp_of_derived_in_carrier[OF assms]] by (induct n) (auto) -subsection \Generated subgroup of a group\ +subsubsection \Generated subgroup of a group\ definition subgroup_generated :: "('a, 'b) monoid_scheme \ 'a set \ ('a, 'b) monoid_scheme" where "subgroup_generated G S = G\carrier := generate G (carrier G \ S)\" @@ -600,4 +602,114 @@ "kernel G (subgroup_generated H S) f = kernel G H f" by (simp add: kernel_def) +subsection \And homomorphisms\ + +lemma (in group) hom_from_subgroup_generated: + "h \ hom G H \ h \ hom(subgroup_generated G A) H" + apply (simp add: hom_def carrier_subgroup_generated Pi_iff) + apply (metis group.generate_in_carrier inf_le1 is_group) + done + +lemma hom_into_subgroup: + "\h \ hom G G'; h ` (carrier G) \ H\ \ h \ hom G (subgroup_generated G' H)" + by (auto simp: hom_def carrier_subgroup_generated Pi_iff generate.incl image_subset_iff) + +lemma hom_into_subgroup_eq_gen: + "group G \ + h \ hom K (subgroup_generated G H) + \ h \ hom K G \ h ` (carrier K) \ carrier(subgroup_generated G H)" + using group.carrier_subgroup_generated_subset [of G H] by (auto simp: hom_def) + +lemma hom_into_subgroup_eq: + "\subgroup H G; group G\ + \ (h \ hom K (subgroup_generated G H) \ h \ hom K G \ h ` (carrier K) \ H)" + by (simp add: hom_into_subgroup_eq_gen image_subset_iff subgroup.carrier_subgroup_generated_subgroup) + +lemma (in group_hom) hom_between_subgroups: + assumes "h ` A \ B" + shows "h \ hom (subgroup_generated G A) (subgroup_generated H B)" +proof - + have [simp]: "group G" "group H" + by (simp_all add: G.is_group H.is_group) + have "x \ generate G (carrier G \ A) \ h x \ generate H (carrier H \ B)" for x + proof (induction x rule: generate.induct) + case (incl h) + then show ?case + by (meson IntE IntI assms generate.incl hom_closed image_subset_iff) + next + case (inv h) + then show ?case + by (metis G.inv_closed G.inv_inv IntE IntI assms generate.simps hom_inv image_subset_iff local.inv_closed) + next + case (eng h1 h2) + then show ?case + by (metis G.generate_in_carrier generate.simps inf.cobounded1 local.hom_mult) + qed (auto simp: generate.intros) + then have "h ` carrier (subgroup_generated G A) \ carrier (subgroup_generated H B)" + using group.carrier_subgroup_generated_subset [of G A] + by (auto simp: carrier_subgroup_generated) + then show ?thesis + by (simp add: hom_into_subgroup_eq_gen group.hom_from_subgroup_generated homh) +qed + +lemma (in group_hom) subgroup_generated_by_image: + assumes "S \ carrier G" + shows "carrier (subgroup_generated H (h ` S)) = h ` (carrier(subgroup_generated G S))" +proof + have "x \ generate H (carrier H \ h ` S) \ x \ h ` generate G (carrier G \ S)" for x + proof (erule generate.induct) + show "\\<^bsub>H\<^esub> \ h ` generate G (carrier G \ S)" + using generate.one by force + next + fix f + assume "f \ carrier H \ h ` S" + with assms show "f \ h ` generate G (carrier G \ S)" "inv\<^bsub>H\<^esub> f \ h ` generate G (carrier G \ S)" + apply (auto simp: Int_absorb1 generate.incl) + apply (metis generate.simps hom_inv imageI subsetCE) + done + next + fix h1 h2 + assume + "h1 \ generate H (carrier H \ h ` S)" "h1 \ h ` generate G (carrier G \ S)" + "h2 \ generate H (carrier H \ h ` S)" "h2 \ h ` generate G (carrier G \ S)" + then show "h1 \\<^bsub>H\<^esub> h2 \ h ` generate G (carrier G \ S)" + using H.subgroupE(4) group.generate_is_subgroup subgroup_img_is_subgroup + by (simp add: G.generate_is_subgroup) + qed + then + show "carrier (subgroup_generated H (h ` S)) \ h ` carrier (subgroup_generated G S)" + by (auto simp: carrier_subgroup_generated) +next + have "h ` S \ carrier H" + by (metis (no_types) assms hom_closed image_subset_iff subsetCE) + then show "h ` carrier (subgroup_generated G S) \ carrier (subgroup_generated H (h ` S))" + apply (clarsimp simp: carrier_subgroup_generated) + by (metis Int_absorb1 assms generate_img imageI) +qed + +lemma (in group_hom) iso_between_subgroups: + assumes "h \ iso G H" "S \ carrier G" "h ` S = T" + shows "h \ iso (subgroup_generated G S) (subgroup_generated H T)" + using assms + by (metis G.carrier_subgroup_generated_subset Group.iso_iff hom_between_subgroups inj_on_subset subgroup_generated_by_image subsetI) + +lemma (in group) subgroup_generated_group_carrier: + "subgroup_generated G (carrier G) = G" +proof (rule monoid.equality) + show "carrier (subgroup_generated G (carrier G)) = carrier G" + by (simp add: subgroup.carrier_subgroup_generated_subgroup subgroup_self) +qed (auto simp: subgroup_generated_def) + +lemma iso_onto_image: + assumes "group G" "group H" + shows + "f \ iso G (subgroup_generated H (f ` carrier G)) \ f \ hom G H \ inj_on f (carrier G)" + using assms + apply (auto simp: iso_def bij_betw_def hom_into_subgroup_eq_gen carrier_subgroup_generated hom_carrier generate.incl Int_absorb1 Int_absorb2) + by (metis group.generateI group.subgroupE(1) group.subgroup_self group_hom.generate_img group_hom.intro group_hom_axioms.intro) + +lemma (in group) iso_onto_image: + "group H \ f \ iso G (subgroup_generated H (f ` carrier G)) \ f \ mon G H" + by (simp add: mon_def epi_def hom_into_subgroup_eq_gen iso_onto_image) + end \ No newline at end of file diff -r 3374d16efc61 -r 733e256ecdf3 src/HOL/Algebra/Group.thy --- a/src/HOL/Algebra/Group.thy Wed Apr 03 00:07:26 2019 +0200 +++ b/src/HOL/Algebra/Group.thy Wed Apr 03 12:55:27 2019 +0100 @@ -186,7 +186,10 @@ locale group = monoid + assumes Units: "carrier G <= Units G" -lemma (in group) is_group: "group G" by (rule group_axioms) +lemma (in group) is_group [iff]: "group G" by (rule group_axioms) + +lemma (in group) is_monoid [iff]: "monoid G" + by (rule monoid_axioms) theorem groupI: fixes G (structure) @@ -825,6 +828,9 @@ lemma mult_DirProd [simp]: "(g, h) \\<^bsub>(G \\ H)\<^esub> (g', h') = (g \\<^bsub>G\<^esub> g', h \\<^bsub>H\<^esub> h')" by (simp add: DirProd_def) +lemma mult_DirProd': "x \\<^bsub>(G \\ H)\<^esub> y = (fst x \\<^bsub>G\<^esub> fst y, snd x \\<^bsub>H\<^esub> snd y)" + by (subst mult_DirProd [symmetric]) simp + lemma DirProd_assoc: "(G \\ H \\ I) = (G \\ (H \\ I))" by auto @@ -858,7 +864,7 @@ ultimately show "Group.group ((G \\ K)\carrier := H \ I\)" by simp qed -subsection \Homomorphisms and Isomorphisms\ +subsection \Homomorphisms (mono and epi) and Isomorphisms\ definition hom :: "_ => _ => ('a => 'b) set" where @@ -923,6 +929,14 @@ corollary iso_refl [simp]: "G \ G" using iso_set_refl unfolding is_iso_def by auto +lemma iso_iff: + "h \ iso G H \ h \ hom G H \ h ` (carrier G) = carrier H \ inj_on h (carrier G)" + by (auto simp: iso_def hom_def bij_betw_def) + +lemma iso_imp_homomorphism: + "h \ iso G H \ h \ hom G H" + by (simp add: iso_iff) + lemma trivial_hom: "group H \ (\x. one H) \ hom G H" by (auto simp: hom_def Group.group_def) @@ -965,7 +979,6 @@ by (simp add: Group.iso_def bij_betw_inv_into h) qed - corollary (in group) iso_sym: "G \ H \ H \ G" using iso_set_sym unfolding is_iso_def by auto @@ -979,6 +992,50 @@ lemma iso_same_card: "G \ H \ card (carrier G) = card (carrier H)" using bij_betw_same_card unfolding is_iso_def iso_def by auto +lemma iso_finite: "G \ H \ finite(carrier G) \ finite(carrier H)" + by (auto simp: is_iso_def iso_def bij_betw_finite) + +lemma mon_compose: + "\f \ mon G H; g \ mon H K\ \ (g \ f) \ mon G K" + by (auto simp: mon_def intro: hom_compose comp_inj_on inj_on_subset [OF _ hom_carrier]) + +lemma mon_compose_rev: + "\f \ hom G H; g \ hom H K; (g \ f) \ mon G K\ \ f \ mon G H" + using inj_on_imageI2 by (auto simp: mon_def) + +lemma epi_compose: + "\f \ epi G H; g \ epi H K\ \ (g \ f) \ epi G K" + using hom_compose by (force simp: epi_def hom_compose simp flip: image_image) + +lemma epi_compose_rev: + "\f \ hom G H; g \ hom H K; (g \ f) \ epi G K\ \ g \ epi H K" + by (fastforce simp: epi_def hom_def Pi_iff image_def set_eq_iff) + +lemma iso_compose_rev: + "\f \ hom G H; g \ hom H K; (g \ f) \ iso G K\ \ f \ mon G H \ g \ epi H K" + unfolding iso_iff_mon_epi using mon_compose_rev epi_compose_rev by blast + +lemma epi_iso_compose_rev: + assumes "f \ epi G H" "g \ hom H K" "(g \ f) \ iso G K" + shows "f \ iso G H \ g \ iso H K" +proof + show "f \ iso G H" + by (metis (no_types, lifting) assms epi_def iso_compose_rev iso_iff_mon_epi mem_Collect_eq) + then have "f \ hom G H \ bij_betw f (carrier G) (carrier H)" + using Group.iso_def \f \ Group.iso G H\ by blast + then have "bij_betw g (carrier H) (carrier K)" + using Group.iso_def assms(3) bij_betw_comp_iff by blast + then show "g \ iso H K" + using Group.iso_def assms(2) by blast +qed + +lemma mon_left_invertible: + "\f \ hom G H; \x. x \ carrier G \ g(f x) = x\ \ f \ mon G H" + by (simp add: mon_def inj_on_def) metis + +lemma epi_right_invertible: + "\g \ hom H G; f \ carrier G \ carrier H; \x. x \ carrier G \ g(f x) = x\ \ g \ epi H G" + by (force simp: Pi_iff epi_iff_subset image_subset_iff_funcset subset_iff) lemma (in monoid) hom_imp_img_monoid: \<^marker>\contributor \Paulo Emílio de Vilhena\\ assumes "h \ hom G H" @@ -1109,6 +1166,43 @@ ultimately show ?thesis by simp qed +subsubsection \HOL Light's concept of an isomorphism pair\ + +definition group_isomorphisms + where + "group_isomorphisms G H f g \ + f \ hom G H \ g \ hom H G \ + (\x \ carrier G. g(f x) = x) \ + (\y \ carrier H. f(g y) = y)" + +lemma group_isomorphisms_sym: "group_isomorphisms G H f g \ group_isomorphisms H G g f" + by (auto simp: group_isomorphisms_def) + +lemma group_isomorphisms_imp_iso: "group_isomorphisms G H f g \ f \ iso G H" +by (auto simp: iso_def inj_on_def image_def group_isomorphisms_def hom_def bij_betw_def Pi_iff, metis+) + +lemma (in group) iso_iff_group_isomorphisms: + "f \ iso G H \ (\g. group_isomorphisms G H f g)" +proof safe + show "\g. group_isomorphisms G H f g" if "f \ Group.iso G H" + unfolding group_isomorphisms_def + proof (intro exI conjI) + let ?g = "inv_into (carrier G) f" + show "\x\carrier G. ?g (f x) = x" + by (metis (no_types, lifting) Group.iso_def bij_betw_inv_into_left mem_Collect_eq that) + show "\y\carrier H. f (?g y) = y" + by (metis (no_types, lifting) Group.iso_def bij_betw_inv_into_right mem_Collect_eq that) + qed (use Group.iso_def iso_set_sym that in \blast+\) +next + fix g + assume "group_isomorphisms G H f g" + then show "f \ Group.iso G H" + by (auto simp: iso_def group_isomorphisms_def hom_in_carrier intro: bij_betw_byWitness) +qed + + +subsubsection \Involving direct products\ + lemma DirProd_commute_iso_set: shows "(\(x,y). (y,x)) \ iso (G \\ H) (H \\ G)" by (auto simp add: iso_def hom_def inj_on_def bij_betw_def) @@ -1141,6 +1235,53 @@ shows "G \\ H \ G2 \\ I" using DirProd_iso_set_trans assms unfolding is_iso_def by blast +lemma hom_pairwise: "f \ hom G (DirProd H K) \ (fst \ f) \ hom G H \ (snd \ f) \ hom G K" + apply (auto simp: hom_def mult_DirProd' dest: Pi_mem) + apply (metis Product_Type.mem_Times_iff comp_eq_dest_lhs funcset_mem) + by (metis mult_DirProd prod.collapse) + +lemma hom_paired: + "(\x. (f x,g x)) \ hom G (DirProd H K) \ f \ hom G H \ g \ hom G K" + by (simp add: hom_pairwise o_def) + +lemma hom_paired2: + assumes "group G" "group H" + shows "(\(x,y). (f x,g y)) \ hom (DirProd G H) (DirProd G' H') \ f \ hom G G' \ g \ hom H H'" + using assms + by (fastforce simp: hom_def Pi_def dest!: group.is_monoid) + +lemma image_paired_Times: + "(\(x,y). (f x,g y)) ` (A \ B) = (f ` A) \ (g ` B)" + by auto + +lemma iso_paired2: + assumes "group G" "group H" + shows "(\(x,y). (f x,g y)) \ iso (DirProd G H) (DirProd G' H') \ f \ iso G G' \ g \ iso H H'" + using assms + by (fastforce simp add: iso_def inj_on_def bij_betw_def hom_paired2 image_paired_Times + times_eq_iff group_def monoid.carrier_not_empty) + +lemma hom_of_fst: + assumes "group H" + shows "(f \ fst) \ hom (DirProd G H) K \ f \ hom G K" +proof - + interpret group H + by (rule assms) + show ?thesis + using one_closed by (auto simp: hom_def Pi_def) +qed + +lemma hom_of_snd: + assumes "group G" + shows "(f \ snd) \ hom (DirProd G H) K \ f \ hom H K" +proof - + interpret group G + by (rule assms) + show ?thesis + using one_closed by (auto simp: hom_def Pi_def) +qed + + subsection\The locale for a homomorphism between two groups\ text\Basis for homomorphism proofs: we assume two groups \<^term>\G\ and @@ -1172,7 +1313,8 @@ proof - have "h \ \\<^bsub>H\<^esub> \\<^bsub>H\<^esub> = h \ \\<^bsub>H\<^esub> h \" by (simp add: hom_mult [symmetric] del: hom_mult) - then show ?thesis by (simp del: r_one) + then show ?thesis + by (metis H.Units_eq H.Units_l_cancel H.one_closed local.one_closed) qed lemma hom_one: @@ -1383,6 +1525,11 @@ finally show "x \\<^bsub>(?h_img)\<^esub> y = y \\<^bsub>(?h_img)\<^esub> x" . qed +lemma (in comm_group) hom_group_mult: + assumes "f \ hom H G" "g \ hom H G" + shows "(\x. f x \\<^bsub>G\<^esub> g x) \ hom H G" + using assms by (auto simp: hom_def Pi_def m_ac) + lemma (in comm_group) hom_imp_img_comm_group: \<^marker>\contributor \Paulo Emílio de Vilhena\\ assumes "h \ hom G H" shows "comm_group (H \ carrier := h ` (carrier G), one := h \\<^bsub>G\<^esub> \)" @@ -1465,10 +1612,6 @@ "subgroup H G ==> group (G\carrier := H\)" by (erule subgroup.subgroup_is_group) (rule group_axioms) -lemma (in group) is_monoid [intro, simp]: - "monoid G" - by (auto intro: monoid.intro m_assoc) - lemma (in group) subgroup_mult_equality: "\ subgroup H G; h1 \ H; h2 \ H \ \ h1 \\<^bsub>G \ carrier := H \\<^esub> h2 = h1 \ h2" unfolding subgroup_def by simp