l3lab/ntp-mathlib huggingface dataset:
theorem monomial_natDegree_leadingCoeff_eq_self (h : p.support.card ≤ 1) :
    monomial p.natDegree p.leadingCoeff = p := by
  classical
  rcases card_support_le_one_iff_monomial.1 h with ⟨n, a, rfl⟩
  by_cases ha : a = 0 <;> 

Proof state:
case neg
R : Type u
S : Type v
a✝ b c d : R
n✝ m : ℕ
inst✝ : Semiring R
q : R[X]
ι : Type u_1
n : ℕ
a : R
h : card (support ((monomial n) a)) ≤ 1
ha : ¬a = 0
⊢ (monomial (natDegree ((monomial n) a))) (leadingCoeff ((monomial n) a)) = (monomial n) a

Next tactic:
simp [ha]
theorem C_mul_X_pow_eq_self (h : p.support.card ≤ 1) : C p.leadingCoeff * X ^ p.natDegree = p := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
h : card (support p) ≤ 1
⊢ C (leadingCoeff p) * X ^ natDegree p = p

Next tactic:
rw [C_mul_X_pow_eq_monomial, monomial_natDegree_leadingCoeff_eq_self h]
theorem leadingCoeff_pow' : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
  Nat.recOn n (by 

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
⊢ leadingCoeff p ^ Nat.zero ≠ 0 → leadingCoeff (p ^ Nat.zero) = leadingCoeff p ^ Nat.zero

Next tactic:
simp
theorem leadingCoeff_pow' : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
  Nat.recOn n (by simp) fun n ih h => by
    

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
ih : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n
h : leadingCoeff p ^ Nat.succ n ≠ 0
⊢ leadingCoeff (p ^ Nat.succ n) = leadingCoeff p ^ Nat.succ n

Next tactic:
have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by rw [pow_succ, h₁, mul_zero]
theorem leadingCoeff_pow' : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
  Nat.recOn n (by simp) fun n ih h => by
    have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
ih : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n
h : leadingCoeff p ^ Nat.succ n ≠ 0
h₁ : leadingCoeff p ^ n = 0
⊢ leadingCoeff p ^ Nat.succ n = 0

Next tactic:
rw [pow_succ, h₁, mul_zero]
theorem leadingCoeff_pow' : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
  Nat.recOn n (by simp) fun n ih h => by
    have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by rw [pow_succ, h₁, mul_zero]
    

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
ih : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n
h : leadingCoeff p ^ Nat.succ n ≠ 0
h₁ : leadingCoeff p ^ n ≠ 0
⊢ leadingCoeff (p ^ Nat.succ n) = leadingCoeff p ^ Nat.succ n

Next tactic:
have h₂ : leadingCoeff p * leadingCoeff (p ^ n) ≠ 0 := by rwa [pow_succ, ← ih h₁] at h
theorem leadingCoeff_pow' : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
  Nat.recOn n (by simp) fun n ih h => by
    have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by rw [pow_succ, h₁, mul_zero]
    have h₂ : leadingCoeff p * leadingCoeff (p ^ n) ≠ 0 := by 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
ih : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n
h : leadingCoeff p ^ Nat.succ n ≠ 0
h₁ : leadingCoeff p ^ n ≠ 0
⊢ leadingCoeff p * leadingCoeff (p ^ n) ≠ 0

Next tactic:
rwa [pow_succ, ← ih h₁] at h
theorem leadingCoeff_pow' : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n :=
  Nat.recOn n (by simp) fun n ih h => by
    have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by rw [pow_succ, h₁, mul_zero]
    have h₂ : leadingCoeff p * leadingCoeff (p ^ n) ≠ 0 := by rwa [pow_succ, ← ih h₁] at h
    

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
ih : leadingCoeff p ^ n ≠ 0 → leadingCoeff (p ^ n) = leadingCoeff p ^ n
h : leadingCoeff p ^ Nat.succ n ≠ 0
h₁ : leadingCoeff p ^ n ≠ 0
h₂ : leadingCoeff p * leadingCoeff (p ^ n) ≠ 0
⊢ leadingCoeff (p ^ Nat.succ n) = leadingCoeff p ^ Nat.succ n

Next tactic:
rw [pow_succ, pow_succ, leadingCoeff_mul' h₂, ih h₁]
theorem degree_pow' : ∀ {n : ℕ}, leadingCoeff p ^ n ≠ 0 → degree (p ^ n) = n • degree p
  | 0 => fun h => by 

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
h : leadingCoeff p ^ 0 ≠ 0
⊢ degree (p ^ 0) = 0 • degree p

Next tactic:
rw [pow_zero, ← C_1] at *
theorem degree_pow' : ∀ {n : ℕ}, leadingCoeff p ^ n ≠ 0 → degree (p ^ n) = n • degree p
  | 0 => fun h => by rw [pow_zero, ← C_1] at *; 

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
h : 1 ≠ 0
⊢ degree (C 1) = 0 • degree p

Next tactic:
rw [degree_C h, zero_nsmul]
theorem degree_pow' : ∀ {n : ℕ}, leadingCoeff p ^ n ≠ 0 → degree (p ^ n) = n • degree p
  | 0 => fun h => by rw [pow_zero, ← C_1] at *; rw [degree_C h, zero_nsmul]
  | n + 1 => fun h => by
    

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ (n + 1) ≠ 0
⊢ degree (p ^ (n + 1)) = (n + 1) • degree p

Next tactic:
have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by rw [pow_succ, h₁, mul_zero]
theorem degree_pow' : ∀ {n : ℕ}, leadingCoeff p ^ n ≠ 0 → degree (p ^ n) = n • degree p
  | 0 => fun h => by rw [pow_zero, ← C_1] at *; rw [degree_C h, zero_nsmul]
  | n + 1 => fun h => by
    have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ (n + 1) ≠ 0
h₁ : leadingCoeff p ^ n = 0
⊢ leadingCoeff p ^ (n + 1) = 0

Next tactic:
rw [pow_succ, h₁, mul_zero]
theorem degree_pow' : ∀ {n : ℕ}, leadingCoeff p ^ n ≠ 0 → degree (p ^ n) = n • degree p
  | 0 => fun h => by rw [pow_zero, ← C_1] at *; rw [degree_C h, zero_nsmul]
  | n + 1 => fun h => by
    have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by rw [pow_succ, h₁, mul_zero]
    

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ (n + 1) ≠ 0
h₁ : leadingCoeff p ^ n ≠ 0
⊢ degree (p ^ (n + 1)) = (n + 1) • degree p

Next tactic:
have h₂ : leadingCoeff p * leadingCoeff (p ^ n) ≠ 0 := by
      rwa [pow_succ, ← leadingCoeff_pow' h₁] at h
theorem degree_pow' : ∀ {n : ℕ}, leadingCoeff p ^ n ≠ 0 → degree (p ^ n) = n • degree p
  | 0 => fun h => by rw [pow_zero, ← C_1] at *; rw [degree_C h, zero_nsmul]
  | n + 1 => fun h => by
    have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by rw [pow_succ, h₁, mul_zero]
    have h₂ : leadingCoeff p * leadingCoeff (p ^ n) ≠ 0 := by
      

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ (n + 1) ≠ 0
h₁ : leadingCoeff p ^ n ≠ 0
⊢ leadingCoeff p * leadingCoeff (p ^ n) ≠ 0

Next tactic:
rwa [pow_succ, ← leadingCoeff_pow' h₁] at h
theorem degree_pow' : ∀ {n : ℕ}, leadingCoeff p ^ n ≠ 0 → degree (p ^ n) = n • degree p
  | 0 => fun h => by rw [pow_zero, ← C_1] at *; rw [degree_C h, zero_nsmul]
  | n + 1 => fun h => by
    have h₁ : leadingCoeff p ^ n ≠ 0 := fun h₁ => h <| by rw [pow_succ, h₁, mul_zero]
    have h₂ : leadingCoeff p * leadingCoeff (p ^ n) ≠ 0 := by
      rwa [pow_succ, ← leadingCoeff_pow' h₁] at h
    

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ (n + 1) ≠ 0
h₁ : leadingCoeff p ^ n ≠ 0
h₂ : leadingCoeff p * leadingCoeff (p ^ n) ≠ 0
⊢ degree (p ^ (n + 1)) = (n + 1) • degree p

Next tactic:
rw [pow_succ, degree_mul' h₂, succ_nsmul, degree_pow' h₁]
theorem natDegree_pow' {n : ℕ} (h : leadingCoeff p ^ n ≠ 0) : natDegree (p ^ n) = n * natDegree p :=
  letI := Classical.decEq R
  if hp0 : p = 0 then
    if hn0 : n = 0 then by 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ n ≠ 0
this : DecidableEq R := Classical.decEq R
hp0 : p = 0
hn0 : n = 0
⊢ natDegree (p ^ n) = n * natDegree p

Next tactic:
simp [*]
theorem natDegree_pow' {n : ℕ} (h : leadingCoeff p ^ n ≠ 0) : natDegree (p ^ n) = n * natDegree p :=
  letI := Classical.decEq R
  if hp0 : p = 0 then
    if hn0 : n = 0 then by simp [*] else by 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ n ≠ 0
this : DecidableEq R := Classical.decEq R
hp0 : p = 0
hn0 : ¬n = 0
⊢ natDegree (p ^ n) = n * natDegree p

Next tactic:
rw [hp0, zero_pow (Nat.pos_of_ne_zero hn0)]
theorem natDegree_pow' {n : ℕ} (h : leadingCoeff p ^ n ≠ 0) : natDegree (p ^ n) = n * natDegree p :=
  letI := Classical.decEq R
  if hp0 : p = 0 then
    if hn0 : n = 0 then by simp [*] else by rw [hp0, zero_pow (Nat.pos_of_ne_zero hn0)]; 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ n ≠ 0
this : DecidableEq R := Classical.decEq R
hp0 : p = 0
hn0 : ¬n = 0
⊢ natDegree 0 = n * natDegree 0

Next tactic:
simp
theorem natDegree_pow' {n : ℕ} (h : leadingCoeff p ^ n ≠ 0) : natDegree (p ^ n) = n * natDegree p :=
  letI := Classical.decEq R
  if hp0 : p = 0 then
    if hn0 : n = 0 then by simp [*] else by rw [hp0, zero_pow (Nat.pos_of_ne_zero hn0)]; simp
  else
    have hpn : p ^ n ≠ 0 := fun hpn0 => by
      

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ n ≠ 0
this : DecidableEq R := Classical.decEq R
hp0 : ¬p = 0
hpn0 : p ^ n = 0
⊢ False

Next tactic:
have h1 := h
theorem natDegree_pow' {n : ℕ} (h : leadingCoeff p ^ n ≠ 0) : natDegree (p ^ n) = n * natDegree p :=
  letI := Classical.decEq R
  if hp0 : p = 0 then
    if hn0 : n = 0 then by simp [*] else by rw [hp0, zero_pow (Nat.pos_of_ne_zero hn0)]; simp
  else
    have hpn : p ^ n ≠ 0 := fun hpn0 => by
      have h1 := h
      

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ n ≠ 0
this : DecidableEq R := Classical.decEq R
hp0 : ¬p = 0
hpn0 : p ^ n = 0
h1 : leadingCoeff p ^ n ≠ 0
⊢ False

Next tactic:
rw [← leadingCoeff_pow' h1, hpn0, leadingCoeff_zero] at h
theorem natDegree_pow' {n : ℕ} (h : leadingCoeff p ^ n ≠ 0) : natDegree (p ^ n) = n * natDegree p :=
  letI := Classical.decEq R
  if hp0 : p = 0 then
    if hn0 : n = 0 then by simp [*] else by rw [hp0, zero_pow (Nat.pos_of_ne_zero hn0)]; simp
  else
    have hpn : p ^ n ≠ 0 := fun hpn0 => by
      have h1 := h
      rw [← leadingCoeff_pow' h1, hpn0, leadingCoeff_zero] at h; 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : 0 ≠ 0
this : DecidableEq R := Classical.decEq R
hp0 : ¬p = 0
hpn0 : p ^ n = 0
h1 : leadingCoeff p ^ n ≠ 0
⊢ False

Next tactic:
exact h rfl
theorem natDegree_pow' {n : ℕ} (h : leadingCoeff p ^ n ≠ 0) : natDegree (p ^ n) = n * natDegree p :=
  letI := Classical.decEq R
  if hp0 : p = 0 then
    if hn0 : n = 0 then by simp [*] else by rw [hp0, zero_pow (Nat.pos_of_ne_zero hn0)]; simp
  else
    have hpn : p ^ n ≠ 0 := fun hpn0 => by
      have h1 := h
      rw [← leadingCoeff_pow' h1, hpn0, leadingCoeff_zero] at h; exact h rfl
    Option.some_inj.1 <|
      show (natDegree (p ^ n) : WithBot ℕ) = (n * natDegree p : ℕ) by
        

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ n ≠ 0
this : DecidableEq R := Classical.decEq R
hp0 : ¬p = 0
hpn : p ^ n ≠ 0
⊢ ↑(natDegree (p ^ n)) = ↑(n * natDegree p)

Next tactic:
rw [← degree_eq_natDegree hpn, degree_pow' h, degree_eq_natDegree hp0]
theorem natDegree_pow' {n : ℕ} (h : leadingCoeff p ^ n ≠ 0) : natDegree (p ^ n) = n * natDegree p :=
  letI := Classical.decEq R
  if hp0 : p = 0 then
    if hn0 : n = 0 then by simp [*] else by rw [hp0, zero_pow (Nat.pos_of_ne_zero hn0)]; simp
  else
    have hpn : p ^ n ≠ 0 := fun hpn0 => by
      have h1 := h
      rw [← leadingCoeff_pow' h1, hpn0, leadingCoeff_zero] at h; exact h rfl
    Option.some_inj.1 <|
      show (natDegree (p ^ n) : WithBot ℕ) = (n * natDegree p : ℕ) by
        rw [← degree_eq_natDegree hpn, degree_pow' h, degree_eq_natDegree hp0]; 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q : R[X]
ι : Type u_1
n : ℕ
h : leadingCoeff p ^ n ≠ 0
this : DecidableEq R := Classical.decEq R
hp0 : ¬p = 0
hpn : p ^ n ≠ 0
⊢ n • ↑(natDegree p) = ↑(n * natDegree p)

Next tactic:
simp
theorem leadingCoeff_monic_mul {p q : R[X]} (hp : Monic p) :
    leadingCoeff (p * q) = leadingCoeff q := by
  

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

Next tactic:
rcases eq_or_ne q 0 with (rfl | H)
theorem leadingCoeff_monic_mul {p q : R[X]} (hp : Monic p) :
    leadingCoeff (p * q) = leadingCoeff q := by
  rcases eq_or_ne q 0 with (rfl | H)
  · 

Proof state:
case inl
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
hp : Monic p
⊢ leadingCoeff (p * 0) = leadingCoeff 0

Next tactic:
simp
theorem leadingCoeff_monic_mul {p q : R[X]} (hp : Monic p) :
    leadingCoeff (p * q) = leadingCoeff q := by
  rcases eq_or_ne q 0 with (rfl | H)
  · simp
  · 

Proof state:
case inr
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
hp : Monic p
H : q ≠ 0
⊢ leadingCoeff (p * q) = leadingCoeff q

Next tactic:
rw [leadingCoeff_mul', hp.leadingCoeff, one_mul]
theorem leadingCoeff_monic_mul {p q : R[X]} (hp : Monic p) :
    leadingCoeff (p * q) = leadingCoeff q := by
  rcases eq_or_ne q 0 with (rfl | H)
  · simp
  · rw [leadingCoeff_mul', hp.leadingCoeff, one_mul]
    

Proof state:
case inr
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
hp : Monic p
H : q ≠ 0
⊢ leadingCoeff p * leadingCoeff q ≠ 0

Next tactic:
rwa [hp.leadingCoeff, one_mul, Ne.def, leadingCoeff_eq_zero]
theorem leadingCoeff_mul_monic {p q : R[X]} (hq : Monic q) :
    leadingCoeff (p * q) = leadingCoeff p :=
  letI := Classical.decEq R
  Decidable.byCases
    (fun H : leadingCoeff p = 0 => by
      

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
hq : Monic q
this : DecidableEq R := Classical.decEq R
H : leadingCoeff p = 0
⊢ leadingCoeff (p * q) = leadingCoeff p

Next tactic:
rw [H, leadingCoeff_eq_zero.1 H, zero_mul, leadingCoeff_zero]
theorem leadingCoeff_mul_monic {p q : R[X]} (hq : Monic q) :
    leadingCoeff (p * q) = leadingCoeff p :=
  letI := Classical.decEq R
  Decidable.byCases
    (fun H : leadingCoeff p = 0 => by
      rw [H, leadingCoeff_eq_zero.1 H, zero_mul, leadingCoeff_zero])
    fun H : leadingCoeff p ≠ 0 => by
      

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
hq : Monic q
this : DecidableEq R := Classical.decEq R
H : leadingCoeff p ≠ 0
⊢ leadingCoeff (p * q) = leadingCoeff p

Next tactic:
rw [leadingCoeff_mul', hq.leadingCoeff, mul_one]
theorem leadingCoeff_mul_monic {p q : R[X]} (hq : Monic q) :
    leadingCoeff (p * q) = leadingCoeff p :=
  letI := Classical.decEq R
  Decidable.byCases
    (fun H : leadingCoeff p = 0 => by
      rw [H, leadingCoeff_eq_zero.1 H, zero_mul, leadingCoeff_zero])
    fun H : leadingCoeff p ≠ 0 => by
      rw [leadingCoeff_mul', hq.leadingCoeff, mul_one]
      

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
hq : Monic q
this : DecidableEq R := Classical.decEq R
H : leadingCoeff p ≠ 0
⊢ leadingCoeff p * leadingCoeff q ≠ 0

Next tactic:
rwa [hq.leadingCoeff, mul_one]
theorem natDegree_mul_le {p q : R[X]} : natDegree (p * q) ≤ natDegree p + natDegree q := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
⊢ natDegree (p * q) ≤ natDegree p + natDegree q

Next tactic:
apply natDegree_le_of_degree_le
theorem natDegree_mul_le {p q : R[X]} : natDegree (p * q) ≤ natDegree p + natDegree q := by
  apply natDegree_le_of_degree_le
  

Proof state:
case a
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
⊢ degree (p * q) ≤ ↑(natDegree p + natDegree q)

Next tactic:
apply le_trans (degree_mul_le p q)
theorem natDegree_mul_le {p q : R[X]} : natDegree (p * q) ≤ natDegree p + natDegree q := by
  apply natDegree_le_of_degree_le
  apply le_trans (degree_mul_le p q)
  

Proof state:
case a
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
⊢ degree p + degree q ≤ ↑(natDegree p + natDegree q)

Next tactic:
rw [Nat.cast_add]
theorem natDegree_mul_le {p q : R[X]} : natDegree (p * q) ≤ natDegree p + natDegree q := by
  apply natDegree_le_of_degree_le
  apply le_trans (degree_mul_le p q)
  rw [Nat.cast_add]
  

Proof state:
case a
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
⊢ degree p + degree q ≤ ↑(natDegree p) + ↑(natDegree q)

Next tactic:
apply add_le_add
theorem natDegree_mul_le {p q : R[X]} : natDegree (p * q) ≤ natDegree p + natDegree q := by
  apply natDegree_le_of_degree_le
  apply le_trans (degree_mul_le p q)
  rw [Nat.cast_add]
  apply add_le_add <;> 

Proof state:
case a.h₁
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
⊢ degree p ≤ ↑(natDegree p)

Next tactic:
apply degree_le_natDegree
theorem natDegree_mul_le {p q : R[X]} : natDegree (p * q) ≤ natDegree p + natDegree q := by
  apply natDegree_le_of_degree_le
  apply le_trans (degree_mul_le p q)
  rw [Nat.cast_add]
  apply add_le_add <;> 

Proof state:
case a.h₂
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ : R[X]
ι : Type u_1
p q : R[X]
⊢ degree q ≤ ↑(natDegree q)

Next tactic:
apply degree_le_natDegree
theorem natDegree_pow_le {p : R[X]} {n : ℕ} : (p ^ n).natDegree ≤ n * p.natDegree := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
n : ℕ
⊢ natDegree (p ^ n) ≤ n * natDegree p

Next tactic:
induction' n with i hi
theorem natDegree_pow_le {p : R[X]} {n : ℕ} : (p ^ n).natDegree ≤ n * p.natDegree := by
  induction' n with i hi
  · 

Proof state:
case zero
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
⊢ natDegree (p ^ Nat.zero) ≤ Nat.zero * natDegree p

Next tactic:
simp
theorem natDegree_pow_le {p : R[X]} {n : ℕ} : (p ^ n).natDegree ≤ n * p.natDegree := by
  induction' n with i hi
  · simp
  · 

Proof state:
case succ
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
i : ℕ
hi : natDegree (p ^ i) ≤ i * natDegree p
⊢ natDegree (p ^ Nat.succ i) ≤ Nat.succ i * natDegree p

Next tactic:
rw [pow_succ, Nat.succ_mul, add_comm]
theorem natDegree_pow_le {p : R[X]} {n : ℕ} : (p ^ n).natDegree ≤ n * p.natDegree := by
  induction' n with i hi
  · simp
  · rw [pow_succ, Nat.succ_mul, add_comm]
    

Proof state:
case succ
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
i : ℕ
hi : natDegree (p ^ i) ≤ i * natDegree p
⊢ natDegree (p * p ^ i) ≤ natDegree p + i * natDegree p

Next tactic:
apply le_trans natDegree_mul_le
theorem natDegree_pow_le {p : R[X]} {n : ℕ} : (p ^ n).natDegree ≤ n * p.natDegree := by
  induction' n with i hi
  · simp
  · rw [pow_succ, Nat.succ_mul, add_comm]
    apply le_trans natDegree_mul_le
    

Proof state:
case succ
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
i : ℕ
hi : natDegree (p ^ i) ≤ i * natDegree p
⊢ natDegree p + natDegree (p ^ i) ≤ natDegree p + i * natDegree p

Next tactic:
exact add_le_add_left hi _
@[simp]
theorem coeff_pow_mul_natDegree (p : R[X]) (n : ℕ) :
    (p ^ n).coeff (n * p.natDegree) = p.leadingCoeff ^ n := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
n : ℕ
⊢ coeff (p ^ n) (n * natDegree p) = leadingCoeff p ^ n

Next tactic:
induction' n with i hi
@[simp]
theorem coeff_pow_mul_natDegree (p : R[X]) (n : ℕ) :
    (p ^ n).coeff (n * p.natDegree) = p.leadingCoeff ^ n := by
  induction' n with i hi
  · 

Proof state:
case zero
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
⊢ coeff (p ^ Nat.zero) (Nat.zero * natDegree p) = leadingCoeff p ^ Nat.zero

Next tactic:
simp
@[simp]
theorem coeff_pow_mul_natDegree (p : R[X]) (n : ℕ) :
    (p ^ n).coeff (n * p.natDegree) = p.leadingCoeff ^ n := by
  induction' n with i hi
  · simp
  · 

Proof state:
case succ
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
i : ℕ
hi : coeff (p ^ i) (i * natDegree p) = leadingCoeff p ^ i
⊢ coeff (p ^ Nat.succ i) (Nat.succ i * natDegree p) = leadingCoeff p ^ Nat.succ i

Next tactic:
rw [pow_succ', pow_succ', Nat.succ_mul]
@[simp]
theorem coeff_pow_mul_natDegree (p : R[X]) (n : ℕ) :
    (p ^ n).coeff (n * p.natDegree) = p.leadingCoeff ^ n := by
  induction' n with i hi
  · simp
  · rw [pow_succ', pow_succ', Nat.succ_mul]
    

Proof state:
case succ
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
i : ℕ
hi : coeff (p ^ i) (i * natDegree p) = leadingCoeff p ^ i
⊢ coeff (p ^ i * p) (i * natDegree p + natDegree p) = leadingCoeff p ^ i * leadingCoeff p

Next tactic:
by_cases hp1 : p.leadingCoeff ^ i = 0
@[simp]
theorem coeff_pow_mul_natDegree (p : R[X]) (n : ℕ) :
    (p ^ n).coeff (n * p.natDegree) = p.leadingCoeff ^ n := by
  induction' n with i hi
  · simp
  · rw [pow_succ', pow_succ', Nat.succ_mul]
    by_cases hp1 : p.leadingCoeff ^ i = 0
    · 

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
i : ℕ
hi : coeff (p ^ i) (i * natDegree p) = leadingCoeff p ^ i
hp1 : leadingCoeff p ^ i = 0
⊢ coeff (p ^ i * p) (i * natDegree p + natDegree p) = leadingCoeff p ^ i * leadingCoeff p

Next tactic:
rw [hp1, zero_mul]
@[simp]
theorem coeff_pow_mul_natDegree (p : R[X]) (n : ℕ) :
    (p ^ n).coeff (n * p.natDegree) = p.leadingCoeff ^ n := by
  induction' n with i hi
  · simp
  · rw [pow_succ', pow_succ', Nat.succ_mul]
    by_cases hp1 : p.leadingCoeff ^ i = 0
    · rw [hp1, zero_mul]
      

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
i : ℕ
hi : coeff (p ^ i) (i * natDegree p) = leadingCoeff p ^ i
hp1 : leadingCoeff p ^ i = 0
⊢ coeff (p ^ i * p) (i * natDegree p + natDegree p) = 0

Next tactic:
by_cases hp2 : p ^ i = 0
@[simp]
theorem coeff_pow_mul_natDegree (p : R[X]) (n : ℕ) :
    (p ^ n).coeff (n * p.natDegree) = p.leadingCoeff ^ n := by
  induction' n with i hi
  · simp
  · rw [pow_succ', pow_succ', Nat.succ_mul]
    by_cases hp1 : p.leadingCoeff ^ i = 0
    · rw [hp1, zero_mul]
      by_cases hp2 : p ^ i = 0
      · 

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
i : ℕ
hi : coeff (p ^ i) (i * natDegree p) = leadingCoeff p ^ i
hp1 : leadingCoeff p ^ i = 0
hp2 : p ^ i = 0
⊢ coeff (p ^ i * p) (i * natDegree p + natDegree p) = 0

Next tactic:
rw [hp2, zero_mul, coeff_zero]
@[simp]
theorem coeff_pow_mul_natDegree (p : R[X]) (n : ℕ) :
    (p ^ n).coeff (n * p.natDegree) = p.leadingCoeff ^ n := by
  induction' n with i hi
  · simp
  · rw [pow_succ', pow_succ', Nat.succ_mul]
    by_cases hp1 : p.leadingCoeff ^ i = 0
    · rw [hp1, zero_mul]
      by_cases hp2 : p ^ i = 0
      · rw [hp2, zero_mul, coeff_zero]
      · 

Proof state:
case neg
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q : R[X]
ι : Type u_1
p : R[X]
i : ℕ
hi : coeff (p ^ i) (i * natDegree p) = leadingCoeff p ^ i
hp1 : leadingCoeff p ^ i = 0
hp2 : ¬p ^ i = 0
⊢ coeff (p ^ i * p) (i * natDegree p + natDegree p) = 0

Next tactic:
apply coeff_eq_zero_of_natDegree_lt