l3lab/ntp-mathlib huggingface dataset:
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
⊢ ∀ x ∈ support f,
    ∑ b in support g, derivative ((fun j a => (monomial (x + j)) (coeff f x * a)) b (coeff g b)) =
      (fun n a => sum g fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1))) x (coeff f x)

Next tactic:
intro n _
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
f g : R[X]
n : ℕ
a✝ : n ∈ support f
⊢ ∑ b in support g, derivative ((fun j a => (monomial (n + j)) (coeff f n * a)) b (coeff g b)) =
    (fun n a => sum g fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1))) n (coeff f n)

Next tactic:
apply Finset.sum_congr rfl
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
f g : R[X]
n : ℕ
a✝ : n ∈ support f
⊢ ∀ x ∈ support g,
    derivative ((fun j a => (monomial (n + j)) (coeff f n * a)) x (coeff g x)) =
      (fun m b => (n + m) • (C (coeff f n * b) * X ^ (n + m - 1))) x (coeff g x)

Next tactic:
intro m _
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
f g : R[X]
n : ℕ
a✝¹ : n ∈ support f
m : ℕ
a✝ : m ∈ support g
⊢ derivative ((fun j a => (monomial (n + j)) (coeff f n * a)) m (coeff g m)) =
    (fun m b => (n + m) • (C (coeff f n * b) * X ^ (n + m - 1))) m (coeff g m)

Next tactic:
trans
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
f g : R[X]
n : ℕ
a✝¹ : n ∈ support f
m : ℕ
a✝ : m ∈ support g
⊢ derivative ((fun j a => (monomial (n + j)) (coeff f n * a)) m (coeff g m)) = ?m.410289

Next tactic:
exact congr_arg _ C_mul_X_pow_eq_monomial.symm
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
f g : R[X]
n : ℕ
a✝¹ : n ∈ support f
m : ℕ
a✝ : m ∈ support g
⊢ derivative (C (coeff f n * coeff g m) * X ^ (n + m)) =
    (fun m b => (n + m) • (C (coeff f n * b) * X ^ (n + m - 1))) m (coeff g m)

Next tactic:
dsimp
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
f g : R[X]
n : ℕ
a✝¹ : n ∈ support f
m : ℕ
a✝ : m ∈ support g
⊢ derivative (C (coeff f n * coeff g m) * X ^ (n + m)) = (n + m) • (C (coeff f n * coeff g m) * X ^ (n + m - 1))

Next tactic:
rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
f g : R[X]
n : ℕ
a✝¹ : n ∈ support f
m : ℕ
a✝ : m ∈ support g
⊢ derivative (C (coeff f n * coeff g m) * X ^ (n + m)) = C (coeff f n * coeff g m * ↑(n + m)) * X ^ (n + m - 1)

Next tactic:
exact derivative_C_mul_X_pow _ _
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
f g : R[X]
n : ℕ
hn : n ∈ support f
m : ℕ
hm : m ∈ support g
⊢ (fun m b => (n + m) • (C (coeff f n * b) * X ^ (n + m - 1))) m (coeff g m) =
    (fun m b => n • (C (coeff f n) * X ^ (n - 1)) * (C b * X ^ m) + C (coeff f n) * X ^ n * m • (C b * X ^ (m - 1))) m
      (coeff g m)

Next tactic:
cases n
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> 

Proof state:
case zero
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
m : ℕ
hm : m ∈ support g
hn : Nat.zero ∈ support f
⊢ (fun m b => (Nat.zero + m) • (C (coeff f Nat.zero * b) * X ^ (Nat.zero + m - 1))) m (coeff g m) =
    (fun m b =>
        Nat.zero • (C (coeff f Nat.zero) * X ^ (Nat.zero - 1)) * (C b * X ^ m) +
          C (coeff f Nat.zero) * X ^ Nat.zero * m • (C b * X ^ (m - 1)))
      m (coeff g m)

Next tactic:
cases m
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> 

Proof state:
case succ
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
m : ℕ
hm : m ∈ support g
n✝ : ℕ
hn : Nat.succ n✝ ∈ support f
⊢ (fun m b => (Nat.succ n✝ + m) • (C (coeff f (Nat.succ n✝) * b) * X ^ (Nat.succ n✝ + m - 1))) m (coeff g m) =
    (fun m b =>
        Nat.succ n✝ • (C (coeff f (Nat.succ n✝)) * X ^ (Nat.succ n✝ - 1)) * (C b * X ^ m) +
          C (coeff f (Nat.succ n✝)) * X ^ Nat.succ n✝ * m • (C b * X ^ (m - 1)))
      m (coeff g m)

Next tactic:
cases m
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> cases m <;>
            

Proof state:
case zero.zero
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
hn : Nat.zero ∈ support f
hm : Nat.zero ∈ support g
⊢ (fun m b => (Nat.zero + m) • (C (coeff f Nat.zero * b) * X ^ (Nat.zero + m - 1))) Nat.zero (coeff g Nat.zero) =
    (fun m b =>
        Nat.zero • (C (coeff f Nat.zero) * X ^ (Nat.zero - 1)) * (C b * X ^ m) +
          C (coeff f Nat.zero) * X ^ Nat.zero * m • (C b * X ^ (m - 1)))
      Nat.zero (coeff g Nat.zero)

Next tactic:
simp_rw [add_smul, mul_smul_comm, smul_mul_assoc, X_pow_mul_assoc, ← mul_assoc, ←
              C_mul, mul_assoc, ← pow_add]
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> cases m <;>
            

Proof state:
case zero.succ
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
hn : Nat.zero ∈ support f
n✝ : ℕ
hm : Nat.succ n✝ ∈ support g
⊢ (fun m b => (Nat.zero + m) • (C (coeff f Nat.zero * b) * X ^ (Nat.zero + m - 1))) (Nat.succ n✝)
      (coeff g (Nat.succ n✝)) =
    (fun m b =>
        Nat.zero • (C (coeff f Nat.zero) * X ^ (Nat.zero - 1)) * (C b * X ^ m) +
          C (coeff f Nat.zero) * X ^ Nat.zero * m • (C b * X ^ (m - 1)))
      (Nat.succ n✝) (coeff g (Nat.succ n✝))

Next tactic:
simp_rw [add_smul, mul_smul_comm, smul_mul_assoc, X_pow_mul_assoc, ← mul_assoc, ←
              C_mul, mul_assoc, ← pow_add]
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> cases m <;>
            

Proof state:
case succ.zero
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
n✝ : ℕ
hn : Nat.succ n✝ ∈ support f
hm : Nat.zero ∈ support g
⊢ (fun m b => (Nat.succ n✝ + m) • (C (coeff f (Nat.succ n✝) * b) * X ^ (Nat.succ n✝ + m - 1))) Nat.zero
      (coeff g Nat.zero) =
    (fun m b =>
        Nat.succ n✝ • (C (coeff f (Nat.succ n✝)) * X ^ (Nat.succ n✝ - 1)) * (C b * X ^ m) +
          C (coeff f (Nat.succ n✝)) * X ^ Nat.succ n✝ * m • (C b * X ^ (m - 1)))
      Nat.zero (coeff g Nat.zero)

Next tactic:
simp_rw [add_smul, mul_smul_comm, smul_mul_assoc, X_pow_mul_assoc, ← mul_assoc, ←
              C_mul, mul_assoc, ← pow_add]
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> cases m <;>
            

Proof state:
case succ.succ
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
n✝¹ : ℕ
hn : Nat.succ n✝¹ ∈ support f
n✝ : ℕ
hm : Nat.succ n✝ ∈ support g
⊢ (fun m b => (Nat.succ n✝¹ + m) • (C (coeff f (Nat.succ n✝¹) * b) * X ^ (Nat.succ n✝¹ + m - 1))) (Nat.succ n✝)
      (coeff g (Nat.succ n✝)) =
    (fun m b =>
        Nat.succ n✝¹ • (C (coeff f (Nat.succ n✝¹)) * X ^ (Nat.succ n✝¹ - 1)) * (C b * X ^ m) +
          C (coeff f (Nat.succ n✝¹)) * X ^ Nat.succ n✝¹ * m • (C b * X ^ (m - 1)))
      (Nat.succ n✝) (coeff g (Nat.succ n✝))

Next tactic:
simp_rw [add_smul, mul_smul_comm, smul_mul_assoc, X_pow_mul_assoc, ← mul_assoc, ←
              C_mul, mul_assoc, ← pow_add]
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> cases m <;>
            simp_rw [add_smul, mul_smul_comm, smul_mul_assoc, X_pow_mul_assoc, ← mul_assoc, ←
              C_mul, mul_assoc, ← pow_add] <;>
            

Proof state:
case zero.succ
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
hn : Nat.zero ∈ support f
n✝ : ℕ
hm : Nat.succ n✝ ∈ support g
⊢ Nat.zero • (C (coeff f Nat.zero * coeff g (Nat.succ n✝)) * X ^ (Nat.zero + Nat.succ n✝ - 1)) +
      Nat.succ n✝ • (C (coeff f Nat.zero * coeff g (Nat.succ n✝)) * X ^ (Nat.zero + Nat.succ n✝ - 1)) =
    Nat.zero • (C (coeff f Nat.zero * coeff g (Nat.succ n✝)) * X ^ (Nat.succ n✝ + (Nat.zero - 1))) +
      Nat.succ n✝ • (C (coeff f Nat.zero * coeff g (Nat.succ n✝)) * X ^ (Nat.succ n✝ - 1 + Nat.zero))

Next tactic:
simp [Nat.add_succ, Nat.succ_add, Nat.add_one_sub_one, zero_smul, add_comm]
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> cases m <;>
            simp_rw [add_smul, mul_smul_comm, smul_mul_assoc, X_pow_mul_assoc, ← mul_assoc, ←
              C_mul, mul_assoc, ← pow_add] <;>
            

Proof state:
case succ.zero
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
n✝ : ℕ
hn : Nat.succ n✝ ∈ support f
hm : Nat.zero ∈ support g
⊢ Nat.succ n✝ • (C (coeff f (Nat.succ n✝) * coeff g Nat.zero) * X ^ (Nat.succ n✝ + Nat.zero - 1)) +
      Nat.zero • (C (coeff f (Nat.succ n✝) * coeff g Nat.zero) * X ^ (Nat.succ n✝ + Nat.zero - 1)) =
    Nat.succ n✝ • (C (coeff f (Nat.succ n✝) * coeff g Nat.zero) * X ^ (Nat.zero + (Nat.succ n✝ - 1))) +
      Nat.zero • (C (coeff f (Nat.succ n✝) * coeff g Nat.zero) * X ^ (Nat.zero - 1 + Nat.succ n✝))

Next tactic:
simp [Nat.add_succ, Nat.succ_add, Nat.add_one_sub_one, zero_smul, add_comm]
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> cases m <;>
            simp_rw [add_smul, mul_smul_comm, smul_mul_assoc, X_pow_mul_assoc, ← mul_assoc, ←
              C_mul, mul_assoc, ← pow_add] <;>
            

Proof state:
case succ.succ
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
n✝¹ : ℕ
hn : Nat.succ n✝¹ ∈ support f
n✝ : ℕ
hm : Nat.succ n✝ ∈ support g
⊢ Nat.succ n✝¹ • (C (coeff f (Nat.succ n✝¹) * coeff g (Nat.succ n✝)) * X ^ (Nat.succ n✝¹ + Nat.succ n✝ - 1)) +
      Nat.succ n✝ • (C (coeff f (Nat.succ n✝¹) * coeff g (Nat.succ n✝)) * X ^ (Nat.succ n✝¹ + Nat.succ n✝ - 1)) =
    Nat.succ n✝¹ • (C (coeff f (Nat.succ n✝¹) * coeff g (Nat.succ n✝)) * X ^ (Nat.succ n✝ + (Nat.succ n✝¹ - 1))) +
      Nat.succ n✝ • (C (coeff f (Nat.succ n✝¹) * coeff g (Nat.succ n✝)) * X ^ (Nat.succ n✝ - 1 + Nat.succ n✝¹))

Next tactic:
simp [Nat.add_succ, Nat.succ_add, Nat.add_one_sub_one, zero_smul, add_comm]
@[simp]
theorem derivative_mul {f g : R[X]} : derivative (f * g) = derivative f * g + f * derivative g :=
  calc
    derivative (f * g) =
        f.sum fun n a => g.sum fun m b => (n + m) • (C (a * b) * X ^ (n + m - 1)) := by
      rw [mul_eq_sum_sum, derivative_sum]
      trans
      · apply Finset.sum_congr rfl
        intro x _
        exact derivative_sum
      apply Finset.sum_congr rfl; intro n _; apply Finset.sum_congr rfl; intro m _
      trans
      · exact congr_arg _ C_mul_X_pow_eq_monomial.symm
      dsimp; rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']; exact derivative_C_mul_X_pow _ _
    _ =
        f.sum fun n a =>
          g.sum fun m b =>
            n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1)) :=
      (sum_congr rfl fun n hn =>
        sum_congr rfl fun m hm => by
          cases n <;> cases m <;>
            simp_rw [add_smul, mul_smul_comm, smul_mul_assoc, X_pow_mul_assoc, ← mul_assoc, ←
              C_mul, mul_assoc, ← pow_add] <;>
            simp [Nat.add_succ, Nat.succ_add, Nat.add_one_sub_one, zero_smul, add_comm])
    _ = derivative f * g + f * derivative g := by
      

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
f g : R[X]
⊢ (sum f fun n a => sum g fun m b => n • (C a * X ^ (n - 1)) * (C b * X ^ m) + C a * X ^ n * m • (C b * X ^ (m - 1))) =
    derivative f * g + f * derivative g

Next tactic:
conv =>
        rhs
        congr
        · rw [← sum_C_mul_X_pow_eq g]
        · rw [← sum_C_mul_X_pow_eq f]