l3lab/ntp-mathlib huggingface dataset:
/-- `Polynomial.sum` as a linear map. -/
@[simps]
def lsum {R A M : Type*} [Semiring R] [Semiring A] [AddCommMonoid M] [Module R A] [Module R M]
    (f : ℕ → A →ₗ[R] M) : A[X] →ₗ[R] M
    where
  toFun p := p.sum (f · ·)
  map_add' p q := sum_add_index p q _ (fun n => (f n).map_zero) fun n _ _ => (f n).map_add _ _
  map_smul' c p := by
    -- Porting note: `dsimp only []` is required for beta reduction.
    

Proof state:
R✝ : Type u
S : Type v
a b : R✝
n m : ℕ
inst✝⁵ : Semiring R✝
p✝ q r : R✝[X]
R : Type u_1
A : Type u_2
M : Type u_3
inst✝⁴ : Semiring R
inst✝³ : Semiring A
inst✝² : AddCommMonoid M
inst✝¹ : Module R A
inst✝ : Module R M
f : ℕ → A →ₗ[R] M
c : R
p : A[X]
⊢ AddHom.toFun
      { toFun := fun p => sum p fun x x_1 => (f x) x_1,
        map_add' :=
          (_ :
            ∀ (p q : A[X]),
              (sum (p + q) fun x x_1 => (f x) x_1) = (sum p fun x x_1 => (f x) x_1) + sum q fun x x_1 => (f x) x_1) }
      (c • p) =
    (RingHom.id R) c •
      AddHom.toFun
        { toFun := fun p => sum p fun x x_1 => (f x) x_1,
          map_add' :=
            (_ :
              ∀ (p q : A[X]),
                (sum (p + q) fun x x_1 => (f x) x_1) = (sum p fun x x_1 => (f x) x_1) + sum q fun x x_1 => (f x) x_1) }
        p

Next tactic:
dsimp only []
/-- `Polynomial.sum` as a linear map. -/
@[simps]
def lsum {R A M : Type*} [Semiring R] [Semiring A] [AddCommMonoid M] [Module R A] [Module R M]
    (f : ℕ → A →ₗ[R] M) : A[X] →ₗ[R] M
    where
  toFun p := p.sum (f · ·)
  map_add' p q := sum_add_index p q _ (fun n => (f n).map_zero) fun n _ _ => (f n).map_add _ _
  map_smul' c p := by
    -- Porting note: `dsimp only []` is required for beta reduction.
    dsimp only []
    

Proof state:
R✝ : Type u
S : Type v
a b : R✝
n m : ℕ
inst✝⁵ : Semiring R✝
p✝ q r : R✝[X]
R : Type u_1
A : Type u_2
M : Type u_3
inst✝⁴ : Semiring R
inst✝³ : Semiring A
inst✝² : AddCommMonoid M
inst✝¹ : Module R A
inst✝ : Module R M
f : ℕ → A →ₗ[R] M
c : R
p : A[X]
⊢ (sum (c • p) fun x x_1 => (f x) x_1) = (RingHom.id R) c • sum p fun x x_1 => (f x) x_1

Next tactic:
rw [sum_eq_of_subset (f · ·) (fun n => (f n).map_zero) (support_smul c p)]
/-- `Polynomial.sum` as a linear map. -/
@[simps]
def lsum {R A M : Type*} [Semiring R] [Semiring A] [AddCommMonoid M] [Module R A] [Module R M]
    (f : ℕ → A →ₗ[R] M) : A[X] →ₗ[R] M
    where
  toFun p := p.sum (f · ·)
  map_add' p q := sum_add_index p q _ (fun n => (f n).map_zero) fun n _ _ => (f n).map_add _ _
  map_smul' c p := by
    -- Porting note: `dsimp only []` is required for beta reduction.
    dsimp only []
    rw [sum_eq_of_subset (f · ·) (fun n => (f n).map_zero) (support_smul c p)]
    

Proof state:
R✝ : Type u
S : Type v
a b : R✝
n m : ℕ
inst✝⁵ : Semiring R✝
p✝ q r : R✝[X]
R : Type u_1
A : Type u_2
M : Type u_3
inst✝⁴ : Semiring R
inst✝³ : Semiring A
inst✝² : AddCommMonoid M
inst✝¹ : Module R A
inst✝ : Module R M
f : ℕ → A →ₗ[R] M
c : R
p : A[X]
⊢ ∑ n in support p, (f n) (coeff (c • p) n) = (RingHom.id R) c • sum p fun x x_1 => (f x) x_1

Next tactic:
simp only [sum_def, Finset.smul_sum, coeff_smul, LinearMap.map_smul, RingHom.id_apply]
theorem coeff_sum [Semiring S] (n : ℕ) (f : ℕ → R → S[X]) :
    coeff (p.sum f) n = p.sum fun a b => coeff (f a b) n := by
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝¹ : Semiring R
p q r : R[X]
inst✝ : Semiring S
n : ℕ
f : ℕ → R → S[X]
⊢ coeff (sum p f) n = sum p fun a b => coeff (f a b) n

Next tactic:
rcases p with ⟨⟩
theorem coeff_sum [Semiring S] (n : ℕ) (f : ℕ → R → S[X]) :
    coeff (p.sum f) n = p.sum fun a b => coeff (f a b) n := by
  rcases p with ⟨⟩
  -- Porting note: Was `simp [Polynomial.sum, support, coeff]`.
  

Proof state:
case ofFinsupp
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝¹ : Semiring R
q r : R[X]
inst✝ : Semiring S
n : ℕ
f : ℕ → R → S[X]
toFinsupp✝ : R[ℕ]
⊢ coeff (sum { toFinsupp := toFinsupp✝ } f) n = sum { toFinsupp := toFinsupp✝ } fun a b => coeff (f a b) n

Next tactic:
simp [Polynomial.sum, support_ofFinsupp, coeff_ofFinsupp]
/-- Decomposes the coefficient of the product `p * q` as a sum
over `antidiagonal`. A version which sums over `range (n + 1)` can be obtained
by using `Finset.Nat.sum_antidiagonal_eq_sum_range_succ`. -/
theorem coeff_mul (p q : R[X]) (n : ℕ) :
    coeff (p * q) n = ∑ x in antidiagonal n, coeff p x.1 * coeff q x.2 := by
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q✝ r p q : R[X]
n : ℕ
⊢ coeff (p * q) n = ∑ x in antidiagonal n, coeff p x.1 * coeff q x.2

Next tactic:
rcases p with ⟨p⟩
/-- Decomposes the coefficient of the product `p * q` as a sum
over `antidiagonal`. A version which sums over `range (n + 1)` can be obtained
by using `Finset.Nat.sum_antidiagonal_eq_sum_range_succ`. -/
theorem coeff_mul (p q : R[X]) (n : ℕ) :
    coeff (p * q) n = ∑ x in antidiagonal n, coeff p x.1 * coeff q x.2 := by
  rcases p with ⟨p⟩; 

Proof state:
case ofFinsupp
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q✝ r q : R[X]
n : ℕ
p : R[ℕ]
⊢ coeff ({ toFinsupp := p } * q) n = ∑ x in antidiagonal n, coeff { toFinsupp := p } x.1 * coeff q x.2

Next tactic:
rcases q with ⟨q⟩
/-- Decomposes the coefficient of the product `p * q` as a sum
over `antidiagonal`. A version which sums over `range (n + 1)` can be obtained
by using `Finset.Nat.sum_antidiagonal_eq_sum_range_succ`. -/
theorem coeff_mul (p q : R[X]) (n : ℕ) :
    coeff (p * q) n = ∑ x in antidiagonal n, coeff p x.1 * coeff q x.2 := by
  rcases p with ⟨p⟩; rcases q with ⟨q⟩
  

Proof state:
case ofFinsupp.ofFinsupp
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q✝ r : R[X]
n : ℕ
p q : R[ℕ]
⊢ coeff ({ toFinsupp := p } * { toFinsupp := q }) n =
    ∑ x in antidiagonal n, coeff { toFinsupp := p } x.1 * coeff { toFinsupp := q } x.2

Next tactic:
simp_rw [← ofFinsupp_mul, coeff]
/-- Decomposes the coefficient of the product `p * q` as a sum
over `antidiagonal`. A version which sums over `range (n + 1)` can be obtained
by using `Finset.Nat.sum_antidiagonal_eq_sum_range_succ`. -/
theorem coeff_mul (p q : R[X]) (n : ℕ) :
    coeff (p * q) n = ∑ x in antidiagonal n, coeff p x.1 * coeff q x.2 := by
  rcases p with ⟨p⟩; rcases q with ⟨q⟩
  simp_rw [← ofFinsupp_mul, coeff]
  

Proof state:
case ofFinsupp.ofFinsupp
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q✝ r : R[X]
n : ℕ
p q : R[ℕ]
⊢ (p * q) n = ∑ x in antidiagonal n, p x.1 * q x.2

Next tactic:
exact AddMonoidAlgebra.mul_apply_antidiagonal p q n _ Finset.mem_antidiagonal
@[simp]
theorem mul_coeff_zero (p q : R[X]) : coeff (p * q) 0 = coeff p 0 * coeff q 0 := by 

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

Next tactic:
simp [coeff_mul]
theorem coeff_mul_X_zero (p : R[X]) : coeff (p * X) 0 = 0 := by 

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

Next tactic:
simp
theorem coeff_X_mul_zero (p : R[X]) : coeff (X * p) 0 = 0 := by 

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

Next tactic:
simp
theorem coeff_C_mul_X_pow (x : R) (k n : ℕ) :
    coeff (C x * X ^ k : R[X]) n = if n = k then x else 0 := by
  

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

Next tactic:
rw [C_mul_X_pow_eq_monomial, coeff_monomial]
theorem coeff_C_mul_X_pow (x : R) (k n : ℕ) :
    coeff (C x * X ^ k : R[X]) n = if n = k then x else 0 := by
  rw [C_mul_X_pow_eq_monomial, coeff_monomial]
  

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

Next tactic:
congr 1
theorem coeff_C_mul_X_pow (x : R) (k n : ℕ) :
    coeff (C x * X ^ k : R[X]) n = if n = k then x else 0 := by
  rw [C_mul_X_pow_eq_monomial, coeff_monomial]
  congr 1
  

Proof state:
case e_c
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p q r : R[X]
x : R
k n : ℕ
⊢ (k = n) = (n = k)

Next tactic:
simp [eq_comm]
theorem coeff_C_mul_X (x : R) (n : ℕ) : coeff (C x * X : R[X]) n = if n = 1 then x else 0 := by
  

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

Next tactic:
rw [← pow_one X, coeff_C_mul_X_pow]
@[simp]
theorem coeff_C_mul (p : R[X]) : coeff (C a * p) n = a * coeff p n := by
  

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

Next tactic:
rcases p with ⟨p⟩
@[simp]
theorem coeff_C_mul (p : R[X]) : coeff (C a * p) n = a * coeff p n := by
  rcases p with ⟨p⟩
  

Proof state:
case ofFinsupp
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p✝ q r : R[X]
p : R[ℕ]
⊢ coeff (C a * { toFinsupp := p }) n = a * coeff { toFinsupp := p } n

Next tactic:
simp_rw [← monomial_zero_left, ← ofFinsupp_single, ← ofFinsupp_mul, coeff]
@[simp]
theorem coeff_C_mul (p : R[X]) : coeff (C a * p) n = a * coeff p n := by
  rcases p with ⟨p⟩
  simp_rw [← monomial_zero_left, ← ofFinsupp_single, ← ofFinsupp_mul, coeff]
  

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

Next tactic:
exact AddMonoidAlgebra.single_zero_mul_apply p a n
theorem C_mul' (a : R) (f : R[X]) : C a * f = a • f := by
  

Proof state:
R : Type u
S : Type v
a✝ b : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
f : R[X]
⊢ C a * f = a • f

Next tactic:
ext
theorem C_mul' (a : R) (f : R[X]) : C a * f = a • f := by
  ext
  

Proof state:
case a
R : Type u
S : Type v
a✝ b : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
a : R
f : R[X]
n✝ : ℕ
⊢ coeff (C a * f) n✝ = coeff (a • f) n✝

Next tactic:
rw [coeff_C_mul, coeff_smul, smul_eq_mul]
@[simp]
theorem coeff_mul_C (p : R[X]) (n : ℕ) (a : R) : coeff (p * C a) n = coeff p n * a := by
  

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

Next tactic:
rcases p with ⟨p⟩
@[simp]
theorem coeff_mul_C (p : R[X]) (n : ℕ) (a : R) : coeff (p * C a) n = coeff p n * a := by
  rcases p with ⟨p⟩
  

Proof state:
case ofFinsupp
R : Type u
S : Type v
a✝ b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r : R[X]
n : ℕ
a : R
p : R[ℕ]
⊢ coeff ({ toFinsupp := p } * C a) n = coeff { toFinsupp := p } n * a

Next tactic:
simp_rw [← monomial_zero_left, ← ofFinsupp_single, ← ofFinsupp_mul, coeff]
@[simp]
theorem coeff_mul_C (p : R[X]) (n : ℕ) (a : R) : coeff (p * C a) n = coeff p n * a := by
  rcases p with ⟨p⟩
  simp_rw [← monomial_zero_left, ← ofFinsupp_single, ← ofFinsupp_mul, coeff]
  

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

Next tactic:
exact AddMonoidAlgebra.mul_single_zero_apply p a n
@[simp]
theorem coeff_X_pow (k n : ℕ) : coeff (X ^ k : R[X]) n = if n = k then 1 else 0 := by
  

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

Next tactic:
simp only [one_mul, RingHom.map_one, ← coeff_C_mul_X_pow]
theorem coeff_X_pow_self (n : ℕ) : coeff (X ^ n : R[X]) n = 1 := by 

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

Next tactic:
simp
theorem support_binomial {k m : ℕ} (hkm : k ≠ m) {x y : R} (hx : x ≠ 0) (hy : y ≠ 0) :
    support (C x * X ^ k + C y * X ^ m) = {k, m} := by
  

Proof state:
R : Type u
S : Type v
a b : R
n m✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
k m : ℕ
hkm : k ≠ m
x y : R
hx : x ≠ 0
hy : y ≠ 0
⊢ support (C x * X ^ k + C y * X ^ m) = {k, m}

Next tactic:
apply subset_antisymm (support_binomial' k m x y)
theorem support_binomial {k m : ℕ} (hkm : k ≠ m) {x y : R} (hx : x ≠ 0) (hy : y ≠ 0) :
    support (C x * X ^ k + C y * X ^ m) = {k, m} := by
  apply subset_antisymm (support_binomial' k m x y)
  

Proof state:
R : Type u
S : Type v
a b : R
n m✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
k m : ℕ
hkm : k ≠ m
x y : R
hx : x ≠ 0
hy : y ≠ 0
⊢ {k, m} ⊆ support (C x * X ^ k + C y * X ^ m)

Next tactic:
simp_rw [insert_subset_iff, singleton_subset_iff, mem_support_iff, coeff_add, coeff_C_mul,
    coeff_X_pow_self, mul_one, coeff_X_pow, if_neg hkm, if_neg hkm.symm, mul_zero, zero_add,
    add_zero, Ne.def, hx, hy, not_false_eq_true, and_true]
theorem support_trinomial {k m n : ℕ} (hkm : k < m) (hmn : m < n) {x y z : R} (hx : x ≠ 0)
    (hy : y ≠ 0) (hz : z ≠ 0) :
    support (C x * X ^ k + C y * X ^ m + C z * X ^ n) = {k, m, n} := by
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
k m n : ℕ
hkm : k < m
hmn : m < n
x y z : R
hx : x ≠ 0
hy : y ≠ 0
hz : z ≠ 0
⊢ support (C x * X ^ k + C y * X ^ m + C z * X ^ n) = {k, m, n}

Next tactic:
apply subset_antisymm (support_trinomial' k m n x y z)
theorem support_trinomial {k m n : ℕ} (hkm : k < m) (hmn : m < n) {x y z : R} (hx : x ≠ 0)
    (hy : y ≠ 0) (hz : z ≠ 0) :
    support (C x * X ^ k + C y * X ^ m + C z * X ^ n) = {k, m, n} := by
  apply subset_antisymm (support_trinomial' k m n x y z)
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
k m n : ℕ
hkm : k < m
hmn : m < n
x y z : R
hx : x ≠ 0
hy : y ≠ 0
hz : z ≠ 0
⊢ {k, m, n} ⊆ support (C x * X ^ k + C y * X ^ m + C z * X ^ n)

Next tactic:
simp_rw [insert_subset_iff, singleton_subset_iff, mem_support_iff, coeff_add, coeff_C_mul,
    coeff_X_pow_self, mul_one, coeff_X_pow, if_neg hkm.ne, if_neg hkm.ne', if_neg hmn.ne,
    if_neg hmn.ne', if_neg (hkm.trans hmn).ne, if_neg (hkm.trans hmn).ne', mul_zero, add_zero,
    zero_add, Ne.def, hx, hy, hz, not_false_eq_true, and_true]
theorem card_support_binomial {k m : ℕ} (h : k ≠ m) {x y : R} (hx : x ≠ 0) (hy : y ≠ 0) :
    card (support (C x * X ^ k + C y * X ^ m)) = 2 := by
  

Proof state:
R : Type u
S : Type v
a b : R
n m✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
k m : ℕ
h : k ≠ m
x y : R
hx : x ≠ 0
hy : y ≠ 0
⊢ card (support (C x * X ^ k + C y * X ^ m)) = 2

Next tactic:
rw [support_binomial h hx hy, card_insert_of_not_mem (mt mem_singleton.mp h), card_singleton]
theorem card_support_trinomial {k m n : ℕ} (hkm : k < m) (hmn : m < n) {x y z : R} (hx : x ≠ 0)
    (hy : y ≠ 0) (hz : z ≠ 0) : card (support (C x * X ^ k + C y * X ^ m + C z * X ^ n)) = 3 := by
  

Proof state:
R : Type u
S : Type v
a b : R
n✝ m✝ : ℕ
inst✝ : Semiring R
p q r : R[X]
k m n : ℕ
hkm : k < m
hmn : m < n
x y z : R
hx : x ≠ 0
hy : y ≠ 0
hz : z ≠ 0
⊢ card (support (C x * X ^ k + C y * X ^ m + C z * X ^ n)) = 3

Next tactic:
rw [support_trinomial hkm hmn hx hy hz,
    card_insert_of_not_mem
      (mt mem_insert.mp (not_or_of_not hkm.ne (mt mem_singleton.mp (hkm.trans hmn).ne))),
    card_insert_of_not_mem (mt mem_singleton.mp hmn.ne), card_singleton]
@[simp]
theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) :
    coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by
  

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

Next tactic:
rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one]
@[simp]
theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) :
    coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by
  rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one]
  · 

Proof state:
case h₀
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n d : ℕ
⊢ ∀ b ∈ antidiagonal (d + n), b ≠ (d, n) → coeff p b.1 * coeff (X ^ n) b.2 = 0

Next tactic:
rintro ⟨i, j⟩ h1 h2
@[simp]
theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) :
    coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by
  rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one]
  · rintro ⟨i, j⟩ h1 h2
    

Proof state:
case h₀.mk
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n d i j : ℕ
h1 : (i, j) ∈ antidiagonal (d + n)
h2 : (i, j) ≠ (d, n)
⊢ coeff p (i, j).1 * coeff (X ^ n) (i, j).2 = 0

Next tactic:
rw [coeff_X_pow, if_neg, mul_zero]
@[simp]
theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) :
    coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by
  rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one]
  · rintro ⟨i, j⟩ h1 h2
    rw [coeff_X_pow, if_neg, mul_zero]
    

Proof state:
case h₀.mk.hnc
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n d i j : ℕ
h1 : (i, j) ∈ antidiagonal (d + n)
h2 : (i, j) ≠ (d, n)
⊢ ¬(i, j).2 = n

Next tactic:
rintro rfl
@[simp]
theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) :
    coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by
  rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one]
  · rintro ⟨i, j⟩ h1 h2
    rw [coeff_X_pow, if_neg, mul_zero]
    rintro rfl
    

Proof state:
case h₀.mk.hnc
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
d i j : ℕ
h1 : (i, j) ∈ antidiagonal (d + (i, j).2)
h2 : (i, j) ≠ (d, (i, j).2)
⊢ False

Next tactic:
apply h2
@[simp]
theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) :
    coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by
  rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one]
  · rintro ⟨i, j⟩ h1 h2
    rw [coeff_X_pow, if_neg, mul_zero]
    rintro rfl
    apply h2
    

Proof state:
case h₀.mk.hnc
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
d i j : ℕ
h1 : (i, j) ∈ antidiagonal (d + (i, j).2)
h2 : (i, j) ≠ (d, (i, j).2)
⊢ (i, j) = (d, (i, j).2)

Next tactic:
rw [mem_antidiagonal, add_right_cancel_iff] at h1
@[simp]
theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) :
    coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by
  rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one]
  · rintro ⟨i, j⟩ h1 h2
    rw [coeff_X_pow, if_neg, mul_zero]
    rintro rfl
    apply h2
    rw [mem_antidiagonal, add_right_cancel_iff] at h1
    

Proof state:
case h₀.mk.hnc
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
d i j : ℕ
h1 : (i, j).1 = d
h2 : (i, j) ≠ (d, (i, j).2)
⊢ (i, j) = (d, (i, j).2)

Next tactic:
subst h1
@[simp]
theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) :
    coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by
  rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one]
  · rintro ⟨i, j⟩ h1 h2
    rw [coeff_X_pow, if_neg, mul_zero]
    rintro rfl
    apply h2
    rw [mem_antidiagonal, add_right_cancel_iff] at h1
    subst h1
    

Proof state:
case h₀.mk.hnc
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
i j : ℕ
h2 : (i, j) ≠ ((i, j).1, (i, j).2)
⊢ (i, j) = ((i, j).1, (i, j).2)

Next tactic:
rfl
@[simp]
theorem coeff_mul_X_pow (p : R[X]) (n d : ℕ) :
    coeff (p * Polynomial.X ^ n) (d + n) = coeff p d := by
  rw [coeff_mul, Finset.sum_eq_single (d, n), coeff_X_pow, if_pos rfl, mul_one]
  · rintro ⟨i, j⟩ h1 h2
    rw [coeff_X_pow, if_neg, mul_zero]
    rintro rfl
    apply h2
    rw [mem_antidiagonal, add_right_cancel_iff] at h1
    subst h1
    rfl
  · 

Proof state:
case h₁
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n d : ℕ
⊢ (d, n) ∉ antidiagonal (d + n) → coeff p (d, n).1 * coeff (X ^ n) (d, n).2 = 0

Next tactic:
exact fun h1 => (h1 (mem_antidiagonal.2 rfl)).elim
@[simp]
theorem coeff_X_pow_mul (p : R[X]) (n d : ℕ) : coeff (Polynomial.X ^ n * p) (d + n) = coeff p d :=
  by 

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

Next tactic:
rw [(commute_X_pow p n).eq, coeff_mul_X_pow]
theorem coeff_mul_X_pow' (p : R[X]) (n d : ℕ) :
    (p * X ^ n).coeff d = ite (n ≤ d) (p.coeff (d - n)) 0 := by
  

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

Next tactic:
split_ifs with h
theorem coeff_mul_X_pow' (p : R[X]) (n d : ℕ) :
    (p * X ^ n).coeff d = ite (n ≤ d) (p.coeff (d - n)) 0 := by
  split_ifs with h
  · 

Proof state:
case pos
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n d : ℕ
h : n ≤ d
⊢ coeff (p * X ^ n) d = coeff p (d - n)

Next tactic:
rw [← tsub_add_cancel_of_le h, coeff_mul_X_pow, add_tsub_cancel_right]
theorem coeff_mul_X_pow' (p : R[X]) (n d : ℕ) :
    (p * X ^ n).coeff d = ite (n ≤ d) (p.coeff (d - n)) 0 := by
  split_ifs with h
  · rw [← tsub_add_cancel_of_le h, coeff_mul_X_pow, add_tsub_cancel_right]
  · 

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

Next tactic:
refine' (coeff_mul _ _ _).trans (Finset.sum_eq_zero fun x hx => _)
theorem coeff_mul_X_pow' (p : R[X]) (n d : ℕ) :
    (p * X ^ n).coeff d = ite (n ≤ d) (p.coeff (d - n)) 0 := by
  split_ifs with h
  · rw [← tsub_add_cancel_of_le h, coeff_mul_X_pow, add_tsub_cancel_right]
  · refine' (coeff_mul _ _ _).trans (Finset.sum_eq_zero fun x hx => _)
    

Proof state:
case neg
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n d : ℕ
h : ¬n ≤ d
x : ℕ × ℕ
hx : x ∈ antidiagonal d
⊢ coeff p x.1 * coeff (X ^ n) x.2 = 0

Next tactic:
rw [coeff_X_pow, if_neg, mul_zero]
theorem coeff_mul_X_pow' (p : R[X]) (n d : ℕ) :
    (p * X ^ n).coeff d = ite (n ≤ d) (p.coeff (d - n)) 0 := by
  split_ifs with h
  · rw [← tsub_add_cancel_of_le h, coeff_mul_X_pow, add_tsub_cancel_right]
  · refine' (coeff_mul _ _ _).trans (Finset.sum_eq_zero fun x hx => _)
    rw [coeff_X_pow, if_neg, mul_zero]
    

Proof state:
case neg.hnc
R : Type u
S : Type v
a b : R
n✝ m : ℕ
inst✝ : Semiring R
p✝ q r p : R[X]
n d : ℕ
h : ¬n ≤ d
x : ℕ × ℕ
hx : x ∈ antidiagonal d
⊢ ¬x.2 = n

Next tactic:
exact ((le_of_add_le_right (mem_antidiagonal.mp hx).le).trans_lt <| not_le.mp h).ne
theorem coeff_X_pow_mul' (p : R[X]) (n d : ℕ) :
    (X ^ n * p).coeff d = ite (n ≤ d) (p.coeff (d - n)) 0 := by
  

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

Next tactic:
rw [(commute_X_pow p n).eq, coeff_mul_X_pow']
@[simp]
theorem coeff_mul_X (p : R[X]) (n : ℕ) : coeff (p * X) (n + 1) = coeff p n := by
  

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

Next tactic:
simpa only [pow_one] using coeff_mul_X_pow p 1 n
@[simp]
theorem coeff_X_mul (p : R[X]) (n : ℕ) : coeff (X * p) (n + 1) = coeff p n := by
  

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

Next tactic:
rw [(commute_X p).eq, coeff_mul_X]
theorem coeff_mul_monomial (p : R[X]) (n d : ℕ) (r : R) :
    coeff (p * monomial n r) (d + n) = coeff p d * r := by
  

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

Next tactic:
rw [← C_mul_X_pow_eq_monomial, ← X_pow_mul, ← mul_assoc, coeff_mul_C, coeff_mul_X_pow]
theorem coeff_monomial_mul (p : R[X]) (n d : ℕ) (r : R) :
    coeff (monomial n r * p) (d + n) = r * coeff p d := by
  

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

Next tactic:
rw [← C_mul_X_pow_eq_monomial, mul_assoc, coeff_C_mul, X_pow_mul, coeff_mul_X_pow]
@[simp] theorem isRegular_X : IsRegular (X : R[X]) := by
  

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

Next tactic:
suffices : IsLeftRegular (X : R[X])
@[simp] theorem isRegular_X : IsRegular (X : R[X]) := by
  suffices : IsLeftRegular (X : R[X])
  · 

Proof state:
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
this : IsLeftRegular X
⊢ IsRegular X

Next tactic:
exact ⟨this, this.right_of_commute commute_X⟩
@[simp] theorem isRegular_X : IsRegular (X : R[X]) := by
  suffices : IsLeftRegular (X : R[X])
  · exact ⟨this, this.right_of_commute commute_X⟩
  

Proof state:
case this
R : Type u
S : Type v
a b : R
n m : ℕ
inst✝ : Semiring R
p q r : R[X]
⊢ IsLeftRegular X

Next tactic:
intro P Q (hPQ : X * P = X * Q)