l3lab/ntp-mathlib huggingface dataset:
theorem monic_C_mul_of_mul_leadingCoeff_eq_one {b : R} (hp : b * p.leadingCoeff = 1) :
    Monic (C b * p) := by
  unfold Monic
  nontriviality
  rw [leadingCoeff_mul' _] <;> 

Proof state:
R : Type u
S : Type v
a b✝ : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
b : R
hp : b * leadingCoeff p = 1
✝ : Nontrivial R
⊢ leadingCoeff (C b) * leadingCoeff p ≠ 0

Next tactic:
simp [leadingCoeff_C b, hp]
theorem monic_mul_C_of_leadingCoeff_mul_eq_one {b : R} (hp : p.leadingCoeff * b = 1) :
    Monic (p * C b) := by
  

Proof state:
R : Type u
S : Type v
a b✝ : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
b : R
hp : leadingCoeff p * b = 1
⊢ Monic (p * C b)

Next tactic:
unfold Monic
theorem monic_mul_C_of_leadingCoeff_mul_eq_one {b : R} (hp : p.leadingCoeff * b = 1) :
    Monic (p * C b) := by
  unfold Monic
  

Proof state:
R : Type u
S : Type v
a b✝ : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
b : R
hp : leadingCoeff p * b = 1
⊢ leadingCoeff (p * C b) = 1

Next tactic:
nontriviality
theorem monic_mul_C_of_leadingCoeff_mul_eq_one {b : R} (hp : p.leadingCoeff * b = 1) :
    Monic (p * C b) := by
  unfold Monic
  nontriviality
  

Proof state:
R : Type u
S : Type v
a b✝ : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
b : R
hp : leadingCoeff p * b = 1
✝ : Nontrivial R
⊢ leadingCoeff (p * C b) = 1

Next tactic:
rw [leadingCoeff_mul' _]
theorem monic_mul_C_of_leadingCoeff_mul_eq_one {b : R} (hp : p.leadingCoeff * b = 1) :
    Monic (p * C b) := by
  unfold Monic
  nontriviality
  rw [leadingCoeff_mul' _] <;> 

Proof state:
R : Type u
S : Type v
a b✝ : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
b : R
hp : leadingCoeff p * b = 1
✝ : Nontrivial R
⊢ leadingCoeff p * leadingCoeff (C b) = 1

Next tactic:
simp [leadingCoeff_C b, hp]
theorem monic_mul_C_of_leadingCoeff_mul_eq_one {b : R} (hp : p.leadingCoeff * b = 1) :
    Monic (p * C b) := by
  unfold Monic
  nontriviality
  rw [leadingCoeff_mul' _] <;> 

Proof state:
R : Type u
S : Type v
a b✝ : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
b : R
hp : leadingCoeff p * b = 1
✝ : Nontrivial R
⊢ leadingCoeff p * leadingCoeff (C b) ≠ 0

Next tactic:
simp [leadingCoeff_C b, hp]
theorem monic_of_degree_le (n : ℕ) (H1 : degree p ≤ n) (H2 : coeff p n = 1) : Monic p :=
  Decidable.byCases
    (fun H : degree p < n => eq_of_zero_eq_one (H2 ▸ (coeff_eq_zero_of_degree_lt H).symm) _ _)
    fun H : ¬degree p < n => by
    

Proof state:
R : Type u
S : Type v
a b : R
m n✝ : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
n : ℕ
H1 : degree p ≤ ↑n
H2 : coeff p n = 1
H : ¬degree p < ↑n
⊢ Monic p

Next tactic:
rwa [Monic, Polynomial.leadingCoeff, natDegree, (lt_or_eq_of_le H1).resolve_left H]
theorem monic_X_pow_add {n : ℕ} (H : degree p ≤ n) : Monic (X ^ (n + 1) + p) :=
  have H1 : degree p < (n + 1 : ℕ) := lt_of_le_of_lt H (WithBot.coe_lt_coe.2 (Nat.lt_succ_self n))
  monic_of_degree_le (n + 1)
    (le_trans (degree_add_le _ _) (max_le (degree_X_pow_le _) (le_of_lt H1)))
    (by 

Proof state:
R : Type u
S : Type v
a b : R
m n✝ : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
n : ℕ
H : degree p ≤ ↑n
H1 : degree p < ↑(n + 1)
⊢ coeff (X ^ (n + 1) + p) (n + 1) = 1

Next tactic:
rw [coeff_add, coeff_X_pow, if_pos rfl, coeff_eq_zero_of_degree_lt H1, add_zero]
theorem Monic.mul (hp : Monic p) (hq : Monic q) : Monic (p * q) :=
  letI := Classical.decEq R
  if h0 : (0 : R) = 1 then
    haveI := subsingleton_of_zero_eq_one h0
    Subsingleton.elim _ _
  else by
    

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
this : DecidableEq R := Classical.decEq R
h0 : ¬0 = 1
⊢ Monic (p * q)

Next tactic:
have : p.leadingCoeff * q.leadingCoeff ≠ 0 := by
      simp [Monic.def.1 hp, Monic.def.1 hq, Ne.symm h0]
theorem Monic.mul (hp : Monic p) (hq : Monic q) : Monic (p * q) :=
  letI := Classical.decEq R
  if h0 : (0 : R) = 1 then
    haveI := subsingleton_of_zero_eq_one h0
    Subsingleton.elim _ _
  else by
    have : p.leadingCoeff * q.leadingCoeff ≠ 0 := by
      

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
this : DecidableEq R := Classical.decEq R
h0 : ¬0 = 1
⊢ Polynomial.leadingCoeff p * Polynomial.leadingCoeff q ≠ 0

Next tactic:
simp [Monic.def.1 hp, Monic.def.1 hq, Ne.symm h0]
theorem Monic.mul (hp : Monic p) (hq : Monic q) : Monic (p * q) :=
  letI := Classical.decEq R
  if h0 : (0 : R) = 1 then
    haveI := subsingleton_of_zero_eq_one h0
    Subsingleton.elim _ _
  else by
    have : p.leadingCoeff * q.leadingCoeff ≠ 0 := by
      simp [Monic.def.1 hp, Monic.def.1 hq, Ne.symm h0]
    

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
this✝ : DecidableEq R := Classical.decEq R
h0 : ¬0 = 1
this : Polynomial.leadingCoeff p * Polynomial.leadingCoeff q ≠ 0
⊢ Monic (p * q)

Next tactic:
rw [Monic.def, leadingCoeff_mul' this, Monic.def.1 hp, Monic.def.1 hq, one_mul]
theorem Monic.pow (hp : Monic p) : ∀ n : ℕ, Monic (p ^ n)
  | 0 => monic_one
  | n + 1 => by
    

Proof state:
R : Type u
S : Type v
a b : R
m n✝ : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
n : ℕ
⊢ Monic (p ^ (n + 1))

Next tactic:
rw [pow_succ]
theorem Monic.pow (hp : Monic p) : ∀ n : ℕ, Monic (p ^ n)
  | 0 => monic_one
  | n + 1 => by
    rw [pow_succ]
    

Proof state:
R : Type u
S : Type v
a b : R
m n✝ : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
n : ℕ
⊢ Monic (p * p ^ n)

Next tactic:
exact hp.mul (Monic.pow hp n)
theorem Monic.add_of_left (hp : Monic p) (hpq : degree q < degree p) : Monic (p + q) := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hpq : degree q < degree p
⊢ Monic (p + q)

Next tactic:
rwa [Monic, add_comm, leadingCoeff_add_of_degree_lt hpq]
theorem Monic.add_of_right (hq : Monic q) (hpq : degree p < degree q) : Monic (p + q) := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hq : Monic q
hpq : degree p < degree q
⊢ Monic (p + q)

Next tactic:
rwa [Monic, leadingCoeff_add_of_degree_lt hpq]
theorem Monic.of_mul_monic_left (hp : p.Monic) (hpq : (p * q).Monic) : q.Monic := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hpq : Monic (p * q)
⊢ Monic q

Next tactic:
contrapose! hpq
theorem Monic.of_mul_monic_left (hp : p.Monic) (hpq : (p * q).Monic) : q.Monic := by
  contrapose! hpq
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hpq : ¬Monic q
⊢ ¬Monic (p * q)

Next tactic:
rw [Monic.def] at hpq ⊢
theorem Monic.of_mul_monic_left (hp : p.Monic) (hpq : (p * q).Monic) : q.Monic := by
  contrapose! hpq
  rw [Monic.def] at hpq ⊢
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hpq : ¬Polynomial.leadingCoeff q = 1
⊢ ¬Polynomial.leadingCoeff (p * q) = 1

Next tactic:
rwa [leadingCoeff_monic_mul hp]
theorem Monic.of_mul_monic_right (hq : q.Monic) (hpq : (p * q).Monic) : p.Monic := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hq : Monic q
hpq : Monic (p * q)
⊢ Monic p

Next tactic:
contrapose! hpq
theorem Monic.of_mul_monic_right (hq : q.Monic) (hpq : (p * q).Monic) : p.Monic := by
  contrapose! hpq
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hq : Monic q
hpq : ¬Monic p
⊢ ¬Monic (p * q)

Next tactic:
rw [Monic.def] at hpq ⊢
theorem Monic.of_mul_monic_right (hq : q.Monic) (hpq : (p * q).Monic) : p.Monic := by
  contrapose! hpq
  rw [Monic.def] at hpq ⊢
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hq : Monic q
hpq : ¬Polynomial.leadingCoeff p = 1
⊢ ¬Polynomial.leadingCoeff (p * q) = 1

Next tactic:
rwa [leadingCoeff_mul_monic hq]
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
⊢ natDegree p = 0 ↔ p = 1

Next tactic:
constructor
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> 

Proof state:
case mp
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
⊢ natDegree p = 0 → p = 1

Next tactic:
intro h
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> 

Proof state:
case mpr
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
⊢ p = 1 → natDegree p = 0

Next tactic:
intro h
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> intro h
  

Proof state:
case mp
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h : natDegree p = 0
⊢ p = 1
case mpr
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h : p = 1
⊢ natDegree p = 0

Next tactic:
swap
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> intro h
  swap
  · 

Proof state:
case mpr
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h : p = 1
⊢ natDegree p = 0

Next tactic:
rw [h]
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> intro h
  swap
  · rw [h]
    

Proof state:
case mpr
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h : p = 1
⊢ natDegree 1 = 0

Next tactic:
exact natDegree_one
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> intro h
  swap
  · rw [h]
    exact natDegree_one
  

Proof state:
case mp
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h : natDegree p = 0
⊢ p = 1

Next tactic:
have : p = C (p.coeff 0) := by
    rw [← Polynomial.degree_le_zero_iff]
    rwa [Polynomial.natDegree_eq_zero_iff_degree_le_zero] at h
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> intro h
  swap
  · rw [h]
    exact natDegree_one
  have : p = C (p.coeff 0) := by
    

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h : natDegree p = 0
⊢ p = C (coeff p 0)

Next tactic:
rw [← Polynomial.degree_le_zero_iff]
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> intro h
  swap
  · rw [h]
    exact natDegree_one
  have : p = C (p.coeff 0) := by
    rw [← Polynomial.degree_le_zero_iff]
    

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h : natDegree p = 0
⊢ degree p ≤ 0

Next tactic:
rwa [Polynomial.natDegree_eq_zero_iff_degree_le_zero] at h
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> intro h
  swap
  · rw [h]
    exact natDegree_one
  have : p = C (p.coeff 0) := by
    rw [← Polynomial.degree_le_zero_iff]
    rwa [Polynomial.natDegree_eq_zero_iff_degree_le_zero] at h
  

Proof state:
case mp
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h : natDegree p = 0
this : p = C (coeff p 0)
⊢ p = 1

Next tactic:
rw [this]
@[simp]
theorem natDegree_eq_zero_iff_eq_one (hp : p.Monic) : p.natDegree = 0 ↔ p = 1 := by
  constructor <;> intro h
  swap
  · rw [h]
    exact natDegree_one
  have : p = C (p.coeff 0) := by
    rw [← Polynomial.degree_le_zero_iff]
    rwa [Polynomial.natDegree_eq_zero_iff_degree_le_zero] at h
  rw [this]
  

Proof state:
case mp
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h : natDegree p = 0
this : p = C (coeff p 0)
⊢ C (coeff p 0) = 1

Next tactic:
rw [← h, ← Polynomial.leadingCoeff, Monic.def.1 hp, C_1]
@[simp]
theorem degree_le_zero_iff_eq_one (hp : p.Monic) : p.degree ≤ 0 ↔ p = 1 := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
⊢ degree p ≤ 0 ↔ p = 1

Next tactic:
rw [← hp.natDegree_eq_zero_iff_eq_one, natDegree_eq_zero_iff_degree_le_zero]
theorem natDegree_mul (hp : p.Monic) (hq : q.Monic) :
    (p * q).natDegree = p.natDegree + q.natDegree := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
⊢ natDegree (p * q) = natDegree p + natDegree q

Next tactic:
nontriviality R
theorem natDegree_mul (hp : p.Monic) (hq : q.Monic) :
    (p * q).natDegree = p.natDegree + q.natDegree := by
  nontriviality R
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
✝ : Nontrivial R
⊢ natDegree (p * q) = natDegree p + natDegree q

Next tactic:
apply natDegree_mul'
theorem natDegree_mul (hp : p.Monic) (hq : q.Monic) :
    (p * q).natDegree = p.natDegree + q.natDegree := by
  nontriviality R
  apply natDegree_mul'
  

Proof state:
case h
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
✝ : Nontrivial R
⊢ Polynomial.leadingCoeff p * Polynomial.leadingCoeff q ≠ 0

Next tactic:
simp [hp.leadingCoeff, hq.leadingCoeff]
theorem degree_mul_comm (hp : p.Monic) (q : R[X]) : (p * q).degree = (q * p).degree := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q✝ r : R[X]
hp : Monic p
q : R[X]
⊢ degree (p * q) = degree (q * p)

Next tactic:
by_cases h : q = 0
theorem degree_mul_comm (hp : p.Monic) (q : R[X]) : (p * q).degree = (q * p).degree := by
  by_cases h : q = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q✝ r : R[X]
hp : Monic p
q : R[X]
h : q = 0
⊢ degree (p * q) = degree (q * p)

Next tactic:
simp [h]
theorem degree_mul_comm (hp : p.Monic) (q : R[X]) : (p * q).degree = (q * p).degree := by
  by_cases h : q = 0
  · simp [h]
  

Proof state:
case neg
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q✝ r : R[X]
hp : Monic p
q : R[X]
h : ¬q = 0
⊢ degree (p * q) = degree (q * p)

Next tactic:
rw [degree_mul', hp.degree_mul]
theorem degree_mul_comm (hp : p.Monic) (q : R[X]) : (p * q).degree = (q * p).degree := by
  by_cases h : q = 0
  · simp [h]
  rw [degree_mul', hp.degree_mul]
  · 

Proof state:
case neg
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q✝ r : R[X]
hp : Monic p
q : R[X]
h : ¬q = 0
⊢ degree p + degree q = degree q + degree p

Next tactic:
exact add_comm _ _
theorem degree_mul_comm (hp : p.Monic) (q : R[X]) : (p * q).degree = (q * p).degree := by
  by_cases h : q = 0
  · simp [h]
  rw [degree_mul', hp.degree_mul]
  · exact add_comm _ _
  · 

Proof state:
case neg
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q✝ r : R[X]
hp : Monic p
q : R[X]
h : ¬q = 0
⊢ Polynomial.leadingCoeff p * Polynomial.leadingCoeff q ≠ 0

Next tactic:
rwa [hp.leadingCoeff, one_mul, leadingCoeff_ne_zero]
nonrec theorem natDegree_mul' (hp : p.Monic) (hq : q ≠ 0) :
    (p * q).natDegree = p.natDegree + q.natDegree := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : q ≠ 0
⊢ natDegree (p * q) = natDegree p + natDegree q

Next tactic:
rw [natDegree_mul', add_comm]
nonrec theorem natDegree_mul' (hp : p.Monic) (hq : q ≠ 0) :
    (p * q).natDegree = p.natDegree + q.natDegree := by
  rw [natDegree_mul', add_comm]
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : q ≠ 0
⊢ Polynomial.leadingCoeff p * Polynomial.leadingCoeff q ≠ 0

Next tactic:
simpa [hp.leadingCoeff, leadingCoeff_ne_zero]
theorem natDegree_mul_comm (hp : p.Monic) (q : R[X]) : (p * q).natDegree = (q * p).natDegree := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q✝ r : R[X]
hp : Monic p
q : R[X]
⊢ natDegree (p * q) = natDegree (q * p)

Next tactic:
by_cases h : q = 0
theorem natDegree_mul_comm (hp : p.Monic) (q : R[X]) : (p * q).natDegree = (q * p).natDegree := by
  by_cases h : q = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q✝ r : R[X]
hp : Monic p
q : R[X]
h : q = 0
⊢ natDegree (p * q) = natDegree (q * p)

Next tactic:
simp [h]
theorem natDegree_mul_comm (hp : p.Monic) (q : R[X]) : (p * q).natDegree = (q * p).natDegree := by
  by_cases h : q = 0
  · simp [h]
  

Proof state:
case neg
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q✝ r : R[X]
hp : Monic p
q : R[X]
h : ¬q = 0
⊢ natDegree (p * q) = natDegree (q * p)

Next tactic:
rw [hp.natDegree_mul' h, Polynomial.natDegree_mul', add_comm]
theorem natDegree_mul_comm (hp : p.Monic) (q : R[X]) : (p * q).natDegree = (q * p).natDegree := by
  by_cases h : q = 0
  · simp [h]
  rw [hp.natDegree_mul' h, Polynomial.natDegree_mul', add_comm]
  

Proof state:
case neg
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q✝ r : R[X]
hp : Monic p
q : R[X]
h : ¬q = 0
⊢ Polynomial.leadingCoeff q * Polynomial.leadingCoeff p ≠ 0

Next tactic:
simpa [hp.leadingCoeff, leadingCoeff_ne_zero]
theorem not_dvd_of_natDegree_lt (hp : Monic p) (h0 : q ≠ 0) (hl : natDegree q < natDegree p) :
    ¬p ∣ q := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
h0 : q ≠ 0
hl : natDegree q < natDegree p
⊢ ¬p ∣ q

Next tactic:
rintro ⟨r, rfl⟩
theorem not_dvd_of_natDegree_lt (hp : Monic p) (h0 : q ≠ 0) (hl : natDegree q < natDegree p) :
    ¬p ∣ q := by
  rintro ⟨r, rfl⟩
  

Proof state:
case intro
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p r✝ : R[X]
hp : Monic p
r : R[X]
h0 : p * r ≠ 0
hl : natDegree (p * r) < natDegree p
⊢ False

Next tactic:
rw [hp.natDegree_mul' <| right_ne_zero_of_mul h0] at hl
theorem not_dvd_of_natDegree_lt (hp : Monic p) (h0 : q ≠ 0) (hl : natDegree q < natDegree p) :
    ¬p ∣ q := by
  rintro ⟨r, rfl⟩
  rw [hp.natDegree_mul' <| right_ne_zero_of_mul h0] at hl
  

Proof state:
case intro
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p r✝ : R[X]
hp : Monic p
r : R[X]
h0 : p * r ≠ 0
hl : natDegree p + natDegree r < natDegree p
⊢ False

Next tactic:
exact hl.not_le (Nat.le_add_right _ _)
theorem nextCoeff_mul (hp : Monic p) (hq : Monic q) :
    nextCoeff (p * q) = nextCoeff p + nextCoeff q := by
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
⊢ nextCoeff (p * q) = nextCoeff p + nextCoeff q

Next tactic:
nontriviality
theorem nextCoeff_mul (hp : Monic p) (hq : Monic q) :
    nextCoeff (p * q) = nextCoeff p + nextCoeff q := by
  nontriviality
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
✝ : Nontrivial R
⊢ nextCoeff (p * q) = nextCoeff p + nextCoeff q

Next tactic:
simp only [← coeff_one_reverse]
theorem nextCoeff_mul (hp : Monic p) (hq : Monic q) :
    nextCoeff (p * q) = nextCoeff p + nextCoeff q := by
  nontriviality
  simp only [← coeff_one_reverse]
  

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
✝ : Nontrivial R
⊢ coeff (reverse (p * q)) 1 = coeff (reverse p) 1 + coeff (reverse q) 1

Next tactic:
rw [reverse_mul]
theorem nextCoeff_mul (hp : Monic p) (hq : Monic q) :
    nextCoeff (p * q) = nextCoeff p + nextCoeff q := by
  nontriviality
  simp only [← coeff_one_reverse]
  rw [reverse_mul] <;>
    

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
✝ : Nontrivial R
⊢ coeff (reverse p * reverse q) 1 = coeff (reverse p) 1 + coeff (reverse q) 1

Next tactic:
simp [coeff_mul, antidiagonal, hp.leadingCoeff, hq.leadingCoeff, add_comm,
      show Nat.succ 0 = 1 from rfl]
theorem nextCoeff_mul (hp : Monic p) (hq : Monic q) :
    nextCoeff (p * q) = nextCoeff p + nextCoeff q := by
  nontriviality
  simp only [← coeff_one_reverse]
  rw [reverse_mul] <;>
    

Proof state:
R : Type u
S : Type v
a b : R
m n : ℕ
ι : Type y
inst✝ : Semiring R
p q r : R[X]
hp : Monic p
hq : Monic q
✝ : Nontrivial R
⊢ Polynomial.leadingCoeff p * Polynomial.leadingCoeff q ≠ 0

Next tactic:
simp [coeff_mul, antidiagonal, hp.leadingCoeff, hq.leadingCoeff, add_comm,
      show Nat.succ 0 = 1 from rfl]
theorem eq_one_of_map_eq_one {S : Type*} [Semiring S] [Nontrivial S] (f : R →+* S) (hp : p.Monic)
    (map_eq : p.map f = 1) : p = 1 := by
  

Proof state:
R : Type u
S✝ : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : Semiring R
p q r : R[X]
S : Type u_1
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
hp : Monic p
map_eq : Polynomial.map f p = 1
⊢ p = 1

Next tactic:
nontriviality R
theorem eq_one_of_map_eq_one {S : Type*} [Semiring S] [Nontrivial S] (f : R →+* S) (hp : p.Monic)
    (map_eq : p.map f = 1) : p = 1 := by
  nontriviality R
  

Proof state:
R : Type u
S✝ : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : Semiring R
p q r : R[X]
S : Type u_1
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
hp : Monic p
map_eq : Polynomial.map f p = 1
✝ : Nontrivial R
⊢ p = 1

Next tactic:
have hdeg : p.degree = 0 := by
    rw [← degree_map_eq_of_leadingCoeff_ne_zero f _, map_eq, degree_one]
    · rw [hp.leadingCoeff, f.map_one]
      exact one_ne_zero
theorem eq_one_of_map_eq_one {S : Type*} [Semiring S] [Nontrivial S] (f : R →+* S) (hp : p.Monic)
    (map_eq : p.map f = 1) : p = 1 := by
  nontriviality R
  have hdeg : p.degree = 0 := by
    

Proof state:
R : Type u
S✝ : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : Semiring R
p q r : R[X]
S : Type u_1
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
hp : Monic p
map_eq : Polynomial.map f p = 1
✝ : Nontrivial R
⊢ degree p = 0

Next tactic:
rw [← degree_map_eq_of_leadingCoeff_ne_zero f _, map_eq, degree_one]
theorem eq_one_of_map_eq_one {S : Type*} [Semiring S] [Nontrivial S] (f : R →+* S) (hp : p.Monic)
    (map_eq : p.map f = 1) : p = 1 := by
  nontriviality R
  have hdeg : p.degree = 0 := by
    rw [← degree_map_eq_of_leadingCoeff_ne_zero f _, map_eq, degree_one]
    · 

Proof state:
R : Type u
S✝ : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : Semiring R
p q r : R[X]
S : Type u_1
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
hp : Monic p
map_eq : Polynomial.map f p = 1
✝ : Nontrivial R
⊢ f (Polynomial.leadingCoeff p) ≠ 0

Next tactic:
rw [hp.leadingCoeff, f.map_one]
theorem eq_one_of_map_eq_one {S : Type*} [Semiring S] [Nontrivial S] (f : R →+* S) (hp : p.Monic)
    (map_eq : p.map f = 1) : p = 1 := by
  nontriviality R
  have hdeg : p.degree = 0 := by
    rw [← degree_map_eq_of_leadingCoeff_ne_zero f _, map_eq, degree_one]
    · rw [hp.leadingCoeff, f.map_one]
      

Proof state:
R : Type u
S✝ : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : Semiring R
p q r : R[X]
S : Type u_1
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
hp : Monic p
map_eq : Polynomial.map f p = 1
✝ : Nontrivial R
⊢ 1 ≠ 0

Next tactic:
exact one_ne_zero
theorem eq_one_of_map_eq_one {S : Type*} [Semiring S] [Nontrivial S] (f : R →+* S) (hp : p.Monic)
    (map_eq : p.map f = 1) : p = 1 := by
  nontriviality R
  have hdeg : p.degree = 0 := by
    rw [← degree_map_eq_of_leadingCoeff_ne_zero f _, map_eq, degree_one]
    · rw [hp.leadingCoeff, f.map_one]
      exact one_ne_zero
  

Proof state:
R : Type u
S✝ : Type v
a b : R
m n : ℕ
ι : Type y
inst✝² : Semiring R
p q r : R[X]
S : Type u_1
inst✝¹ : Semiring S
inst✝ : Nontrivial S
f : R →+* S
hp : Monic p
map_eq : Polynomial.map f p = 1
✝ : Nontrivial R
hdeg : degree p = 0
⊢ p = 1

Next tactic:
have hndeg : p.natDegree = 0 :=
    WithBot.coe_eq_coe.mp ((degree_eq_natDegree hp.ne_zero).symm.trans hdeg)