Skip to content

Commit

Permalink
feat(Data/Polynomial/RingDivision): improvements to `Polynomial.rootM…
Browse files Browse the repository at this point in the history
…ultiplicity` (#8563)

Main changes:

- add `Monic.mem_nonZeroDivisors` and `mem_nonZeroDivisors_of_leadingCoeff` which states that a monic polynomial (resp. a polynomial whose leading coefficient is not zero divisor) is not a zero divisor.
- add `rootMultiplicity_mul_X_sub_C_pow` which states that `* (X - a) ^ n` adds the root multiplicity at `a` by `n`.
- change the conditions in `rootMultiplicity_X_sub_C_self`, `rootMultiplicity_X_sub_C` and `rootMultiplicity_X_sub_C_pow` from `IsDomain` to `Nontrivial`.
- add `rootMultiplicity_eq_natTrailingDegree` which relates `rootMultiplicity` and `natTrailingDegree`, and `eval_divByMonic_eq_trailingCoeff_comp`.
- add `le_rootMultiplicity_mul` which is similar to `le_trailingDegree_mul`.
- add `rootMultiplicity_mul'` which slightly generalizes `rootMultiplicity_mul`

In `Data/Polynomial/FieldDivision`:

- add `rootMultiplicity_sub_one_le_derivative_rootMultiplicity_of_ne_zero` which slightly generalizes `rootMultiplicity_sub_one_le_derivative_rootMultiplicity`.
- add `derivative_rootMultiplicity_of_root_of_mem_nonZeroDivisors` which slightly generalizes `derivative_rootMultiplicity_of_root`.
- add several theorems relating roots of iterate derivative to `rootMultiplicity`

In addition:

- move `eq_of_monic_of_associated` from RingDivision to Monic and generalize.
- add `dvd_cancel` lemmas to NonZeroDivisors.
- add `algEquivOfCompEqX`: two polynomials that compose to X both ways induces an isomorphism of the polynomial algebra.
- add divisibility lemmas to Polynomial/Derivative.



Co-authored-by: Junyan Xu <junyanxu.math@gmail.com>
  • Loading branch information
acmepjz and alreadydone committed Dec 13, 2023
1 parent c4988d1 commit 8a22187
Show file tree
Hide file tree
Showing 10 changed files with 326 additions and 76 deletions.
9 changes: 5 additions & 4 deletions Mathlib/Algebra/Divisibility/Basic.lean
Expand Up @@ -95,17 +95,18 @@ theorem dvd_of_mul_right_dvd (h : a * b ∣ c) : a ∣ c :=

section map_dvd

variable {M N : Type*} [Monoid M] [Monoid N]
variable {M N : Type*}

theorem map_dvd {F : Type*} [MulHomClass F M N] (f : F) {a b} : a ∣ b → f a ∣ f b
theorem map_dvd [Semigroup M] [Semigroup N] {F : Type*} [MulHomClass F M N] (f : F) {a b} :
a ∣ b → f a ∣ f b
| ⟨c, h⟩ => ⟨f c, h.symm ▸ map_mul f a c⟩
#align map_dvd map_dvd

theorem MulHom.map_dvd (f : M →ₙ* N) {a b} : a ∣ b → f a ∣ f b :=
theorem MulHom.map_dvd [Semigroup M] [Semigroup N] (f : M →ₙ* N) {a b} : a ∣ b → f a ∣ f b :=
_root_.map_dvd f
#align mul_hom.map_dvd MulHom.map_dvd

theorem MonoidHom.map_dvd (f : M →* N) {a b} : a ∣ b → f a ∣ f b :=
theorem MonoidHom.map_dvd [Monoid M] [Monoid N] (f : M →* N) {a b} : a ∣ b → f a ∣ f b :=
_root_.map_dvd f
#align monoid_hom.map_dvd MonoidHom.map_dvd

Expand Down
14 changes: 14 additions & 0 deletions Mathlib/Algebra/GroupWithZero/NonZeroDivisors.lean
Expand Up @@ -141,6 +141,20 @@ theorem mul_cancel_left_coe_nonZeroDivisors {x y : R'} {c : R'⁰} : (c : R') *
mul_cancel_left_mem_nonZeroDivisors c.prop
#align mul_cancel_left_coe_non_zero_divisor mul_cancel_left_coe_nonZeroDivisors

theorem dvd_cancel_right_mem_nonZeroDivisors {x y r : R'} (hr : r ∈ R'⁰) : x * r ∣ y * r ↔ x ∣ y :=
fun ⟨z, _⟩ ↦ ⟨z, by rwa [← mul_cancel_right_mem_nonZeroDivisors hr, mul_assoc, mul_comm z r,
← mul_assoc]⟩, fun ⟨z, h⟩ ↦ ⟨z, by rw [h, mul_assoc, mul_comm z r, ← mul_assoc]⟩⟩

theorem dvd_cancel_right_coe_nonZeroDivisors {x y : R'} {c : R'⁰} : x * c ∣ y * c ↔ x ∣ y :=
dvd_cancel_right_mem_nonZeroDivisors c.prop

theorem dvd_cancel_left_mem_nonZeroDivisors {x y r : R'} (hr : r ∈ R'⁰) : r * x ∣ r * y ↔ x ∣ y :=
fun ⟨z, _⟩ ↦ ⟨z, by rwa [← mul_cancel_left_mem_nonZeroDivisors hr, ← mul_assoc]⟩,
fun ⟨z, h⟩ ↦ ⟨z, by rw [h, ← mul_assoc]⟩⟩

theorem dvd_cancel_left_coe_nonZeroDivisors {x y : R'} {c : R'⁰} : c * x ∣ c * y ↔ x ∣ y :=
dvd_cancel_left_mem_nonZeroDivisors c.prop

theorem nonZeroDivisors.ne_zero [Nontrivial M] {x} (hx : x ∈ M⁰) : x ≠ 0 := fun h ↦
one_ne_zero (hx _ <| (one_mul _).trans h)
#align non_zero_divisors.ne_zero nonZeroDivisors.ne_zero
Expand Down
5 changes: 5 additions & 0 deletions Mathlib/Algebra/Ring/Divisibility/Basic.lean
Expand Up @@ -20,6 +20,11 @@ imports. Further results about divisibility in rings may be found in

variable {α β : Type*}

theorem map_dvd_iff [Semigroup α] [Semigroup β] {F : Type*} [MulEquivClass F α β] (f : F) {a b} :
f a ∣ f b ↔ a ∣ b :=
let f := MulEquivClass.toMulEquiv f
fun h ↦ by rw [← f.left_inv a, ← f.left_inv b]; exact map_dvd f.symm h, map_dvd f⟩

section DistribSemigroup

variable [Add α] [Semigroup α]
Expand Down
15 changes: 15 additions & 0 deletions Mathlib/Data/Polynomial/AlgebraMap.lean
Expand Up @@ -257,11 +257,26 @@ theorem aeval_mul : aeval x (p * q) = aeval x p * aeval x q :=
AlgHom.map_mul _ _ _
#align polynomial.aeval_mul Polynomial.aeval_mul

theorem comp_eq_aeval : p.comp q = aeval q p := rfl

theorem aeval_comp {A : Type*} [CommSemiring A] [Algebra R A] (x : A) :
aeval x (p.comp q) = aeval (aeval x q) p :=
eval₂_comp (algebraMap R A)
#align polynomial.aeval_comp Polynomial.aeval_comp

/-- Two polynomials `p` and `q` such that `p(q(X))=X` and `q(p(X))=X`
induces an automorphism of the polynomial algebra. -/
@[simps!]
def algEquivOfCompEqX (p q : R[X]) (hpq : p.comp q = X) (hqp : q.comp p = X) : R[X] ≃ₐ[R] R[X] := by
refine AlgEquiv.ofAlgHom (aeval p) (aeval q) ?_ ?_ <;>
exact AlgHom.ext fun _ ↦ by simp [← comp_eq_aeval, comp_assoc, hpq, hqp]

/-- The automorphism of the polynomial algebra given by `p(X) ↦ p(X+t)`,
with inverse `p(X) ↦ p(X-t)`. -/
@[simps!]
def algEquivAevalXAddC {R} [CommRing R] (t : R) : R[X] ≃ₐ[R] R[X] :=
algEquivOfCompEqX (X + C t) (X - C t) (by simp) (by simp)

theorem aeval_algHom (f : A →ₐ[R] B) (x : A) : aeval (f x) = f.comp (aeval x) :=
algHom_ext <| by simp only [aeval_X, AlgHom.comp_apply]
#align polynomial.aeval_alg_hom Polynomial.aeval_algHom
Expand Down
23 changes: 22 additions & 1 deletion Mathlib/Data/Polynomial/Derivative.lean
Expand Up @@ -475,6 +475,23 @@ theorem derivative_sq (p : R[X]) : derivative (p ^ 2) = C 2 * p * derivative p :
rw [derivative_pow_succ, Nat.cast_one, one_add_one_eq_two, pow_one]
#align polynomial.derivative_sq Polynomial.derivative_sq

theorem pow_sub_one_dvd_derivative_of_pow_dvd {p q : R[X]} {n : ℕ}
(dvd : q ^ n ∣ p) : q ^ (n - 1) ∣ derivative p := by
obtain ⟨r, rfl⟩ := dvd
rw [derivative_mul, derivative_pow]
exact (((dvd_mul_left _ _).mul_right _).mul_right _).add ((pow_dvd_pow q n.pred_le).mul_right _)

theorem pow_sub_dvd_iterate_derivative_of_pow_dvd {p q : R[X]} {n : ℕ} (m : ℕ)
(dvd : q ^ n ∣ p) : q ^ (n - m) ∣ derivative^[m] p := by
revert p
induction' m with m ih <;> intro p h
· exact h
· rw [Nat.sub_succ, Function.iterate_succ']
exact pow_sub_one_dvd_derivative_of_pow_dvd (ih h)

theorem pow_sub_dvd_iterate_derivative_pow (p : R[X]) (n m : ℕ) :
p ^ (n - m) ∣ derivative^[m] (p ^ n) := pow_sub_dvd_iterate_derivative_of_pow_dvd m dvd_rfl

theorem dvd_iterate_derivative_pow (f : R[X]) (n : ℕ) {m : ℕ} (c : R) (hm : m ≠ 0) :
(n : R) ∣ eval c (derivative^[m] (f ^ n)) := by
obtain ⟨m, rfl⟩ := Nat.exists_eq_succ_of_ne_zero hm
Expand Down Expand Up @@ -658,11 +675,15 @@ set_option linter.uppercaseLean3 false in
#align polynomial.derivative_X_sub_C_sq Polynomial.derivative_X_sub_C_sq

theorem iterate_derivative_X_sub_pow (n k : ℕ) (c : R) :
(derivative^[k]) ((X - C c) ^ n : R[X]) = n.descFactorial k • (X - C c) ^ (n - k) := by
derivative^[k] ((X - C c) ^ n) = n.descFactorial k • (X - C c) ^ (n - k) := by
rw [sub_eq_add_neg, ← C_neg, iterate_derivative_X_add_pow]
set_option linter.uppercaseLean3 false in
#align polynomial.iterate_derivative_X_sub_pow Polynomial.iterate_derivative_X_sub_powₓ

theorem iterate_derivative_X_sub_pow_self (n : ℕ) (c : R) :
derivative^[n] ((X - C c) ^ n) = n.factorial := by
rw [iterate_derivative_X_sub_pow, n.sub_self, pow_zero, nsmul_one, n.descFactorial_self]

end CommRing

end Derivative
Expand Down
6 changes: 6 additions & 0 deletions Mathlib/Data/Polynomial/Div.lean
Expand Up @@ -540,6 +540,12 @@ theorem pow_mul_divByMonic_rootMultiplicity_eq (p : R[X]) (a : R) :
simp
#align polynomial.div_by_monic_mul_pow_root_multiplicity_eq Polynomial.pow_mul_divByMonic_rootMultiplicity_eq

theorem exists_eq_pow_rootMultiplicity_mul_and_not_dvd (p : R[X]) (hp : p ≠ 0) (a : R) :
∃ q : R[X], p = (X - C a) ^ p.rootMultiplicity a * q ∧ ¬ (X - C a) ∣ q := by
classical
rw [rootMultiplicity_eq_multiplicity, dif_neg hp]
apply multiplicity.exists_eq_pow_mul_and_not_dvd

end multiplicity

end Ring
Expand Down
148 changes: 126 additions & 22 deletions Mathlib/Data/Polynomial/FieldDivision.lean
Expand Up @@ -27,34 +27,125 @@ universe u v w y z

variable {R : Type u} {S : Type v} {k : Type y} {A : Type z} {a b : R} {n : ℕ}

section CommRing

variable [CommRing R]

theorem rootMultiplicity_sub_one_le_derivative_rootMultiplicity_of_ne_zero
(p : R[X]) (t : R) (hnezero : derivative p ≠ 0) :
p.rootMultiplicity t - 1 ≤ p.derivative.rootMultiplicity t :=
(le_rootMultiplicity_iff hnezero).2 <|
pow_sub_one_dvd_derivative_of_pow_dvd (p.pow_rootMultiplicity_dvd t)

theorem derivative_rootMultiplicity_of_root_of_mem_nonZeroDivisors
{p : R[X]} {t : R} (hpt : Polynomial.IsRoot p t)
(hnzd : (p.rootMultiplicity t : R) ∈ nonZeroDivisors R) :
(derivative p).rootMultiplicity t = p.rootMultiplicity t - 1 := by
by_cases h : p = 0
· simp only [h, map_zero, rootMultiplicity_zero]
obtain ⟨g, hp, hndvd⟩ := p.exists_eq_pow_rootMultiplicity_mul_and_not_dvd h t
set m := p.rootMultiplicity t
have hm : m - 1 + 1 = m := Nat.sub_add_cancel <| (rootMultiplicity_pos h).2 hpt
have hndvd : ¬(X - C t) ^ m ∣ derivative p := by
rw [hp, derivative_mul, dvd_add_left (dvd_mul_right _ _),
derivative_X_sub_C_pow, ← hm, pow_succ', hm, mul_comm (C _), mul_assoc,
dvd_cancel_left_mem_nonZeroDivisors (monic_X_sub_C t |>.pow _ |>.mem_nonZeroDivisors)]
rw [dvd_iff_isRoot, IsRoot] at hndvd ⊢
rwa [eval_mul, eval_C, mul_left_mem_nonZeroDivisors_eq_zero_iff hnzd]
have hnezero : derivative p ≠ 0 := fun h ↦ hndvd (by rw [h]; exact dvd_zero _)
exact le_antisymm (by rwa [rootMultiplicity_le_iff hnezero, hm])
(rootMultiplicity_sub_one_le_derivative_rootMultiplicity_of_ne_zero _ t hnezero)

theorem isRoot_iterate_derivative_of_lt_rootMultiplicity {p : R[X]} {t : R} {n : ℕ}
(hn : n < p.rootMultiplicity t) : (derivative^[n] p).IsRoot t :=
dvd_iff_isRoot.mp <| (dvd_pow_self _ <| Nat.sub_ne_zero_of_lt hn).trans
(pow_sub_dvd_iterate_derivative_of_pow_dvd _ <| p.pow_rootMultiplicity_dvd t)

open Finset in
theorem eval_iterate_derivative_rootMultiplicity {p : R[X]} {t : R} :
(derivative^[p.rootMultiplicity t] p).eval t =
(p.rootMultiplicity t).factorial • (p /ₘ (X - C t) ^ p.rootMultiplicity t).eval t := by
set m := p.rootMultiplicity t with hm
conv_lhs => rw [← p.pow_mul_divByMonic_rootMultiplicity_eq t, ← hm]
rw [iterate_derivative_mul, eval_finset_sum, sum_eq_single_of_mem _ (mem_range.mpr m.succ_pos)]
· rw [m.choose_zero_right, one_smul, eval_mul, m.sub_zero, iterate_derivative_X_sub_pow_self,
eval_nat_cast, nsmul_eq_mul]; rfl
· intro b hb hb0
rw [iterate_derivative_X_sub_pow, eval_smul, eval_mul, eval_smul, eval_pow,
Nat.sub_sub_self (mem_range_succ_iff.mp hb), eval_sub, eval_X, eval_C, sub_self,
zero_pow' b hb0, smul_zero, zero_mul, smul_zero]

theorem lt_rootMultiplicity_of_isRoot_iterate_derivative_of_mem_nonZeroDivisors
{p : R[X]} {t : R} {n : ℕ} (h : p ≠ 0)
(hroot : ∀ m ≤ n, (derivative^[m] p).IsRoot t)
(hnzd : (n.factorial : R) ∈ nonZeroDivisors R) :
n < p.rootMultiplicity t := by
by_contra! h'
replace hroot := hroot _ h'
simp only [IsRoot, eval_iterate_derivative_rootMultiplicity] at hroot
obtain ⟨q, hq⟩ := Nat.coe_nat_dvd (α := R) <| Nat.factorial_dvd_factorial h'
rw [hq, mul_mem_nonZeroDivisors] at hnzd
rw [nsmul_eq_mul, mul_left_mem_nonZeroDivisors_eq_zero_iff hnzd.1] at hroot
exact eval_divByMonic_pow_rootMultiplicity_ne_zero t h hroot

theorem lt_rootMultiplicity_of_isRoot_iterate_derivative_of_mem_nonZeroDivisors'
{p : R[X]} {t : R} {n : ℕ} (h : p ≠ 0)
(hroot : ∀ m ≤ n, (derivative^[m] p).IsRoot t)
(hnzd : ∀ m ≤ n, m ≠ 0 → (m : R) ∈ nonZeroDivisors R) :
n < p.rootMultiplicity t := by
apply lt_rootMultiplicity_of_isRoot_iterate_derivative_of_mem_nonZeroDivisors h hroot
clear hroot
induction' n with n ih
· simp only [Nat.zero_eq, Nat.factorial_zero, Nat.cast_one]
exact Submonoid.one_mem _
· rw [Nat.factorial_succ, Nat.cast_mul, mul_mem_nonZeroDivisors]
exact ⟨hnzd _ le_rfl n.succ_ne_zero, ih fun m h ↦ hnzd m (h.trans n.le_succ)⟩

theorem lt_rootMultiplicity_iff_isRoot_iterate_derivative_of_mem_nonZeroDivisors
{p : R[X]} {t : R} {n : ℕ} (h : p ≠ 0)
(hnzd : (n.factorial : R) ∈ nonZeroDivisors R) :
n < p.rootMultiplicity t ↔ ∀ m ≤ n, (derivative^[m] p).IsRoot t :=
fun hn _ hm ↦ isRoot_iterate_derivative_of_lt_rootMultiplicity <| hm.trans_lt hn,
fun hr ↦ lt_rootMultiplicity_of_isRoot_iterate_derivative_of_mem_nonZeroDivisors h hr hnzd⟩

theorem lt_rootMultiplicity_iff_isRoot_iterate_derivative_of_mem_nonZeroDivisors'
{p : R[X]} {t : R} {n : ℕ} (h : p ≠ 0)
(hnzd : ∀ m ≤ n, m ≠ 0 → (m : R) ∈ nonZeroDivisors R) :
n < p.rootMultiplicity t ↔ ∀ m ≤ n, (derivative^[m] p).IsRoot t :=
fun hn _ hm ↦ isRoot_iterate_derivative_of_lt_rootMultiplicity <| Nat.lt_of_le_of_lt hm hn,
fun hr ↦ lt_rootMultiplicity_of_isRoot_iterate_derivative_of_mem_nonZeroDivisors' h hr hnzd⟩

theorem one_lt_rootMultiplicity_iff_isRoot_iterate_derivative
{p : R[X]} {t : R} (h : p ≠ 0) :
1 < p.rootMultiplicity t ↔ ∀ m ≤ 1, (derivative^[m] p).IsRoot t :=
lt_rootMultiplicity_iff_isRoot_iterate_derivative_of_mem_nonZeroDivisors h
(by rw [Nat.factorial_one, Nat.cast_one]; exact Submonoid.one_mem _)

theorem one_lt_rootMultiplicity_iff_isRoot
{p : R[X]} {t : R} (h : p ≠ 0) :
1 < p.rootMultiplicity t ↔ p.IsRoot t ∧ (derivative p).IsRoot t := by
rw [one_lt_rootMultiplicity_iff_isRoot_iterate_derivative h]
refine ⟨fun h ↦ ⟨h 0 (by norm_num), h 1 (by norm_num)⟩, fun ⟨h0, h1⟩ m hm ↦ ?_⟩
obtain (_|_|m) := m
exacts [h0, h1, by linarith [hm]]

end CommRing

section IsDomain

variable [CommRing R] [IsDomain R]

theorem one_lt_rootMultiplicity_iff_isRoot_gcd
[GCDMonoid R[X]] {p : R[X]} {t : R} (h : p ≠ 0) :
1 < p.rootMultiplicity t ↔ (gcd p (derivative p)).IsRoot t := by
simp_rw [one_lt_rootMultiplicity_iff_isRoot h, ← dvd_iff_isRoot, dvd_gcd_iff]

theorem derivative_rootMultiplicity_of_root [CharZero R] {p : R[X]} {t : R} (hpt : p.IsRoot t) :
p.derivative.rootMultiplicity t = p.rootMultiplicity t - 1 := by
rcases eq_or_ne p 0 with (rfl | hp)
· simp
nth_rw 1 [← p.pow_mul_divByMonic_rootMultiplicity_eq t, mul_comm]
simp only [derivative_pow, derivative_mul, derivative_sub, derivative_X, derivative_C, sub_zero,
mul_one]
set n := p.rootMultiplicity t - 1
have hn : n + 1 = _ := tsub_add_cancel_of_le ((rootMultiplicity_pos hp).mpr hpt)
rw [← hn]
set q := p /ₘ (X - C t) ^ (n + 1) with _hq
convert_to rootMultiplicity t ((X - C t) ^ n * (derivative q * (X - C t) + q * C ↑(n + 1))) = n
· congr
rw [mul_add, mul_left_comm <| (X - C t) ^ n, ← pow_succ']
congr 1
rw [mul_left_comm <| (X - C t) ^ n, mul_comm <| (X - C t) ^ n]
have h : eval t (derivative q * (X - C t) + q * C (R := R) ↑(n + 1)) ≠ 0 := by
suffices eval t q * ↑(n + 1) ≠ 0 by simpa
refine' mul_ne_zero _ (Nat.cast_ne_zero.mpr n.succ_ne_zero)
convert eval_divByMonic_pow_rootMultiplicity_ne_zero t hp
rw [rootMultiplicity_mul, rootMultiplicity_X_sub_C_pow, rootMultiplicity_eq_zero h, add_zero]
refine' mul_ne_zero (pow_ne_zero n <| X_sub_C_ne_zero t) _
contrapose! h
rw [h, eval_zero]
by_cases h : p = 0
· rw [h, map_zero, rootMultiplicity_zero]
exact derivative_rootMultiplicity_of_root_of_mem_nonZeroDivisors hpt <|
mem_nonZeroDivisors_of_ne_zero <| Nat.cast_ne_zero.2 ((rootMultiplicity_pos h).2 hpt).ne'
#align polynomial.derivative_root_multiplicity_of_root Polynomial.derivative_rootMultiplicity_of_root

theorem rootMultiplicity_sub_one_le_derivative_rootMultiplicity [CharZero R] (p : R[X]) (t : R) :
Expand All @@ -65,6 +156,19 @@ theorem rootMultiplicity_sub_one_le_derivative_rootMultiplicity [CharZero R] (p
exact zero_le _
#align polynomial.root_multiplicity_sub_one_le_derivative_root_multiplicity Polynomial.rootMultiplicity_sub_one_le_derivative_rootMultiplicity

theorem lt_rootMultiplicity_of_isRoot_iterate_derivative
[CharZero R] {p : R[X]} {t : R} {n : ℕ} (h : p ≠ 0)
(hroot : ∀ m ≤ n, (derivative^[m] p).IsRoot t) :
n < p.rootMultiplicity t :=
lt_rootMultiplicity_of_isRoot_iterate_derivative_of_mem_nonZeroDivisors h hroot <|
mem_nonZeroDivisors_of_ne_zero <| Nat.cast_ne_zero.2 <| Nat.factorial_ne_zero n

theorem lt_rootMultiplicity_iff_isRoot_iterate_derivative
[CharZero R] {p : R[X]} {t : R} {n : ℕ} (h : p ≠ 0) :
n < p.rootMultiplicity t ↔ ∀ m ≤ n, (derivative^[m] p).IsRoot t :=
fun hn _ hm ↦ isRoot_iterate_derivative_of_lt_rootMultiplicity <| Nat.lt_of_le_of_lt hm hn,
fun hr ↦ lt_rootMultiplicity_of_isRoot_iterate_derivative h hr⟩

section NormalizationMonoid

variable [NormalizationMonoid R]
Expand Down
5 changes: 5 additions & 0 deletions Mathlib/Data/Polynomial/Monic.lean
Expand Up @@ -254,6 +254,11 @@ theorem Monic.isUnit_iff (hm : p.Monic) : IsUnit p ↔ p = 1 :=
⟨hm.eq_one_of_isUnit, fun h => h.symm ▸ isUnit_one⟩
#align polynomial.monic.is_unit_iff Polynomial.Monic.isUnit_iff

theorem eq_of_monic_of_associated (hp : p.Monic) (hq : q.Monic) (hpq : Associated p q) : p = q := by
obtain ⟨u, rfl⟩ := hpq
rw [(hp.of_mul_monic_left hq).eq_one_of_isUnit u.isUnit, mul_one]
#align polynomial.eq_of_monic_of_associated Polynomial.eq_of_monic_of_associated

end Semiring

section CommSemiring
Expand Down

0 comments on commit 8a22187

Please sign in to comment.