Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit e8e0526

Browse files
committed
feat(field_theory/polynomial_galois_group): New file (#5861)
This PR adds the file `polynomial_galois_group`. It contains some of the groundwork needed for proving the Abel-Ruffini theorem. Co-authored-by: tb65536 <tb65536@users.noreply.github.com>
1 parent 62cf420 commit e8e0526

File tree

5 files changed

+265
-1
lines changed

5 files changed

+265
-1
lines changed

src/data/polynomial/field_division.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,10 @@ begin
276276
rw polynomial.eval_map,
277277
end
278278

279+
lemma mem_root_set [field k] [algebra R k] {x : k} (hp : p ≠ 0) :
280+
x ∈ p.root_set k ↔ aeval x p = 0 :=
281+
iff.trans multiset.mem_to_finset (mem_roots_map hp)
282+
279283
lemma exists_root_of_degree_eq_one (h : degree p = 1) : ∃ x, is_root p x :=
280284
⟨-(p.coeff 0 / p.coeff 1),
281285
have p.coeff 10,

src/data/polynomial/ring_division.lean

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,21 @@ begin
488488
rw [eval_sub, sub_eq_zero, ext],
489489
end
490490

491+
/-- The set of distinct roots of `p` in `E`.
492+
493+
If you have a non-separable polynomial, use `polynomial.roots` for the multiset
494+
where multiple roots have the appropriate multiplicity. -/
495+
def root_set (p : polynomial R) (S) [integral_domain S] [algebra R S] : set S :=
496+
(p.map (algebra_map R S)).roots.to_finset
497+
498+
lemma root_set_def (p : polynomial R) (S) [integral_domain S] [algebra R S] :
499+
p.root_set S = (p.map (algebra_map R S)).roots.to_finset :=
500+
rfl
501+
502+
@[simp] lemma root_set_zero (S) [integral_domain S] [algebra R S] :
503+
(0 : polynomial R).root_set S = ∅ :=
504+
by rw [root_set_def, polynomial.map_zero, roots_zero, to_finset_zero, finset.coe_empty]
505+
491506
end roots
492507

493508
theorem is_unit_iff {f : polynomial R} : is_unit f ↔ ∃ r : R, is_unit r ∧ C r = f :=

src/field_theory/normal.lean

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ end
9797
lemma alg_equiv.transfer_normal (f : E ≃ₐ[F] E') : normal F E ↔ normal F E' :=
9898
⟨λ h, by exactI normal.of_alg_equiv f, λ h, by exactI normal.of_alg_equiv f.symm⟩
9999

100-
lemma normal.of_is_splitting_field {p : polynomial F} [hFEp : is_splitting_field F E p] :
100+
lemma normal.of_is_splitting_field (p : polynomial F) [hFEp : is_splitting_field F E p] :
101101
normal F E :=
102102
begin
103103
by_cases hp : p = 0,
@@ -160,6 +160,8 @@ begin
160160
rw [set.image_singleton, ring_hom.algebra_map_to_algebra, adjoin_root.lift_root]
161161
end
162162

163+
instance (p : polynomial F) : normal F p.splitting_field := normal.of_is_splitting_field p
164+
163165
end normal_tower
164166

165167
variables {F} {K} (ϕ ψ : K →ₐ[F] K) (χ ω : K ≃ₐ[F] K)
Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
/-
2+
Copyright (c) 2020 Thomas Browning and Patrick Lutz. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Thomas Browning and Patrick Lutz
5+
-/
6+
7+
import field_theory.galois
8+
9+
/-!
10+
# Galois Groups of Polynomials
11+
12+
In this file we introduce the Galois group of a polynomial, defined as
13+
the automorphism group of the splitting field.
14+
15+
## Main definitions
16+
17+
- `gal p`: the Galois group of a polynomial p.
18+
- `restrict p E`: the restriction homomorphism `(E ≃ₐ[F] E) → gal p`.
19+
- `gal_action p E`: the action of `gal p` on the roots of `p` in `E`.
20+
21+
## Main results
22+
23+
- `restrict_smul`: `restrict p E` is compatible with `gal_action p E`.
24+
- `gal_action_hom_injective`: the action of `gal p` on the roots of `p` in `E` is faithful.
25+
- `restrict_prod_inj`: `gal (p * q)` embeds as a subgroup of `gal p × gal q`.
26+
-/
27+
28+
noncomputable theory
29+
open_locale classical
30+
31+
open finite_dimensional
32+
33+
namespace polynomial
34+
35+
variables {F : Type*} [field F] (p q : polynomial F) (E : Type*) [field E] [algebra F E]
36+
37+
/-- The Galois group of a polynomial -/
38+
@[derive [has_coe_to_fun, group, fintype]]
39+
def gal := p.splitting_field ≃ₐ[F] p.splitting_field
40+
41+
namespace gal
42+
43+
instance [h : fact (p.splits (ring_hom.id F))] : unique p.gal :=
44+
{ default := 1,
45+
uniq := λ f, alg_equiv.ext (λ x, by { obtain ⟨y, rfl⟩ := algebra.mem_bot.mp
46+
((subalgebra.ext_iff.mp ((is_splitting_field.splits_iff _ p).mp h) x).mp algebra.mem_top),
47+
rw [alg_equiv.commutes, alg_equiv.commutes] }) }
48+
49+
instance : unique (0 : polynomial F).gal :=
50+
begin
51+
haveI : fact ((0 : polynomial F).splits (ring_hom.id F)) := splits_zero _,
52+
apply_instance,
53+
end
54+
55+
instance [h : fact (p.splits (algebra_map F E))] : algebra p.splitting_field E :=
56+
(is_splitting_field.lift p.splitting_field p h).to_ring_hom.to_algebra
57+
58+
instance [h : fact (p.splits (algebra_map F E))] : is_scalar_tower F p.splitting_field E :=
59+
is_scalar_tower.of_algebra_map_eq
60+
(λ x, ((is_splitting_field.lift p.splitting_field p h).commutes x).symm)
61+
62+
/-- The restriction homomorphism -/
63+
def restrict [h : fact (p.splits (algebra_map F E))] : (E ≃ₐ[F] E) →* p.gal :=
64+
alg_equiv.restrict_normal_hom p.splitting_field
65+
66+
section roots_action
67+
68+
/-- The function from `roots p p.splitting_field` to `roots p E` -/
69+
def map_roots [h : fact (p.splits (algebra_map F E))] :
70+
root_set p p.splitting_field → root_set p E :=
71+
λ x, ⟨is_scalar_tower.to_alg_hom F p.splitting_field E x, begin
72+
have key := subtype.mem x,
73+
by_cases p = 0,
74+
{ simp only [h, root_set_zero] at key,
75+
exact false.rec _ key },
76+
{ rw [mem_root_set h, aeval_alg_hom_apply, (mem_root_set h).mp key, alg_hom.map_zero] } end
77+
78+
lemma map_roots_bijective [h : fact (p.splits (algebra_map F E))] :
79+
function.bijective (map_roots p E) :=
80+
begin
81+
split,
82+
{ exact λ _ _ h, subtype.ext (ring_hom.injective _ (subtype.ext_iff.mp h)) },
83+
{ intro y,
84+
have key := roots_map
85+
(is_scalar_tower.to_alg_hom F p.splitting_field E : p.splitting_field →+* E)
86+
((splits_id_iff_splits _).mpr (is_splitting_field.splits p.splitting_field p)),
87+
rw [map_map, alg_hom.comp_algebra_map] at key,
88+
have hy := subtype.mem y,
89+
simp only [root_set, finset.mem_coe, multiset.mem_to_finset, key, multiset.mem_map] at hy,
90+
rcases hy with ⟨x, hx1, hx2⟩,
91+
exact ⟨⟨x, multiset.mem_to_finset.mpr hx1⟩, subtype.ext hx2⟩ }
92+
end
93+
94+
/-- The bijection between `root_set p p.splitting_field` and `root_set p E` -/
95+
def roots_equiv_roots [h : fact (p.splits (algebra_map F E))] :
96+
(root_set p p.splitting_field) ≃ (root_set p E) :=
97+
equiv.of_bijective (map_roots p E) (map_roots_bijective p E)
98+
99+
instance gal_action_aux : mul_action p.gal (root_set p p.splitting_field) :=
100+
{ smul := λ ϕ x, ⟨ϕ x, begin
101+
have key := subtype.mem x,
102+
--simp only [root_set, finset.mem_coe, multiset.mem_to_finset] at *,
103+
by_cases p = 0,
104+
{ simp only [h, root_set_zero] at key,
105+
exact false.rec _ key },
106+
{ rw mem_root_set h,
107+
change aeval (ϕ.to_alg_hom x) p = 0,
108+
rw [aeval_alg_hom_apply, (mem_root_set h).mp key, alg_hom.map_zero] } end⟩,
109+
one_smul := λ _, by { ext, refl },
110+
mul_smul := λ _ _ _, by { ext, refl } }
111+
112+
instance gal_action [h : fact (p.splits (algebra_map F E))] : mul_action p.gal (root_set p E) :=
113+
{ smul := λ ϕ x, roots_equiv_roots p E (ϕ • ((roots_equiv_roots p E).symm x)),
114+
one_smul := λ _, by simp only [equiv.apply_symm_apply, one_smul],
115+
mul_smul := λ _ _ _, by simp only [equiv.apply_symm_apply, equiv.symm_apply_apply, mul_smul] }
116+
117+
variables {p E}
118+
119+
@[simp] lemma restrict_smul [h : fact (p.splits (algebra_map F E))]
120+
(ϕ : E ≃ₐ[F] E) (x : root_set p E) : ↑((restrict p E ϕ) • x) = ϕ x :=
121+
begin
122+
let ψ := alg_hom.alg_equiv.of_injective_field (is_scalar_tower.to_alg_hom F p.splitting_field E),
123+
change ↑(ψ (ψ.symm _)) = ϕ x,
124+
rw alg_equiv.apply_symm_apply ψ,
125+
change ϕ (roots_equiv_roots p E ((roots_equiv_roots p E).symm x)) = ϕ x,
126+
rw equiv.apply_symm_apply (roots_equiv_roots p E),
127+
end
128+
129+
variables (p E)
130+
131+
/-- `gal_action` as a permutation representation -/
132+
def gal_action_hom [h : fact (p.splits (algebra_map F E))] : p.gal →* equiv.perm (root_set p E) :=
133+
{ to_fun := λ ϕ, equiv.mk (λ x, ϕ • x) (λ x, ϕ⁻¹ • x)
134+
(λ x, inv_smul_smul ϕ x) (λ x, smul_inv_smul ϕ x),
135+
map_one' := by { ext1 x, exact mul_action.one_smul x },
136+
map_mul' := λ x y, by { ext1 z, exact mul_action.mul_smul x y z } }
137+
138+
lemma gal_action_hom_injective [h : fact (p.splits (algebra_map F E))] :
139+
function.injective (gal_action_hom p E) :=
140+
begin
141+
rw monoid_hom.injective_iff,
142+
intros ϕ hϕ,
143+
let equalizer := alg_hom.equalizer ϕ.to_alg_hom (alg_hom.id F p.splitting_field),
144+
suffices : equalizer = ⊤,
145+
{ exact alg_equiv.ext (λ x, (subalgebra.ext_iff.mp this x).mpr algebra.mem_top) },
146+
rw [eq_top_iff, ←splitting_field.adjoin_roots, algebra.adjoin_le_iff],
147+
intros x hx,
148+
have key := equiv.perm.ext_iff.mp hϕ (roots_equiv_roots p E ⟨x, hx⟩),
149+
change roots_equiv_roots p E (ϕ • (roots_equiv_roots p E).symm
150+
(roots_equiv_roots p E ⟨x, hx⟩)) = roots_equiv_roots p E ⟨x, hx⟩ at key,
151+
rw equiv.symm_apply_apply at key,
152+
exact subtype.ext_iff.mp (equiv.injective (roots_equiv_roots p E) key),
153+
end
154+
155+
end roots_action
156+
157+
variables {p q}
158+
159+
/-- The restriction homomorphism between Galois groups -/
160+
def restrict_dvd (hpq : p ∣ q) : q.gal →* p.gal :=
161+
if hq : q = 0 then 1 else @restrict F _ p _ _ _
162+
(splits_of_splits_of_dvd (algebra_map F q.splitting_field) hq (splitting_field.splits q) hpq)
163+
164+
variables (p q)
165+
166+
/-- The Galois group of a product embeds into the product of the Galois groups -/
167+
def restrict_prod : (p * q).gal →* p.gal × q.gal :=
168+
monoid_hom.prod (restrict_dvd (dvd_mul_right p q)) (restrict_dvd (dvd_mul_left q p))
169+
170+
lemma restrict_prod_injective : function.injective (restrict_prod p q) :=
171+
begin
172+
by_cases hpq : (p * q) = 0,
173+
{ haveI : unique (gal (p * q)) := by { rw hpq, apply_instance },
174+
exact λ f g h, eq.trans (unique.eq_default f) (unique.eq_default g).symm },
175+
intros f g hfg,
176+
dsimp only [restrict_prod, restrict_dvd] at hfg,
177+
simp only [dif_neg hpq, monoid_hom.prod_apply, prod.mk.inj_iff] at hfg,
178+
suffices : alg_hom.equalizer f.to_alg_hom g.to_alg_hom = ⊤,
179+
{ exact alg_equiv.ext (λ x, (subalgebra.ext_iff.mp this x).mpr algebra.mem_top) },
180+
rw [eq_top_iff, ←splitting_field.adjoin_roots, algebra.adjoin_le_iff],
181+
intros x hx,
182+
rw [map_mul, polynomial.roots_mul] at hx,
183+
cases multiset.mem_add.mp (multiset.mem_to_finset.mp hx) with h h,
184+
{ change f x = g x,
185+
haveI : fact (p.splits (algebra_map F (p * q).splitting_field)) :=
186+
splits_of_splits_of_dvd _ hpq (splitting_field.splits (p * q)) (dvd_mul_right p q),
187+
have key : x = algebra_map (p.splitting_field) (p * q).splitting_field
188+
((roots_equiv_roots p _).inv_fun ⟨x, multiset.mem_to_finset.mpr h⟩) :=
189+
subtype.ext_iff.mp (equiv.apply_symm_apply (roots_equiv_roots p _) ⟨x, _⟩).symm,
190+
rw [key, ←alg_equiv.restrict_normal_commutes, ←alg_equiv.restrict_normal_commutes],
191+
exact congr_arg _ (alg_equiv.ext_iff.mp hfg.1 _) },
192+
{ change f x = g x,
193+
haveI : fact (q.splits (algebra_map F (p * q).splitting_field)) :=
194+
splits_of_splits_of_dvd _ hpq (splitting_field.splits (p * q)) (dvd_mul_left q p),
195+
have key : x = algebra_map (q.splitting_field) (p * q).splitting_field
196+
((roots_equiv_roots q _).inv_fun ⟨x, multiset.mem_to_finset.mpr h⟩) :=
197+
subtype.ext_iff.mp (equiv.apply_symm_apply (roots_equiv_roots q _) ⟨x, _⟩).symm,
198+
rw [key, ←alg_equiv.restrict_normal_commutes, ←alg_equiv.restrict_normal_commutes],
199+
exact congr_arg _ (alg_equiv.ext_iff.mp hfg.2 _) },
200+
{ rwa [ne.def, mul_eq_zero, map_eq_zero, map_eq_zero, ←mul_eq_zero] }
201+
end
202+
203+
variables {p q}
204+
205+
lemma card_of_separable (hp : p.separable) :
206+
fintype.card p.gal = findim F p.splitting_field :=
207+
begin
208+
haveI : is_galois F p.splitting_field := is_galois.of_separable_splitting_field hp,
209+
exact is_galois.card_aut_eq_findim F p.splitting_field,
210+
end
211+
212+
lemma prime_degree_dvd_card [char_zero F] (p_irr : irreducible p) (p_deg : p.nat_degree.prime) :
213+
p.nat_degree ∣ fintype.card p.gal :=
214+
begin
215+
rw gal.card_of_separable p_irr.separable,
216+
have hp : p.degree ≠ 0 :=
217+
λ h, nat.prime.ne_zero p_deg (nat_degree_eq_zero_iff_degree_le_zero.mpr (le_of_eq h)),
218+
let α : p.splitting_field := root_of_splits (algebra_map F p.splitting_field)
219+
(splitting_field.splits p) hp,
220+
have hα : is_integral F α :=
221+
(is_algebraic_iff_is_integral F).mp (algebra.is_algebraic_of_finite α),
222+
use finite_dimensional.findim F⟮α⟯ p.splitting_field,
223+
suffices : (minpoly F α).nat_degree = p.nat_degree,
224+
{ rw [←finite_dimensional.findim_mul_findim F F⟮α⟯ p.splitting_field,
225+
intermediate_field.adjoin.findim hα, this] },
226+
suffices : minpoly F α ∣ p,
227+
{ have key := dvd_symm_of_irreducible (minpoly.irreducible hα) p_irr this,
228+
apply le_antisymm,
229+
{ exact nat_degree_le_of_dvd this p_irr.ne_zero },
230+
{ exact nat_degree_le_of_dvd key (minpoly.ne_zero hα) } },
231+
apply minpoly.dvd F α,
232+
rw [aeval_def, map_root_of_splits _ (splitting_field.splits p) hp],
233+
end
234+
235+
end gal
236+
237+
end polynomial

src/field_theory/splitting_field.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -641,6 +641,9 @@ theorem adjoin_roots : algebra.adjoin α
641641
(↑(f.map (algebra_map α $ splitting_field f)).roots.to_finset : set (splitting_field f)) = ⊤ :=
642642
splitting_field_aux.adjoin_roots _ _ _
643643

644+
theorem adjoin_root_set : algebra.adjoin α (f.root_set f.splitting_field) = ⊤ :=
645+
adjoin_roots f
646+
644647
end splitting_field
645648

646649
variables (α β) [algebra α β]
@@ -716,6 +719,9 @@ finite_dimensional.iff_fg.2 $ @algebra.coe_top α β _ _ _ ▸ adjoin_roots β f
716719
else (is_algebraic_iff_is_integral _).1 ⟨f, hf, (eval₂_eq_eval_map _).trans $
717720
(mem_roots $ by exact map_ne_zero hf).1 (multiset.mem_to_finset.mp hy)⟩)
718721

722+
instance (f : polynomial α) : _root_.finite_dimensional α f.splitting_field :=
723+
finite_dimensional f.splitting_field f
724+
719725
/-- Any splitting field is isomorphic to `splitting_field f`. -/
720726
def alg_equiv (f : polynomial α) [is_splitting_field α β f] : β ≃ₐ[α] splitting_field f :=
721727
begin

0 commit comments

Comments
 (0)