Skip to content

Commit a5783c9

Browse files
committed
feat(FieldTheory/Minpoly): minpoly K x splits implies minpoly K (algebraMap K L a - x) splits (#17369)
Add `minpoly K x` splits implies `minpoly K (- x)` splits and `minpoly K (algebraMap K L a - x)` splits. This is after #17093 . Co-authored-by: Jiang Jiedong <107380768+jjdishere@users.noreply.github.com>
1 parent 8ad393d commit a5783c9

File tree

3 files changed

+112
-21
lines changed

3 files changed

+112
-21
lines changed

Mathlib/Algebra/Polynomial/AlgebraMap.lean

Lines changed: 39 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -306,22 +306,46 @@ theorem algEquivOfCompEqX_eq_iff (p q p' q' : R[X])
306306
theorem algEquivOfCompEqX_symm (p q : R[X]) (hpq : p.comp q = X) (hqp : q.comp p = X) :
307307
(algEquivOfCompEqX p q hpq hqp).symm = algEquivOfCompEqX q p hqp hpq := rfl
308308

309+
/-- The automorphism of the polynomial algebra given by `p(X) ↦ p(a * X + b)`,
310+
with inverse `p(X) ↦ p(a⁻¹ * (X - b))`. -/
311+
@[simps!]
312+
def algEquivCMulXAddC {R : Type*} [CommRing R] (a b : R) [Invertible a] : R[X] ≃ₐ[R] R[X] :=
313+
algEquivOfCompEqX (C a * X + C b) (C ⅟ a * (X - C b))
314+
(by simp [← C_mul, ← mul_assoc]) (by simp [← C_mul, ← mul_assoc])
315+
316+
theorem algEquivCMulXAddC_symm_eq {R : Type*} [CommRing R] (a b : R) [Invertible a] :
317+
(algEquivCMulXAddC a b).symm = algEquivCMulXAddC (⅟ a) (- ⅟ a * b) := by
318+
ext p : 1
319+
simp only [algEquivCMulXAddC_symm_apply, neg_mul, algEquivCMulXAddC_apply, map_neg, map_mul]
320+
congr
321+
simp [mul_add, sub_eq_add_neg]
322+
309323
/-- The automorphism of the polynomial algebra given by `p(X) ↦ p(X+t)`,
310324
with inverse `p(X) ↦ p(X-t)`. -/
311325
@[simps!]
312-
def algEquivAevalXAddC {R} [CommRing R] (t : R) : R[X] ≃ₐ[R] R[X] :=
326+
def algEquivAevalXAddC {R : Type*} [CommRing R] (t : R) : R[X] ≃ₐ[R] R[X] :=
313327
algEquivOfCompEqX (X + C t) (X - C t) (by simp) (by simp)
314328

315329
@[simp]
316-
theorem algEquivAevalXAddC_eq_iff {R} [CommRing R] (t t' : R) :
330+
theorem algEquivAevalXAddC_eq_iff {R : Type*} [CommRing R] (t t' : R) :
317331
algEquivAevalXAddC t = algEquivAevalXAddC t' ↔ t = t' := by
318332
simp [algEquivAevalXAddC]
319333

320334
@[simp]
321-
theorem algEquivAevalXAddC_symm {R} [CommRing R] (t : R) :
335+
theorem algEquivAevalXAddC_symm {R : Type*} [CommRing R] (t : R) :
322336
(algEquivAevalXAddC t).symm = algEquivAevalXAddC (-t) := by
323337
simp [algEquivAevalXAddC, sub_eq_add_neg]
324338

339+
/-- The involutive automorphism of the polynomial algebra given by `p(X) ↦ p(-X)`. -/
340+
@[simps!]
341+
def algEquivAevalNegX {R : Type*} [CommRing R] : R[X] ≃ₐ[R] R[X] :=
342+
algEquivOfCompEqX (-X) (-X) (by simp) (by simp)
343+
344+
theorem comp_neg_X_comp_neg_X {R : Type*} [CommRing R] (p : R[X]) :
345+
(p.comp (-X)).comp (-X) = p := by
346+
rw [comp_assoc]
347+
simp only [neg_comp, X_comp, neg_neg, comp_X]
348+
325349
theorem aeval_algHom (f : A →ₐ[R] B) (x : A) : aeval (f x) = f.comp (aeval x) :=
326350
algHom_ext <| by simp only [aeval_X, AlgHom.comp_apply]
327351

@@ -570,16 +594,25 @@ lemma comp_X_add_C_eq_zero_iff : p.comp (X + C t) = 0 ↔ p = 0 :=
570594

571595
lemma comp_X_add_C_ne_zero_iff : p.comp (X + C t) ≠ 0 ↔ p ≠ 0 := comp_X_add_C_eq_zero_iff.not
572596

597+
lemma dvd_comp_C_mul_X_add_C_iff (p q : R[X]) (a b : R) [Invertible a] :
598+
p ∣ q.comp (C a * X + C b) ↔ p.comp (C ⅟ a * (X - C b)) ∣ q := by
599+
convert map_dvd_iff <| algEquivCMulXAddC a b using 2
600+
simp [← comp_eq_aeval, comp_assoc, ← mul_assoc, ← C_mul]
601+
573602
lemma dvd_comp_X_sub_C_iff (p q : R[X]) (a : R) :
574603
p ∣ q.comp (X - C a) ↔ p.comp (X + C a) ∣ q := by
575-
convert (map_dvd_iff <| algEquivAevalXAddC a).symm using 2
576-
rw [C_eq_algebraMap, algEquivAevalXAddC_apply, ← comp_eq_aeval]
577-
simp [comp_assoc]
604+
let _ := invertibleOne (α := R)
605+
simpa using dvd_comp_C_mul_X_add_C_iff p q 1 (-a)
578606

579607
lemma dvd_comp_X_add_C_iff (p q : R[X]) (a : R) :
580608
p ∣ q.comp (X + C a) ↔ p.comp (X - C a) ∣ q := by
581609
simpa using dvd_comp_X_sub_C_iff p q (-a)
582610

611+
lemma dvd_comp_neg_X_iff (p q : R[X]) : p ∣ q.comp (-X) ↔ p.comp (-X) ∣ q := by
612+
let _ := invertibleOne (α := R)
613+
let _ := invertibleNeg (α := R) 1
614+
simpa using dvd_comp_C_mul_X_add_C_iff p q (-1) 0
615+
583616
variable [IsDomain R]
584617

585618
lemma units_coeff_zero_smul (c : R[X]ˣ) (p : R[X]) : (c : R[X]).coeff 0 • p = c * p := by

Mathlib/Algebra/Polynomial/Splits.lean

Lines changed: 61 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -139,26 +139,72 @@ theorem splits_X_pow (n : ℕ) : (X ^ n).Splits i :=
139139
theorem splits_id_iff_splits {f : K[X]} : (f.map i).Splits (RingHom.id L) ↔ f.Splits i := by
140140
rw [splits_map_iff, RingHom.id_comp]
141141

142-
theorem Splits.comp_X_sub_C {i : L →+* F} (a : L) {f : L[X]}
143-
(h : f.Splits i) : (f.comp (X - C a)).Splits i := by
142+
variable {i}
143+
144+
theorem Splits.comp_of_map_degree_le_one {f : K[X]} {p : K[X]} (hd : (p.map i).degree ≤ 1)
145+
(h : f.Splits i) : (f.comp p).Splits i := by
146+
by_cases hzero : map i (f.comp p) = 0
147+
· exact Or.inl hzero
144148
cases h with
145149
| inl h0 =>
146-
left
147-
simp only [map_eq_zero] at h0 ⊢
148-
exact h0.symm ▸ zero_comp
150+
exact Or.inl <| map_comp i _ _ ▸ h0.symm ▸ zero_comp
149151
| inr h =>
150152
right
151153
intro g irr dvd
152-
rw [map_comp, Polynomial.map_sub, map_X, map_C, dvd_comp_X_sub_C_iff] at dvd
153-
have := h (irr.map (algEquivAevalXAddC _)) dvd
154-
rw [degree_eq_natDegree irr.ne_zero]
155-
rwa [algEquivAevalXAddC_apply, ← comp_eq_aeval,
156-
degree_eq_natDegree (fun h => WithBot.bot_ne_one (h ▸ this)),
157-
natDegree_comp, natDegree_X_add_C, mul_one] at this
158-
159-
theorem Splits.comp_X_add_C {i : L →+* F} (a : L) {f : L[X]}
160-
(h : f.Splits i) : (f.comp (X + C a)).Splits i := by
161-
simpa only [map_neg, sub_neg_eq_add] using h.comp_X_sub_C (-a)
154+
rw [map_comp] at dvd hzero
155+
cases lt_or_eq_of_le hd with
156+
| inl hd =>
157+
rw [eq_C_of_degree_le_zero (Nat.WithBot.lt_one_iff_le_zero.mp hd), comp_C] at dvd hzero
158+
refine False.elim (irr.1 (isUnit_of_dvd_unit dvd ?_))
159+
simpa using hzero
160+
| inr hd =>
161+
let _ := invertibleOfNonzero (leadingCoeff_ne_zero.mpr
162+
(ne_zero_of_degree_gt (n := ⊥) (by rw [hd]; decide)))
163+
rw [eq_X_add_C_of_degree_eq_one hd, dvd_comp_C_mul_X_add_C_iff _ _] at dvd
164+
have := h (irr.map (algEquivCMulXAddC _ _).symm) dvd
165+
rw [degree_eq_natDegree irr.ne_zero]
166+
rwa [algEquivCMulXAddC_symm_apply, ← comp_eq_aeval,
167+
degree_eq_natDegree (fun h => WithBot.bot_ne_one (h ▸ this)),
168+
natDegree_comp, natDegree_C_mul (invertibleInvOf.ne_zero),
169+
natDegree_X_sub_C, mul_one] at this
170+
171+
theorem splits_iff_comp_splits_of_degree_eq_one {f : K[X]} {p : K[X]} (hd : (p.map i).degree = 1) :
172+
f.Splits i ↔ (f.comp p).Splits i := by
173+
rw [← splits_id_iff_splits, ← splits_id_iff_splits (f := f.comp p), map_comp]
174+
refine ⟨fun h => Splits.comp_of_map_degree_le_one
175+
(le_of_eq (map_id (R := L) ▸ hd)) h, fun h => ?_⟩
176+
let _ := invertibleOfNonzero (leadingCoeff_ne_zero.mpr
177+
(ne_zero_of_degree_gt (n := ⊥) (by rw [hd]; decide)))
178+
have : (map i f) = ((map i f).comp (map i p)).comp ((C ⅟ (map i p).leadingCoeff *
179+
(X - C ((map i p).coeff 0)))) := by
180+
rw [comp_assoc]
181+
nth_rw 1 [eq_X_add_C_of_degree_eq_one hd]
182+
simp only [coeff_map, invOf_eq_inv, mul_sub, ← C_mul, add_comp, mul_comp, C_comp, X_comp,
183+
← mul_assoc]
184+
simp
185+
refine this ▸ Splits.comp_of_map_degree_le_one ?_ h
186+
simp [degree_C (inv_ne_zero (Invertible.ne_zero (a := (map i p).leadingCoeff)))]
187+
188+
/--
189+
This is a weaker variant of `Splits.comp_of_map_degree_le_one`,
190+
but its conditions are easier to check.
191+
-/
192+
theorem Splits.comp_of_degree_le_one {f : K[X]} {p : K[X]} (hd : p.degree ≤ 1)
193+
(h : f.Splits i) : (f.comp p).Splits i :=
194+
Splits.comp_of_map_degree_le_one ((degree_map_le i _).trans hd) h
195+
196+
theorem Splits.comp_X_sub_C (a : K) {f : K[X]}
197+
(h : f.Splits i) : (f.comp (X - C a)).Splits i :=
198+
Splits.comp_of_degree_le_one (degree_X_sub_C_le _) h
199+
200+
theorem Splits.comp_X_add_C (a : K) {f : K[X]}
201+
(h : f.Splits i) : (f.comp (X + C a)).Splits i :=
202+
Splits.comp_of_degree_le_one (by simpa using degree_X_sub_C_le (-a)) h
203+
204+
theorem Splits.comp_neg_X {f : K[X]} (h : f.Splits i) : (f.comp (-X)).Splits i :=
205+
Splits.comp_of_degree_le_one (by simpa using degree_X_sub_C_le (0 : K)) h
206+
207+
variable (i)
162208

163209
theorem exists_root_of_splits' {f : K[X]} (hs : Splits i f) (hf0 : degree (f.map i) ≠ 0) :
164210
∃ x, eval₂ i x f = 0 :=

Mathlib/RingTheory/Adjoin/Field.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ theorem IsIntegral.mem_range_algebraMap_of_minpoly_splits [Algebra K L] [IsScala
9797
x ∈ (algebraMap K L).range :=
9898
int.mem_range_algHom_of_minpoly_splits h (IsScalarTower.toAlgHom R K L)
9999

100+
theorem minpoly_neg_splits [Algebra K L] {x : L} (g : (minpoly K x).Splits (algebraMap K L)) :
101+
(minpoly K (-x)).Splits (algebraMap K L) := by
102+
rw [minpoly.neg]
103+
apply splits_mul _ _ g.comp_neg_X
104+
simpa only [map_pow, map_neg, map_one] using
105+
splits_C (algebraMap K L) ((-1) ^ (minpoly K x).natDegree)
106+
100107
theorem minpoly_add_algebraMap_splits [Algebra K L] {x : L} (r : K)
101108
(g : (minpoly K x).Splits (algebraMap K L)) :
102109
(minpoly K (x + algebraMap K L r)).Splits (algebraMap K L) := by
@@ -112,6 +119,11 @@ theorem minpoly_algebraMap_add_splits [Algebra K L] {x : L} (r : K)
112119
(minpoly K (algebraMap K L r + x)).Splits (algebraMap K L) := by
113120
simpa only [add_comm] using minpoly_add_algebraMap_splits r g
114121

122+
theorem minpoly_algebraMap_sub_splits [Algebra K L] {x : L} (r : K)
123+
(g : (minpoly K x).Splits (algebraMap K L)) :
124+
(minpoly K (algebraMap K L r - x)).Splits (algebraMap K L) := by
125+
simpa only [neg_sub] using minpoly_neg_splits (minpoly_sub_algebraMap_splits r g)
126+
115127
end
116128

117129
variable [Algebra K M] [IsScalarTower R K M] {x : M}

0 commit comments

Comments
 (0)