Skip to content

Commit 812fedb

Browse files
committed
feat(Algebra/Polynomial): add lemmas (#23252)
1 parent c768c54 commit 812fedb

File tree

6 files changed

+53
-7
lines changed

6 files changed

+53
-7
lines changed

Mathlib/Algebra/Polynomial/BigOperators.lean

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ theorem prod_X_sub_C_coeff_card_pred (s : Finset ι) (f : ι → R) (hs : 0 < #s
275275
(∏ i ∈ s, (X - C (f i))).coeff (#s - 1) = -∑ i ∈ s, f i := by
276276
simpa using multiset_prod_X_sub_C_coeff_card_pred (s.1.map f) (by simpa using hs)
277277

278-
variable [IsDomain R]
278+
variable [Nontrivial R]
279279

280280
@[simp]
281281
lemma natDegree_multiset_prod_X_sub_C_eq_card (s : Multiset R) :
@@ -285,6 +285,11 @@ lemma natDegree_multiset_prod_X_sub_C_eq_card (s : Multiset R) :
285285
mul_one]
286286
· exact Multiset.forall_mem_map_iff.2 fun a _ => monic_X_sub_C a
287287

288+
@[simp] lemma natDegree_finset_prod_X_sub_C_eq_card {α} (s : Finset α) (f : α → R) :
289+
(∏ a ∈ s, (X - C (f a))).natDegree = s.card := by
290+
rw [Finset.prod, ← (X - C ·).comp_def f, ← Multiset.map_map,
291+
natDegree_multiset_prod_X_sub_C_eq_card, Multiset.card_map, Finset.card]
292+
288293
end CommRing
289294

290295
section NoZeroDivisors

Mathlib/Algebra/Polynomial/Lifts.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -226,6 +226,10 @@ theorem smul_mem_lifts {p : S[X]} (r : R) (hp : p ∈ lifts (algebraMap R S)) :
226226
rw [mem_lifts_iff_mem_alg] at hp ⊢
227227
exact Subalgebra.smul_mem (mapAlg R S).range hp r
228228

229+
theorem monic_of_monic_mapAlg [FaithfulSMul R S] {p : Polynomial R} (hp : (mapAlg R S p).Monic) :
230+
p.Monic :=
231+
monic_of_injective (FaithfulSMul.algebraMap_injective R S) hp
232+
229233
end Algebra
230234

231235
end Polynomial

Mathlib/Algebra/Polynomial/Monic.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,15 @@ theorem monic_prod_of_monic (s : Finset ι) (f : ι → R[X]) (hs : ∀ i ∈ s,
258258
Monic (∏ i ∈ s, f i) :=
259259
monic_multiset_prod_of_monic s.1 f hs
260260

261+
theorem monic_finprod_of_monic (α : Type*) (f : α → R[X])
262+
(hf : ∀ i ∈ Function.mulSupport f, Monic (f i)) :
263+
Monic (finprod f) := by
264+
classical
265+
rw [finprod_def]
266+
split_ifs
267+
· exact monic_prod_of_monic _ _ fun a ha => hf a ((Set.Finite.mem_toFinset _).mp ha)
268+
· exact monic_one
269+
261270
theorem Monic.nextCoeff_multiset_prod (t : Multiset ι) (f : ι → R[X]) (h : ∀ i ∈ t, Monic (f i)) :
262271
nextCoeff (t.map f).prod = (t.map fun i => nextCoeff (f i)).sum := by
263272
revert h

Mathlib/Algebra/Polynomial/RingDivision.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,12 @@ theorem mem_nonZeroDivisors_of_trailingCoeff {p : R[X]} (h : p.trailingCoeff ∈
130130

131131
end nonZeroDivisors
132132

133+
theorem natDegree_pos_of_monic_of_aeval_eq_zero [Nontrivial R] [Semiring S] [Algebra R S]
134+
[FaithfulSMul R S] {p : R[X]} (hp : p.Monic) {x : S} (hx : aeval x p = 0) :
135+
0 < p.natDegree :=
136+
natDegree_pos_of_aeval_root (Monic.ne_zero hp) hx
137+
((injective_iff_map_eq_zero (algebraMap R S)).mp (FaithfulSMul.algebraMap_injective R S))
138+
133139
theorem rootMultiplicity_mul_X_sub_C_pow {p : R[X]} {a : R} {n : ℕ} (h : p ≠ 0) :
134140
(p * (X - C a) ^ n).rootMultiplicity a = p.rootMultiplicity a + n := by
135141
have h2 := monic_X_sub_C a |>.pow n |>.mul_left_ne_zero h

Mathlib/Algebra/Polynomial/Roots.lean

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -618,9 +618,22 @@ lemma exists_eval_ne_zero_of_natDegree_lt_card (f : R[X]) (hf : f ≠ 0) (hfR :
618618
contrapose! hf
619619
exact eq_zero_of_forall_eval_zero_of_natDegree_lt_card f hf hfR
620620

621-
theorem monic_prod_multiset_X_sub_C : Monic (p.roots.map fun a => X - C a).prod :=
621+
section
622+
623+
omit [IsDomain R]
624+
625+
theorem monic_multisetProd_X_sub_C (s : Multiset R) : Monic (s.map fun a => X - C a).prod :=
622626
monic_multiset_prod_of_monic _ _ fun a _ => monic_X_sub_C a
623627

628+
theorem monic_prod_X_sub_C {α : Type*} (b : α → R) (s : Finset α) :
629+
Monic (∏ a ∈ s, (X - C (b a))) :=
630+
monic_prod_of_monic _ _ fun a _ => monic_X_sub_C (b a)
631+
632+
theorem monic_finprod_X_sub_C {α : Type*} (b : α → R) : Monic (∏ᶠ k, (X - C (b k))) :=
633+
monic_finprod_of_monic _ _ fun a _ => monic_X_sub_C (b a)
634+
635+
end
636+
624637
theorem prod_multiset_root_eq_finset_root [DecidableEq R] :
625638
(p.roots.map fun a => X - C a).prod =
626639
p.roots.toFinset.prod fun a => (X - C a) ^ rootMultiplicity a p := by
@@ -629,7 +642,8 @@ theorem prod_multiset_root_eq_finset_root [DecidableEq R] :
629642
/-- The product `∏ (X - a)` for `a` inside the multiset `p.roots` divides `p`. -/
630643
theorem prod_multiset_X_sub_C_dvd (p : R[X]) : (p.roots.map fun a => X - C a).prod ∣ p := by
631644
classical
632-
rw [← map_dvd_map _ (IsFractionRing.injective R <| FractionRing R) monic_prod_multiset_X_sub_C]
645+
rw [← map_dvd_map _ (IsFractionRing.injective R <| FractionRing R)
646+
(monic_multisetProd_X_sub_C p.roots)]
633647
rw [prod_multiset_root_eq_finset_root, Polynomial.map_prod]
634648
refine Finset.prod_dvd_of_coprime (fun a _ b _ h => ?_) fun a _ => ?_
635649
· simp_rw [Polynomial.map_pow, Polynomial.map_sub, map_C, map_X]
@@ -660,16 +674,17 @@ theorem exists_prod_multiset_X_sub_C_mul (p : R[X]) :
660674
simp
661675
constructor
662676
· conv_rhs => rw [he]
663-
rw [monic_prod_multiset_X_sub_C.natDegree_mul' hq, natDegree_multiset_prod_X_sub_C_eq_card]
677+
rw [(monic_multisetProd_X_sub_C p.roots).natDegree_mul' hq,
678+
natDegree_multiset_prod_X_sub_C_eq_card]
664679
· replace he := congr_arg roots he.symm
665680
rw [roots_mul, roots_multiset_prod_X_sub_C] at he
666-
exacts [add_eq_left.1 he, mul_ne_zero monic_prod_multiset_X_sub_C.ne_zero hq]
681+
exacts [add_eq_left.1 he, mul_ne_zero (monic_multisetProd_X_sub_C p.roots).ne_zero hq]
667682

668683
/-- A polynomial `p` that has as many roots as its degree
669684
can be written `p = p.leadingCoeff * ∏(X - a)`, for `a` in `p.roots`. -/
670685
theorem C_leadingCoeff_mul_prod_multiset_X_sub_C (hroots : Multiset.card p.roots = p.natDegree) :
671686
C p.leadingCoeff * (p.roots.map fun a => X - C a).prod = p :=
672-
(eq_leadingCoeff_mul_of_monic_of_dvd_of_natDegree_le monic_prod_multiset_X_sub_C
687+
(eq_leadingCoeff_mul_of_monic_of_dvd_of_natDegree_le (monic_multisetProd_X_sub_C p.roots)
673688
p.prod_multiset_X_sub_C_dvd
674689
((natDegree_multiset_prod_X_sub_C_eq_card _).trans hroots).ge).symm
675690

Mathlib/Algebra/Polynomial/Splits.lean

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,14 +248,21 @@ theorem natDegree_eq_card_roots' {p : K[X]} {i : K →+* L} (hsplit : Splits i p
248248
· rw [map_id] at this
249249
exact this hr
250250
· rw [map_id]
251-
exact mul_ne_zero monic_prod_multiset_X_sub_C.ne_zero hq
251+
exact mul_ne_zero (monic_multisetProd_X_sub_C _).ne_zero hq
252252

253253
theorem degree_eq_card_roots' {p : K[X]} {i : K →+* L} (p_ne_zero : p.map i ≠ 0)
254254
(hsplit : Splits i p) : (p.map i).degree = Multiset.card (p.map i).roots := by
255255
simp [degree_eq_natDegree p_ne_zero, natDegree_eq_card_roots' hsplit]
256256

257257
end CommRing
258258

259+
theorem aeval_root_of_mapAlg_eq_multiset_prod_X_sub_C [CommSemiring R] [CommRing L] [Algebra R L]
260+
(s : Multiset L) {x : L} (hx : x ∈ s) {p : R[X]}
261+
(hp : mapAlg R L p = (Multiset.map (fun a : L ↦ X - C a) s).prod) : aeval x p = 0 := by
262+
rw [← aeval_map_algebraMap L, ← mapAlg_eq_map, hp, map_multiset_prod, Multiset.prod_eq_zero]
263+
rw [Multiset.map_map, Multiset.mem_map]
264+
exact ⟨x, hx, by simp⟩
265+
259266
variable [CommRing R] [Field K] [Field L] [Field F]
260267
variable (i : K →+* L)
261268

0 commit comments

Comments
 (0)