Skip to content

Commit 21fb5ac

Browse files
feat: port Archive.Wiedijk100Theorems.AbelRuffini (leanprover-community#5457)
Co-authored-by: Ruben Van de Velde <65514131+Ruben-VandeVelde@users.noreply.github.com>
1 parent 68a3466 commit 21fb5ac

File tree

2 files changed

+194
-0
lines changed

2 files changed

+194
-0
lines changed

Archive.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import Archive.Imo.Imo2019Q4
2626
import Archive.Imo.Imo2020Q2
2727
import Archive.Imo.Imo2021Q1
2828
import Archive.Sensitivity
29+
import Archive.Wiedijk100Theorems.AbelRuffini
2930
import Archive.Wiedijk100Theorems.AreaOfACircle
3031
import Archive.Wiedijk100Theorems.AscendingDescendingSequences
3132
import Archive.Wiedijk100Theorems.BallotProblem
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/-
2+
Copyright (c) 2021 Thomas Browning. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Thomas Browning
5+
6+
! This file was ported from Lean 3 source module wiedijk_100_theorems.abel_ruffini
7+
! leanprover-community/mathlib commit 5563b1b49e86e135e8c7b556da5ad2f5ff881cad
8+
! Please do not edit these lines, except to modify the commit id
9+
! if you have ported upstream changes.
10+
-/
11+
import Mathlib.Analysis.Calculus.LocalExtr
12+
import Mathlib.FieldTheory.AbelRuffini
13+
import Mathlib.RingTheory.RootsOfUnity.Minpoly
14+
import Mathlib.RingTheory.EisensteinCriterion
15+
16+
/-!
17+
# Construction of an algebraic number that is not solvable by radicals.
18+
19+
The main ingredients are:
20+
* `solvableByRad.isSolvable'` in `FieldTheory/AbelRuffini` :
21+
an irreducible polynomial with an `IsSolvableByRad` root has solvable Galois group
22+
* `galActionHom_bijective_of_prime_degree'` in `FieldTheory/PolynomialGaloisGroup` :
23+
an irreducible polynomial of prime degree with 1-3 non-real roots has full Galois group
24+
* `Equiv.Perm.not_solvable` in `GroupTheory/Solvable` : the symmetric group is not solvable
25+
26+
Then all that remains is the construction of a specific polynomial satisfying the conditions of
27+
`galActionHom_bijective_of_prime_degree'`, which is done in this file.
28+
29+
-/
30+
31+
32+
namespace AbelRuffini
33+
34+
set_option linter.uppercaseLean3 false
35+
36+
local macro_rules | `($x ^ $y) => `(HPow.hPow $x $y) -- Porting note: See issue #2220
37+
38+
open Function Polynomial Polynomial.Gal Ideal
39+
40+
open scoped Polynomial
41+
42+
attribute [local instance] splits_ℚ_ℂ
43+
44+
variable (R : Type _) [CommRing R] (a b : ℕ)
45+
46+
/-- A quintic polynomial that we will show is irreducible -/
47+
noncomputable def Φ : R[X] :=
48+
X ^ 5 - C (a : R) * X + C (b : R)
49+
#align abel_ruffini.Φ AbelRuffini.Φ
50+
51+
variable {R}
52+
53+
@[simp]
54+
theorem map_Phi {S : Type _} [CommRing S] (f : R →+* S) : (Φ R a b).map f = Φ S a b := by simp [Φ]
55+
#align abel_ruffini.map_Phi AbelRuffini.map_Phi
56+
57+
@[simp]
58+
theorem coeff_zero_Phi : (Φ R a b).coeff 0 = ↑b := by simp [Φ, coeff_X_pow]
59+
#align abel_ruffini.coeff_zero_Phi AbelRuffini.coeff_zero_Phi
60+
61+
@[simp]
62+
theorem coeff_five_Phi : (Φ R a b).coeff 5 = 1 := by
63+
simp [Φ, coeff_X, coeff_C, -map_natCast]
64+
#align abel_ruffini.coeff_five_Phi AbelRuffini.coeff_five_Phi
65+
66+
variable [Nontrivial R]
67+
68+
theorem degree_Phi : (Φ R a b).degree = ↑5 := by
69+
suffices degree (X ^ 5 - C (a : R) * X) = ↑5 by
70+
rwa [Φ, degree_add_eq_left_of_degree_lt]
71+
convert (degree_C_le (R := R)).trans_lt (WithBot.coe_lt_coe.mpr (show 0 < 5 by norm_num))
72+
rw [degree_sub_eq_left_of_degree_lt]; · simp
73+
rw [degree_X_pow]
74+
exact (degree_C_mul_X_le _).trans_lt (WithBot.coe_lt_coe.mpr (show 1 < 5 by norm_num))
75+
#align abel_ruffini.degree_Phi AbelRuffini.degree_Phi
76+
77+
theorem natDegree_Phi : (Φ R a b).natDegree = 5 :=
78+
natDegree_eq_of_degree_eq_some (degree_Phi a b)
79+
#align abel_ruffini.nat_degree_Phi AbelRuffini.natDegree_Phi
80+
81+
theorem leadingCoeff_Phi : (Φ R a b).leadingCoeff = 1 := by
82+
rw [Polynomial.leadingCoeff, natDegree_Phi, coeff_five_Phi]
83+
#align abel_ruffini.leading_coeff_Phi AbelRuffini.leadingCoeff_Phi
84+
85+
theorem monic_Phi : (Φ R a b).Monic :=
86+
leadingCoeff_Phi a b
87+
#align abel_ruffini.monic_Phi AbelRuffini.monic_Phi
88+
89+
theorem irreducible_Phi (p : ℕ) (hp : p.Prime) (hpa : p ∣ a) (hpb : p ∣ b) (hp2b : ¬p ^ 2 ∣ b) :
90+
Irreducible (Φ ℚ a b) := by
91+
rw [← map_Phi a b (Int.castRingHom ℚ), ← IsPrimitive.Int.irreducible_iff_irreducible_map_cast]
92+
apply irreducible_of_eisenstein_criterion
93+
· rwa [span_singleton_prime (Int.coe_nat_ne_zero.mpr hp.ne_zero), Int.prime_iff_natAbs_prime]
94+
· rw [leadingCoeff_Phi, mem_span_singleton]
95+
exact_mod_cast mt Nat.dvd_one.mp hp.ne_one
96+
· intro n hn
97+
rw [mem_span_singleton]
98+
rw [degree_Phi] at hn; norm_cast at hn
99+
interval_cases hn : n <;>
100+
simp only [Φ, coeff_X_pow, coeff_C, Int.coe_nat_dvd.mpr, hpb, if_true, coeff_C_mul, if_false,
101+
coeff_X_zero, hpa, coeff_add, zero_add, mul_zero, coeff_sub, add_zero, zero_sub, dvd_neg,
102+
neg_zero, dvd_mul_of_dvd_left]
103+
· simp only [degree_Phi, ← WithBot.coe_zero, WithBot.coe_lt_coe, Nat.succ_pos']
104+
· rw [coeff_zero_Phi, span_singleton_pow, mem_span_singleton]
105+
exact mt Int.coe_nat_dvd.mp hp2b
106+
all_goals exact Monic.isPrimitive (monic_Phi a b)
107+
#align abel_ruffini.irreducible_Phi AbelRuffini.irreducible_Phi
108+
109+
theorem real_roots_Phi_le : Fintype.card ((Φ ℚ a b).rootSet ℝ) ≤ 3 := by
110+
rw [← map_Phi a b (algebraMap ℤ ℚ), Φ, ← one_mul (X ^ 5), ← C_1]
111+
refine' (card_rootSet_le_derivative _).trans
112+
(Nat.succ_le_succ ((card_rootSet_le_derivative _).trans (Nat.succ_le_succ _)))
113+
simp [-map_ofNat]
114+
rw [Fintype.card_le_one_iff_subsingleton, ← mul_assoc, ← _root_.map_mul, rootSet_C_mul_X_pow] <;>
115+
norm_num
116+
#align abel_ruffini.real_roots_Phi_le AbelRuffini.real_roots_Phi_le
117+
118+
theorem real_roots_Phi_ge_aux (hab : b < a) :
119+
∃ x y : ℝ, x ≠ y ∧ aeval x (Φ ℚ a b) = 0 ∧ aeval y (Φ ℚ a b) = 0 := by
120+
let f := fun x : ℝ => aeval x (Φ ℚ a b)
121+
have hf : f = fun x : ℝ => x ^ 5 - a * x + b := by simp [Φ]
122+
have hc : ∀ s : Set ℝ, ContinuousOn f s := fun s => (Φ ℚ a b).continuousOn_aeval
123+
have ha : (1 : ℝ) ≤ a := Nat.one_le_cast.mpr (Nat.one_le_of_lt hab)
124+
have hle : (0 : ℝ) ≤ 1 := zero_le_one
125+
have hf0 : 0 ≤ f 0 := by simp [hf]
126+
by_cases hb : (1 : ℝ) - a + b < 0
127+
· have hf1 : f 1 < 0 := by simp [hf, hb]
128+
have hfa : 0 ≤ f a := by
129+
simp [hf, ← sq]
130+
refine' add_nonneg (sub_nonneg.mpr (pow_le_pow ha _)) _ <;> norm_num
131+
obtain ⟨x, ⟨-, hx1⟩, hx2⟩ := intermediate_value_Ico' hle (hc _) (Set.mem_Ioc.mpr ⟨hf1, hf0⟩)
132+
obtain ⟨y, ⟨hy1, -⟩, hy2⟩ := intermediate_value_Ioc ha (hc _) (Set.mem_Ioc.mpr ⟨hf1, hfa⟩)
133+
exact ⟨x, y, (hx1.trans hy1).ne, hx2, hy2⟩
134+
· replace hb : (b : ℝ) = a - 1 := by linarith [show (b : ℝ) + 1 ≤ a by exact_mod_cast hab]
135+
have hf1 : f 1 = 0 := by simp [hf, hb]
136+
have hfa :=
137+
calc
138+
f (-a) = ↑a ^ 2 - ↑a ^ 5 + b := by simp [hf, ← sq]; rw [Odd.neg_pow]; ring; norm_num
139+
_ ≤ ↑a ^ 2 - ↑a ^ 3 + (a - 1) := by
140+
refine' add_le_add (sub_le_sub_left (pow_le_pow ha _) _) _ <;> linarith
141+
_ = -((a : ℝ) - 1) ^ 2 * (a + 1) := by ring
142+
_ ≤ 0 := by nlinarith
143+
have ha' := neg_nonpos.mpr (hle.trans ha)
144+
obtain ⟨x, ⟨-, hx1⟩, hx2⟩ := intermediate_value_Icc ha' (hc _) (Set.mem_Icc.mpr ⟨hfa, hf0⟩)
145+
exact ⟨x, 1, (hx1.trans_lt zero_lt_one).ne, hx2, hf1⟩
146+
#align abel_ruffini.real_roots_Phi_ge_aux AbelRuffini.real_roots_Phi_ge_aux
147+
148+
theorem real_roots_Phi_ge (hab : b < a) : 2 ≤ Fintype.card ((Φ ℚ a b).rootSet ℝ) := by
149+
have q_ne_zero : Φ ℚ a b ≠ 0 := (monic_Phi a b).ne_zero
150+
obtain ⟨x, y, hxy, hx, hy⟩ := real_roots_Phi_ge_aux a b hab
151+
have key : ↑({x, y} : Finset ℝ) ⊆ (Φ ℚ a b).rootSet ℝ := by
152+
simp [Set.insert_subset, mem_rootSet_of_ne q_ne_zero, hx, hy]
153+
convert Fintype.card_le_of_embedding (Set.embeddingOfSubset _ _ key)
154+
simp only [Finset.coe_sort_coe, Fintype.card_coe, Finset.card_singleton,
155+
Finset.card_insert_of_not_mem (mt Finset.mem_singleton.mp hxy)]
156+
#align abel_ruffini.real_roots_Phi_ge AbelRuffini.real_roots_Phi_ge
157+
158+
theorem complex_roots_Phi (h : (Φ ℚ a b).Separable) : Fintype.card ((Φ ℚ a b).rootSet ℂ) = 5 :=
159+
(card_rootSet_eq_natDegree h (IsAlgClosed.splits_codomain _)).trans (natDegree_Phi a b)
160+
#align abel_ruffini.complex_roots_Phi AbelRuffini.complex_roots_Phi
161+
162+
theorem gal_Phi (hab : b < a) (h_irred : Irreducible (Φ ℚ a b)) :
163+
Bijective (galActionHom (Φ ℚ a b) ℂ) := by
164+
apply galActionHom_bijective_of_prime_degree' h_irred
165+
· rw [natDegree_Phi]; norm_num
166+
· rw [complex_roots_Phi a b h_irred.separable, Nat.succ_le_succ_iff]
167+
exact (real_roots_Phi_le a b).trans (Nat.le_succ 3)
168+
· simp_rw [complex_roots_Phi a b h_irred.separable, Nat.succ_le_succ_iff]
169+
exact real_roots_Phi_ge a b hab
170+
#align abel_ruffini.gal_Phi AbelRuffini.gal_Phi
171+
172+
theorem not_solvable_by_rad (p : ℕ) (x : ℂ) (hx : aeval x (Φ ℚ a b) = 0) (hab : b < a)
173+
(hp : p.Prime) (hpa : p ∣ a) (hpb : p ∣ b) (hp2b : ¬p ^ 2 ∣ b) : ¬IsSolvableByRad ℚ x := by
174+
have h_irred := irreducible_Phi a b p hp hpa hpb hp2b
175+
apply mt (solvableByRad.isSolvable' h_irred hx)
176+
intro h
177+
refine' Equiv.Perm.not_solvable _ (le_of_eq _)
178+
(solvable_of_surjective (gal_Phi a b hab h_irred).2)
179+
rw_mod_cast [Cardinal.mk_fintype, complex_roots_Phi a b h_irred.separable]
180+
#align abel_ruffini.not_solvable_by_rad AbelRuffini.not_solvable_by_rad
181+
182+
theorem not_solvable_by_rad' (x : ℂ) (hx : aeval x (Φ ℚ 4 2) = 0) : ¬IsSolvableByRad ℚ x := by
183+
apply not_solvable_by_rad 4 2 2 x hx <;> norm_num
184+
#align abel_ruffini.not_solvable_by_rad' AbelRuffini.not_solvable_by_rad'
185+
186+
/-- **Abel-Ruffini Theorem** -/
187+
theorem exists_not_solvable_by_rad : ∃ x : ℂ, IsAlgebraic ℚ x ∧ ¬IsSolvableByRad ℚ x := by
188+
obtain ⟨x, hx⟩ := exists_root_of_splits (algebraMap ℚ ℂ) (IsAlgClosed.splits_codomain (Φ ℚ 4 2))
189+
(ne_of_eq_of_ne (degree_Phi 4 2) (mt WithBot.coe_eq_coe.mp (show 50 by norm_num)))
190+
exact ⟨x, ⟨Φ ℚ 4 2, (monic_Phi 4 2).ne_zero, hx⟩, not_solvable_by_rad' x hx⟩
191+
#align abel_ruffini.exists_not_solvable_by_rad AbelRuffini.exists_not_solvable_by_rad
192+
193+
end AbelRuffini

0 commit comments

Comments
 (0)