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; 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
      conv =>
        

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:
rhs
        congr
        · rw [← sum_C_mul_X_pow_eq g]
        · rw [← sum_C_mul_X_pow_eq f]
@[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
      conv =>
        

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:
rhs
@[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
      conv =>
        rhs
        

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]
| derivative f * g + f * derivative g

Next tactic:
congr
@[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
      conv =>
        rhs
        congr
        

Proof state:
case a
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]
| derivative f * g
case a
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]
| f * derivative g

Next tactic:
· rw [← sum_C_mul_X_pow_eq g]
@[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
      conv =>
        rhs
        congr
        · 

Proof state:
case a
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]
| derivative f * g

Next tactic:
rw [← sum_C_mul_X_pow_eq g]
@[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
      conv =>
        rhs
        congr
        · rw [← sum_C_mul_X_pow_eq g]
        

Proof state:
case a
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]
| f * derivative g

Next tactic:
· rw [← sum_C_mul_X_pow_eq f]
@[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
      conv =>
        rhs
        congr
        · rw [← sum_C_mul_X_pow_eq g]
        · 

Proof state:
case a
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]
| f * derivative g

Next tactic:
rw [← sum_C_mul_X_pow_eq f]
@[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
      conv =>
        rhs
        congr
        · rw [← sum_C_mul_X_pow_eq g]
        · rw [← sum_C_mul_X_pow_eq f]
      

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 * sum g fun n a => C a * X ^ n) + (sum f fun n a => C a * X ^ n) * derivative g

Next tactic:
simp only [sum, sum_add_distrib, Finset.mul_sum, Finset.sum_mul, derivative_apply]
@[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
      conv =>
        rhs
        congr
        · rw [← sum_C_mul_X_pow_eq g]
        · rw [← sum_C_mul_X_pow_eq f]
      simp only [sum, sum_add_distrib, Finset.mul_sum, Finset.sum_mul, derivative_apply]
      

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 in support f, ∑ x_1 in support g, x • (C (coeff f x) * X ^ (x - 1)) * (C (coeff g x_1) * X ^ x_1) +
      ∑ x in support f, ∑ x_1 in support g, C (coeff f x) * X ^ x * x_1 • (C (coeff g x_1) * X ^ (x_1 - 1)) =
    ∑ x in support g, ∑ x_1 in support f, C (coeff f x_1 * ↑x_1) * X ^ (x_1 - 1) * (C (coeff g x) * X ^ x) +
      ∑ x in support g, ∑ x_1 in support f, C (coeff f x_1) * X ^ x_1 * (C (coeff g x * ↑x) * X ^ (x - 1))

Next tactic:
simp_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']; 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
      conv =>
        rhs
        congr
        · rw [← sum_C_mul_X_pow_eq g]
        · rw [← sum_C_mul_X_pow_eq f]
      simp only [sum, sum_add_distrib, Finset.mul_sum, Finset.sum_mul, derivative_apply]
      simp_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]
⊢ ∑ x in support f, ∑ x_1 in support g, C (coeff f x * ↑x) * X ^ (x - 1) * (C (coeff g x_1) * X ^ x_1) +
      ∑ x in support f, ∑ x_1 in support g, C (coeff f x) * X ^ x * (C (coeff g x_1 * ↑x_1) * X ^ (x_1 - 1)) =
    ∑ x in support g, ∑ x_1 in support f, C (coeff f x_1 * ↑x_1) * X ^ (x_1 - 1) * (C (coeff g x) * X ^ x) +
      ∑ x in support g, ∑ x_1 in support f, C (coeff f x_1) * X ^ x_1 * (C (coeff g x * ↑x) * X ^ (x - 1))

Next tactic:
rw [Finset.sum_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
      conv =>
        rhs
        congr
        · rw [← sum_C_mul_X_pow_eq g]
        · rw [← sum_C_mul_X_pow_eq f]
      simp only [sum, sum_add_distrib, Finset.mul_sum, Finset.sum_mul, derivative_apply]
      simp_rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']
      rw [Finset.sum_comm]
      

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]
⊢ ∑ y in support g, ∑ x in support f, C (coeff f x * ↑x) * X ^ (x - 1) * (C (coeff g y) * X ^ y) +
      ∑ x in support f, ∑ x_1 in support g, C (coeff f x) * X ^ x * (C (coeff g x_1 * ↑x_1) * X ^ (x_1 - 1)) =
    ∑ x in support g, ∑ x_1 in support f, C (coeff f x_1 * ↑x_1) * X ^ (x_1 - 1) * (C (coeff g x) * X ^ x) +
      ∑ x in support g, ∑ x_1 in support f, C (coeff f x_1) * X ^ x_1 * (C (coeff g x * ↑x) * X ^ (x - 1))

Next tactic:
congr 1
@[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
      conv =>
        rhs
        congr
        · rw [← sum_C_mul_X_pow_eq g]
        · rw [← sum_C_mul_X_pow_eq f]
      simp only [sum, sum_add_distrib, Finset.mul_sum, Finset.sum_mul, derivative_apply]
      simp_rw [← smul_mul_assoc, smul_C, nsmul_eq_mul']
      rw [Finset.sum_comm]
      congr 1
      

Proof state:
case e_a
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 in support f, ∑ x_1 in support g, C (coeff f x) * X ^ x * (C (coeff g x_1 * ↑x_1) * X ^ (x_1 - 1)) =
    ∑ x in support g, ∑ x_1 in support f, C (coeff f x_1) * X ^ x_1 * (C (coeff g x * ↑x) * X ^ (x - 1))

Next tactic:
rw [Finset.sum_comm]
theorem derivative_eval (p : R[X]) (x : R) :
    p.derivative.eval x = p.sum fun n a => a * n * x ^ (n - 1) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p : R[X]
x : R
⊢ eval x (derivative p) = sum p fun n a => a * ↑n * x ^ (n - 1)

Next tactic:
simp_rw [derivative_apply, eval_sum, eval_mul_X_pow, eval_C]
@[simp]
theorem derivative_map [Semiring S] (p : R[X]) (f : R →+* S) :
    derivative (p.map f) = p.derivative.map f := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
f : R →+* S
⊢ derivative (map f p) = map f (derivative p)

Next tactic:
let n := max p.natDegree (map f p).natDegree
@[simp]
theorem derivative_map [Semiring S] (p : R[X]) (f : R →+* S) :
    derivative (p.map f) = p.derivative.map f := by
  let n := max p.natDegree (map f p).natDegree
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
f : R →+* S
n : ℕ := max (natDegree p) (natDegree (map f p))
⊢ derivative (map f p) = map f (derivative p)

Next tactic:
rw [derivative_apply, derivative_apply]
@[simp]
theorem derivative_map [Semiring S] (p : R[X]) (f : R →+* S) :
    derivative (p.map f) = p.derivative.map f := by
  let n := max p.natDegree (map f p).natDegree
  rw [derivative_apply, derivative_apply]
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
f : R →+* S
n : ℕ := max (natDegree p) (natDegree (map f p))
⊢ (sum (map f p) fun n a => C (a * ↑n) * X ^ (n - 1)) = map f (sum p fun n a => C (a * ↑n) * X ^ (n - 1))

Next tactic:
rw [sum_over_range' _ _ (n + 1) ((le_max_left _ _).trans_lt (lt_add_one _))]
@[simp]
theorem derivative_map [Semiring S] (p : R[X]) (f : R →+* S) :
    derivative (p.map f) = p.derivative.map f := by
  let n := max p.natDegree (map f p).natDegree
  rw [derivative_apply, derivative_apply]
  rw [sum_over_range' _ _ (n + 1) ((le_max_left _ _).trans_lt (lt_add_one _))]
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
f : R →+* S
n : ℕ := max (natDegree p) (natDegree (map f p))
⊢ (sum (map f p) fun n a => C (a * ↑n) * X ^ (n - 1)) = map f (∑ a in range (n + 1), C (coeff p a * ↑a) * X ^ (a - 1))
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
f : R →+* S
n : ℕ := max (natDegree p) (natDegree (map f p))
⊢ ∀ (n : ℕ), C (0 * ↑n) * X ^ (n - 1) = 0

Next tactic:
rw [sum_over_range' _ _ (n + 1) ((le_max_right _ _).trans_lt (lt_add_one _))]
@[simp]
theorem derivative_map [Semiring S] (p : R[X]) (f : R →+* S) :
    derivative (p.map f) = p.derivative.map f := by
  let n := max p.natDegree (map f p).natDegree
  rw [derivative_apply, derivative_apply]
  rw [sum_over_range' _ _ (n + 1) ((le_max_left _ _).trans_lt (lt_add_one _))]
  rw [sum_over_range' _ _ (n + 1) ((le_max_right _ _).trans_lt (lt_add_one _))]
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
f : R →+* S
n : ℕ := max (natDegree p) (natDegree (map f p))
⊢ ∑ a in range (n + 1), C (coeff (map f p) a * ↑a) * X ^ (a - 1) =
    map f (∑ a in range (n + 1), C (coeff p a * ↑a) * X ^ (a - 1))
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
f : R →+* S
n : ℕ := max (natDegree p) (natDegree (map f p))
⊢ ∀ (n : ℕ), C (0 * ↑n) * X ^ (n - 1) = 0
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝¹ : Semiring R
inst✝ : Semiring S
p : R[X]
f : R →+* S
n : ℕ := max (natDegree p) (natDegree (map f p))
⊢ ∀ (n : ℕ), C (0 * ↑n) * X ^ (n - 1) = 0

Next tactic:
simp only [Polynomial.map_sum, Polynomial.map_mul, Polynomial.map_C, map_mul, coeff_map,
    map_natCast, Polynomial.map_nat_cast, Polynomial.map_pow, map_X]