-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
-
81
-
82
-
83
-
84
-
85
-
86
-
87
-
88
-
89
-
90
-
91
-
92
-
93
-
94
-
95
-
96
-
97
-
98
-
99
-
100
-
101
-
102
-
103
-
104
-
105
-
106
-
107
-
108
-
109
-
110
-
111
-
112
-
113
-
114
-
115
-
116
-
117
-
118
-
119
-
120
-
121
-
122
-
123
-
124
-
125
-
126
-
127
-
128
-
129
-
130
-
131
-
132
-
133
-
134
-
135
-
136
-
137
-
138
-
139
-
140
-
141
-
142
-
143
-
144
-
145
-
146
-
147
-
148
-
149
-
150
-
151
-
152
-
153
-
154
-
155
-
156
-
157
-
158
-
159
-
160
-
161
-
162
-
163
-
164
-
165
-
166
import Mathlib.GroupTheory.Sylow
import Mathlib.GroupTheory.Perm.Cycle.Concrete
import Mathlib.GroupTheory.Perm.Subgroup
import Mathlib.GroupTheory.PresentedGroup
import MIL.Common
def conjugate {G : Type*} [Group G] (x : G) (H : Subgroup G) : Subgroup G where
carrier := {a : G | ∃ h, h ∈ H ∧ a = x * h * x⁻¹}
one_mem' := by
dsimp
use 1
constructor
exact H.one_mem
group
inv_mem' := by
dsimp
rintro - ⟨h, h_in, rfl⟩
use h⁻¹, H.inv_mem h_in
group
mul_mem' := by
dsimp
rintro - - ⟨h, h_in, rfl⟩ ⟨k, k_in, rfl⟩
use h*k, H.mul_mem h_in k_in
group
section exercises
variable {G H : Type*} [Group G] [Group H]
open Subgroup
example (φ : G →* H) (S T : Subgroup H) (hST : S ≤ T) : comap φ S ≤ comap φ T := by
intro x hx
rw [mem_comap] at * -- Lean does not need this line
exact hST hx
example (φ : G →* H) (S T : Subgroup G) (hST : S ≤ T) : map φ S ≤ map φ T := by
intro x hx
rw [mem_map] at * -- Lean does not need this line
rcases hx with ⟨y, hy, rfl⟩
use y, hST hy
variable {K : Type*} [Group K]
-- Remember you can use the `ext` tactic to prove an equality of subgroups.
example (φ : G →* H) (ψ : H →* K) (U : Subgroup K) :
comap (ψ.comp φ) U = comap φ (comap ψ U) := by
-- The whole proof could be ``rfl``, but let's decompose it a bit.
ext x
simp only [mem_comap]
rfl
-- Pushing a subgroup along one homomorphism and then another is equal to
-- pushing it forward along the composite of the homomorphisms.
example (φ : G →* H) (ψ : H →* K) (S : Subgroup G) :
map (ψ.comp φ) S = map ψ (S.map φ) := by
ext x
simp only [mem_map]
constructor
· rintro ⟨y, y_in, hy⟩
exact ⟨φ y, ⟨y, y_in, rfl⟩, hy⟩
· rintro ⟨y, ⟨z, z_in, hz⟩, hy⟩
use z, z_in
calc ψ.comp φ z = ψ (φ z) := rfl
_ = ψ y := by congr
_ = x := hy
end exercises
open scoped Classical
open Fintype
open Subgroup
lemma eq_bot_iff_card {G : Type*} [Group G] {H : Subgroup G} [Fintype H] :
H = ⊥ ↔ card H = 1 := by
suffices (∀ x ∈ H, x = 1) ↔ ∃ x ∈ H, ∀ a ∈ H, a = x by
simpa [eq_bot_iff_forall, card_eq_one_iff]
constructor
· intro h
use 1, H.one_mem
· rintro ⟨y, -, hy'⟩ x hx
calc x = y := hy' x hx
_ = 1 := (hy' 1 H.one_mem).symm
lemma inf_bot_of_coprime {G : Type*} [Group G] (H K : Subgroup G) [Fintype H] [Fintype K]
(h : (card H).Coprime (card K)) : H ⊓ K = ⊥ := by
have D₁ : card (H ⊓ K : Subgroup G) ∣ card H := card_dvd_of_le inf_le_left
have D₂ : card (H ⊓ K : Subgroup G) ∣ card K := card_dvd_of_le inf_le_right
exact eq_bot_iff_card.2 (Nat.eq_one_of_dvd_coprimes h D₁ D₂)
noncomputable section GroupActions
variable {G : Type*} [Group G]
lemma conjugate_one (H : Subgroup G) : conjugate 1 H = H := by
ext x
simp [conjugate]
instance : MulAction G (Subgroup G) where
smul := conjugate
one_smul := by
exact conjugate_one
mul_smul := by
intro x y H
ext z
constructor
· rintro ⟨h, h_in, rfl⟩
use y*h*y⁻¹
constructor
· use h
· group
· rintro ⟨-, ⟨h, h_in, rfl⟩, rfl⟩
use h, h_in
group
end GroupActions
noncomputable section QuotientGroup
section
variable {G : Type*} [Group G] {H K : Subgroup G}
open MonoidHom
#check card_pos -- The nonempty argument will be automatically inferred for subgroups
#check Subgroup.index_eq_card
#check Subgroup.index_mul_card
#check Nat.eq_of_mul_eq_mul_right
lemma aux_card_eq [Fintype G] (h' : card G = card H * card K) : card (G ⧸ H) = card K := by
have := calc
card (G ⧸ H) * card H = card G := by rw [← H.index_eq_card, H.index_mul_card]
_ = card K * card H := by rw [h', mul_comm]
exact Nat.eq_of_mul_eq_mul_right card_pos this
variable [H.Normal] [K.Normal] [Fintype G] (h : Disjoint H K) (h' : card G = card H * card K)
#check bijective_iff_injective_and_card
#check ker_eq_bot_iff
#check restrict
#check ker_restrict
def iso₁ [Fintype G] (h : Disjoint H K) (h' : card G = card H * card K) : K ≃* G ⧸ H := by
apply MulEquiv.ofBijective ((QuotientGroup.mk' H).restrict K)
rw [bijective_iff_injective_and_card]
constructor
· rw [← ker_eq_bot_iff, (QuotientGroup.mk' H).ker_restrict K]
simp [h]
· symm
exact aux_card_eq h'
def iso₂ : G ≃* (G ⧸ K) × (G ⧸ H) := by
apply MulEquiv.ofBijective <| (QuotientGroup.mk' K).prod (QuotientGroup.mk' H)
rw [bijective_iff_injective_and_card]
constructor
· rw [← ker_eq_bot_iff, ker_prod]
simp [h.symm.eq_bot]
· rw [card_prod, aux_card_eq h', aux_card_eq (mul_comm (card H) _▸ h'), h']
def finalIso : G ≃* H × K :=
(iso₂ h h').trans ((iso₁ h.symm (mul_comm (card H) _ ▸ h')).prodCongr (iso₁ h h')).symm
end
end QuotientGroup