l3lab/ntp-mathlib huggingface dataset:
theorem degree_eq_iff_natDegree_eq {p : R[X]} {n : ℕ} (hp : p ≠ 0) :
    p.degree = n ↔ p.natDegree = n := by rw [degree_eq_natDegree hp]; 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
hp : p ≠ 0
⊢ ↑(natDegree p) = ↑n ↔ natDegree p = n

Next tactic:
exact WithBot.coe_eq_coe
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
hn : 0 < n
⊢ degree p = ↑n ↔ natDegree p = n

Next tactic:
constructor
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · 

Proof state:
case mp
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
hn : 0 < n
⊢ degree p = ↑n → natDegree p = n

Next tactic:
intro H
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    

Proof state:
case mp
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
hn : 0 < n
H : degree p = ↑n
⊢ natDegree p = n

Next tactic:
rwa [← degree_eq_iff_natDegree_eq]
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    rwa [← degree_eq_iff_natDegree_eq]
    

Proof state:
case mp
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
hn : 0 < n
H : degree p = ↑n
⊢ p ≠ 0

Next tactic:
rintro rfl
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    rwa [← degree_eq_iff_natDegree_eq]
    rintro rfl
    

Proof state:
case mp
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
hn : 0 < n
H : degree 0 = ↑n
⊢ False

Next tactic:
rw [degree_zero] at H
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    rwa [← degree_eq_iff_natDegree_eq]
    rintro rfl
    rw [degree_zero] at H
    

Proof state:
case mp
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
hn : 0 < n
H : ⊥ = ↑n
⊢ False

Next tactic:
exact Option.noConfusion H
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    rwa [← degree_eq_iff_natDegree_eq]
    rintro rfl
    rw [degree_zero] at H
    exact Option.noConfusion H
  · 

Proof state:
case mpr
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
hn : 0 < n
⊢ natDegree p = n → degree p = ↑n

Next tactic:
intro H
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    rwa [← degree_eq_iff_natDegree_eq]
    rintro rfl
    rw [degree_zero] at H
    exact Option.noConfusion H
  · intro H
    

Proof state:
case mpr
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
hn : 0 < n
H : natDegree p = n
⊢ degree p = ↑n

Next tactic:
rwa [degree_eq_iff_natDegree_eq]
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    rwa [← degree_eq_iff_natDegree_eq]
    rintro rfl
    rw [degree_zero] at H
    exact Option.noConfusion H
  · intro H
    rwa [degree_eq_iff_natDegree_eq]
    

Proof state:
case mpr
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
hn : 0 < n
H : natDegree p = n
⊢ p ≠ 0

Next tactic:
rintro rfl
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    rwa [← degree_eq_iff_natDegree_eq]
    rintro rfl
    rw [degree_zero] at H
    exact Option.noConfusion H
  · intro H
    rwa [degree_eq_iff_natDegree_eq]
    rintro rfl
    

Proof state:
case mpr
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
hn : 0 < n
H : natDegree 0 = n
⊢ False

Next tactic:
rw [natDegree_zero] at H
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    rwa [← degree_eq_iff_natDegree_eq]
    rintro rfl
    rw [degree_zero] at H
    exact Option.noConfusion H
  · intro H
    rwa [degree_eq_iff_natDegree_eq]
    rintro rfl
    rw [natDegree_zero] at H
    

Proof state:
case mpr
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
hn : 0 < n
H : 0 = n
⊢ False

Next tactic:
rw [H] at hn
theorem degree_eq_iff_natDegree_eq_of_pos {p : R[X]} {n : ℕ} (hn : 0 < n) :
    p.degree = n ↔ p.natDegree = n := by
  constructor
  · intro H
    rwa [← degree_eq_iff_natDegree_eq]
    rintro rfl
    rw [degree_zero] at H
    exact Option.noConfusion H
  · intro H
    rwa [degree_eq_iff_natDegree_eq]
    rintro rfl
    rw [natDegree_zero] at H
    rw [H] at hn
    

Proof state:
case mpr
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
hn : n < n
H : 0 = n
⊢ False

Next tactic:
exact lt_irrefl _ hn
theorem natDegree_eq_of_degree_eq_some {p : R[X]} {n : ℕ} (h : degree p = n) : natDegree p = n := by
  -- Porting note: `Nat.cast_withBot` is required.
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
h : degree p = ↑n
⊢ natDegree p = n

Next tactic:
rw [natDegree, h, Nat.cast_withBot, WithBot.unbot'_coe]
theorem natDegree_eq_of_degree_eq [Semiring S] {q : S[X]} (h : degree p = degree 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 : R[X]
inst✝ : Semiring S
q : S[X]
h : degree p = degree q
⊢ natDegree p = natDegree q

Next tactic:
unfold natDegree
theorem natDegree_eq_of_degree_eq [Semiring S] {q : S[X]} (h : degree p = degree q) :
    natDegree p = natDegree q := by unfold natDegree; 

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝¹ : Semiring R
p q✝ r : R[X]
inst✝ : Semiring S
q : S[X]
h : degree p = degree q
⊢ WithBot.unbot' 0 (degree p) = WithBot.unbot' 0 (degree q)

Next tactic:
rw [h]
theorem le_natDegree_of_ne_zero (h : coeff p n ≠ 0) : 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 : R[X]
h : coeff p n ≠ 0
⊢ n ≤ natDegree p

Next tactic:
rw [← Nat.cast_le (α := WithBot ℕ), ← degree_eq_natDegree]
theorem le_natDegree_of_ne_zero (h : coeff p n ≠ 0) : n ≤ natDegree p := by
  rw [← Nat.cast_le (α := WithBot ℕ), ← degree_eq_natDegree]
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : coeff p n ≠ 0
⊢ ↑n ≤ degree p
R : Type u S : Type v a b c d : R n m : ℕ inst✝ : Semiring R p q r : R[X] h : coeff p n ≠ 0 ⊢ p ≠ 0

Next tactic:
exact le_degree_of_ne_zero h
theorem le_natDegree_of_ne_zero (h : coeff p n ≠ 0) : n ≤ natDegree p := by
  rw [← Nat.cast_le (α := WithBot ℕ), ← degree_eq_natDegree]
  exact le_degree_of_ne_zero h
  · 

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : coeff p n ≠ 0
⊢ p ≠ 0

Next tactic:
rintro rfl
theorem le_natDegree_of_ne_zero (h : coeff p n ≠ 0) : n ≤ natDegree p := by
  rw [← Nat.cast_le (α := WithBot ℕ), ← degree_eq_natDegree]
  exact le_degree_of_ne_zero h
  · rintro rfl
    

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
q r : R[X]
h : coeff 0 n ≠ 0
⊢ False

Next tactic:
exact h rfl
theorem degree_le_degree (h : coeff q (natDegree p) ≠ 0) : degree p ≤ degree q := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : coeff q (natDegree p) ≠ 0
⊢ degree p ≤ degree q

Next tactic:
by_cases hp : p = 0
theorem degree_le_degree (h : coeff q (natDegree p) ≠ 0) : degree p ≤ degree q := by
  by_cases hp : p = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : coeff q (natDegree p) ≠ 0
hp : p = 0
⊢ degree p ≤ degree q

Next tactic:
rw [hp]
theorem degree_le_degree (h : coeff q (natDegree p) ≠ 0) : degree p ≤ degree q := by
  by_cases hp : p = 0
  · rw [hp]
    

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : coeff q (natDegree p) ≠ 0
hp : p = 0
⊢ degree 0 ≤ degree q

Next tactic:
exact bot_le
theorem degree_le_degree (h : coeff q (natDegree p) ≠ 0) : degree p ≤ degree q := by
  by_cases hp : p = 0
  · rw [hp]
    exact bot_le
  · 

Proof state:
case neg
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : coeff q (natDegree p) ≠ 0
hp : ¬p = 0
⊢ degree p ≤ degree q

Next tactic:
rw [degree_eq_natDegree hp]
theorem degree_le_degree (h : coeff q (natDegree p) ≠ 0) : degree p ≤ degree q := by
  by_cases hp : p = 0
  · rw [hp]
    exact bot_le
  · rw [degree_eq_natDegree hp]
    

Proof state:
case neg
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : coeff q (natDegree p) ≠ 0
hp : ¬p = 0
⊢ ↑(natDegree p) ≤ degree q

Next tactic:
exact le_degree_of_ne_zero h
theorem natDegree_lt_natDegree {p q : R[X]} (hp : p ≠ 0) (hpq : p.degree < q.degree) :
    p.natDegree < q.natDegree := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ r p q : R[X]
hp : p ≠ 0
hpq : degree p < degree q
⊢ natDegree p < natDegree q

Next tactic:
by_cases hq : q = 0
theorem natDegree_lt_natDegree {p q : R[X]} (hp : p ≠ 0) (hpq : p.degree < q.degree) :
    p.natDegree < q.natDegree := by
  by_cases hq : q = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ r p q : R[X]
hp : p ≠ 0
hpq : degree p < degree q
hq : q = 0
⊢ natDegree p < natDegree q

Next tactic:
exact (not_lt_bot <| hq ▸ hpq).elim
theorem natDegree_lt_natDegree {p q : R[X]} (hp : p ≠ 0) (hpq : p.degree < q.degree) :
    p.natDegree < q.natDegree := by
  by_cases hq : q = 0
  · exact (not_lt_bot <| hq ▸ hpq).elim
  

Proof state:
case neg
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p✝ q✝ r p q : R[X]
hp : p ≠ 0
hpq : degree p < degree q
hq : ¬q = 0
⊢ natDegree p < natDegree q

Next tactic:
rwa [degree_eq_natDegree hp, degree_eq_natDegree hq, Nat.cast_lt] at hpq
@[simp]
theorem degree_C (ha : a ≠ 0) : degree (C a) = (0 : WithBot ℕ) := by
  

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

Next tactic:
rw [degree, ← monomial_zero_left, support_monomial 0 ha, max_eq_sup_coe, sup_singleton,
    WithBot.coe_zero]
theorem degree_C_le : degree (C a) ≤ 0 := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
⊢ degree (C a) ≤ 0

Next tactic:
by_cases h : a = 0
theorem degree_C_le : degree (C a) ≤ 0 := by
  by_cases h : a = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : a = 0
⊢ degree (C a) ≤ 0

Next tactic:
rw [h, C_0]
theorem degree_C_le : degree (C a) ≤ 0 := by
  by_cases h : a = 0
  · rw [h, C_0]
    

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : a = 0
⊢ degree 0 ≤ 0

Next tactic:
exact bot_le
theorem degree_C_le : degree (C a) ≤ 0 := by
  by_cases h : a = 0
  · rw [h, C_0]
    exact bot_le
  · 

Proof state:
case neg
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
h : ¬a = 0
⊢ degree (C a) ≤ 0

Next tactic:
rw [degree_C h]
theorem degree_one_le : degree (1 : R[X]) ≤ (0 : WithBot ℕ) := by 

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
⊢ degree 1 ≤ 0

Next tactic:
rw [← C_1]
theorem degree_one_le : degree (1 : R[X]) ≤ (0 : WithBot ℕ) := by rw [← C_1]; 

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
⊢ degree (C 1) ≤ 0

Next tactic:
exact degree_C_le
@[simp]
theorem natDegree_C (a : R) : natDegree (C a) = 0 := by
  

Proof state:
R : Type u
S : Type v
a✝ b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
⊢ natDegree (C a) = 0

Next tactic:
by_cases ha : a = 0
@[simp]
theorem natDegree_C (a : R) : natDegree (C a) = 0 := by
  by_cases ha : a = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
a✝ b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
ha : a = 0
⊢ natDegree (C a) = 0

Next tactic:
have : C a = 0 := by rw [ha, C_0]
@[simp]
theorem natDegree_C (a : R) : natDegree (C a) = 0 := by
  by_cases ha : a = 0
  · have : C a = 0 := by 

Proof state:
R : Type u
S : Type v
a✝ b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
ha : a = 0
⊢ C a = 0

Next tactic:
rw [ha, C_0]
@[simp]
theorem natDegree_C (a : R) : natDegree (C a) = 0 := by
  by_cases ha : a = 0
  · have : C a = 0 := by rw [ha, C_0]
    

Proof state:
case pos
R : Type u
S : Type v
a✝ b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
ha : a = 0
this : C a = 0
⊢ natDegree (C a) = 0

Next tactic:
rw [natDegree, degree_eq_bot.2 this]
@[simp]
theorem natDegree_C (a : R) : natDegree (C a) = 0 := by
  by_cases ha : a = 0
  · have : C a = 0 := by rw [ha, C_0]
    rw [natDegree, degree_eq_bot.2 this]
    

Proof state:
case pos
R : Type u
S : Type v
a✝ b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
ha : a = 0
this : C a = 0
⊢ WithBot.unbot' 0 ⊥ = 0

Next tactic:
rfl
@[simp]
theorem natDegree_C (a : R) : natDegree (C a) = 0 := by
  by_cases ha : a = 0
  · have : C a = 0 := by rw [ha, C_0]
    rw [natDegree, degree_eq_bot.2 this]
    rfl
  · 

Proof state:
case neg
R : Type u
S : Type v
a✝ b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
ha : ¬a = 0
⊢ natDegree (C a) = 0

Next tactic:
rw [natDegree, degree_C ha]
@[simp]
theorem natDegree_C (a : R) : natDegree (C a) = 0 := by
  by_cases ha : a = 0
  · have : C a = 0 := by rw [ha, C_0]
    rw [natDegree, degree_eq_bot.2 this]
    rfl
  · rw [natDegree, degree_C ha]
    

Proof state:
case neg
R : Type u
S : Type v
a✝ b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
ha : ¬a = 0
⊢ WithBot.unbot' 0 0 = 0

Next tactic:
rfl
@[simp]
theorem natDegree_nat_cast (n : ℕ) : natDegree (n : R[X]) = 0 := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
⊢ natDegree ↑n = 0

Next tactic:
simp only [← C_eq_nat_cast, natDegree_C]
theorem degree_nat_cast_le (n : ℕ) : degree (n : R[X]) ≤ 0 := degree_le_of_natDegree_le (by 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
⊢ natDegree ↑n ≤ Zero.zero

Next tactic:
simp
@[simp]
theorem degree_monomial (n : ℕ) (ha : a ≠ 0) : degree (monomial n a) = n := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
ha : a ≠ 0
⊢ degree ((monomial n) a) = ↑n

Next tactic:
rw [degree, support_monomial n ha]
@[simp]
theorem degree_monomial (n : ℕ) (ha : a ≠ 0) : degree (monomial n a) = n := by
  rw [degree, support_monomial n ha]; 

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
ha : a ≠ 0
⊢ Finset.max {n} = ↑n

Next tactic:
rfl
@[simp]
theorem degree_C_mul_X_pow (n : ℕ) (ha : a ≠ 0) : degree (C a * X ^ n) = n := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
ha : a ≠ 0
⊢ degree (C a * X ^ n) = ↑n

Next tactic:
rw [C_mul_X_pow_eq_monomial, degree_monomial n ha]
theorem degree_C_mul_X (ha : a ≠ 0) : degree (C a * X) = 1 := by
  

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

Next tactic:
simpa only [pow_one] using degree_C_mul_X_pow 1 ha
theorem degree_monomial_le (n : ℕ) (a : R) : degree (monomial n a) ≤ n :=
  letI := Classical.decEq R
  if h : a = 0 then by 

Proof state:
R : Type u
S : Type v
a✝ b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
a : R
this : DecidableEq R := Classical.decEq R
h : a = 0
⊢ degree ((monomial n) a) ≤ ↑n

Next tactic:
rw [h, (monomial n).map_zero]
theorem degree_monomial_le (n : ℕ) (a : R) : degree (monomial n a) ≤ n :=
  letI := Classical.decEq R
  if h : a = 0 then by rw [h, (monomial n).map_zero]; 

Proof state:
R : Type u
S : Type v
a✝ b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
a : R
this : DecidableEq R := Classical.decEq R
h : a = 0
⊢ degree 0 ≤ ↑n

Next tactic:
exact bot_le
theorem degree_C_mul_X_pow_le (n : ℕ) (a : R) : degree (C a * X ^ n) ≤ n := by
  

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

Next tactic:
rw [C_mul_X_pow_eq_monomial]
theorem degree_C_mul_X_pow_le (n : ℕ) (a : R) : degree (C a * X ^ n) ≤ n := by
  rw [C_mul_X_pow_eq_monomial]
  

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

Next tactic:
apply degree_monomial_le
theorem degree_C_mul_X_le (a : R) : degree (C a * X) ≤ 1 := by
  

Proof state:
R : Type u
S : Type v
a✝ b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
⊢ degree (C a * X) ≤ 1

Next tactic:
simpa only [pow_one] using degree_C_mul_X_pow_le 1 a
@[simp]
theorem natDegree_C_mul_X (a : R) (ha : a ≠ 0) : natDegree (C a * X) = 1 := by
  

Proof state:
R : Type u
S : Type v
a✝ b c d : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
ha : a ≠ 0
⊢ natDegree (C a * X) = 1

Next tactic:
simpa only [pow_one] using natDegree_C_mul_X_pow 1 a ha
@[simp]
theorem natDegree_monomial [DecidableEq R] (i : ℕ) (r : R) :
    natDegree (monomial i r) = if r = 0 then 0 else i := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝¹ : Semiring R
p q r✝ : R[X]
inst✝ : DecidableEq R
i : ℕ
r : R
⊢ natDegree ((monomial i) r) = if r = 0 then 0 else i

Next tactic:
split_ifs with hr
@[simp]
theorem natDegree_monomial [DecidableEq R] (i : ℕ) (r : R) :
    natDegree (monomial i r) = if r = 0 then 0 else i := by
  split_ifs with hr
  · 

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝¹ : Semiring R
p q r✝ : R[X]
inst✝ : DecidableEq R
i : ℕ
r : R
hr : r = 0
⊢ natDegree ((monomial i) r) = 0

Next tactic:
simp [hr]
@[simp]
theorem natDegree_monomial [DecidableEq R] (i : ℕ) (r : R) :
    natDegree (monomial i r) = if r = 0 then 0 else i := by
  split_ifs with hr
  · simp [hr]
  · 

Proof state:
case neg
R : Type u
S : Type v
a b c d : R
n m : ℕ
inst✝¹ : Semiring R
p q r✝ : R[X]
inst✝ : DecidableEq R
i : ℕ
r : R
hr : ¬r = 0
⊢ natDegree ((monomial i) r) = i

Next tactic:
rw [← C_mul_X_pow_eq_monomial, natDegree_C_mul_X_pow i r hr]
theorem natDegree_monomial_le (a : R) {m : ℕ} : (monomial m a).natDegree ≤ m := by
  

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

Next tactic:
classical
  rw [Polynomial.natDegree_monomial]
  split_ifs
  exacts [Nat.zero_le _, rfl.le]
theorem natDegree_monomial_le (a : R) {m : ℕ} : (monomial m a).natDegree ≤ m := by
  classical
  

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

Next tactic:
rw [Polynomial.natDegree_monomial]
theorem natDegree_monomial_le (a : R) {m : ℕ} : (monomial m a).natDegree ≤ m := by
  classical
  rw [Polynomial.natDegree_monomial]
  

Proof state:
R : Type u
S : Type v
a✝ b c d : R
n m✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
m : ℕ
⊢ (if a = 0 then 0 else m) ≤ m

Next tactic:
split_ifs
theorem natDegree_monomial_le (a : R) {m : ℕ} : (monomial m a).natDegree ≤ m := by
  classical
  rw [Polynomial.natDegree_monomial]
  split_ifs
  

Proof state:
case pos
R : Type u
S : Type v
a✝ b c d : R
n m✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
m : ℕ
h✝ : a = 0
⊢ 0 ≤ m
case neg R : Type u S : Type v a✝ b c d : R n m✝ : ℕ inst✝ : Semiring R p q r : R[X] a : R m : ℕ h✝ : ¬a = 0 ⊢ m ≤ m

Next tactic:
exacts [Nat.zero_le _, rfl.le]
theorem coeff_eq_zero_of_natDegree_lt {p : R[X]} {n : ℕ} (h : p.natDegree < n) :
    p.coeff n = 0 := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
h : natDegree p < n
⊢ coeff p n = 0

Next tactic:
apply coeff_eq_zero_of_degree_lt
theorem coeff_eq_zero_of_natDegree_lt {p : R[X]} {n : ℕ} (h : p.natDegree < n) :
    p.coeff n = 0 := by
  apply coeff_eq_zero_of_degree_lt
  

Proof state:
case h
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
h : natDegree p < n
⊢ degree p < ↑n

Next tactic:
by_cases hp : p = 0
theorem coeff_eq_zero_of_natDegree_lt {p : R[X]} {n : ℕ} (h : p.natDegree < n) :
    p.coeff n = 0 := by
  apply coeff_eq_zero_of_degree_lt
  by_cases hp : p = 0
  · 

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
h : natDegree p < n
hp : p = 0
⊢ degree p < ↑n

Next tactic:
subst hp
theorem coeff_eq_zero_of_natDegree_lt {p : R[X]} {n : ℕ} (h : p.natDegree < n) :
    p.coeff n = 0 := by
  apply coeff_eq_zero_of_degree_lt
  by_cases hp : p = 0
  · subst hp
    

Proof state:
case pos
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
n : ℕ
h : natDegree 0 < n
⊢ degree 0 < ↑n

Next tactic:
exact WithBot.bot_lt_coe n
theorem coeff_eq_zero_of_natDegree_lt {p : R[X]} {n : ℕ} (h : p.natDegree < n) :
    p.coeff n = 0 := by
  apply coeff_eq_zero_of_degree_lt
  by_cases hp : p = 0
  · subst hp
    exact WithBot.bot_lt_coe n
  · 

Proof state:
case neg
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
h : natDegree p < n
hp : ¬p = 0
⊢ degree p < ↑n

Next tactic:
rwa [degree_eq_natDegree hp, Nat.cast_lt]
theorem ext_iff_natDegree_le {p q : R[X]} {n : ℕ} (hp : p.natDegree ≤ n) (hq : q.natDegree ≤ n) :
    p = q ↔ ∀ i ≤ n, p.coeff i = q.coeff i := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q✝ r p q : R[X]
n : ℕ
hp : natDegree p ≤ n
hq : natDegree q ≤ n
⊢ p = q ↔ ∀ i ≤ n, coeff p i = coeff q i

Next tactic:
refine' Iff.trans Polynomial.ext_iff _
theorem ext_iff_natDegree_le {p q : R[X]} {n : ℕ} (hp : p.natDegree ≤ n) (hq : q.natDegree ≤ n) :
    p = q ↔ ∀ i ≤ n, p.coeff i = q.coeff i := by
  refine' Iff.trans Polynomial.ext_iff _
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q✝ r p q : R[X]
n : ℕ
hp : natDegree p ≤ n
hq : natDegree q ≤ n
⊢ (∀ (n : ℕ), coeff p n = coeff q n) ↔ ∀ i ≤ n, coeff p i = coeff q i

Next tactic:
refine' forall_congr' fun i => ⟨fun h _ => h, fun h => _⟩
theorem ext_iff_natDegree_le {p q : R[X]} {n : ℕ} (hp : p.natDegree ≤ n) (hq : q.natDegree ≤ n) :
    p = q ↔ ∀ i ≤ n, p.coeff i = q.coeff i := by
  refine' Iff.trans Polynomial.ext_iff _
  refine' forall_congr' fun i => ⟨fun h _ => h, fun h => _⟩
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q✝ r p q : R[X]
n : ℕ
hp : natDegree p ≤ n
hq : natDegree q ≤ n
i : ℕ
h : i ≤ n → coeff p i = coeff q i
⊢ coeff p i = coeff q i

Next tactic:
refine' (le_or_lt i n).elim h fun k => _
theorem ext_iff_natDegree_le {p q : R[X]} {n : ℕ} (hp : p.natDegree ≤ n) (hq : q.natDegree ≤ n) :
    p = q ↔ ∀ i ≤ n, p.coeff i = q.coeff i := by
  refine' Iff.trans Polynomial.ext_iff _
  refine' forall_congr' fun i => ⟨fun h _ => h, fun h => _⟩
  refine' (le_or_lt i n).elim h fun k => _
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q✝ r p q : R[X]
n : ℕ
hp : natDegree p ≤ n
hq : natDegree q ≤ n
i : ℕ
h : i ≤ n → coeff p i = coeff q i
k : n < i
⊢ coeff p i = coeff q i

Next tactic:
exact
    (coeff_eq_zero_of_natDegree_lt (hp.trans_lt k)).trans
      (coeff_eq_zero_of_natDegree_lt (hq.trans_lt k)).symm
theorem ite_le_natDegree_coeff (p : R[X]) (n : ℕ) (I : Decidable (n < 1 + natDegree p)) :
    @ite _ (n < 1 + natDegree p) I (coeff p n) 0 = coeff p n := by
  

Proof state:
R : Type u
S : Type v
a b c d : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n : ℕ
I : Decidable (n < 1 + natDegree p)
⊢ (if n < 1 + natDegree p then coeff p n else 0) = coeff p n

Next tactic:
split_ifs with h