Skip to content

Commit dbaa152

Browse files
committed
feat(RingTheory): lemmas about scaleRoots (#30984)
1 parent 8da6dc5 commit dbaa152

File tree

2 files changed

+120
-5
lines changed

2 files changed

+120
-5
lines changed

Mathlib/RingTheory/Polynomial/IntegralNormalization.lean

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,21 @@ theorem integralNormalization_coeff_ne_natDegree {i : ℕ} (hi : i ≠ natDegree
7373
coeff (integralNormalization p) i = coeff p i * p.leadingCoeff ^ (p.natDegree - 1 - i) :=
7474
integralNormalization_coeff_degree_ne (degree_ne_of_natDegree_ne hi.symm)
7575

76+
@[simp]
77+
lemma degree_integralNormalization : p.integralNormalization.degree = p.degree := by
78+
nontriviality R
79+
by_cases hp : p = 0; · simp [hp]
80+
rw [degree_eq_natDegree hp]
81+
refine degree_eq_of_le_of_coeff_ne_zero ?_ (by simp [integralNormalization_coeff_natDegree, *])
82+
exact (Finset.sup_le fun i h =>
83+
WithBot.coe_le_coe.2 <| le_natDegree_of_mem_supp i <| support_integralNormalization_subset h)
84+
85+
@[simp]
86+
lemma natDegree_integralNormalization : p.integralNormalization.natDegree = p.natDegree := by
87+
nontriviality R
88+
by_cases hp : p = 0; · simp [hp]
89+
exact natDegree_eq_of_degree_eq p.degree_integralNormalization
90+
7691
theorem monic_integralNormalization (hp : p ≠ 0) : Monic (integralNormalization p) :=
7792
monic_of_degree_le p.natDegree
7893
(Finset.sup_le fun i h =>
@@ -157,6 +172,12 @@ theorem integralNormalization_aeval_eq_zero [Algebra S A] {f : S[X]} {z : A} (hz
157172
integralNormalization_eval₂_eq_zero_of_commute (algebraMap S A) hz
158173
(Algebra.commute_algebraMap_left _ _) (.map (.all _ _) _) inj
159174

175+
lemma integralNormalization_map (f : R →+* A) (p : R[X]) (H : f p.leadingCoeff ≠ 0) :
176+
(p.map f).integralNormalization = p.integralNormalization.map f := by
177+
ext i
178+
simp [integralNormalization_coeff, degree_map_eq_of_leadingCoeff_ne_zero _ H, apply_ite f,
179+
leadingCoeff_map_of_leadingCoeff_ne_zero _ H, natDegree_map_eq_iff.mpr (.inl H)]
180+
160181
end Semiring
161182

162183
section IsCancelMulZero

Mathlib/RingTheory/Polynomial/ScaleRoots.lean

Lines changed: 99 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,7 @@ Copyright (c) 2020 Anne Baanen. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Anne Baanen, Devon Tuma
55
-/
6-
import Mathlib.Algebra.GroupWithZero.NonZeroDivisors
7-
import Mathlib.Algebra.Polynomial.AlgebraMap
8-
import Mathlib.RingTheory.Coprime.Basic
9-
import Mathlib.Tactic.AdaptationNote
6+
import Mathlib.Algebra.Polynomial.Factors
107

118
/-!
129
# Scaling the roots of a polynomial
@@ -78,8 +75,13 @@ theorem degree_scaleRoots (p : R[X]) {s : R} : degree (scaleRoots p s) = degree
7875
theorem natDegree_scaleRoots (p : R[X]) (s : R) : natDegree (scaleRoots p s) = natDegree p := by
7976
simp only [natDegree, degree_scaleRoots]
8077

78+
@[simp]
79+
lemma leadingCoeff_scaleRoots (p : R[X]) (r : R) :
80+
(p.scaleRoots r).leadingCoeff = p.leadingCoeff := by
81+
rw [leadingCoeff, natDegree_scaleRoots, coeff_scaleRoots_natDegree]
82+
8183
theorem monic_scaleRoots_iff {p : R[X]} (s : R) : Monic (scaleRoots p s) ↔ Monic p := by
82-
simp only [Monic, leadingCoeff, natDegree_scaleRoots, coeff_scaleRoots_natDegree]
84+
simp only [Monic, leadingCoeff_scaleRoots]
8385

8486
theorem map_scaleRoots (p : R[X]) (x : R) (f : R →+* S) (h : f p.leadingCoeff ≠ 0) :
8587
(p.scaleRoots x).map f = (p.map f).scaleRoots (f x) := by
@@ -110,6 +112,11 @@ lemma scaleRoots_zero (p : R[X]) :
110112
lemma one_scaleRoots (r : R) :
111113
(1 : R[X]).scaleRoots r = 1 := by ext; simp
112114

115+
@[simp]
116+
lemma X_add_C_scaleRoots (r s : R) : (X + C r).scaleRoots s = (X + C (r * s)) := by
117+
nontriviality R
118+
ext (_|_|i) <;> simp
119+
113120
end Semiring
114121

115122
section CommSemiring
@@ -143,6 +150,10 @@ theorem scaleRoots_eval₂_mul {p : S[X]} (f : S →+* R) (r : R) (s : S) :
143150
theorem scaleRoots_eval₂_eq_zero {p : S[X]} (f : S →+* R) {r : R} {s : S} (hr : eval₂ f r p = 0) :
144151
eval₂ f (f s * r) (scaleRoots p s) = 0 := by rw [scaleRoots_eval₂_mul, hr, mul_zero]
145152

153+
lemma scaleRoots_eval_mul (p : R[X]) (r s : R) :
154+
eval (s * r) (p.scaleRoots s) = s ^ p.natDegree * eval r p :=
155+
scaleRoots_eval₂_mul _ _ _
156+
146157
theorem scaleRoots_aeval_eq_zero [Algebra R A] {p : R[X]} {a : A} {r : R} (ha : aeval a p = 0) :
147158
aeval (algebraMap R A r * a) (scaleRoots p r) = 0 := by
148159
rw [aeval_def, scaleRoots_eval₂_mul_of_commute, ← aeval_def, ha, mul_zero]
@@ -206,6 +217,24 @@ lemma mul_scaleRoots_of_noZeroDivisors (p q : R[X]) (r : R) [NoZeroDivisors R] :
206217
apply mul_scaleRoots'
207218
simp only [ne_eq, mul_eq_zero, leadingCoeff_eq_zero, hp, hq, or_self, not_false_eq_true]
208219

220+
lemma pow_scaleRoots' (p : R[X]) (r : R) (n : ℕ)
221+
(hp : p.leadingCoeff ^ n ≠ 0) :
222+
(p ^ n).scaleRoots r = p.scaleRoots r ^ n := by
223+
induction n with
224+
| zero => simp
225+
| succ n IH =>
226+
rw [pow_succ, mul_scaleRoots', IH, pow_succ]
227+
· refine mt (by simp +contextual [pow_succ]) hp
228+
· rwa [leadingCoeff_pow' (mt (by simp +contextual [pow_succ]) hp), ← pow_succ]
229+
230+
lemma pow_scaleRoots_of_isReduced [IsReduced R] (p : R[X]) (r : R) (n : ℕ) :
231+
(p ^ n).scaleRoots r = p.scaleRoots r ^ n := by
232+
by_cases hp : p = 0
233+
· simp [hp, zero_pow_eq, apply_ite (scaleRoots · r)]
234+
by_cases hn : n = 0
235+
· simp [hn]
236+
exact pow_scaleRoots' _ _ _ (by simp_all)
237+
209238
lemma add_scaleRoots_of_natDegree_eq (p q : R[X]) (r : R) (h : natDegree p = natDegree q) :
210239
r ^ (natDegree p - natDegree (p + q)) • (p + q).scaleRoots r =
211240
p.scaleRoots r + q.scaleRoots r := by
@@ -252,8 +281,73 @@ lemma isCoprime_scaleRoots (p q : R[X]) (r : R) (hr : IsUnit r) (h : IsCoprime p
252281
simp only [s, smul_mul_assoc, ← mul_scaleRoots, smul_smul, mul_assoc,
253282
← mul_pow, IsUnit.val_inv_mul, one_pow, mul_one, ← smul_add, one_smul, e, natDegree_one,
254283
one_scaleRoots, ← add_scaleRoots_of_natDegree_eq _ _ _ this, tsub_zero]
284+
255285
alias _root_.IsCoprime.scaleRoots := isCoprime_scaleRoots
256286

287+
lemma Factors.scaleRoots {p : R[X]} (hp : p.Factors) (r : R) :
288+
(p.scaleRoots r).Factors := by
289+
cases subsingleton_or_nontrivial R
290+
· rwa [Subsingleton.elim (p.scaleRoots r) p]
291+
obtain rfl | hp0 := eq_or_ne p 0
292+
· simp
293+
obtain ⟨m, hm⟩ := factors_iff_exists_multiset'.mp hp
294+
rw [hm, mul_scaleRoots', scaleRoots_C]
295+
· clear hm
296+
refine .mul (.C _) ?_
297+
induction m using Multiset.induction_on with
298+
| empty => simp
299+
| cons a s IH =>
300+
rw [Multiset.map_cons, Multiset.prod_cons, mul_scaleRoots', X_add_C_scaleRoots]
301+
· exact .mul (.X_add_C _) IH
302+
· simp only [leadingCoeff_X_add_C, one_mul, ne_eq, leadingCoeff_eq_zero]
303+
exact (monic_multiset_prod_of_monic _ _ fun a _ ↦ monic_X_add_C _).ne_zero
304+
· rw [(monic_multiset_prod_of_monic _ _ fun a _ ↦ monic_X_add_C _).leadingCoeff]
305+
simpa
306+
257307
end CommSemiring
258308

309+
section Ring
310+
311+
@[simp]
312+
lemma X_sub_C_scaleRoots [Ring R] (r s : R) :
313+
(X - C r).scaleRoots s = (X - C (r * s)) := by
314+
nontriviality R
315+
ext (_|_|i) <;> simp
316+
317+
end Ring
318+
319+
section CommRing
320+
321+
variable [CommRing R]
322+
323+
lemma rootMultiplicity_scaleRoots (p : R[X]) {r a : R} (hr : IsLeftRegular r) :
324+
rootMultiplicity (r * a) (p.scaleRoots r) = rootMultiplicity a p := by
325+
cases subsingleton_or_nontrivial R
326+
· simp [Subsingleton.elim p 0]
327+
obtain rfl | hp := eq_or_ne p 0
328+
· simp
329+
obtain ⟨q, e, hq⟩ := exists_eq_pow_rootMultiplicity_mul_and_not_dvd p hp a
330+
have hq0 : q ≠ 0 := by contrapose! hp; simp_all
331+
conv_lhs => rw [e]
332+
rw [mul_scaleRoots', pow_scaleRoots', X_sub_C_scaleRoots, mul_comm, mul_comm _ (q.scaleRoots r),
333+
rootMultiplicity_mul_X_sub_C_pow (q.scaleRoots_ne_zero hq0 _)]
334+
· rw [dvd_iff_isRoot, IsRoot.def] at hq
335+
simp only [Nat.add_eq_right, rootMultiplicity_eq_zero_iff, IsRoot.def]
336+
rw [mul_comm, scaleRoots_eval_mul, (hr.pow q.natDegree).mul_left_eq_zero_iff]
337+
tauto
338+
· simp
339+
· rwa [leadingCoeff_pow' (by simp), leadingCoeff_X_sub_C,
340+
one_pow, one_mul, ne_eq, leadingCoeff_eq_zero]
341+
342+
lemma roots_scaleRoots [IsDomain R] (p : R[X]) {r : R} (hr : IsUnit r) :
343+
(p.scaleRoots r).roots = p.roots.map (r * ·) := by
344+
classical
345+
ext a
346+
have : Function.Bijective (α := R) (r * ·) := IsUnit.isUnit_iff_mulLeft_bijective.mp hr
347+
obtain ⟨a, rfl⟩ := this.2 a
348+
simp [Multiset.count_map_eq_count' _ p.roots this.1 a,
349+
rootMultiplicity_scaleRoots _ hr.isRegular.left]
350+
351+
end CommRing
352+
259353
end Polynomial

0 commit comments

Comments
 (0)