Module docstring
{"# Theory of degrees of polynomials
Some of the main results include
- natDegree_comp_le : The degree of the composition is at most the product of degrees
","Useful lemmas for the \"monicization\" of a nonzero polynomial p. "}
{"# Theory of degrees of polynomials
Some of the main results include
- natDegree_comp_le : The degree of the composition is at most the product of degrees
","Useful lemmas for the \"monicization\" of a nonzero polynomial p. "}
Polynomial.natDegree_comp_le
theorem
: natDegree (p.comp q) ≤ natDegree p * natDegree q
theorem natDegree_comp_le : natDegree (p.comp q) ≤ natDegree p * natDegree q :=
letI := Classical.decEq R
if h0 : p.comp q = 0 then by rw [h0, natDegree_zero]; exact Nat.zero_le _
else
WithBot.coe_le_coe.1 <|
calc
↑(natDegree (p.comp q)) = degree (p.comp q) := (degree_eq_natDegree h0).symm
_ = _ := congr_arg degree comp_eq_sum_left
_ ≤ _ := degree_sum_le _ _
_ ≤ _ :=
Finset.sup_le fun n hn =>
calc
degree (C (coeff p n) * q ^ n) ≤ degree (C (coeff p n)) + degree (q ^ n) :=
degree_mul_le _ _
_ ≤ natDegree (C (coeff p n)) + n • degree q :=
(add_le_add degree_le_natDegree (degree_pow_le _ _))
_ ≤ natDegree (C (coeff p n)) + n • ↑(natDegree q) :=
(add_le_add_left (nsmul_le_nsmul_right (@degree_le_natDegree _ _ q) n) _)
_ = (n * natDegree q : ℕ) := by
rw [natDegree_C, Nat.cast_zero, zero_add, nsmul_eq_mul]
simp
_ ≤ (natDegree p * natDegree q : ℕ) :=
WithBot.coe_le_coe.2 <|
mul_le_mul_of_nonneg_right (le_natDegree_of_ne_zero (mem_support_iff.1 hn))
(Nat.zero_le _)
Polynomial.natDegree_comp_eq_of_mul_ne_zero
theorem
(h : p.leadingCoeff * q.leadingCoeff ^ p.natDegree ≠ 0) : natDegree (p.comp q) = natDegree p * natDegree q
theorem natDegree_comp_eq_of_mul_ne_zero (h : p.leadingCoeff * q.leadingCoeff ^ p.natDegree ≠ 0) :
natDegree (p.comp q) = natDegree p * natDegree q := by
by_cases hq : natDegree q = 0
· exact le_antisymm natDegree_comp_le (by simp [hq])
apply natDegree_eq_of_le_of_coeff_ne_zero natDegree_comp_le
rwa [coeff_comp_degree_mul_degree hq]
Polynomial.degree_pos_of_root
theorem
{p : R[X]} (hp : p ≠ 0) (h : IsRoot p a) : 0 < degree p
theorem degree_pos_of_root {p : R[X]} (hp : p ≠ 0) (h : IsRoot p a) : 0 < degree p :=
lt_of_not_ge fun hlt => by
have := eq_C_of_degree_le_zero hlt
rw [IsRoot, this, eval_C] at h
simp only [h, RingHom.map_zero] at this
exact hp this
Polynomial.natDegree_le_iff_coeff_eq_zero
theorem
: p.natDegree ≤ n ↔ ∀ N : ℕ, n < N → p.coeff N = 0
Polynomial.natDegree_add_le_iff_left
theorem
{n : ℕ} (p q : R[X]) (qn : q.natDegree ≤ n) : (p + q).natDegree ≤ n ↔ p.natDegree ≤ n
theorem natDegree_add_le_iff_left {n : ℕ} (p q : R[X]) (qn : q.natDegree ≤ n) :
(p + q).natDegree ≤ n ↔ p.natDegree ≤ n := by
refine ⟨fun h => ?_, fun h => natDegree_add_le_of_degree_le h qn⟩
refine natDegree_le_iff_coeff_eq_zero.mpr fun m hm => ?_
convert natDegree_le_iff_coeff_eq_zero.mp h m hm using 1
rw [coeff_add, natDegree_le_iff_coeff_eq_zero.mp qn _ hm, add_zero]
Polynomial.natDegree_add_le_iff_right
theorem
{n : ℕ} (p q : R[X]) (pn : p.natDegree ≤ n) : (p + q).natDegree ≤ n ↔ q.natDegree ≤ n
theorem natDegree_add_le_iff_right {n : ℕ} (p q : R[X]) (pn : p.natDegree ≤ n) :
(p + q).natDegree ≤ n ↔ q.natDegree ≤ n := by
rw [add_comm]
exact natDegree_add_le_iff_left _ _ pn
Polynomial.natDegree_C_mul_le
theorem
(a : R) (f : R[X]) : (C a * f).natDegree ≤ f.natDegree
theorem natDegree_C_mul_le (a : R) (f : R[X]) : (C a * f).natDegree ≤ f.natDegree := by
simpa using natDegree_mul_le (p := C a)
Polynomial.natDegree_mul_C_le
theorem
(f : R[X]) (a : R) : (f * C a).natDegree ≤ f.natDegree
theorem natDegree_mul_C_le (f : R[X]) (a : R) : (f * C a).natDegree ≤ f.natDegree := by
simpa using natDegree_mul_le (q := C a)
Polynomial.natDegree_C_mul_eq_of_mul_eq_one
theorem
{ai : R} (au : ai * a = 1) : (C a * p).natDegree = p.natDegree
theorem natDegree_C_mul_eq_of_mul_eq_one {ai : R} (au : ai * a = 1) :
(C a * p).natDegree = p.natDegree :=
le_antisymm (natDegree_C_mul_le a p)
(calc
p.natDegree = (1 * p).natDegree := by nth_rw 1 [← one_mul p]
_ = (C ai * (C a * p)).natDegree := by rw [← C_1, ← au, RingHom.map_mul, ← mul_assoc]
_ ≤ (C a * p).natDegree := natDegree_C_mul_le ai (C a * p))
Polynomial.natDegree_mul_C_eq_of_mul_eq_one
theorem
{ai : R} (au : a * ai = 1) : (p * C a).natDegree = p.natDegree
theorem natDegree_mul_C_eq_of_mul_eq_one {ai : R} (au : a * ai = 1) :
(p * C a).natDegree = p.natDegree :=
le_antisymm (natDegree_mul_C_le p a)
(calc
p.natDegree = (p * 1).natDegree := by nth_rw 1 [← mul_one p]
_ = (p * C a * C ai).natDegree := by rw [← C_1, ← au, RingHom.map_mul, ← mul_assoc]
_ ≤ (p * C a).natDegree := natDegree_mul_C_le (p * C a) ai)
Polynomial.natDegree_mul_C_eq_of_mul_ne_zero
theorem
(h : p.leadingCoeff * a ≠ 0) : (p * C a).natDegree = p.natDegree
/-- Although not explicitly stated, the assumptions of lemma `natDegree_mul_C_eq_of_mul_ne_zero`
force the polynomial `p` to be non-zero, via `p.leadingCoeff ≠ 0`.
-/
theorem natDegree_mul_C_eq_of_mul_ne_zero (h : p.leadingCoeff * a ≠ 0) :
(p * C a).natDegree = p.natDegree := by
refine eq_natDegree_of_le_mem_support (natDegree_mul_C_le p a) ?_
refine mem_support_iff.mpr ?_
rwa [coeff_mul_C]
Polynomial.natDegree_C_mul_of_mul_ne_zero
theorem
(h : a * p.leadingCoeff ≠ 0) : (C a * p).natDegree = p.natDegree
/-- Although not explicitly stated, the assumptions of lemma `natDegree_C_mul_of_mul_ne_zero`
force the polynomial `p` to be non-zero, via `p.leadingCoeff ≠ 0`.
-/
theorem natDegree_C_mul_of_mul_ne_zero (h : a * p.leadingCoeff ≠ 0) :
(C a * p).natDegree = p.natDegree := by
refine eq_natDegree_of_le_mem_support (natDegree_C_mul_le a p) ?_
refine mem_support_iff.mpr ?_
rwa [coeff_C_mul]
Polynomial.degree_C_mul_of_mul_ne_zero
theorem
(h : a * p.leadingCoeff ≠ 0) : (C a * p).degree = p.degree
lemma degree_C_mul_of_mul_ne_zero (h : a * p.leadingCoeff ≠ 0) : (C a * p).degree = p.degree := by
rw [degree_mul' (by simpa)]; simp [left_ne_zero_of_mul h]
Polynomial.natDegree_add_coeff_mul
theorem
(f g : R[X]) : (f * g).coeff (f.natDegree + g.natDegree) = f.coeff f.natDegree * g.coeff g.natDegree
theorem natDegree_add_coeff_mul (f g : R[X]) :
(f * g).coeff (f.natDegree + g.natDegree) = f.coeff f.natDegree * g.coeff g.natDegree := by
simp only [coeff_natDegree, coeff_mul_degree_add_degree]
Polynomial.natDegree_lt_coeff_mul
theorem
(h : p.natDegree + q.natDegree < m + n) : (p * q).coeff (m + n) = 0
theorem natDegree_lt_coeff_mul (h : p.natDegree + q.natDegree < m + n) :
(p * q).coeff (m + n) = 0 :=
coeff_eq_zero_of_natDegree_lt (natDegree_mul_le.trans_lt h)
Polynomial.coeff_mul_of_natDegree_le
theorem
(pm : p.natDegree ≤ m) (qn : q.natDegree ≤ n) : (p * q).coeff (m + n) = p.coeff m * q.coeff n
theorem coeff_mul_of_natDegree_le (pm : p.natDegree ≤ m) (qn : q.natDegree ≤ n) :
(p * q).coeff (m + n) = p.coeff m * q.coeff n := by
simp_rw [← Polynomial.toFinsupp_apply, toFinsupp_mul]
refine AddMonoidAlgebra.apply_add_of_supDegree_le ?_ Function.injective_id ?_ ?_
· simp
· rwa [supDegree_eq_natDegree, id_eq]
· rwa [supDegree_eq_natDegree, id_eq]
Polynomial.coeff_pow_of_natDegree_le
theorem
(pn : p.natDegree ≤ n) : (p ^ m).coeff (m * n) = p.coeff n ^ m
theorem coeff_pow_of_natDegree_le (pn : p.natDegree ≤ n) :
(p ^ m).coeff (m * n) = p.coeff n ^ m := by
induction' m with m hm
· simp
· rw [pow_succ, pow_succ, ← hm, Nat.succ_mul, coeff_mul_of_natDegree_le _ pn]
refine natDegree_pow_le.trans (le_trans ?_ (le_refl _))
exact mul_le_mul_of_nonneg_left pn m.zero_le
Polynomial.coeff_pow_eq_ite_of_natDegree_le_of_le
theorem
{o : ℕ} (pn : natDegree p ≤ n) (mno : m * n ≤ o) : coeff (p ^ m) o = if o = m * n then (coeff p n) ^ m else 0
theorem coeff_pow_eq_ite_of_natDegree_le_of_le {o : ℕ}
(pn : natDegree p ≤ n) (mno : m * n ≤ o) :
coeff (p ^ m) o = if o = m * n then (coeff p n) ^ m else 0 := by
rcases eq_or_ne o (m * n) with rfl | h
· simpa only [ite_true] using coeff_pow_of_natDegree_le pn
· simpa only [h, ite_false] using coeff_eq_zero_of_natDegree_lt <|
lt_of_le_of_lt (natDegree_pow_le_of_le m pn) (lt_of_le_of_ne mno h.symm)
Polynomial.coeff_add_eq_left_of_lt
theorem
(qn : q.natDegree < n) : (p + q).coeff n = p.coeff n
theorem coeff_add_eq_left_of_lt (qn : q.natDegree < n) : (p + q).coeff n = p.coeff n :=
(coeff_add _ _ _).trans <|
(congr_arg _ <| coeff_eq_zero_of_natDegree_lt <| qn).trans <| add_zero _
Polynomial.coeff_add_eq_right_of_lt
theorem
(pn : p.natDegree < n) : (p + q).coeff n = q.coeff n
theorem coeff_add_eq_right_of_lt (pn : p.natDegree < n) : (p + q).coeff n = q.coeff n := by
rw [add_comm]
exact coeff_add_eq_left_of_lt pn
Polynomial.degree_sum_eq_of_disjoint
theorem
(f : S → R[X]) (s : Finset S) (h : Set.Pairwise {i | i ∈ s ∧ f i ≠ 0} (Ne on degree ∘ f)) :
degree (s.sum f) = s.sup fun i => degree (f i)
theorem degree_sum_eq_of_disjoint (f : S → R[X]) (s : Finset S)
(h : Set.Pairwise { i | i ∈ s ∧ f i ≠ 0 } (NeNe on degree ∘ f)) :
degree (s.sum f) = s.sup fun i => degree (f i) := by
classical
induction' s using Finset.induction_on with x s hx IH
· simp
· simp only [hx, Finset.sum_insert, not_false_iff, Finset.sup_insert]
specialize IH (h.mono fun _ => by simp +contextual)
rcases lt_trichotomy (degree (f x)) (degree (s.sum f)) with (H | H | H)
· rw [← IH, sup_eq_right.mpr H.le, degree_add_eq_right_of_degree_lt H]
· rcases s.eq_empty_or_nonempty with (rfl | hs)
· simp
obtain ⟨y, hy, hy'⟩ := Finset.exists_mem_eq_sup s hs fun i => degree (f i)
rw [IH, hy'] at H
by_cases hx0 : f x = 0
· simp [hx0, IH]
have hy0 : f y ≠ 0 := by
contrapose! H
simpa [H, degree_eq_bot] using hx0
refine absurd H (h ?_ ?_ fun H => hx ?_)
· simp [hx0]
· simp [hy, hy0]
· exact H.symm ▸ hy
· rw [← IH, sup_eq_left.mpr H.le, degree_add_eq_left_of_degree_lt H]
Polynomial.natDegree_sum_eq_of_disjoint
theorem
(f : S → R[X]) (s : Finset S) (h : Set.Pairwise {i | i ∈ s ∧ f i ≠ 0} (Ne on natDegree ∘ f)) :
natDegree (s.sum f) = s.sup fun i => natDegree (f i)
theorem natDegree_sum_eq_of_disjoint (f : S → R[X]) (s : Finset S)
(h : Set.Pairwise { i | i ∈ s ∧ f i ≠ 0 } (NeNe on natDegree ∘ f)) :
natDegree (s.sum f) = s.sup fun i => natDegree (f i) := by
by_cases H : ∃ x ∈ s, f x ≠ 0
· obtain ⟨x, hx, hx'⟩ := H
have hs : s.Nonempty := ⟨x, hx⟩
refine natDegree_eq_of_degree_eq_some ?_
rw [degree_sum_eq_of_disjoint]
· rw [← Finset.sup'_eq_sup hs, ← Finset.sup'_eq_sup hs,
Nat.cast_withBot, Finset.coe_sup' hs, ←
Finset.sup'_eq_sup hs]
refine le_antisymm ?_ ?_
· rw [Finset.sup'_le_iff]
intro b hb
by_cases hb' : f b = 0
· simpa [hb'] using hs
rw [degree_eq_natDegree hb', Nat.cast_withBot]
exact Finset.le_sup' (fun i : S => (natDegree (f i) : WithBot ℕ)) hb
· rw [Finset.sup'_le_iff]
intro b hb
simp only [Finset.le_sup'_iff, exists_prop, Function.comp_apply]
by_cases hb' : f b = 0
· refine ⟨x, hx, ?_⟩
contrapose! hx'
simpa [← Nat.cast_withBot, hb', degree_eq_bot] using hx'
exact ⟨b, hb, (degree_eq_natDegree hb').ge⟩
· exact h.imp fun x y hxy hxy' => hxy (natDegree_eq_of_degree_eq hxy')
· push_neg at H
rw [Finset.sum_eq_zero H, natDegree_zero, eq_comm, show 0 = ⊥ from rfl, Finset.sup_eq_bot_iff]
intro x hx
simp [H x hx]
Polynomial.natDegree_pos_of_eval₂_root
theorem
{p : R[X]} (hp : p ≠ 0) (f : R →+* S) {z : S} (hz : eval₂ f z p = 0) (inj : ∀ x : R, f x = 0 → x = 0) : 0 < natDegree p
theorem natDegree_pos_of_eval₂_root {p : R[X]} (hp : p ≠ 0) (f : R →+* S) {z : S}
(hz : eval₂ f z p = 0) (inj : ∀ x : R, f x = 0 → x = 0) : 0 < natDegree p :=
lt_of_not_ge fun hlt => by
have A : p = C (p.coeff 0) := eq_C_of_natDegree_le_zero hlt
rw [A, eval₂_C] at hz
simp only [inj (p.coeff 0) hz, RingHom.map_zero] at A
exact hp A
Polynomial.degree_pos_of_eval₂_root
theorem
{p : R[X]} (hp : p ≠ 0) (f : R →+* S) {z : S} (hz : eval₂ f z p = 0) (inj : ∀ x : R, f x = 0 → x = 0) : 0 < degree p
theorem degree_pos_of_eval₂_root {p : R[X]} (hp : p ≠ 0) (f : R →+* S) {z : S}
(hz : eval₂ f z p = 0) (inj : ∀ x : R, f x = 0 → x = 0) : 0 < degree p :=
natDegree_pos_iff_degree_pos.mp (natDegree_pos_of_eval₂_root hp f hz inj)
Polynomial.coe_lt_degree
theorem
{p : R[X]} {n : ℕ} : (n : WithBot ℕ) < degree p ↔ n < natDegree p
@[simp]
theorem coe_lt_degree {p : R[X]} {n : ℕ} : (n : WithBot ℕ) < degree p ↔ n < natDegree p := by
by_cases h : p = 0
· simp [h]
simp [degree_eq_natDegree h, Nat.cast_lt]
Polynomial.degree_map_eq_iff
theorem
{f : R →+* S} {p : Polynomial R} : degree (map f p) = degree p ↔ f (leadingCoeff p) ≠ 0 ∨ p = 0
@[simp]
theorem degree_map_eq_iff {f : R →+* S} {p : Polynomial R} :
degreedegree (map f p) = degree p ↔ f (leadingCoeff p) ≠ 0 ∨ p = 0 := by
rcases eq_or_ne p 0 with h|h
· simp [h]
simp only [h, or_false]
refine ⟨fun h2 ↦ ?_, degree_map_eq_of_leadingCoeff_ne_zero f⟩
have h3 : natDegree (map f p) = natDegree p := by simp_rw [natDegree, h2]
have h4 : mapmap f p ≠ 0 := by
rwa [ne_eq, ← degree_eq_bot, h2, degree_eq_bot]
rwa [← coeff_natDegree, ← coeff_map, ← h3, coeff_natDegree, ne_eq, leadingCoeff_eq_zero]
Polynomial.natDegree_map_eq_iff
theorem
{f : R →+* S} {p : Polynomial R} : natDegree (map f p) = natDegree p ↔ f (p.leadingCoeff) ≠ 0 ∨ natDegree p = 0
@[simp]
theorem natDegree_map_eq_iff {f : R →+* S} {p : Polynomial R} :
natDegreenatDegree (map f p) = natDegree p ↔ f (p.leadingCoeff) ≠ 0 ∨ natDegree p = 0 := by
rcases eq_or_ne (natDegree p) 0 with h|h
· simp_rw [h, ne_eq, or_true, iff_true, ← Nat.le_zero, ← h, natDegree_map_le]
have h2 : p ≠ 0 := by rintro rfl; simp at h
simp_all [natDegree, WithBot.unbotD_eq_unbotD_iff]
Polynomial.natDegree_pos_of_nextCoeff_ne_zero
theorem
(h : p.nextCoeff ≠ 0) : 0 < p.natDegree
theorem natDegree_pos_of_nextCoeff_ne_zero (h : p.nextCoeff ≠ 0) : 0 < p.natDegree := by
rw [nextCoeff] at h
by_cases hpz : p.natDegree = 0
· simp_all only [ne_eq, zero_le, ite_true, not_true_eq_false]
· apply Nat.zero_lt_of_ne_zero hpz
Polynomial.natDegree_sub
theorem
: (p - q).natDegree = (q - p).natDegree
theorem natDegree_sub : (p - q).natDegree = (q - p).natDegree := by rw [← natDegree_neg, neg_sub]
Polynomial.natDegree_sub_le_iff_left
theorem
(qn : q.natDegree ≤ n) : (p - q).natDegree ≤ n ↔ p.natDegree ≤ n
theorem natDegree_sub_le_iff_left (qn : q.natDegree ≤ n) :
(p - q).natDegree ≤ n ↔ p.natDegree ≤ n := by
rw [← natDegree_neg] at qn
rw [sub_eq_add_neg, natDegree_add_le_iff_left _ _ qn]
Polynomial.natDegree_sub_le_iff_right
theorem
(pn : p.natDegree ≤ n) : (p - q).natDegree ≤ n ↔ q.natDegree ≤ n
theorem natDegree_sub_le_iff_right (pn : p.natDegree ≤ n) :
(p - q).natDegree ≤ n ↔ q.natDegree ≤ n := by rwa [natDegree_sub, natDegree_sub_le_iff_left]
Polynomial.coeff_sub_eq_left_of_lt
theorem
(dg : q.natDegree < n) : (p - q).coeff n = p.coeff n
theorem coeff_sub_eq_left_of_lt (dg : q.natDegree < n) : (p - q).coeff n = p.coeff n := by
rw [← natDegree_neg] at dg
rw [sub_eq_add_neg, coeff_add_eq_left_of_lt dg]
Polynomial.coeff_sub_eq_neg_right_of_lt
theorem
(df : p.natDegree < n) : (p - q).coeff n = -q.coeff n
theorem coeff_sub_eq_neg_right_of_lt (df : p.natDegree < n) : (p - q).coeff n = -q.coeff n := by
rwa [sub_eq_add_neg, coeff_add_eq_right_of_lt, coeff_neg]
Polynomial.nextCoeff_C_mul_X_add_C
theorem
(ha : a ≠ 0) (c : R) : nextCoeff (C a * X + C c) = c
@[simp]
lemma nextCoeff_C_mul_X_add_C (ha : a ≠ 0) (c : R) : nextCoeff (C a * X + C c) = c := by
rw [nextCoeff_of_natDegree_pos] <;> simp [ha]
Polynomial.natDegree_eq_one
theorem
: p.natDegree = 1 ↔ ∃ a ≠ 0, ∃ b, C a * X + C b = p
lemma natDegree_eq_one : p.natDegree = 1 ↔ ∃ a ≠ 0, ∃ b, C a * X + C b = p := by
refine ⟨fun hp ↦ ⟨p.coeff 1, fun h ↦ ?_, p.coeff 0, ?_⟩, ?_⟩
· rw [← hp, coeff_natDegree, leadingCoeff_eq_zero] at h
aesop
· ext n
obtain _ | _ | n := n
· simp
· simp
· simp only [coeff_add, coeff_mul_X, coeff_C_succ, add_zero]
rw [coeff_eq_zero_of_natDegree_lt]
simp [hp]
· rintro ⟨a, ha, b, rfl⟩
simp [ha]
Polynomial.degree_mul_C
theorem
(a0 : a ≠ 0) : (p * C a).degree = p.degree
theorem degree_mul_C (a0 : a ≠ 0) : (p * C a).degree = p.degree := by
rw [degree_mul, degree_C a0, add_zero]
Polynomial.degree_C_mul
theorem
(a0 : a ≠ 0) : (C a * p).degree = p.degree
theorem degree_C_mul (a0 : a ≠ 0) : (C a * p).degree = p.degree := by
rw [degree_mul, degree_C a0, zero_add]
Polynomial.natDegree_mul_C
theorem
(a0 : a ≠ 0) : (p * C a).natDegree = p.natDegree
theorem natDegree_mul_C (a0 : a ≠ 0) : (p * C a).natDegree = p.natDegree := by
simp only [natDegree, degree_mul_C a0]
Polynomial.natDegree_C_mul
theorem
(a0 : a ≠ 0) : (C a * p).natDegree = p.natDegree
theorem natDegree_C_mul (a0 : a ≠ 0) : (C a * p).natDegree = p.natDegree := by
simp only [natDegree, degree_C_mul a0]
Polynomial.natDegree_comp
theorem
: natDegree (p.comp q) = natDegree p * natDegree q
theorem natDegree_comp : natDegree (p.comp q) = natDegree p * natDegree q := by
by_cases q0 : q.natDegree = 0
· rw [degree_le_zero_iff.mp (natDegree_eq_zero_iff_degree_le_zero.mp q0), comp_C, natDegree_C,
natDegree_C, mul_zero]
· by_cases p0 : p = 0
· simp only [p0, zero_comp, natDegree_zero, zero_mul]
· simp only [Ne, mul_eq_zero, leadingCoeff_eq_zero, p0, natDegree_comp_eq_of_mul_ne_zero,
ne_zero_of_natDegree_gt (Nat.pos_of_ne_zero q0), not_false_eq_true, pow_ne_zero, or_self]
Polynomial.natDegree_iterate_comp
theorem
(k : ℕ) : (p.comp^[k] q).natDegree = p.natDegree ^ k * q.natDegree
@[simp]
theorem natDegree_iterate_comp (k : ℕ) :
(p.comp^[k] q).natDegree = p.natDegree ^ k * q.natDegree := by
induction k with
| zero => simp
| succ k IH => rw [Function.iterate_succ_apply', natDegree_comp, IH, pow_succ', mul_assoc]
Polynomial.leadingCoeff_comp
theorem
(hq : natDegree q ≠ 0) : leadingCoeff (p.comp q) = leadingCoeff p * leadingCoeff q ^ natDegree p
theorem leadingCoeff_comp (hq : natDegreenatDegree q ≠ 0) :
leadingCoeff (p.comp q) = leadingCoeff p * leadingCoeff q ^ natDegree p := by
rw [← coeff_comp_degree_mul_degree hq, ← natDegree_comp, coeff_natDegree]
Polynomial.comp_neg_X_leadingCoeff_eq
theorem
[Ring R] (p : R[X]) : (p.comp (-X)).leadingCoeff = (-1) ^ p.natDegree * p.leadingCoeff
@[simp] lemma comp_neg_X_leadingCoeff_eq [Ring R] (p : R[X]) :
(p.comp (-X)).leadingCoeff = (-1) ^ p.natDegree * p.leadingCoeff := by
nontriviality R
by_cases h : p = 0
· simp [h]
rw [Polynomial.leadingCoeff, natDegree_comp_eq_of_mul_ne_zero, coeff_comp_degree_mul_degree] <;>
simp [((Commute.neg_one_left _).pow_left _).eq, h]
Polynomial.comp_eq_zero_iff
theorem
[Semiring R] [NoZeroDivisors R] {p q : R[X]} : p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0)
lemma comp_eq_zero_iff [Semiring R] [NoZeroDivisors R] {p q : R[X]} :
p.comp q = 0 ↔ p = 0 ∨ p.eval (q.coeff 0) = 0 ∧ q = C (q.coeff 0) := by
refine ⟨fun h ↦ ?_, Or.rec (fun h ↦ by simp [h]) fun h ↦ by rw [h.2, comp_C, h.1, C_0]⟩
have key : p.natDegree = 0 ∨ q.natDegree = 0 := by
rw [← mul_eq_zero, ← natDegree_comp, h, natDegree_zero]
obtain key | key := Or.imp eq_C_of_natDegree_eq_zero eq_C_of_natDegree_eq_zero key
· rw [key, C_comp] at h
exact Or.inl (key.trans h)
· rw [key, comp_C, C_eq_zero] at h
exact Or.inr ⟨h, key⟩
Polynomial.irreducible_mul_leadingCoeff_inv
theorem
{p : K[X]} : Irreducible (p * C (leadingCoeff p)⁻¹) ↔ Irreducible p
@[simp]
theorem irreducible_mul_leadingCoeff_inv {p : K[X]} :
IrreducibleIrreducible (p * C (leadingCoeff p)⁻¹) ↔ Irreducible p := by
by_cases hp0 : p = 0
· simp [hp0]
exact irreducible_mul_isUnit
(isUnit_C.mpr (IsUnit.mk0 _ (inv_ne_zero (leadingCoeff_ne_zero.mpr hp0))))
Polynomial.dvd_mul_leadingCoeff_inv
theorem
{p q : K[X]} (hp0 : p ≠ 0) : q ∣ p * C (leadingCoeff p)⁻¹ ↔ q ∣ p
@[simp] lemma dvd_mul_leadingCoeff_inv {p q : K[X]} (hp0 : p ≠ 0) :
q ∣ p * C (leadingCoeff p)⁻¹q ∣ p * C (leadingCoeff p)⁻¹ ↔ q ∣ p :=
IsUnit.dvd_mul_right <| isUnit_C.mpr <| IsUnit.mk0 _ <|
inv_ne_zero <| leadingCoeff_ne_zero.mpr hp0
Polynomial.monic_mul_leadingCoeff_inv
theorem
{p : K[X]} (h : p ≠ 0) : Monic (p * C (leadingCoeff p)⁻¹)
theorem monic_mul_leadingCoeff_inv {p : K[X]} (h : p ≠ 0) : Monic (p * C (leadingCoeff p)⁻¹) := by
rw [Monic, leadingCoeff_mul, leadingCoeff_C,
mul_inv_cancel₀ (show leadingCoeffleadingCoeff p ≠ 0 from mt leadingCoeff_eq_zero.1 h)]
Polynomial.degree_leadingCoeff_inv
theorem
{p : K[X]} (hp0 : p ≠ 0) : degree (C (leadingCoeff p)⁻¹) = 0
@[simp] lemma degree_leadingCoeff_inv {p : K[X]} (hp0 : p ≠ 0) :
degree (C (leadingCoeff p)⁻¹) = 0 :=
degree_C (inv_ne_zero <| leadingCoeff_ne_zero.mpr hp0)
Polynomial.degree_mul_leadingCoeff_inv
theorem
(p : K[X]) {q : K[X]} (h : q ≠ 0) : degree (p * C (leadingCoeff q)⁻¹) = degree p
theorem degree_mul_leadingCoeff_inv (p : K[X]) {q : K[X]} (h : q ≠ 0) :
degree (p * C (leadingCoeff q)⁻¹) = degree p := by
have h₁ : (leadingCoeff q)⁻¹(leadingCoeff q)⁻¹ ≠ 0 := inv_ne_zero (mt leadingCoeff_eq_zero.1 h)
rw [degree_mul_C h₁]
Polynomial.natDegree_mul_leadingCoeff_inv
theorem
(p : K[X]) {q : K[X]} (h : q ≠ 0) : natDegree (p * C (leadingCoeff q)⁻¹) = natDegree p
theorem natDegree_mul_leadingCoeff_inv (p : K[X]) {q : K[X]} (h : q ≠ 0) :
natDegree (p * C (leadingCoeff q)⁻¹) = natDegree p :=
natDegree_eq_of_degree_eq (degree_mul_leadingCoeff_inv _ h)
Polynomial.degree_mul_leadingCoeff_self_inv
theorem
(p : K[X]) : degree (p * C (leadingCoeff p)⁻¹) = degree p
theorem degree_mul_leadingCoeff_self_inv (p : K[X]) :
degree (p * C (leadingCoeff p)⁻¹) = degree p := by
by_cases hp : p = 0
· simp [hp]
exact degree_mul_leadingCoeff_inv _ hp
Polynomial.natDegree_mul_leadingCoeff_self_inv
theorem
(p : K[X]) : natDegree (p * C (leadingCoeff p)⁻¹) = natDegree p
theorem natDegree_mul_leadingCoeff_self_inv (p : K[X]) :
natDegree (p * C (leadingCoeff p)⁻¹) = natDegree p :=
natDegree_eq_of_degree_eq (degree_mul_leadingCoeff_self_inv _)
Polynomial.degree_add_degree_leadingCoeff_inv
theorem
(p : K[X]) : degree p + degree (C (leadingCoeff p)⁻¹) = degree p
@[simp] lemma degree_add_degree_leadingCoeff_inv (p : K[X]) :
degree p + degree (C (leadingCoeff p)⁻¹) = degree p := by
rw [← degree_mul, degree_mul_leadingCoeff_self_inv]