l3lab/ntp-mathlib huggingface dataset:
/-- Monomials generate the additive monoid of polynomials. -/
theorem addSubmonoid_closure_setOf_eq_monomial :
    AddSubmonoid.closure { p : R[X] | ∃ n a, p = monomial n a } = ⊤ := by
  apply top_unique
  

Proof state:
case h
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ ⊤ ≤ AddSubmonoid.closure {p | ∃ n a, p = (monomial n) a}

Next tactic:
rw [← AddSubmonoid.map_equiv_top (toFinsuppIso R).symm.toAddEquiv, ←
    Finsupp.add_closure_setOf_eq_single, AddMonoidHom.map_mclosure]
/-- Monomials generate the additive monoid of polynomials. -/
theorem addSubmonoid_closure_setOf_eq_monomial :
    AddSubmonoid.closure { p : R[X] | ∃ n a, p = monomial n a } = ⊤ := by
  apply top_unique
  rw [← AddSubmonoid.map_equiv_top (toFinsuppIso R).symm.toAddEquiv, ←
    Finsupp.add_closure_setOf_eq_single, AddMonoidHom.map_mclosure]
  

Proof state:
case h
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ AddSubmonoid.closure
      (⇑(AddEquiv.toAddMonoidHom (RingEquiv.toAddEquiv (RingEquiv.symm (toFinsuppIso R)))) ''
        {f | ∃ a b, f = fun₀ | a => b}) ≤
    AddSubmonoid.closure {p | ∃ n a, p = (monomial n) a}

Next tactic:
refine' AddSubmonoid.closure_mono (Set.image_subset_iff.2 _)
/-- Monomials generate the additive monoid of polynomials. -/
theorem addSubmonoid_closure_setOf_eq_monomial :
    AddSubmonoid.closure { p : R[X] | ∃ n a, p = monomial n a } = ⊤ := by
  apply top_unique
  rw [← AddSubmonoid.map_equiv_top (toFinsuppIso R).symm.toAddEquiv, ←
    Finsupp.add_closure_setOf_eq_single, AddMonoidHom.map_mclosure]
  refine' AddSubmonoid.closure_mono (Set.image_subset_iff.2 _)
  

Proof state:
case h
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ {f | ∃ a b, f = fun₀ | a => b} ⊆
    ⇑(AddEquiv.toAddMonoidHom (RingEquiv.toAddEquiv (RingEquiv.symm (toFinsuppIso R)))) ⁻¹'
      {p | ∃ n a, p = (monomial n) a}

Next tactic:
rintro _ ⟨n, a, rfl⟩
/-- Monomials generate the additive monoid of polynomials. -/
theorem addSubmonoid_closure_setOf_eq_monomial :
    AddSubmonoid.closure { p : R[X] | ∃ n a, p = monomial n a } = ⊤ := by
  apply top_unique
  rw [← AddSubmonoid.map_equiv_top (toFinsuppIso R).symm.toAddEquiv, ←
    Finsupp.add_closure_setOf_eq_single, AddMonoidHom.map_mclosure]
  refine' AddSubmonoid.closure_mono (Set.image_subset_iff.2 _)
  rintro _ ⟨n, a, rfl⟩
  

Proof state:
case h.intro.intro
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
a : R
⊢ (fun₀ | n => a) ∈
    ⇑(AddEquiv.toAddMonoidHom (RingEquiv.toAddEquiv (RingEquiv.symm (toFinsuppIso R)))) ⁻¹'
      {p | ∃ n a, p = (monomial n) a}

Next tactic:
exact ⟨n, a, Polynomial.ofFinsupp_single _ _⟩
theorem addHom_ext {M : Type*} [AddMonoid M] {f g : R[X] →+ M}
    (h : ∀ n a, f (monomial n a) = g (monomial n a)) : f = g :=
  AddMonoidHom.eq_of_eqOn_denseM addSubmonoid_closure_setOf_eq_monomial <| by
    

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q : R[X]
M : Type u_1
inst✝ : AddMonoid M
f g : R[X] →+ M
h : ∀ (n : ℕ) (a : R), f ((monomial n) a) = g ((monomial n) a)
⊢ Set.EqOn ⇑f ⇑g {p | ∃ n a, p = (monomial n) a}

Next tactic:
rintro p ⟨n, a, rfl⟩
theorem addHom_ext {M : Type*} [AddMonoid M] {f g : R[X] →+ M}
    (h : ∀ n a, f (monomial n a) = g (monomial n a)) : f = g :=
  AddMonoidHom.eq_of_eqOn_denseM addSubmonoid_closure_setOf_eq_monomial <| by
    rintro p ⟨n, a, rfl⟩
    

Proof state:
case intro.intro
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q : R[X]
M : Type u_1
inst✝ : AddMonoid M
f g : R[X] →+ M
h : ∀ (n : ℕ) (a : R), f ((monomial n) a) = g ((monomial n) a)
n : ℕ
a : R
⊢ f ((monomial n) a) = g ((monomial n) a)

Next tactic:
exact h n a
theorem eq_zero_of_eq_zero (h : (0 : R) = (1 : R)) (p : R[X]) : p = 0 := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p✝ q : R[X]
h : 0 = 1
p : R[X]
⊢ p = 0

Next tactic:
rw [← one_smul R p, ← h, zero_smul]
theorem support_monomial (n) {a : R} (H : a ≠ 0) : (monomial n a).support = singleton n := by
  

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
a : R
H : a ≠ 0
⊢ support ((monomial n) a) = {n}

Next tactic:
rw [← ofFinsupp_single, support]
theorem support_monomial (n) {a : R} (H : a ≠ 0) : (monomial n a).support = singleton n := by
  rw [← ofFinsupp_single, support]; 

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
a : R
H : a ≠ 0
⊢ (match { toFinsupp := fun₀ | n => a } with
    | { toFinsupp := p } => p.support) =
    {n}

Next tactic:
exact Finsupp.support_single_ne_zero _ H
theorem support_monomial' (n) (a : R) : (monomial n a).support ⊆ singleton n := by
  

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
a : R
⊢ support ((monomial n) a) ⊆ {n}

Next tactic:
rw [← ofFinsupp_single, support]
theorem support_monomial' (n) (a : R) : (monomial n a).support ⊆ singleton n := by
  rw [← ofFinsupp_single, support]
  

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
a : R
⊢ (match { toFinsupp := fun₀ | n => a } with
    | { toFinsupp := p } => p.support) ⊆
    {n}

Next tactic:
exact Finsupp.support_single_subset
theorem support_C_mul_X {c : R} (h : c ≠ 0) : Polynomial.support (C c * X) = singleton 1 := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
c : R
h : c ≠ 0
⊢ support (C c * X) = {1}

Next tactic:
rw [C_mul_X_eq_monomial, support_monomial 1 h]
theorem support_C_mul_X' (c : R) : Polynomial.support (C c * X) ⊆ singleton 1 := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
c : R
⊢ support (C c * X) ⊆ {1}

Next tactic:
simpa only [C_mul_X_eq_monomial] using support_monomial' 1 c
theorem support_C_mul_X_pow (n : ℕ) {c : R} (h : c ≠ 0) :
    Polynomial.support (C c * X ^ n) = singleton n := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
c : R
h : c ≠ 0
⊢ support (C c * X ^ n) = {n}

Next tactic:
rw [C_mul_X_pow_eq_monomial, support_monomial n h]
theorem support_C_mul_X_pow' (n : ℕ) (c : R) : Polynomial.support (C c * X ^ n) ⊆ singleton n := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
c : R
⊢ support (C c * X ^ n) ⊆ {n}

Next tactic:
simpa only [C_mul_X_pow_eq_monomial] using support_monomial' n c
theorem X_pow_eq_monomial (n) : X ^ n = monomial n (1 : R) := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
⊢ X ^ n = (monomial n) 1

Next tactic:
induction' n with n hn
theorem X_pow_eq_monomial (n) : X ^ n = monomial n (1 : R) := by
  induction' n with n hn
  · 

Proof state:
case zero
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ X ^ Nat.zero = (monomial Nat.zero) 1

Next tactic:
rw [pow_zero, monomial_zero_one]
theorem X_pow_eq_monomial (n) : X ^ n = monomial n (1 : R) := by
  induction' n with n hn
  · rw [pow_zero, monomial_zero_one]
  · 

Proof state:
case succ
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
hn : X ^ n = (monomial n) 1
⊢ X ^ Nat.succ n = (monomial (Nat.succ n)) 1

Next tactic:
rw [pow_succ', hn, X, monomial_mul_monomial, one_mul]
@[simp high]
theorem toFinsupp_X_pow (n : ℕ) : (X ^ n).toFinsupp = Finsupp.single n (1 : R) := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
⊢ (X ^ n).toFinsupp = fun₀ | n => 1

Next tactic:
rw [X_pow_eq_monomial, toFinsupp_monomial]
theorem smul_X_eq_monomial {n} : a • X ^ n = monomial n (a : R) := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
⊢ a • X ^ n = (monomial n) a

Next tactic:
rw [X_pow_eq_monomial, smul_monomial, smul_eq_mul, mul_one]
theorem support_X_pow (H : ¬(1 : R) = 0) (n : ℕ) : (X ^ n : R[X]).support = singleton n := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
H : ¬1 = 0
n : ℕ
⊢ support (X ^ n) = {n}

Next tactic:
convert support_monomial n H
theorem support_X_pow (H : ¬(1 : R) = 0) (n : ℕ) : (X ^ n : R[X]).support = singleton n := by
  convert support_monomial n H
  

Proof state:
case h.e'_2.h.e'_3
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
H : ¬1 = 0
n : ℕ
⊢ X ^ n = (monomial n) 1

Next tactic:
exact X_pow_eq_monomial n
theorem support_X_empty (H : (1 : R) = 0) : (X : R[X]).support = ∅ := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
H : 1 = 0
⊢ support X = ∅

Next tactic:
rw [X, H, monomial_zero_right, support_zero]
theorem support_X (H : ¬(1 : R) = 0) : (X : R[X]).support = singleton 1 := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
H : ¬1 = 0
⊢ support X = {1}

Next tactic:
rw [← pow_one X, support_X_pow H 1]
theorem monomial_left_inj {a : R} (ha : a ≠ 0) {i j : ℕ} :
    monomial i a = monomial j a ↔ i = j := by
  -- Porting note: Was `simp [← ofFinsupp_single, Finsupp.single_left_inj ha]`
  

Proof state:
R : Type u
a✝ b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
a : R
ha : a ≠ 0
i j : ℕ
⊢ (monomial i) a = (monomial j) a ↔ i = j

Next tactic:
rw [← ofFinsupp_single, ← ofFinsupp_single, ofFinsupp.injEq, Finsupp.single_left_inj ha]
theorem binomial_eq_binomial {k l m n : ℕ} {u v : R} (hu : u ≠ 0) (hv : v ≠ 0) :
    C u * X ^ k + C v * X ^ l = C u * X ^ m + C v * X ^ n ↔
      k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u + v = 0 ∧ k = l ∧ m = n := by
  

Proof state:
R : Type u
a b : R
m✝ n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
k l m n : ℕ
u v : R
hu : u ≠ 0
hv : v ≠ 0
⊢ C u * X ^ k + C v * X ^ l = C u * X ^ m + C v * X ^ n ↔
    k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u + v = 0 ∧ k = l ∧ m = n

Next tactic:
simp_rw [C_mul_X_pow_eq_monomial, ← toFinsupp_inj, toFinsupp_add, toFinsupp_monomial]
theorem binomial_eq_binomial {k l m n : ℕ} {u v : R} (hu : u ≠ 0) (hv : v ≠ 0) :
    C u * X ^ k + C v * X ^ l = C u * X ^ m + C v * X ^ n ↔
      k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u + v = 0 ∧ k = l ∧ m = n := by
  simp_rw [C_mul_X_pow_eq_monomial, ← toFinsupp_inj, toFinsupp_add, toFinsupp_monomial]
  

Proof state:
R : Type u
a b : R
m✝ n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
k l m n : ℕ
u v : R
hu : u ≠ 0
hv : v ≠ 0
⊢ (((fun₀ | k => u) + fun₀ | l => v) = (fun₀ | m => u) + fun₀ | n => v) ↔
    k = m ∧ l = n ∨ u = v ∧ k = n ∧ l = m ∨ u + v = 0 ∧ k = l ∧ m = n

Next tactic:
exact Finsupp.single_add_single_eq_single_add_single hu hv
/-- Expressing the product of two polynomials as a double sum. -/
theorem mul_eq_sum_sum :
    p * q = ∑ i in p.support, q.sum fun j a => (monomial (i + j)) (p.coeff i * a) := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ p * q = ∑ i in support p, sum q fun j a => (monomial (i + j)) (coeff p i * a)

Next tactic:
apply toFinsupp_injective
/-- Expressing the product of two polynomials as a double sum. -/
theorem mul_eq_sum_sum :
    p * q = ∑ i in p.support, q.sum fun j a => (monomial (i + j)) (p.coeff i * a) := by
  apply toFinsupp_injective
  

Proof state:
case a
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ (p * q).toFinsupp = (∑ i in support p, sum q fun j a => (monomial (i + j)) (coeff p i * a)).toFinsupp

Next tactic:
rcases p with ⟨⟩
/-- Expressing the product of two polynomials as a double sum. -/
theorem mul_eq_sum_sum :
    p * q = ∑ i in p.support, q.sum fun j a => (monomial (i + j)) (p.coeff i * a) := by
  apply toFinsupp_injective
  rcases p with ⟨⟩; 

Proof state:
case a.ofFinsupp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
q : R[X]
toFinsupp✝ : R[ℕ]
⊢ ({ toFinsupp := toFinsupp✝ } * q).toFinsupp =
    (∑ i in support { toFinsupp := toFinsupp✝ },
        sum q fun j a => (monomial (i + j)) (coeff { toFinsupp := toFinsupp✝ } i * a)).toFinsupp

Next tactic:
rcases q with ⟨⟩
/-- Expressing the product of two polynomials as a double sum. -/
theorem mul_eq_sum_sum :
    p * q = ∑ i in p.support, q.sum fun j a => (monomial (i + j)) (p.coeff i * a) := by
  apply toFinsupp_injective
  rcases p with ⟨⟩; rcases q with ⟨⟩
  

Proof state:
case a.ofFinsupp.ofFinsupp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
toFinsupp✝¹ toFinsupp✝ : R[ℕ]
⊢ ({ toFinsupp := toFinsupp✝¹ } * { toFinsupp := toFinsupp✝ }).toFinsupp =
    (∑ i in support { toFinsupp := toFinsupp✝¹ },
        sum { toFinsupp := toFinsupp✝ } fun j a =>
          (monomial (i + j)) (coeff { toFinsupp := toFinsupp✝¹ } i * a)).toFinsupp

Next tactic:
simp [support, sum, coeff, toFinsupp_sum]
/-- Expressing the product of two polynomials as a double sum. -/
theorem mul_eq_sum_sum :
    p * q = ∑ i in p.support, q.sum fun j a => (monomial (i + j)) (p.coeff i * a) := by
  apply toFinsupp_injective
  rcases p with ⟨⟩; rcases q with ⟨⟩
  simp [support, sum, coeff, toFinsupp_sum]
  

Proof state:
case a.ofFinsupp.ofFinsupp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
toFinsupp✝¹ toFinsupp✝ : R[ℕ]
⊢ toFinsupp✝¹ * toFinsupp✝ =
    ∑ x in toFinsupp✝¹.support, ∑ x_1 in toFinsupp✝.support, fun₀ | x + x_1 => toFinsupp✝¹ x * toFinsupp✝ x_1

Next tactic:
rfl
@[simp]
theorem sum_zero_index {S : Type*} [AddCommMonoid S] (f : ℕ → R → S) : (0 : R[X]).sum f = 0 := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p q : R[X]
S : Type u_1
inst✝ : AddCommMonoid S
f : ℕ → R → S
⊢ sum 0 f = 0

Next tactic:
simp [sum]
theorem sum_add_index {S : Type*} [AddCommMonoid S] (p q : R[X]) (f : ℕ → R → S)
    (hf : ∀ i, f i 0 = 0) (h_add : ∀ a b₁ b₂, f a (b₁ + b₂) = f a b₁ + f a b₂) :
    (p + q).sum f = p.sum f + q.sum f := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p✝ q✝ : R[X]
S : Type u_1
inst✝ : AddCommMonoid S
p q : R[X]
f : ℕ → R → S
hf : ∀ (i : ℕ), f i 0 = 0
h_add : ∀ (a : ℕ) (b₁ b₂ : R), f a (b₁ + b₂) = f a b₁ + f a b₂
⊢ sum (p + q) f = sum p f + sum q f

Next tactic:
rw [show p + q = ⟨p.toFinsupp + q.toFinsupp⟩ from add_def p q]
theorem sum_add_index {S : Type*} [AddCommMonoid S] (p q : R[X]) (f : ℕ → R → S)
    (hf : ∀ i, f i 0 = 0) (h_add : ∀ a b₁ b₂, f a (b₁ + b₂) = f a b₁ + f a b₂) :
    (p + q).sum f = p.sum f + q.sum f := by
  rw [show p + q = ⟨p.toFinsupp + q.toFinsupp⟩ from add_def p q]
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p✝ q✝ : R[X]
S : Type u_1
inst✝ : AddCommMonoid S
p q : R[X]
f : ℕ → R → S
hf : ∀ (i : ℕ), f i 0 = 0
h_add : ∀ (a : ℕ) (b₁ b₂ : R), f a (b₁ + b₂) = f a b₁ + f a b₂
⊢ sum { toFinsupp := p.toFinsupp + q.toFinsupp } f = sum p f + sum q f

Next tactic:
exact Finsupp.sum_add_index (fun i _ ↦ hf i) (fun a _ b₁ b₂ ↦ h_add a b₁ b₂)
theorem sum_add' {S : Type*} [AddCommMonoid S] (p : R[X]) (f g : ℕ → R → S) :
    p.sum (f + g) = p.sum f + p.sum g := by 

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝¹ : Semiring R
p✝ q : R[X]
S : Type u_1
inst✝ : AddCommMonoid S
p : R[X]
f g : ℕ → R → S
⊢ sum p (f + g) = sum p f + sum p g

Next tactic:
simp [sum_def, Finset.sum_add_distrib]
theorem sum_C_mul_X_pow_eq (p : R[X]) : (p.sum fun n a => C a * X ^ n) = p := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
⊢ (sum p fun n a => C a * X ^ n) = p

Next tactic:
simp_rw [C_mul_X_pow_eq_monomial, sum_monomial_eq]
@[simp]
theorem toFinsupp_erase (p : R[X]) (n : ℕ) : toFinsupp (p.erase n) = p.toFinsupp.erase n := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
⊢ (erase n p).toFinsupp = Finsupp.erase n p.toFinsupp

Next tactic:
rcases p with ⟨⟩
@[simp]
theorem toFinsupp_erase (p : R[X]) (n : ℕ) : toFinsupp (p.erase n) = p.toFinsupp.erase n := by
  rcases p with ⟨⟩
  

Proof state:
case ofFinsupp
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
toFinsupp✝ : R[ℕ]
⊢ (erase n { toFinsupp := toFinsupp✝ }).toFinsupp = Finsupp.erase n { toFinsupp := toFinsupp✝ }.toFinsupp

Next tactic:
simp only [erase_def]
@[simp]
theorem ofFinsupp_erase (p : R[ℕ]) (n : ℕ) :
    (⟨p.erase n⟩ : R[X]) = (⟨p⟩ : R[X]).erase n := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q : R[X]
p : R[ℕ]
n : ℕ
⊢ { toFinsupp := Finsupp.erase n p } = erase n { toFinsupp := p }

Next tactic:
rcases p with ⟨⟩
@[simp]
theorem ofFinsupp_erase (p : R[ℕ]) (n : ℕ) :
    (⟨p.erase n⟩ : R[X]) = (⟨p⟩ : R[X]).erase n := by
  rcases p with ⟨⟩
  

Proof state:
case mk
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
support✝ : Finset ℕ
toFun✝ : ℕ → R
mem_support_toFun✝ : ∀ (a : ℕ), a ∈ support✝ ↔ toFun✝ a ≠ 0
⊢ { toFinsupp := Finsupp.erase n { support := support✝, toFun := toFun✝, mem_support_toFun := mem_support_toFun✝ } } =
    erase n { toFinsupp := { support := support✝, toFun := toFun✝, mem_support_toFun := mem_support_toFun✝ } }

Next tactic:
simp only [erase_def]
@[simp]
theorem support_erase (p : R[X]) (n : ℕ) : support (p.erase n) = (support p).erase n := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
⊢ support (erase n p) = Finset.erase (support p) n

Next tactic:
rcases p with ⟨⟩
@[simp]
theorem support_erase (p : R[X]) (n : ℕ) : support (p.erase n) = (support p).erase n := by
  rcases p with ⟨⟩
  

Proof state:
case ofFinsupp
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
toFinsupp✝ : R[ℕ]
⊢ support (erase n { toFinsupp := toFinsupp✝ }) = Finset.erase (support { toFinsupp := toFinsupp✝ }) n

Next tactic:
simp only [support, erase_def, Finsupp.support_erase]
theorem monomial_add_erase (p : R[X]) (n : ℕ) : monomial n (coeff p n) + p.erase n = p :=
  toFinsupp_injective <| by
    

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
⊢ ((monomial n) (coeff p n) + erase n p).toFinsupp = p.toFinsupp

Next tactic:
rcases p with ⟨⟩
theorem monomial_add_erase (p : R[X]) (n : ℕ) : monomial n (coeff p n) + p.erase n = p :=
  toFinsupp_injective <| by
    rcases p with ⟨⟩
    

Proof state:
case ofFinsupp
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
toFinsupp✝ : R[ℕ]
⊢ ((monomial n) (coeff { toFinsupp := toFinsupp✝ } n) + erase n { toFinsupp := toFinsupp✝ }).toFinsupp =
    { toFinsupp := toFinsupp✝ }.toFinsupp

Next tactic:
rw [toFinsupp_add, toFinsupp_monomial, toFinsupp_erase, coeff]
theorem monomial_add_erase (p : R[X]) (n : ℕ) : monomial n (coeff p n) + p.erase n = p :=
  toFinsupp_injective <| by
    rcases p with ⟨⟩
    rw [toFinsupp_add, toFinsupp_monomial, toFinsupp_erase, coeff]
    

Proof state:
case ofFinsupp
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
toFinsupp✝ : R[ℕ]
⊢ (fun₀
        | n =>
            (match (motive := R[X] → ℕ → R) { toFinsupp := toFinsupp✝ } with
              | { toFinsupp := p } => ⇑p)
              n) +
      Finsupp.erase n { toFinsupp := toFinsupp✝ }.toFinsupp =
    { toFinsupp := toFinsupp✝ }.toFinsupp

Next tactic:
exact Finsupp.single_add_erase _ _
theorem coeff_erase (p : R[X]) (n i : ℕ) :
    (p.erase n).coeff i = if i = n then 0 else p.coeff i := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n i : ℕ
⊢ coeff (erase n p) i = if i = n then 0 else coeff p i

Next tactic:
rcases p with ⟨⟩
theorem coeff_erase (p : R[X]) (n i : ℕ) :
    (p.erase n).coeff i = if i = n then 0 else p.coeff i := by
  rcases p with ⟨⟩
  

Proof state:
case ofFinsupp
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n i : ℕ
toFinsupp✝ : R[ℕ]
⊢ coeff (erase n { toFinsupp := toFinsupp✝ }) i = if i = n then 0 else coeff { toFinsupp := toFinsupp✝ } i

Next tactic:
simp only [erase_def, coeff]
theorem coeff_erase (p : R[X]) (n i : ℕ) :
    (p.erase n).coeff i = if i = n then 0 else p.coeff i := by
  rcases p with ⟨⟩
  simp only [erase_def, coeff]
  -- Porting note: Was `convert rfl`.
  

Proof state:
case ofFinsupp
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n i : ℕ
toFinsupp✝ : R[ℕ]
⊢ (Finsupp.erase n toFinsupp✝) i = if i = n then 0 else toFinsupp✝ i

Next tactic:
exact ite_congr rfl (fun _ => rfl) (fun _ => rfl)
@[simp]
theorem erase_zero (n : ℕ) : (0 : R[X]).erase n = 0 :=
  toFinsupp_injective <| by 

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
⊢ (erase n 0).toFinsupp = 0.toFinsupp

Next tactic:
simp
@[simp]
theorem erase_monomial {n : ℕ} {a : R} : erase n (monomial n a) = 0 :=
  toFinsupp_injective <| by 

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
a : R
⊢ (erase n ((monomial n) a)).toFinsupp = 0.toFinsupp

Next tactic:
simp
@[simp]
theorem erase_same (p : R[X]) (n : ℕ) : coeff (p.erase n) n = 0 := by 

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
⊢ coeff (erase n p) n = 0

Next tactic:
simp [coeff_erase]
@[simp]
theorem erase_ne (p : R[X]) (n i : ℕ) (h : i ≠ n) : coeff (p.erase n) i = coeff p i := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n i : ℕ
h : i ≠ n
⊢ coeff (erase n p) i = coeff p i

Next tactic:
simp [coeff_erase, h]
theorem coeff_update (p : R[X]) (n : ℕ) (a : R) :
    (p.update n a).coeff = Function.update p.coeff n a := by
  

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
a : R
⊢ coeff (update p n a) = Function.update (coeff p) n a

Next tactic:
ext
theorem coeff_update (p : R[X]) (n : ℕ) (a : R) :
    (p.update n a).coeff = Function.update p.coeff n a := by
  ext
  

Proof state:
case h
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
a : R
x✝ : ℕ
⊢ coeff (update p n a) x✝ = Function.update (coeff p) n a x✝

Next tactic:
cases p
theorem coeff_update (p : R[X]) (n : ℕ) (a : R) :
    (p.update n a).coeff = Function.update p.coeff n a := by
  ext
  cases p
  

Proof state:
case h.ofFinsupp
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
a : R
x✝ : ℕ
toFinsupp✝ : R[ℕ]
⊢ coeff (update { toFinsupp := toFinsupp✝ } n a) x✝ = Function.update (coeff { toFinsupp := toFinsupp✝ }) n a x✝

Next tactic:
simp only [coeff, update, Function.update_apply, coe_update]
theorem coeff_update_apply (p : R[X]) (n : ℕ) (a : R) (i : ℕ) :
    (p.update n a).coeff i = if i = n then a else p.coeff i := by
  

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
a : R
i : ℕ
⊢ coeff (update p n a) i = if i = n then a else coeff p i

Next tactic:
rw [coeff_update, Function.update_apply]
@[simp]
theorem coeff_update_same (p : R[X]) (n : ℕ) (a : R) : (p.update n a).coeff n = a := by
  

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
a : R
⊢ coeff (update p n a) n = a

Next tactic:
rw [p.coeff_update_apply, if_pos rfl]
theorem coeff_update_ne (p : R[X]) {n : ℕ} (a : R) {i : ℕ} (h : i ≠ n) :
    (p.update n a).coeff i = p.coeff i := by 

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
a : R
i : ℕ
h : i ≠ n
⊢ coeff (update p n a) i = coeff p i

Next tactic:
rw [p.coeff_update_apply, if_neg h]
@[simp]
theorem update_zero_eq_erase (p : R[X]) (n : ℕ) : p.update n 0 = p.erase n := by
  

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n : ℕ
⊢ update p n 0 = erase n p

Next tactic:
ext
@[simp]
theorem update_zero_eq_erase (p : R[X]) (n : ℕ) : p.update n 0 = p.erase n := by
  ext
  

Proof state:
case a
R : Type u
a b : R
m n✝¹ : ℕ
inst✝ : Semiring R
p✝ q p : R[X]
n n✝ : ℕ
⊢ coeff (update p n 0) n✝ = coeff (erase n p) n✝

Next tactic:
rw [coeff_update_apply, coeff_erase]
theorem support_update (p : R[X]) (n : ℕ) (a : R) [Decidable (a = 0)] :
    support (p.update n a) = if a = 0 then p.support.erase n else insert n p.support := by
  

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p✝ q p : R[X]
n : ℕ
a : R
inst✝ : Decidable (a = 0)
⊢ support (update p n a) = if a = 0 then Finset.erase (support p) n else insert n (support p)

Next tactic:
classical
    cases p
    simp only [support, update, Finsupp.support_update]
    congr
theorem support_update (p : R[X]) (n : ℕ) (a : R) [Decidable (a = 0)] :
    support (p.update n a) = if a = 0 then p.support.erase n else insert n p.support := by
  classical
    

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝¹ : Semiring R
p✝ q p : R[X]
n : ℕ
a : R
inst✝ : Decidable (a = 0)
⊢ support (update p n a) = if a = 0 then Finset.erase (support p) n else insert n (support p)

Next tactic:
cases p