Skip to content

Commit ac12c87

Browse files
committed
chore(Algebra/Polynomial/RingDivision): move lemmas earlier (#18050)
`Algebra.Polynomial.RingDivision` is a bag grab of lemmas with absolutely no running theme. This PR moves two thirds of them to earlier files with no proof change.
1 parent 818db40 commit ac12c87

File tree

17 files changed

+613
-626
lines changed

17 files changed

+613
-626
lines changed

Mathlib/Algebra/Polynomial/AlgebraMap.lean

Lines changed: 71 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,11 +531,30 @@ theorem not_isUnit_X_sub_C [Nontrivial R] (r : R) : ¬IsUnit (X - C r) :=
531531

532532
end Ring
533533

534-
theorem aeval_endomorphism {M : Type*} [CommRing R] [AddCommGroup M] [Module R M] (f : M →ₗ[R] M)
534+
section CommRing
535+
variable [CommRing R] {p : R[X]} {t : R}
536+
537+
theorem aeval_endomorphism {M : Type*} [AddCommGroup M] [Module R M] (f : M →ₗ[R] M)
535538
(v : M) (p : R[X]) : aeval f p v = p.sum fun n b => b • (f ^ n) v := by
536539
rw [aeval_def, eval₂_eq_sum]
537540
exact map_sum (LinearMap.applyₗ v) _ _
538541

542+
lemma X_sub_C_pow_dvd_iff {n : ℕ} : (X - C t) ^ n ∣ p ↔ X ^ n ∣ p.comp (X + C t) := by
543+
convert (map_dvd_iff <| algEquivAevalXAddC t).symm using 2
544+
simp [C_eq_algebraMap]
545+
546+
lemma comp_X_add_C_eq_zero_iff : p.comp (X + C t) = 0 ↔ p = 0 :=
547+
AddEquivClass.map_eq_zero_iff (algEquivAevalXAddC t)
548+
549+
lemma comp_X_add_C_ne_zero_iff : p.comp (X + C t) ≠ 0 ↔ p ≠ 0 := comp_X_add_C_eq_zero_iff.not
550+
551+
variable [IsDomain R]
552+
553+
lemma units_coeff_zero_smul (c : R[X]ˣ) (p : R[X]) : (c : R[X]).coeff 0 • p = c * p := by
554+
rw [← Polynomial.C_mul', ← Polynomial.eq_C_of_degree_eq_zero (degree_coe_units c)]
555+
556+
end CommRing
557+
539558
section StableSubmodule
540559

541560
variable {M : Type*} [CommSemiring R] [AddCommMonoid M] [Module R M]
@@ -561,4 +580,55 @@ lemma aeval_apply_smul_mem_of_le_comap
561580

562581
end StableSubmodule
563582

583+
section CommSemiring
584+
585+
variable [CommSemiring R] {a p : R[X]}
586+
587+
theorem eq_zero_of_mul_eq_zero_of_smul (P : R[X]) (h : ∀ r : R, r • P = 0 → r = 0) :
588+
∀ (Q : R[X]), P * Q = 0 → Q = 0 := by
589+
intro Q hQ
590+
suffices ∀ i, P.coeff i • Q = 0 by
591+
rw [← leadingCoeff_eq_zero]
592+
apply h
593+
simpa [ext_iff, mul_comm Q.leadingCoeff] using fun i ↦ congr_arg (·.coeff Q.natDegree) (this i)
594+
apply Nat.strong_decreasing_induction
595+
· use P.natDegree
596+
intro i hi
597+
rw [coeff_eq_zero_of_natDegree_lt hi, zero_smul]
598+
intro l IH
599+
obtain _|hl := (natDegree_smul_le (P.coeff l) Q).lt_or_eq
600+
· apply eq_zero_of_mul_eq_zero_of_smul _ h (P.coeff l • Q)
601+
rw [smul_eq_C_mul, mul_left_comm, hQ, mul_zero]
602+
suffices P.coeff l * Q.leadingCoeff = 0 by
603+
rwa [← leadingCoeff_eq_zero, ← coeff_natDegree, coeff_smul, hl, coeff_natDegree, smul_eq_mul]
604+
let m := Q.natDegree
605+
suffices (P * Q).coeff (l + m) = P.coeff l * Q.leadingCoeff by rw [← this, hQ, coeff_zero]
606+
rw [coeff_mul]
607+
apply Finset.sum_eq_single (l, m) _ (by simp)
608+
simp only [Finset.mem_antidiagonal, ne_eq, Prod.forall, Prod.mk.injEq, not_and]
609+
intro i j hij H
610+
obtain hi|rfl|hi := lt_trichotomy i l
611+
· have hj : m < j := by omega
612+
rw [coeff_eq_zero_of_natDegree_lt hj, mul_zero]
613+
· omega
614+
· rw [← coeff_C_mul, ← smul_eq_C_mul, IH _ hi, coeff_zero]
615+
termination_by Q => Q.natDegree
616+
617+
open nonZeroDivisors in
618+
/-- *McCoy theorem*: a polynomial `P : R[X]` is a zerodivisor if and only if there is `a : R`
619+
such that `a ≠ 0` and `a • P = 0`. -/
620+
theorem nmem_nonZeroDivisors_iff {P : R[X]} : P ∉ R[X]⁰ ↔ ∃ a : R, a ≠ 0 ∧ a • P = 0 := by
621+
refine ⟨fun hP ↦ ?_, fun ⟨a, ha, h⟩ h1 ↦ ha <| C_eq_zero.1 <| (h1 _) <| smul_eq_C_mul a ▸ h⟩
622+
by_contra! h
623+
obtain ⟨Q, hQ⟩ := _root_.nmem_nonZeroDivisors_iff.1 hP
624+
refine hQ.2 (eq_zero_of_mul_eq_zero_of_smul P (fun a ha ↦ ?_) Q (mul_comm P _ ▸ hQ.1))
625+
contrapose! ha
626+
exact h a ha
627+
628+
open nonZeroDivisors in
629+
protected lemma mem_nonZeroDivisors_iff {P : R[X]} : P ∈ R[X]⁰ ↔ ∀ a : R, a • P = 0 → a = 0 := by
630+
simpa [not_imp_not] using (nmem_nonZeroDivisors_iff (P := P)).not
631+
632+
end CommSemiring
633+
564634
end Polynomial

Mathlib/Algebra/Polynomial/BigOperators.lean

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,16 @@ theorem prod_X_sub_C_coeff_card_pred (s : Finset ι) (f : ι → R) (hs : 0 < #s
270270
(∏ i ∈ s, (X - C (f i))).coeff (#s - 1) = -∑ i ∈ s, f i := by
271271
simpa using multiset_prod_X_sub_C_coeff_card_pred (s.1.map f) (by simpa using hs)
272272

273+
variable [IsDomain R]
274+
275+
@[simp]
276+
lemma natDegree_multiset_prod_X_sub_C_eq_card (s : Multiset R) :
277+
(s.map (X - C ·)).prod.natDegree = Multiset.card s := by
278+
rw [natDegree_multiset_prod_of_monic, Multiset.map_map]
279+
· simp only [(· ∘ ·), natDegree_X_sub_C, Multiset.map_const', Multiset.sum_replicate, smul_eq_mul,
280+
mul_one]
281+
· exact Multiset.forall_mem_map_iff.2 fun a _ => monic_X_sub_C a
282+
273283
end CommRing
274284

275285
section NoZeroDivisors

Mathlib/Algebra/Polynomial/Degree/Definitions.lean

Lines changed: 185 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1370,8 +1370,188 @@ theorem leadingCoeff_pow_X_add_C (r : R) (i : ℕ) : leadingCoeff ((X + C r) ^ i
13701370
nontriviality
13711371
rw [leadingCoeff_pow'] <;> simp
13721372

1373+
variable [NoZeroDivisors R] {p q : R[X]}
1374+
1375+
@[simp]
1376+
lemma degree_mul : degree (p * q) = degree p + degree q :=
1377+
letI := Classical.decEq R
1378+
if hp0 : p = 0 then by simp only [hp0, degree_zero, zero_mul, WithBot.bot_add]
1379+
else
1380+
if hq0 : q = 0 then by simp only [hq0, degree_zero, mul_zero, WithBot.add_bot]
1381+
else degree_mul' <| mul_ne_zero (mt leadingCoeff_eq_zero.1 hp0) (mt leadingCoeff_eq_zero.1 hq0)
1382+
1383+
/-- `degree` as a monoid homomorphism between `R[X]` and `Multiplicative (WithBot ℕ)`.
1384+
This is useful to prove results about multiplication and degree. -/
1385+
def degreeMonoidHom [Nontrivial R] : R[X] →* Multiplicative (WithBot ℕ) where
1386+
toFun := degree
1387+
map_one' := degree_one
1388+
map_mul' _ _ := degree_mul
1389+
1390+
@[simp]
1391+
lemma degree_pow [Nontrivial R] (p : R[X]) (n : ℕ) : degree (p ^ n) = n • degree p :=
1392+
map_pow (@degreeMonoidHom R _ _ _) _ _
1393+
1394+
@[simp]
1395+
lemma leadingCoeff_mul (p q : R[X]) : leadingCoeff (p * q) = leadingCoeff p * leadingCoeff q := by
1396+
by_cases hp : p = 0
1397+
· simp only [hp, zero_mul, leadingCoeff_zero]
1398+
· by_cases hq : q = 0
1399+
· simp only [hq, mul_zero, leadingCoeff_zero]
1400+
· rw [leadingCoeff_mul']
1401+
exact mul_ne_zero (mt leadingCoeff_eq_zero.1 hp) (mt leadingCoeff_eq_zero.1 hq)
1402+
1403+
/-- `Polynomial.leadingCoeff` bundled as a `MonoidHom` when `R` has `NoZeroDivisors`, and thus
1404+
`leadingCoeff` is multiplicative -/
1405+
def leadingCoeffHom : R[X] →* R where
1406+
toFun := leadingCoeff
1407+
map_one' := by simp
1408+
map_mul' := leadingCoeff_mul
1409+
1410+
@[simp]
1411+
lemma leadingCoeffHom_apply (p : R[X]) : leadingCoeffHom p = leadingCoeff p :=
1412+
rfl
1413+
1414+
@[simp]
1415+
lemma leadingCoeff_pow (p : R[X]) (n : ℕ) : leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
1416+
(leadingCoeffHom : R[X] →* R).map_pow p n
1417+
1418+
lemma leadingCoeff_dvd_leadingCoeff {a p : R[X]} (hap : a ∣ p) :
1419+
a.leadingCoeff ∣ p.leadingCoeff :=
1420+
map_dvd leadingCoeffHom hap
1421+
1422+
instance : NoZeroDivisors R[X] where
1423+
eq_zero_or_eq_zero_of_mul_eq_zero h := by
1424+
rw [← leadingCoeff_eq_zero, ← leadingCoeff_eq_zero]
1425+
refine eq_zero_or_eq_zero_of_mul_eq_zero ?_
1426+
rw [← leadingCoeff_zero, ← leadingCoeff_mul, h]
1427+
lemma natDegree_mul (hp : p ≠ 0) (hq : q ≠ 0) : (p*q).natDegree = p.natDegree + q.natDegree := by
1428+
rw [← Nat.cast_inj (R := WithBot ℕ), ← degree_eq_natDegree (mul_ne_zero hp hq),
1429+
Nat.cast_add, ← degree_eq_natDegree hp, ← degree_eq_natDegree hq, degree_mul]
1430+
1431+
@[simp]
1432+
lemma natDegree_pow (p : R[X]) (n : ℕ) : natDegree (p ^ n) = n * natDegree p := by
1433+
classical
1434+
obtain rfl | hp := eq_or_ne p 0
1435+
· obtain rfl | hn := eq_or_ne n 0 <;> simp [*]
1436+
exact natDegree_pow' <| by
1437+
rw [← leadingCoeff_pow, Ne, leadingCoeff_eq_zero]; exact pow_ne_zero _ hp
1438+
1439+
lemma degree_le_mul_left (p : R[X]) (hq : q ≠ 0) : degree p ≤ degree (p * q) := by
1440+
classical
1441+
obtain rfl | hp := eq_or_ne p 0
1442+
· simp
1443+
· rw [degree_mul, degree_eq_natDegree hp, degree_eq_natDegree hq]
1444+
exact WithBot.coe_le_coe.2 (Nat.le_add_right _ _)
1445+
1446+
lemma natDegree_le_of_dvd (h1 : p ∣ q) (h2 : q ≠ 0) : p.natDegree ≤ q.natDegree := by
1447+
obtain ⟨q, rfl⟩ := h1
1448+
rw [mul_ne_zero_iff] at h2
1449+
rw [natDegree_mul h2.1 h2.2]; exact Nat.le_add_right _ _
1450+
1451+
lemma degree_le_of_dvd (h1 : p ∣ q) (h2 : q ≠ 0) : degree p ≤ degree q := by
1452+
rcases h1 with ⟨q, rfl⟩; rw [mul_ne_zero_iff] at h2
1453+
exact degree_le_mul_left p h2.2
1454+
1455+
lemma eq_zero_of_dvd_of_degree_lt (h₁ : p ∣ q) (h₂ : degree q < degree p) : q = 0 := by
1456+
by_contra hc
1457+
exact (lt_iff_not_ge _ _).mp h₂ (degree_le_of_dvd h₁ hc)
1458+
1459+
lemma eq_zero_of_dvd_of_natDegree_lt (h₁ : p ∣ q) (h₂ : natDegree q < natDegree p) :
1460+
q = 0 := by
1461+
by_contra hc
1462+
exact (lt_iff_not_ge _ _).mp h₂ (natDegree_le_of_dvd h₁ hc)
1463+
1464+
lemma not_dvd_of_degree_lt (h0 : q ≠ 0) (hl : q.degree < p.degree) : ¬p ∣ q := by
1465+
by_contra hcontra
1466+
exact h0 (eq_zero_of_dvd_of_degree_lt hcontra hl)
1467+
1468+
lemma not_dvd_of_natDegree_lt (h0 : q ≠ 0) (hl : q.natDegree < p.natDegree) :
1469+
¬p ∣ q := by
1470+
by_contra hcontra
1471+
exact h0 (eq_zero_of_dvd_of_natDegree_lt hcontra hl)
1472+
1473+
/-- This lemma is useful for working with the `intDegree` of a rational function. -/
1474+
lemma natDegree_sub_eq_of_prod_eq {p₁ p₂ q₁ q₂ : R[X]} (hp₁ : p₁ ≠ 0) (hq₁ : q₁ ≠ 0)
1475+
(hp₂ : p₂ ≠ 0) (hq₂ : q₂ ≠ 0) (h_eq : p₁ * q₂ = p₂ * q₁) :
1476+
(p₁.natDegree : ℤ) - q₁.natDegree = (p₂.natDegree : ℤ) - q₂.natDegree := by
1477+
rw [sub_eq_sub_iff_add_eq_add]
1478+
norm_cast
1479+
rw [← natDegree_mul hp₁ hq₂, ← natDegree_mul hp₂ hq₁, h_eq]
1480+
1481+
lemma natDegree_eq_zero_of_isUnit (h : IsUnit p) : natDegree p = 0 := by
1482+
nontriviality R
1483+
obtain ⟨q, hq⟩ := h.exists_right_inv
1484+
have := natDegree_mul (left_ne_zero_of_mul_eq_one hq) (right_ne_zero_of_mul_eq_one hq)
1485+
rw [hq, natDegree_one, eq_comm, add_eq_zero] at this
1486+
exact this.1
1487+
1488+
lemma degree_eq_zero_of_isUnit [Nontrivial R] (h : IsUnit p) : degree p = 0 :=
1489+
(natDegree_eq_zero_iff_degree_le_zero.mp <| natDegree_eq_zero_of_isUnit h).antisymm
1490+
(zero_le_degree_iff.mpr h.ne_zero)
1491+
1492+
@[simp]
1493+
lemma degree_coe_units [Nontrivial R] (u : R[X]ˣ) : degree (u : R[X]) = 0 :=
1494+
degree_eq_zero_of_isUnit ⟨u, rfl⟩
1495+
1496+
/-- Characterization of a unit of a polynomial ring over an integral domain `R`.
1497+
See `Polynomial.isUnit_iff_coeff_isUnit_isNilpotent` when `R` is a commutative ring. -/
1498+
lemma isUnit_iff : IsUnit p ↔ ∃ r : R, IsUnit r ∧ C r = p :=
1499+
fun hp =>
1500+
⟨p.coeff 0,
1501+
let h := eq_C_of_natDegree_eq_zero (natDegree_eq_zero_of_isUnit hp)
1502+
⟨isUnit_C.1 (h ▸ hp), h.symm⟩⟩,
1503+
fun ⟨_, hr, hrp⟩ => hrp ▸ isUnit_C.2 hr⟩
1504+
1505+
lemma not_isUnit_of_degree_pos (p : R[X]) (hpl : 0 < p.degree) : ¬ IsUnit p := by
1506+
cases subsingleton_or_nontrivial R
1507+
· simp [Subsingleton.elim p 0] at hpl
1508+
intro h
1509+
simp [degree_eq_zero_of_isUnit h] at hpl
1510+
1511+
lemma not_isUnit_of_natDegree_pos (p : R[X]) (hpl : 0 < p.natDegree) : ¬ IsUnit p :=
1512+
not_isUnit_of_degree_pos _ (natDegree_pos_iff_degree_pos.mp hpl)
1513+
1514+
@[simp] lemma natDegree_coe_units (u : R[X]ˣ) : natDegree (u : R[X]) = 0 := by
1515+
nontriviality R
1516+
exact natDegree_eq_of_degree_eq_some (degree_coe_units u)
1517+
1518+
theorem coeff_coe_units_zero_ne_zero [Nontrivial R] (u : R[X]ˣ) : coeff (u : R[X]) 00 := by
1519+
conv in 0 => rw [← natDegree_coe_units u]
1520+
rw [← leadingCoeff, Ne, leadingCoeff_eq_zero]
1521+
exact Units.ne_zero _
1522+
13731523
end Semiring
13741524

1525+
section CommSemiring
1526+
variable [CommSemiring R] {a p : R[X]} (hp : p.Monic)
1527+
include hp
1528+
1529+
lemma Monic.C_dvd_iff_isUnit {a : R} : C a ∣ p ↔ IsUnit a where
1530+
mp h := isUnit_iff_dvd_one.mpr <| hp.coeff_natDegree ▸ (C_dvd_iff_dvd_coeff _ _).mp h p.natDegree
1531+
mpr ha := (ha.map C).dvd
1532+
1533+
lemma Monic.natDegree_pos : 0 < natDegree p ↔ p ≠ 1 :=
1534+
Nat.pos_iff_ne_zero.trans hp.natDegree_eq_zero.not
1535+
1536+
lemma Monic.degree_pos : 0 < degree p ↔ p ≠ 1 :=
1537+
natDegree_pos_iff_degree_pos.symm.trans hp.natDegree_pos
1538+
1539+
lemma Monic.degree_pos_of_not_isUnit (hu : ¬IsUnit p) : 0 < degree p :=
1540+
hp.degree_pos.mpr fun hp' ↦ (hp' ▸ hu) isUnit_one
1541+
1542+
lemma Monic.natDegree_pos_of_not_isUnit (hu : ¬IsUnit p) : 0 < natDegree p :=
1543+
hp.natDegree_pos.mpr fun hp' ↦ (hp' ▸ hu) isUnit_one
1544+
1545+
lemma degree_pos_of_not_isUnit_of_dvd_monic (ha : ¬IsUnit a) (hap : a ∣ p) : 0 < degree a := by
1546+
contrapose! ha with h
1547+
rw [Polynomial.eq_C_of_degree_le_zero h] at hap ⊢
1548+
simpa [hp.C_dvd_iff_isUnit, isUnit_C] using hap
1549+
1550+
lemma natDegree_pos_of_not_isUnit_of_dvd_monic (ha : ¬IsUnit a) (hap : a ∣ p) : 0 < natDegree a :=
1551+
natDegree_pos_iff_degree_pos.mpr <| degree_pos_of_not_isUnit_of_dvd_monic hp ha hap
1552+
1553+
end CommSemiring
1554+
13751555
section Ring
13761556

13771557
variable [Ring R]
@@ -1420,59 +1600,11 @@ theorem natDegree_X_pow_sub_C {n : ℕ} {r : R} : (X ^ n - C r).natDegree = n :=
14201600
theorem leadingCoeff_X_sub_C [Ring S] (r : S) : (X - C r).leadingCoeff = 1 := by
14211601
rw [sub_eq_add_neg, ← map_neg C r, leadingCoeff_X_add_C]
14221602

1423-
end Ring
1424-
1425-
section NoZeroDivisors
1426-
1427-
variable [Semiring R] [NoZeroDivisors R] {p q : R[X]}
1428-
1429-
@[simp]
1430-
theorem degree_mul : degree (p * q) = degree p + degree q :=
1431-
letI := Classical.decEq R
1432-
if hp0 : p = 0 then by simp only [hp0, degree_zero, zero_mul, WithBot.bot_add]
1433-
else
1434-
if hq0 : q = 0 then by simp only [hq0, degree_zero, mul_zero, WithBot.add_bot]
1435-
else degree_mul' <| mul_ne_zero (mt leadingCoeff_eq_zero.1 hp0) (mt leadingCoeff_eq_zero.1 hq0)
1436-
1437-
/-- `degree` as a monoid homomorphism between `R[X]` and `Multiplicative (WithBot ℕ)`.
1438-
This is useful to prove results about multiplication and degree. -/
1439-
def degreeMonoidHom [Nontrivial R] : R[X] →* Multiplicative (WithBot ℕ) where
1440-
toFun := degree
1441-
map_one' := degree_one
1442-
map_mul' _ _ := degree_mul
1603+
variable [IsDomain R] {p q : R[X]}
14431604

1444-
@[simp]
1445-
theorem degree_pow [Nontrivial R] (p : R[X]) (n : ℕ) : degree (p ^ n) = n • degree p :=
1446-
map_pow (@degreeMonoidHom R _ _ _) _ _
1447-
1448-
@[simp]
1449-
theorem leadingCoeff_mul (p q : R[X]) : leadingCoeff (p * q) = leadingCoeff p * leadingCoeff q := by
1450-
by_cases hp : p = 0
1451-
· simp only [hp, zero_mul, leadingCoeff_zero]
1452-
· by_cases hq : q = 0
1453-
· simp only [hq, mul_zero, leadingCoeff_zero]
1454-
· rw [leadingCoeff_mul']
1455-
exact mul_ne_zero (mt leadingCoeff_eq_zero.1 hp) (mt leadingCoeff_eq_zero.1 hq)
1456-
1457-
/-- `Polynomial.leadingCoeff` bundled as a `MonoidHom` when `R` has `NoZeroDivisors`, and thus
1458-
`leadingCoeff` is multiplicative -/
1459-
def leadingCoeffHom : R[X] →* R where
1460-
toFun := leadingCoeff
1461-
map_one' := by simp
1462-
map_mul' := leadingCoeff_mul
1463-
1464-
@[simp]
1465-
theorem leadingCoeffHom_apply (p : R[X]) : leadingCoeffHom p = leadingCoeff p :=
1466-
rfl
1467-
1468-
@[simp]
1469-
theorem leadingCoeff_pow (p : R[X]) (n : ℕ) : leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
1470-
(leadingCoeffHom : R[X] →* R).map_pow p n
1471-
1472-
theorem leadingCoeff_dvd_leadingCoeff {a p : R[X]} (hap : a ∣ p) :
1473-
a.leadingCoeff ∣ p.leadingCoeff :=
1474-
map_dvd leadingCoeffHom hap
1475-
1476-
end NoZeroDivisors
1605+
instance : IsDomain R[X] := NoZeroDivisors.to_isDomain _
14771606

1607+
end Ring
14781608
end Polynomial
1609+
1610+
set_option linter.style.longFile 1700

Mathlib/Algebra/Polynomial/Degree/Lemmas.lean

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,31 @@ theorem leadingCoeff_comp (hq : natDegree q ≠ 0) :
368368

369369
end NoZeroDivisors
370370

371+
section CommRing
372+
variable [CommRing R] {p q : R[X]}
373+
374+
@[simp] lemma comp_neg_X_leadingCoeff_eq (p : R[X]) :
375+
(p.comp (-X)).leadingCoeff = (-1) ^ p.natDegree * p.leadingCoeff := by
376+
nontriviality R
377+
by_cases h : p = 0
378+
· simp [h]
379+
rw [Polynomial.leadingCoeff, natDegree_comp_eq_of_mul_ne_zero, coeff_comp_degree_mul_degree] <;>
380+
simp [mul_comm, h]
381+
382+
variable [IsDomain R]
383+
384+
lemma comp_eq_zero_iff : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
385+
refine ⟨fun h ↦ ?_, Or.rec (fun h ↦ by simp [h]) fun h ↦ by rw [h.2, comp_C, h.1, C_0]⟩
386+
have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
387+
rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
388+
obtain key | key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
389+
· rw [key, C_comp] at h
390+
exact Or.inl (key.trans h)
391+
· rw [key, comp_C, C_eq_zero] at h
392+
exact Or.inr ⟨h, key⟩
393+
394+
end CommRing
395+
371396
section DivisionRing
372397

373398
variable {K : Type*} [DivisionRing K]

0 commit comments

Comments
 (0)