Theory Zassenhaus_Lemma
theory Zassenhaus_Lemma
imports Group_Theory
begin
section ‹The Zassenhaus Lemma›
text ‹
Suppose that @{term H1} is normal in @{term H}, and @{term K1} is normal in
@{term K}. The two wings of the butterfly are obtained by multiplying each
normal subgroup by @{term "H ∩ K"}; their denominators use the smaller
intersections @{term "H ∩ K1"} and @{term "K ∩ H1"}.
A locale records this symmetric configuration once. In particular, no
ambient record updates or HOL-Algebra structures occur in the statement.
›
locale zassenhaus =
G: Group G "(⋅)" 𝟭 +
H: subgroup_of_group H G "(⋅)" 𝟭 +
K: subgroup_of_group K G "(⋅)" 𝟭 +
H1: normal_subgroup H1 H "(⋅)" 𝟭 +
K1: normal_subgroup K1 K "(⋅)" 𝟭
for G H K H1 K1 and composition (infixl ‹⋅› 70) and unit (‹𝟭›)
begin
interpretation HK_sub: Subgroup "H ∩ K" G "(⋅)" 𝟭
by (simp add: G.subgroup_intersection H.Subgroup_axioms K.Subgroup_axioms)
interpretation HK1_subG: Subgroup "H ∩ K1" G "(⋅)" 𝟭
using G.subgroup_intersection H.Subgroup_axioms K.Subgroup_axioms K1.Subgroup_axioms
by (meson subgroup_transitive)
interpretation HK1_sub: Subgroup "H ∩ K1" H "(⋅)" 𝟭
using H.Subgroup_axioms HK1_subG.Subgroup_axioms subgroup_restrict by fastforce
interpretation KH1_sub: Subgroup "K ∩ H1" K "(⋅)" 𝟭
proof -
have "Subgroup (K ∩ H1) G (⋅) 𝟭"
using G.subgroup_intersection H.Subgroup_axioms H1.Subgroup_axioms K.Subgroup_axioms
by (meson subgroup_transitive)
then show "Subgroup (K ∩ H1) K (⋅) 𝟭"
using K.Subgroup_axioms subgroup_restrict by force
qed
interpretation HK1_normal: normal_subgroup "H ∩ K1" "H ∩ K" "(⋅)" 𝟭
proof -
have I_sub: "Subgroup (H ∩ K) K (⋅) 𝟭"
using HK_sub.Subgroup_axioms K.Subgroup_axioms subgroup_restrict by fastforce
have "Subgroup ((H ∩ K) ∩ K1) K (⋅) 𝟭"
by (rule K.sub.subgroup_intersection[OF I_sub K1.Subgroup_axioms])
then have C_K: "Subgroup (H ∩ K1) K (⋅) 𝟭"
using K1.subset by (smt (cvc5, best) dual_order.refl inf.bounded_iff subset_antisym)
have C_sub: "Subgroup (H ∩ K1) (H ∩ K) (⋅) 𝟭"
using C_K I_sub subgroup_restrict by fastforce
interpret C: Subgroup "H ∩ K1" "H ∩ K" "(⋅)" 𝟭 by fact
interpret I: Subgroup "H ∩ K" K "(⋅)" 𝟭 by fact
have I_H_sub: "Subgroup (H ∩ K) H (⋅) 𝟭"
using H.Subgroup_axioms HK_sub.Subgroup_axioms by (meson inf_sup_ord(1) subgroup_restrict)
interpret I_H: Subgroup "H ∩ K" H "(⋅)" 𝟭 by fact
show "normal_subgroup (H ∩ K1) (H ∩ K) (⋅) 𝟭"
proof
fix g c
assume g: "g ∈ H ∩ K" and c: "c ∈ H ∩ K1"
obtain inv_K: "Monoid.inverse (H ∩ K) (⋅) 𝟭 g = K.sub.inverse g"
and inv_H: "Monoid.inverse (H ∩ K) (⋅) 𝟭 g = H.sub.inverse g"
using I_H_sub I_sub g by (metis Subgroup.subgroup_inverse_equality)
have g_H: "g ∈ H" and c_H: "c ∈ H" and g_K: "g ∈ K" and c_K1: "c ∈ K1"
using g c by blast+
have in_H: "H.sub.inverse g ⋅ c ⋅ g ∈ H"
using Monoid.invertible_inverse_closed c_H g_H by blast
have in_K1: "K.sub.inverse g ⋅ c ⋅ g ∈ K1"
by (rule K1.normal[OF g_K c_K1])
show "Monoid.inverse (H ∩ K) (⋅) 𝟭 g ⋅ c ⋅ g ∈ H ∩ K1"
using in_H in_K1 inv_H inv_K by (metis IntI)
qed
qed
interpretation KH1_normal: normal_subgroup "K ∩ H1" "H ∩ K" "(⋅)" 𝟭
proof -
have I_sub: "Subgroup (H ∩ K) H (⋅) 𝟭"
using H.Subgroup_axioms HK_sub.Subgroup_axioms subgroup_restrict by force
have "Subgroup ((H ∩ K) ∩ H1) H (⋅) 𝟭"
by (simp add: H.sub.subgroup_intersection H1.Subgroup_axioms I_sub)
then have C_H: "Subgroup (K ∩ H1) H (⋅) 𝟭"
using H1.subset by (smt (cvc5, best) dual_order.refl inf.bounded_iff subset_antisym)
have C_sub: "Subgroup (K ∩ H1) (H ∩ K) (⋅) 𝟭"
using C_H I_sub subgroup_restrict by fastforce
interpret C: Subgroup "K ∩ H1" "H ∩ K" "(⋅)" 𝟭 by fact
interpret I: Subgroup "H ∩ K" H "(⋅)" 𝟭 by fact
have I_K_sub: "Subgroup (H ∩ K) K (⋅) 𝟭"
using HK_sub.Subgroup_axioms K.Subgroup_axioms subgroup_restrict by fastforce
interpret I_K: Subgroup "H ∩ K" K "(⋅)" 𝟭 by fact
show "normal_subgroup (K ∩ H1) (H ∩ K) (⋅) 𝟭"
proof
fix g c
assume g: "g ∈ H ∩ K" and c: "c ∈ K ∩ H1"
have inv_H: "Monoid.inverse (H ∩ K) (⋅) 𝟭 g = H.sub.inverse g"
using I.subgroup_inverse_equality g by presburger
have inv_K: "Monoid.inverse (H ∩ K) (⋅) 𝟭 g = K.sub.inverse g"
using I_K.subgroup_inverse_equality g by presburger
have g_K: "g ∈ K" and c_K: "c ∈ K" and g_H: "g ∈ H" and c_H1: "c ∈ H1" and in_K: "K.sub.inverse g ⋅ c ⋅ g ∈ K"
using g c by blast+
have in_H1: "H.sub.inverse g ⋅ c ⋅ g ∈ H1"
by (rule H1.normal[OF g_H c_H1])
show "Monoid.inverse (H ∩ K) (⋅) 𝟭 g ⋅ c ⋅ g ∈ K ∩ H1"
using in_H1 in_K inv_H inv_K by (metis IntI)
qed
qed
interpretation middle_H: Subgroup "H ∩ K" H "(⋅)" 𝟭
using H.Subgroup_axioms HK_sub.Subgroup_axioms subgroup_restrict by force
interpretation middle_K: Subgroup "H ∩ K" K "(⋅)" 𝟭
using HK_sub.Subgroup_axioms K.Subgroup_axioms subgroup_restrict by force
interpretation middle_H_group: subgroup_of_group "H ∩ K" H "(⋅)" 𝟭
by (simp add: H.sub.Group_axioms middle_H.Subgroup_axioms subgroup_of_group_def)
interpretation middle_K_group: subgroup_of_group "H ∩ K" K "(⋅)" 𝟭
by (simp add: K.sub.Group_axioms middle_K.Subgroup_axioms subgroup_of_group_def)
interpretation HK1_group: subgroup_of_group "H ∩ K1" H "(⋅)" 𝟭
by (simp add: H.sub.Group_axioms HK1_sub.Subgroup_axioms subgroup_of_groupI)
interpretation KH1_group: subgroup_of_group "K ∩ H1" K "(⋅)" 𝟭
by (simp add: K.sub.Group_axioms KH1_sub.Subgroup_axioms subgroup_of_group_def)
text ‹The four subgroup products making up the two wings.›
definition left_top where
"left_top ≡ (case_prod (⋅)) ` ((H ∩ K) × H1)"
definition left_bottom where
"left_bottom ≡ (case_prod (⋅)) ` ((H ∩ K1) × H1)"
definition right_top where
"right_top ≡ (case_prod (⋅)) ` ((H ∩ K) × K1)"
definition right_bottom where
"right_bottom ≡ (case_prod (⋅)) ` ((K ∩ H1) × K1)"
interpretation left_top_product: normal_subgroup_product H1 "H ∩ K" H "(⋅)" 𝟭 ..
interpretation left_bottom_product: normal_subgroup_product H1 "H ∩ K1" H "(⋅)" 𝟭 ..
interpretation right_top_product: normal_subgroup_product K1 "H ∩ K" K "(⋅)" 𝟭 ..
interpretation right_bottom_product: normal_subgroup_product K1 "K ∩ H1" K "(⋅)" 𝟭 ..
lemma left_top_eq [simp]: "left_top = left_top_product.HK"
by (simp add: left_top_def left_top_product.HK_def)
lemma left_bottom_eq [simp]: "left_bottom = left_bottom_product.HK"
by (simp add: left_bottom_def left_bottom_product.HK_def)
lemma right_top_eq [simp]: "right_top = right_top_product.HK"
by (simp add: right_top_def right_top_product.HK_def)
lemma right_bottom_eq [simp]: "right_bottom = right_bottom_product.HK"
by (simp add: right_bottom_def right_bottom_product.HK_def)
lemma left_top_subgroup: "Subgroup left_top H (⋅) 𝟭"
by (simp add: left_top_product.HK_subgroup)
lemma left_bottom_subgroup: "Subgroup left_bottom H (⋅) 𝟭"
by (simp add: left_bottom_product.HK_subgroup)
lemma right_top_subgroup: "Subgroup right_top K (⋅) 𝟭"
by (simp add: right_top_product.HK_subgroup)
lemma right_bottom_subgroup: "Subgroup right_bottom K (⋅) 𝟭"
by (simp add: right_bottom_product.HK_subgroup)
lemma left_bottom_subset_top: "left_bottom ⊆ left_top"
unfolding left_bottom_def left_top_def
by blast
lemma right_bottom_subset_top: "right_bottom ⊆ right_top"
unfolding right_bottom_def right_top_def
by blast
lemma left_top_memE:
assumes "x ∈ left_top"
obtains b n where "b ∈ H ∩ K" "n ∈ H1" "x = b ⋅ n"
using assms left_top_eq left_top_product.HK_memE by metis
lemma left_bottom_memI:
"⟦c ∈ H ∩ K1; n ∈ H1⟧ ⟹ c ⋅ n ∈ left_bottom"
unfolding left_bottom_eq by (rule left_bottom_product.HK_memI)
lemma left_bottom_memE:
assumes "x ∈ left_bottom"
obtains c n where "c ∈ H ∩ K1" "n ∈ H1" "x = c ⋅ n"
using assms left_bottom_eq left_bottom_product.HK_memE by blast
text ‹The lower subgroup in the left wing is normal in the upper one.›
lemma left_bottom_normal: "normal_subgroup left_bottom left_top (⋅) 𝟭"
proof -
have bottom_top: "Subgroup left_bottom left_top (⋅) 𝟭"
by (rule subgroup_restrict[OF left_bottom_subgroup left_top_subgroup left_bottom_subset_top])
interpret bottom: Subgroup left_bottom left_top "(⋅)" 𝟭 by fact
interpret top_H: Subgroup left_top H "(⋅)" 𝟭 by (rule left_top_subgroup)
show ?thesis
proof
fix x y
assume x: "x ∈ left_top" and y: "y ∈ left_bottom"
obtain b n where b_middle: "b ∈ H ∩ K" and n: "n ∈ H1" and x_eq: "x = b ⋅ n"
using x by (rule left_top_memE)
obtain c m where c: "c ∈ H ∩ K1" and m: "m ∈ H1" and y_eq: "y = c ⋅ m"
using y by (rule left_bottom_memE)
have bH: "b ∈ H" and cH: "c ∈ H" and nH: "n ∈ H" and mH: "m ∈ H"
using b_middle c n m H1.sub by blast+
have inv_middle: "H.sub.inverse b = Monoid.inverse (H ∩ K) (⋅) 𝟭 b"
using b_middle middle_H.subgroup_inverse_equality by blast
have conjugate_c: "H.sub.inverse b ⋅ c ⋅ b ∈ H ∩ K1"
using HK1_normal.normal b_middle c inv_middle by presburger
have conjugate_y: "H.sub.inverse b ⋅ y ⋅ b ∈ left_bottom"
using H1.normal[OF bH m] H.sub.conjugate_composition H.sub.invertible bH cH conjugate_c
left_bottom_memI mH y_eq by presburger
have inv_n: "H.sub.inverse n ∈ H1"
by (rule H1.submonoid_inverse_closed[OF H1.sub.invertible[OF n] n])
have inv_n_bottom: "H.sub.inverse n ∈ left_bottom"
using inv_n left_bottom_eq left_bottom_product.K_subset_HK by blast
have n_bottom: "n ∈ left_bottom"
using left_bottom_product.K_subset_HK n by auto
have inv_x: "H.sub.inverse x = H.sub.inverse n ⋅ H.sub.inverse b"
unfolding x_eq using H.sub.inverse_composition_commute bH nH by blast
obtain inv_b_H: "H.sub.inverse b ∈ H" and inv_n_H: "H.sub.inverse n ∈ H"
using H.sub.invertible_inverse_closed H1.sub bH inv_n by blast
have y_top: "y ∈ left_top" using bottom.subset y by blast
have yH: "y ∈ H" using top_H.subset y_top by blast
have conjugate_expansion: "H.sub.inverse x ⋅ y ⋅ x = H.sub.inverse n ⋅ (H.sub.inverse b ⋅ y ⋅ b) ⋅ n"
using H.sub.associative H.sub_composition_closed bH inv_b_H inv_n_H inv_x nH x_eq yH
by metis
then have "H.sub.inverse x ⋅ y ⋅ x ∈ left_bottom"
using bottom.sub_composition_closed conjugate_y inv_n_bottom n_bottom by presburger
then show "Monoid.inverse left_top (⋅) 𝟭 x ⋅ y ⋅ x ∈ left_bottom"
using top_H.subgroup_inverse_equality x by metis
qed
qed
text ‹
The following two identities are the algebraic centre of the butterfly. An
element of the middle intersection that is written as a product in one wing
forces its normal-subgroup factor into the opposite subgroup.
›
lemma middle_inter_left_bottom:
"(H ∩ K) ∩ left_bottom =
(case_prod (⋅)) ` ((H ∩ K1) × (K ∩ H1))"
proof (intro equalityI subsetI)
fix x
assume x: "x ∈ (H ∩ K) ∩ left_bottom"
then obtain p where p_in: "p ∈ (H ∩ K1) × H1" and p_eq: "x = case_prod (⋅) p"
unfolding left_bottom_def by blast
obtain c h where p: "p = (c,h)" by (cases p)
have c: "c ∈ H ∩ K1" and h: "h ∈ H1"
using p_in unfolding p by blast+
have x_eq: "x = c ⋅ h" using p_eq by (simp only: p prod.case)
have cK: "c ∈ K" using c K1.sub by blast
have xK: "x ∈ K" using x by blast
have cG: "c ∈ G" and hG: "h ∈ G"
using c h H.sub H1.sub by blast+
then have "G.inverse c ⋅ x = h"
using G.invertible_left_inverse2 x_eq by blast
moreover have inv_c_x_K: "G.inverse c ⋅ x ∈ K"
using cK xK by blast
ultimately have hK: "h ∈ K" by meson
show "x ∈ (case_prod (⋅)) ` ((H ∩ K1) × (K ∩ H1))"
using c h hK x_eq by blast
next
fix x
assume "x ∈ (case_prod (⋅)) ` ((H ∩ K1) × (K ∩ H1))"
then obtain p c h where p_in: "p ∈ (H ∩ K1) × (K ∩ H1)"
and p_eq: "x = case_prod (⋅) p" and p: "p = (c,h)" by blast
have c: "c ∈ H ∩ K1" and h: "h ∈ K ∩ H1"
using p_in unfolding p by blast+
have x_eq: "x = c ⋅ h" using p_eq by (simp only: p prod.case)
have "x ∈ H ∩ K"
unfolding x_eq using c h by blast
moreover have "x ∈ left_bottom"
unfolding left_bottom_def using c h x_eq by blast
ultimately show "x ∈ (H ∩ K) ∩ left_bottom" by blast
qed
interpretation symmetric: zassenhaus G K H K1 H1 "(⋅)" 𝟭 ..
lemma middle_inter_right_bottom:
"(H ∩ K) ∩ right_bottom = (case_prod (⋅)) ` ((K ∩ H1) × (H ∩ K1))"
using right_bottom_def symmetric.left_bottom_def symmetric.middle_inter_left_bottom
by (metis Int_commute)
text ‹The normality argument for the right wing is exactly the symmetric instance.›
lemma right_bottom_normal: "normal_subgroup right_bottom right_top (⋅) 𝟭"
using right_bottom_eq right_top_eq symmetric.left_bottom_eq symmetric.left_bottom_normal
symmetric.left_top_eq by (metis inf.commute)
subsection ‹The quotient isomorphism›
interpretation left_quotient: normal_subgroup left_bottom left_top "(⋅)" 𝟭
by (rule left_bottom_normal)
interpretation right_quotient: normal_subgroup right_bottom right_top "(⋅)" 𝟭
by (rule right_bottom_normal)
lemma middle_subset_left_top: "H ∩ K ⊆ left_top"
using left_top_product.H_subset_HK unfolding left_top_eq .
lemma middle_subset_right_top: "H ∩ K ⊆ right_top"
using right_top_product.H_subset_HK unfolding right_top_eq .
lemma middle_left_top_subgroup: "Subgroup (H ∩ K) left_top (⋅) 𝟭"
by (rule subgroup_restrict[OF middle_H.Subgroup_axioms left_top_subgroup middle_subset_left_top])
lemma middle_right_top_subgroup: "Subgroup (H ∩ K) right_top (⋅) 𝟭"
by (rule subgroup_restrict[OF middle_K.Subgroup_axioms right_top_subgroup middle_subset_right_top])
interpretation middle_left_top: subgroup_of_group "H ∩ K" left_top "(⋅)" 𝟭
by (rule subgroup_of_groupI[OF middle_left_top_subgroup left_quotient.Group_axioms])
interpretation middle_right_top: subgroup_of_group "H ∩ K" right_top "(⋅)" 𝟭
by (rule subgroup_of_groupI[OF middle_right_top_subgroup right_quotient.Group_axioms])
interpretation left_second:
second_iso_theorem left_bottom "H ∩ K" left_top "(⋅)" 𝟭 ..
interpretation right_second:
second_iso_theorem right_bottom "H ∩ K" right_top "(⋅)" 𝟭 ..
lemma left_second_product: "left_second.HK = left_top"
proof (intro equalityI subsetI)
fix x
assume "x ∈ left_second.HK"
then obtain h k where h: "h ∈ H ∩ K" and k: "k ∈ left_bottom"
and x_eq: "x = h ⋅ k" by (rule left_second.HK_memE)
show "x ∈ left_top"
unfolding x_eq using h k by blast
next
fix x
assume x: "x ∈ left_top"
then obtain h n where h: "h ∈ H ∩ K" and n: "n ∈ H1" and x_eq: "x = h ⋅ n"
by (rule left_top_memE)
have unit_inter: "𝟭 ∈ H ∩ K1"
using H.sub_unit_closed K1.sub_unit_closed by blast
then have "n ∈ left_bottom"
using H1.sub.left_unit left_bottom_memI n by metis
then show "x ∈ left_second.HK"
using h left_second.HK_memI x_eq by blast
qed
lemma right_second_product: "right_second.HK = right_top"
proof (intro equalityI subsetI)
fix x
assume "x ∈ right_second.HK"
then obtain h k where h: "h ∈ H ∩ K" and k: "k ∈ right_bottom"
and x_eq: "x = h ⋅ k" by (rule right_second.HK_memE)
show "x ∈ right_top"
unfolding x_eq using h k by blast
next
fix x
assume x: "x ∈ right_top"
then obtain h n where h': "h ∈ K ∩ H" and n: "n ∈ K1" and x_eq: "x = h ⋅ n"
using right_top_eq right_top_product.HK_memE by (metis Int_commute)
have unit_inter: "𝟭 ∈ K ∩ H1"
using K.sub_unit_closed H1.sub_unit_closed by blast
then have "n ∈ right_bottom"
using K1.sub.left_unit n right_bottom_eq right_bottom_product.HK_memI by metis
then show "x ∈ right_second.HK" unfolding x_eq
using h' right_second.HK_memI by blast
qed
lemma left_second_factor_group:
"left_second.Fract_HK_K = left_quotient.Factor_Group"
using left_quotient.Partition_def left_second.Fract_HK_K_def left_second_product by argo
lemma right_second_factor_group:
"right_second.Fract_HK_K = right_quotient.Factor_Group"
using right_quotient.Partition_def right_second.Fract_HK_K_def right_second_product by argo
lemma common_denominator:
"(H ∩ K) ∩ left_bottom = (H ∩ K) ∩ right_bottom"
unfolding middle_inter_left_bottom middle_inter_right_bottom
using HK1_normal.subset KH1_normal.set_prod_commute by metis
interpretation left_common:
normal_subgroup "(H ∩ K) ∩ left_bottom" "H ∩ K" "(⋅)" 𝟭
using left_bottom_normal left_quotient.normal_subgroup_intersection middle_left_top_subgroup
by blast
interpretation right_common:
normal_subgroup "(H ∩ K) ∩ right_bottom" "H ∩ K" "(⋅)" 𝟭
using common_denominator left_common.normal_subgroup_axioms by force
lemma left_wing_isomorphism:
"(left_quotient.Factor_Group, left_quotient.quotient_composition,
left_quotient.Class 𝟭) ≅⇩G
(left_second.Fract_H_HIntK, left_common.quotient_composition,
left_common.Class 𝟭)"
using left_second.second_isomorphism
unfolding left_second_factor_group .
lemma right_wing_isomorphism:
"(right_quotient.Factor_Group, right_quotient.quotient_composition,
right_quotient.Class 𝟭) ≅⇩G
(right_second.Fract_H_HIntK, right_common.quotient_composition,
right_common.Class 𝟭)"
using right_second.second_isomorphism
unfolding right_second_factor_group .
lemma common_factor_group:
"(left_second.Fract_H_HIntK, left_common.quotient_composition,
left_common.Class 𝟭) =
(right_second.Fract_H_HIntK, right_common.quotient_composition,
right_common.Class 𝟭)"
using common_denominator left_second.Fract_H_HIntK_def right_second.Fract_H_HIntK_def
by presburger
text ‹
The Zassenhaus lemma: the quotients represented by the two wings of the
butterfly are isomorphic. The quotient operations and units are displayed
explicitly, as is customary in New-Algebra's set-based API.
›
theorem butterfly_lemma:
"(left_quotient.Factor_Group, left_quotient.quotient_composition,
left_quotient.Class 𝟭) ≅⇩G
(right_quotient.Factor_Group, right_quotient.quotient_composition,
right_quotient.Class 𝟭)"
using common_factor_group left_wing_isomorphism right_wing_isomorphism
by (metis isomorphic_as_groups_symmetric isomorphic_as_groups_transitive)
end
end