l3lab/ntp-mathlib huggingface dataset:
/-- `monomial s a` is the monomial `a * X^s` -/
def monomial (n : ℕ) : R →ₗ[R] R[X] where
  toFun t := ⟨Finsupp.single n t⟩
  -- Porting note: Was `simp`.
  map_add' x y := by simp; rw [ofFinsupp_add]
  -- Porting note: Was `simp [← ofFinsupp_smul]`.
  map_smul' r x := by 

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
r x : R
⊢ AddHom.toFun
      { toFun := fun t => { toFinsupp := fun₀ | n => t },
        map_add' :=
          (_ :
            ∀ (x y : R),
              (fun t => { toFinsupp := fun₀ | n => t }) (x + y) =
                (fun t => { toFinsupp := fun₀ | n => t }) x + (fun t => { toFinsupp := fun₀ | n => t }) y) }
      (r • x) =
    (RingHom.id R) r •
      AddHom.toFun
        { toFun := fun t => { toFinsupp := fun₀ | n => t },
          map_add' :=
            (_ :
              ∀ (x y : R),
                (fun t => { toFinsupp := fun₀ | n => t }) (x + y) =
                  (fun t => { toFinsupp := fun₀ | n => t }) x + (fun t => { toFinsupp := fun₀ | n => t }) y) }
        x

Next tactic:
simp
/-- `monomial s a` is the monomial `a * X^s` -/
def monomial (n : ℕ) : R →ₗ[R] R[X] where
  toFun t := ⟨Finsupp.single n t⟩
  -- Porting note: Was `simp`.
  map_add' x y := by simp; rw [ofFinsupp_add]
  -- Porting note: Was `simp [← ofFinsupp_smul]`.
  map_smul' r x := by simp; 

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
r x : R
⊢ { toFinsupp := fun₀ | n => r * x } = r • { toFinsupp := fun₀ | n => x }

Next tactic:
rw [← ofFinsupp_smul, smul_single']
@[simp]
theorem toFinsupp_monomial (n : ℕ) (r : R) : (monomial n r).toFinsupp = Finsupp.single n r := by
  

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

Next tactic:
simp [monomial]
@[simp]
theorem ofFinsupp_single (n : ℕ) (r : R) : (⟨Finsupp.single n r⟩ : R[X]) = monomial n r := by
  

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

Next tactic:
simp [monomial]
theorem monomial_mul_monomial (n m : ℕ) (r s : R) :
    monomial n r * monomial m s = monomial (n + m) (r * s) :=
  toFinsupp_injective <| by
    

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

Next tactic:
simp only [toFinsupp_monomial, toFinsupp_mul, AddMonoidAlgebra.single_mul_single]
@[simp]
theorem monomial_pow (n : ℕ) (r : R) (k : ℕ) : monomial n r ^ k = monomial (n * k) (r ^ k) := by
  

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

Next tactic:
induction' k with k ih
@[simp]
theorem monomial_pow (n : ℕ) (r : R) (k : ℕ) : monomial n r ^ k = monomial (n * k) (r ^ k) := by
  induction' k with k ih
  · 

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

Next tactic:
simp [pow_zero, monomial_zero_one]
@[simp]
theorem monomial_pow (n : ℕ) (r : R) (k : ℕ) : monomial n r ^ k = monomial (n * k) (r ^ k) := by
  induction' k with k ih
  · simp [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 : ℕ
r : R
k : ℕ
ih : (monomial n) r ^ k = (monomial (n * k)) (r ^ k)
⊢ (monomial n) r ^ Nat.succ k = (monomial (n * Nat.succ k)) (r ^ Nat.succ k)

Next tactic:
simp [pow_succ, ih, monomial_mul_monomial, Nat.succ_eq_add_one, mul_add, add_comm]
theorem smul_monomial {S} [SMulZeroClass S R] (a : S) (n : ℕ) (b : R) :
    a • monomial n b = monomial n (a • b) :=
  toFinsupp_injective <| by 

Proof state:
R : Type u
a✝ b✝ : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q : R[X]
S : Type u_1
inst✝ : SMulZeroClass S R
a : S
n : ℕ
b : R
⊢ (a • (monomial n) b).toFinsupp = ((monomial n) (a • b)).toFinsupp

Next tactic:
simp
theorem smul_monomial {S} [SMulZeroClass S R] (a : S) (n : ℕ) (b : R) :
    a • monomial n b = monomial n (a • b) :=
  toFinsupp_injective <| by simp; 

Proof state:
R : Type u
a✝ b✝ : R
m n✝ : ℕ
inst✝¹ : Semiring R
p q : R[X]
S : Type u_1
inst✝ : SMulZeroClass S R
a : S
n : ℕ
b : R
⊢ (a • fun₀ | n => b) = fun₀ | n => a • b

Next tactic:
rw [smul_single]
theorem support_add : (p + q).support ⊆ p.support ∪ q.support := by
  

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

Next tactic:
rcases p with ⟨⟩
theorem support_add : (p + q).support ⊆ p.support ∪ q.support := by
  rcases p with ⟨⟩; 

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

Next tactic:
rcases q with ⟨⟩
theorem support_add : (p + q).support ⊆ p.support ∪ q.support := by
  rcases p with ⟨⟩; rcases q with ⟨⟩
  

Proof state:
case ofFinsupp.ofFinsupp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
toFinsupp✝¹ toFinsupp✝ : R[ℕ]
⊢ support ({ toFinsupp := toFinsupp✝¹ } + { toFinsupp := toFinsupp✝ }) ⊆
    support { toFinsupp := toFinsupp✝¹ } ∪ support { toFinsupp := toFinsupp✝ }

Next tactic:
simp only [← ofFinsupp_add, support]
theorem support_add : (p + q).support ⊆ p.support ∪ q.support := by
  rcases p with ⟨⟩; rcases q with ⟨⟩
  simp only [← ofFinsupp_add, support]
  

Proof state:
case ofFinsupp.ofFinsupp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
toFinsupp✝¹ toFinsupp✝ : R[ℕ]
⊢ (toFinsupp✝¹ + toFinsupp✝).support ⊆ toFinsupp✝¹.support ∪ toFinsupp✝.support

Next tactic:
exact support_add
/-- `C a` is the constant polynomial `a`.
`C` is provided as a ring homomorphism.
-/
def C : R →+* R[X] :=
  { monomial 0 with
    map_one' := by 

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
src✝ : R →ₗ[R] R[X] := monomial 0
⊢ AddHom.toFun src✝.toAddHom 1 = 1

Next tactic:
simp [monomial_zero_one]
/-- `C a` is the constant polynomial `a`.
`C` is provided as a ring homomorphism.
-/
def C : R →+* R[X] :=
  { monomial 0 with
    map_one' := by simp [monomial_zero_one]
    map_mul' := by 

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
src✝ : R →ₗ[R] R[X] := monomial 0
⊢ ∀ (x y : R),
    OneHom.toFun { toFun := src✝.toFun, map_one' := (_ : 1 = 1) } (x * y) =
      OneHom.toFun { toFun := src✝.toFun, map_one' := (_ : 1 = 1) } x *
        OneHom.toFun { toFun := src✝.toFun, map_one' := (_ : 1 = 1) } y

Next tactic:
simp [monomial_mul_monomial]
/-- `C a` is the constant polynomial `a`.
`C` is provided as a ring homomorphism.
-/
def C : R →+* R[X] :=
  { monomial 0 with
    map_one' := by simp [monomial_zero_one]
    map_mul' := by simp [monomial_mul_monomial]
    map_zero' := by 

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
src✝ : R →ₗ[R] R[X] := monomial 0
⊢ OneHom.toFun
      (↑{ toOneHom := { toFun := src✝.toFun, map_one' := (_ : 1 = 1) },
          map_mul' := (_ : ∀ (a a_1 : R), (monomial 0) (a * a_1) = (monomial 0) a * (monomial 0) a_1) })
      0 =
    0

Next tactic:
simp
theorem C_0 : C (0 : R) = 0 := by 

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

Next tactic:
simp
set_option linter.deprecated false in
-- @[simp] -- Porting note: simp can prove this
theorem C_bit1 : C (bit1 a) = bit1 (C a) := by 

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

Next tactic:
simp [bit1, C_bit0]
@[simp]
theorem C_mul_monomial : C a * monomial n b = monomial n (a * b) := by
  

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

Next tactic:
simp only [← monomial_zero_left, monomial_mul_monomial, zero_add]
@[simp]
theorem monomial_mul_C : monomial n a * C b = monomial n (a * b) := by
  

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

Next tactic:
simp only [← monomial_zero_left, monomial_mul_monomial, add_zero]
theorem monomial_one_right_eq_X_pow (n : ℕ) : monomial n (1 : R) = X ^ n := by
  

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

Next tactic:
induction' n with n ih
theorem monomial_one_right_eq_X_pow (n : ℕ) : monomial n (1 : R) = X ^ n := by
  induction' n with n ih
  · 

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

Next tactic:
simp [monomial_zero_one]
theorem monomial_one_right_eq_X_pow (n : ℕ) : monomial n (1 : R) = X ^ n := by
  induction' n with n ih
  · simp [monomial_zero_one]
  · 

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

Next tactic:
rw [pow_succ, ← ih, ← monomial_one_one_eq_X, monomial_mul_monomial, add_comm, one_mul]
/-- `X` commutes with everything, even when the coefficients are noncommutative. -/
theorem X_mul : X * p = p * X := by
  

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

Next tactic:
rcases p with ⟨⟩
/-- `X` commutes with everything, even when the coefficients are noncommutative. -/
theorem X_mul : X * p = p * X := by
  rcases p with ⟨⟩
  -- Porting note: `ofFinsupp.injEq` is required.
  

Proof state:
case ofFinsupp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
q : R[X]
toFinsupp✝ : R[ℕ]
⊢ X * { toFinsupp := toFinsupp✝ } = { toFinsupp := toFinsupp✝ } * X

Next tactic:
simp only [X, ← ofFinsupp_single, ← ofFinsupp_mul, LinearMap.coe_mk, ofFinsupp.injEq]
/-- `X` commutes with everything, even when the coefficients are noncommutative. -/
theorem X_mul : X * p = p * X := by
  rcases p with ⟨⟩
  -- Porting note: `ofFinsupp.injEq` is required.
  simp only [X, ← ofFinsupp_single, ← ofFinsupp_mul, LinearMap.coe_mk, ofFinsupp.injEq]
  -- Porting note: Was `ext`.
  

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

Next tactic:
refine Finsupp.ext fun _ => ?_
/-- `X` commutes with everything, even when the coefficients are noncommutative. -/
theorem X_mul : X * p = p * X := by
  rcases p with ⟨⟩
  -- Porting note: `ofFinsupp.injEq` is required.
  simp only [X, ← ofFinsupp_single, ← ofFinsupp_mul, LinearMap.coe_mk, ofFinsupp.injEq]
  -- Porting note: Was `ext`.
  refine Finsupp.ext fun _ => ?_
  

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

Next tactic:
simp [AddMonoidAlgebra.mul_apply, AddMonoidAlgebra.sum_single_index, add_comm]
theorem X_pow_mul {n : ℕ} : X ^ n * p = p * X ^ n := by
  

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

Next tactic:
induction' n with n ih
theorem X_pow_mul {n : ℕ} : X ^ n * p = p * X ^ n := by
  induction' n with n ih
  · 

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

Next tactic:
simp
theorem X_pow_mul {n : ℕ} : X ^ n * p = p * X ^ n := by
  induction' n with n ih
  · simp
  · 

Proof state:
case succ
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
ih : X ^ n * p = p * X ^ n
⊢ X ^ Nat.succ n * p = p * X ^ Nat.succ n

Next tactic:
conv_lhs => rw [pow_succ']
theorem X_pow_mul {n : ℕ} : X ^ n * p = p * X ^ n := by
  induction' n with n ih
  · simp
  · conv_lhs => 

Proof state:
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
ih : X ^ n * p = p * X ^ n
| X ^ Nat.succ n * p

Next tactic:
rw [pow_succ']
theorem X_pow_mul {n : ℕ} : X ^ n * p = p * X ^ n := by
  induction' n with n ih
  · simp
  · conv_lhs => rw [pow_succ']
    

Proof state:
case succ
R : Type u
a b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
n : ℕ
ih : X ^ n * p = p * X ^ n
⊢ X ^ n * X * p = p * X ^ Nat.succ n

Next tactic:
rw [mul_assoc, X_mul, ← mul_assoc, ih, mul_assoc, ← pow_succ']
theorem X_pow_mul_assoc {n : ℕ} : p * X ^ n * q = p * q * X ^ n := by
  

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

Next tactic:
rw [mul_assoc, X_pow_mul, ← mul_assoc]
@[simp]
theorem monomial_mul_X (n : ℕ) (r : R) : monomial n r * X = monomial (n + 1) r := by
  

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

Next tactic:
erw [monomial_mul_monomial, mul_one]
@[simp]
theorem monomial_mul_X_pow (n : ℕ) (r : R) (k : ℕ) :
    monomial n r * X ^ k = monomial (n + k) r := by
  

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

Next tactic:
induction' k with k ih
@[simp]
theorem monomial_mul_X_pow (n : ℕ) (r : R) (k : ℕ) :
    monomial n r * X ^ k = monomial (n + k) r := by
  induction' k with k ih
  · 

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

Next tactic:
simp
@[simp]
theorem monomial_mul_X_pow (n : ℕ) (r : R) (k : ℕ) :
    monomial n r * X ^ k = monomial (n + k) r := by
  induction' k with k ih
  · simp
  · 

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

Next tactic:
simp [ih, pow_succ', ← mul_assoc, add_assoc]
@[simp]
theorem X_mul_monomial (n : ℕ) (r : R) : X * monomial n r = monomial (n + 1) r := by
  

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

Next tactic:
rw [X_mul, monomial_mul_X]
@[simp]
theorem X_pow_mul_monomial (k n : ℕ) (r : R) : X ^ k * monomial n r = monomial (n + k) r := by
  

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

Next tactic:
rw [X_pow_mul, monomial_mul_X_pow]
@[simp]
theorem coeff_ofFinsupp (p) : coeff (⟨p⟩ : R[X]) = p := by 

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

Next tactic:
rw [coeff]
theorem coeff_injective : Injective (coeff : R[X] → ℕ → R) := by
  

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

Next tactic:
rintro ⟨p⟩ ⟨q⟩
theorem coeff_injective : Injective (coeff : R[X] → ℕ → R) := by
  rintro ⟨p⟩ ⟨q⟩
  -- Porting note: `ofFinsupp.injEq` is required.
  

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

Next tactic:
simp only [coeff, FunLike.coe_fn_eq, imp_self, ofFinsupp.injEq]
theorem toFinsupp_apply (f : R[X]) (i) : f.toFinsupp i = f.coeff i := by 

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q f : R[X]
i : ℕ
⊢ f.toFinsupp i = coeff f i

Next tactic:
cases f
theorem toFinsupp_apply (f : R[X]) (i) : f.toFinsupp i = f.coeff i := by cases f; 

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

Next tactic:
rfl
theorem coeff_monomial : coeff (monomial n a) m = if n = m then a else 0 := by
  -- Porting note: Was `simp [← ofFinsupp_single, coeff, LinearMap.coe_mk]`.
  

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

Next tactic:
rw [← ofFinsupp_single]
theorem coeff_monomial : coeff (monomial n a) m = if n = m then a else 0 := by
  -- Porting note: Was `simp [← ofFinsupp_single, coeff, LinearMap.coe_mk]`.
  rw [← ofFinsupp_single]
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ coeff { toFinsupp := fun₀ | n => a } m = if n = m then a else 0

Next tactic:
simp only [coeff, LinearMap.coe_mk]
theorem coeff_monomial : coeff (monomial n a) m = if n = m then a else 0 := by
  -- Porting note: Was `simp [← ofFinsupp_single, coeff, LinearMap.coe_mk]`.
  rw [← ofFinsupp_single]
  simp only [coeff, LinearMap.coe_mk]
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ (fun₀ | n => a) m = if n = m then a else 0

Next tactic:
rw [Finsupp.single_apply]
theorem coeff_one {n : ℕ} : coeff (1 : R[X]) n = if n = 0 then 1 else 0 := by
  

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

Next tactic:
simp_rw [eq_comm (a := n) (b := 0)]
theorem coeff_one {n : ℕ} : coeff (1 : R[X]) n = if n = 0 then 1 else 0 := by
  simp_rw [eq_comm (a := n) (b := 0)]
  

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

Next tactic:
exact coeff_monomial
@[simp]
theorem coeff_one_zero : coeff (1 : R[X]) 0 = 1 := by
  

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

Next tactic:
simp [coeff_one]
@[simp]
theorem coeff_monomial_succ : coeff (monomial (n + 1) a) 0 = 0 := by 

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

Next tactic:
simp [coeff_monomial]
theorem coeff_X_of_ne_one {n : ℕ} (hn : n ≠ 1) : coeff (X : R[X]) n = 0 := by
  

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

Next tactic:
rw [coeff_X, if_neg hn.symm]
@[simp]
theorem mem_support_iff : n ∈ p.support ↔ p.coeff n ≠ 0 := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ n ∈ support p ↔ coeff p n ≠ 0

Next tactic:
rcases p with ⟨⟩
@[simp]
theorem mem_support_iff : n ∈ p.support ↔ p.coeff n ≠ 0 := by
  rcases p with ⟨⟩
  

Proof state:
case ofFinsupp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
q : R[X]
toFinsupp✝ : R[ℕ]
⊢ n ∈ support { toFinsupp := toFinsupp✝ } ↔ coeff { toFinsupp := toFinsupp✝ } n ≠ 0

Next tactic:
simp
theorem not_mem_support_iff : n ∉ p.support ↔ p.coeff n = 0 := by 

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ n ∉ support p ↔ coeff p n = 0

Next tactic:
simp
theorem coeff_C : coeff (C a) n = ite (n = 0) a 0 := by
  

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

Next tactic:
convert coeff_monomial (a := a) (m := n) (n := 0) using 2
theorem coeff_C : coeff (C a) n = ite (n = 0) a 0 := by
  convert coeff_monomial (a := a) (m := n) (n := 0) using 2
  

Proof state:
case h.e'_3.h₁.a
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ n = 0 ↔ 0 = n

Next tactic:
simp [eq_comm]
theorem coeff_C_ne_zero (h : n ≠ 0) : (C a).coeff n = 0 := by 

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

Next tactic:
rw [coeff_C, if_neg h]
@[simp]
lemma coeff_C_succ {r : R} {n : ℕ} : coeff (C r) (n + 1) = 0 := by 

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

Next tactic:
simp [coeff_C]
@[simp]
theorem coeff_nat_cast_ite : (Nat.cast m : R[X]).coeff n = ite (n = 0) m 0 := by
  

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

Next tactic:
simp only [← C_eq_nat_cast, coeff_C, Nat.cast_ite, Nat.cast_zero]
@[simp]
theorem coeff_ofNat_succ (a n : ℕ) [h : a.AtLeastTwo] :
    coeff (no_index (OfNat.ofNat a : R[X])) (n + 1) = 0 := by
  

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
a n : ℕ
h : Nat.AtLeastTwo a
⊢ coeff (OfNat.ofNat a) (n + 1) = 0

Next tactic:
rw [← Nat.cast_eq_ofNat]
@[simp]
theorem coeff_ofNat_succ (a n : ℕ) [h : a.AtLeastTwo] :
    coeff (no_index (OfNat.ofNat a : R[X])) (n + 1) = 0 := by
  rw [← Nat.cast_eq_ofNat]
  

Proof state:
R : Type u
a✝ b : R
m n✝ : ℕ
inst✝ : Semiring R
p q : R[X]
a n : ℕ
h : Nat.AtLeastTwo a
⊢ coeff (↑a) (n + 1) = 0

Next tactic:
simp
theorem C_mul_X_pow_eq_monomial : ∀ {n : ℕ}, C a * X ^ n = monomial n a
  | 0 => mul_one _
  | n + 1 => by
    

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

Next tactic:
rw [pow_succ', ← mul_assoc, C_mul_X_pow_eq_monomial, X, monomial_mul_monomial, mul_one]
@[simp high]
theorem toFinsupp_C_mul_X_pow (a : R) (n : ℕ) :
    Polynomial.toFinsupp (C a * X ^ n) = Finsupp.single n a := by
  

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

Next tactic:
rw [C_mul_X_pow_eq_monomial, toFinsupp_monomial]
theorem C_mul_X_eq_monomial : C a * X = monomial 1 a := by 

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

Next tactic:
rw [← C_mul_X_pow_eq_monomial, pow_one]
@[simp high]
theorem toFinsupp_C_mul_X (a : R) : Polynomial.toFinsupp (C a * X) = Finsupp.single 1 a := by
  

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

Next tactic:
rw [C_mul_X_eq_monomial, toFinsupp_monomial]
theorem subsingleton_iff_subsingleton : Subsingleton R[X] ↔ Subsingleton R :=
  ⟨@Injective.subsingleton _ _ _ C_injective, by
    

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ Subsingleton R → Subsingleton R[X]

Next tactic:
intro
theorem subsingleton_iff_subsingleton : Subsingleton R[X] ↔ Subsingleton R :=
  ⟨@Injective.subsingleton _ _ _ C_injective, by
    intro
    

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

Next tactic:
infer_instance
theorem forall_eq_iff_forall_eq : (∀ f g : R[X], f = g) ↔ ∀ a b : R, a = b := by
  

Proof state:
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ (∀ (f g : R[X]), f = g) ↔ ∀ (a b : R), a = b

Next tactic:
simpa only [← subsingleton_iff] using subsingleton_iff_subsingleton
theorem ext_iff {p q : R[X]} : p = q ↔ ∀ n, coeff p n = coeff q n := by
  

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

Next tactic:
rcases p with ⟨⟩
theorem ext_iff {p q : R[X]} : p = q ↔ ∀ n, coeff p n = coeff q n := by
  rcases p with ⟨⟩
  

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

Next tactic:
rcases q with ⟨⟩
theorem ext_iff {p q : R[X]} : p = q ↔ ∀ n, coeff p n = coeff q n := by
  rcases p with ⟨⟩
  rcases q with ⟨⟩
  -- Porting note: Was `simp [coeff, FunLike.ext_iff]`
  

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

Next tactic:
simp only [ofFinsupp.injEq, coeff._eq_1]
theorem ext_iff {p q : R[X]} : p = q ↔ ∀ n, coeff p n = coeff q n := by
  rcases p with ⟨⟩
  rcases q with ⟨⟩
  -- Porting note: Was `simp [coeff, FunLike.ext_iff]`
  simp only [ofFinsupp.injEq, coeff._eq_1]
  

Proof state:
case ofFinsupp.ofFinsupp
R : Type u
a b : R
m n : ℕ
inst✝ : Semiring R
p q : R[X]
toFinsupp✝¹ toFinsupp✝ : R[ℕ]
⊢ toFinsupp✝¹ = toFinsupp✝ ↔ ∀ (n : ℕ), toFinsupp✝¹ n = toFinsupp✝ n

Next tactic:
exact FunLike.ext_iff (F := ℕ →₀ R)
/-- 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
  

Proof state:
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:
apply top_unique