l3lab/ntp-mathlib huggingface dataset:
/-- `derivative p` is the formal derivative of the polynomial `p` -/
def derivative : R[X] →ₗ[R] R[X] where
  toFun p := p.sum fun n a => C (a * n) * X ^ (n - 1)
  map_add' p q := by
    dsimp only
    

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

Next tactic:
rw [sum_add_index]
/-- `derivative p` is the formal derivative of the polynomial `p` -/
def derivative : R[X] →ₗ[R] R[X] where
  toFun p := p.sum fun n a => C (a * n) * X ^ (n - 1)
  map_add' p q := by
    dsimp only
    rw [sum_add_index] <;>
      

Proof state:
case hf
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ ∀ (i : ℕ), C (0 * ↑i) * X ^ (i - 1) = 0

Next tactic:
simp only [add_mul, forall_const, RingHom.map_add, eq_self_iff_true, zero_mul,
        RingHom.map_zero]
/-- `derivative p` is the formal derivative of the polynomial `p` -/
def derivative : R[X] →ₗ[R] R[X] where
  toFun p := p.sum fun n a => C (a * n) * X ^ (n - 1)
  map_add' p q := by
    dsimp only
    rw [sum_add_index] <;>
      

Proof state:
case h_add
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p q : R[X]
⊢ ∀ (a : ℕ) (b₁ b₂ : R), C ((b₁ + b₂) * ↑a) * X ^ (a - 1) = C (b₁ * ↑a) * X ^ (a - 1) + C (b₂ * ↑a) * X ^ (a - 1)

Next tactic:
simp only [add_mul, forall_const, RingHom.map_add, eq_self_iff_true, zero_mul,
        RingHom.map_zero]
/-- `derivative p` is the formal derivative of the polynomial `p` -/
def derivative : R[X] →ₗ[R] R[X] where
  toFun p := p.sum fun n a => C (a * n) * X ^ (n - 1)
  map_add' p q := by
    dsimp only
    rw [sum_add_index] <;>
      simp only [add_mul, forall_const, RingHom.map_add, eq_self_iff_true, zero_mul,
        RingHom.map_zero]
  map_smul' a p := by
    

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝ : Semiring R
a : R
p : R[X]
⊢ AddHom.toFun
      { toFun := fun p => sum p fun n a => C (a * ↑n) * X ^ (n - 1),
        map_add' :=
          (_ :
            ∀ (p q : R[X]),
              (fun p => sum p fun n a => C (a * ↑n) * X ^ (n - 1)) (p + q) =
                (fun p => sum p fun n a => C (a * ↑n) * X ^ (n - 1)) p +
                  (fun p => sum p fun n a => C (a * ↑n) * X ^ (n - 1)) q) }
      (a • p) =
    (RingHom.id R) a •
      AddHom.toFun
        { toFun := fun p => sum p fun n a => C (a * ↑n) * X ^ (n - 1),
          map_add' :=
            (_ :
              ∀ (p q : R[X]),
                (fun p => sum p fun n a => C (a * ↑n) * X ^ (n - 1)) (p + q) =
                  (fun p => sum p fun n a => C (a * ↑n) * X ^ (n - 1)) p +
                    (fun p => sum p fun n a => C (a * ↑n) * X ^ (n - 1)) q) }
        p

Next tactic:
dsimp
/-- `derivative p` is the formal derivative of the polynomial `p` -/
def derivative : R[X] →ₗ[R] R[X] where
  toFun p := p.sum fun n a => C (a * n) * X ^ (n - 1)
  map_add' p q := by
    dsimp only
    rw [sum_add_index] <;>
      simp only [add_mul, forall_const, RingHom.map_add, eq_self_iff_true, zero_mul,
        RingHom.map_zero]
  map_smul' a p := by
    dsimp; 

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

Next tactic:
rw [sum_smul_index]
/-- `derivative p` is the formal derivative of the polynomial `p` -/
def derivative : R[X] →ₗ[R] R[X] where
  toFun p := p.sum fun n a => C (a * n) * X ^ (n - 1)
  map_add' p q := by
    dsimp only
    rw [sum_add_index] <;>
      simp only [add_mul, forall_const, RingHom.map_add, eq_self_iff_true, zero_mul,
        RingHom.map_zero]
  map_smul' a p := by
    dsimp; rw [sum_smul_index] <;>
      

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

Next tactic:
simp only [mul_sum, ← C_mul', mul_assoc, coeff_C_mul, RingHom.map_mul, forall_const, zero_mul,
        RingHom.map_zero, sum]
/-- `derivative p` is the formal derivative of the polynomial `p` -/
def derivative : R[X] →ₗ[R] R[X] where
  toFun p := p.sum fun n a => C (a * n) * X ^ (n - 1)
  map_add' p q := by
    dsimp only
    rw [sum_add_index] <;>
      simp only [add_mul, forall_const, RingHom.map_add, eq_self_iff_true, zero_mul,
        RingHom.map_zero]
  map_smul' a p := by
    dsimp; rw [sum_smul_index] <;>
      

Proof state:
case hf
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝ : Semiring R
a : R
p : R[X]
⊢ ∀ (i : ℕ), C (0 * ↑i) * X ^ (i - 1) = 0

Next tactic:
simp only [mul_sum, ← C_mul', mul_assoc, coeff_C_mul, RingHom.map_mul, forall_const, zero_mul,
        RingHom.map_zero, sum]
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (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]
n : ℕ
⊢ coeff (derivative p) n = coeff p (n + 1) * (↑n + 1)

Next tactic:
rw [derivative_apply]
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [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
p : R[X]
n : ℕ
⊢ coeff (sum p fun n a => C (a * ↑n) * X ^ (n - 1)) n = coeff p (n + 1) * (↑n + 1)

Next tactic:
simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  

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]
n : ℕ
⊢ (sum p fun a b => b * ↑a * if n = a - 1 then 1 else 0) = coeff p (n + 1) * (↑n + 1)

Next tactic:
rw [sum, Finset.sum_eq_single (n + 1)]
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  

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]
n : ℕ
⊢ (coeff p (n + 1) * ↑(n + 1) * if n = n + 1 - 1 then 1 else 0) = coeff p (n + 1) * (↑n + 1)
case h₀
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
⊢ ∀ b ∈ support p, b ≠ n + 1 → (coeff p b * ↑b * if n = b - 1 then 1 else 0) = 0
case h₁
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
⊢ n + 1 ∉ support p → (coeff p (n + 1) * ↑(n + 1) * if n = n + 1 - 1 then 1 else 0) = 0

Next tactic:
simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; 

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]
n : ℕ
⊢ coeff p (n + 1) * ↑(n + 1) = coeff p (n + 1) * (↑n + 1)
case h₀
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
⊢ ∀ b ∈ support p, b ≠ n + 1 → (coeff p b * ↑b * if n = b - 1 then 1 else 0) = 0
case h₁
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
⊢ n + 1 ∉ support p → (coeff p (n + 1) * ↑(n + 1) * if n = n + 1 - 1 then 1 else 0) = 0

Next tactic:
norm_cast
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · 

Proof state:
case h₀
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
⊢ ∀ b ∈ support p, b ≠ n + 1 → (coeff p b * ↑b * if n = b - 1 then 1 else 0) = 0

Next tactic:
intro b
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · intro b
    

Proof state:
case h₀
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b✝ : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n b : ℕ
⊢ b ∈ support p → b ≠ n + 1 → (coeff p b * ↑b * if n = b - 1 then 1 else 0) = 0

Next tactic:
cases b
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · intro b
    cases b
    · 

Proof state:
case h₀.zero
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
⊢ Nat.zero ∈ support p → Nat.zero ≠ n + 1 → (coeff p Nat.zero * ↑Nat.zero * if n = Nat.zero - 1 then 1 else 0) = 0

Next tactic:
intros
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · intro b
    cases b
    · intros
      

Proof state:
case h₀.zero
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
a✝¹ : Nat.zero ∈ support p
a✝ : Nat.zero ≠ n + 1
⊢ (coeff p Nat.zero * ↑Nat.zero * if n = Nat.zero - 1 then 1 else 0) = 0

Next tactic:
rw [Nat.cast_zero, mul_zero, zero_mul]
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · intro b
    cases b
    · intros
      rw [Nat.cast_zero, mul_zero, zero_mul]
    · 

Proof state:
case h₀.succ
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝¹ : ℕ
inst✝ : Semiring R
p : R[X]
n n✝ : ℕ
⊢ Nat.succ n✝ ∈ support p →
    Nat.succ n✝ ≠ n + 1 → (coeff p (Nat.succ n✝) * ↑(Nat.succ n✝) * if n = Nat.succ n✝ - 1 then 1 else 0) = 0

Next tactic:
intro _ H
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · intro b
    cases b
    · intros
      rw [Nat.cast_zero, mul_zero, zero_mul]
    · intro _ H
      

Proof state:
case h₀.succ
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝¹ : ℕ
inst✝ : Semiring R
p : R[X]
n n✝ : ℕ
a✝ : Nat.succ n✝ ∈ support p
H : Nat.succ n✝ ≠ n + 1
⊢ (coeff p (Nat.succ n✝) * ↑(Nat.succ n✝) * if n = Nat.succ n✝ - 1 then 1 else 0) = 0

Next tactic:
rw [Nat.add_one_sub_one, if_neg (mt (congr_arg Nat.succ) H.symm), mul_zero]
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · intro b
    cases b
    · intros
      rw [Nat.cast_zero, mul_zero, zero_mul]
    · intro _ H
      rw [Nat.add_one_sub_one, if_neg (mt (congr_arg Nat.succ) H.symm), mul_zero]
  · 

Proof state:
case h₁
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
⊢ n + 1 ∉ support p → (coeff p (n + 1) * ↑(n + 1) * if n = n + 1 - 1 then 1 else 0) = 0

Next tactic:
rw [if_pos (add_tsub_cancel_right n 1).symm, mul_one, Nat.cast_add, Nat.cast_one,
      mem_support_iff]
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · intro b
    cases b
    · intros
      rw [Nat.cast_zero, mul_zero, zero_mul]
    · intro _ H
      rw [Nat.add_one_sub_one, if_neg (mt (congr_arg Nat.succ) H.symm), mul_zero]
  · rw [if_pos (add_tsub_cancel_right n 1).symm, mul_one, Nat.cast_add, Nat.cast_one,
      mem_support_iff]
    

Proof state:
case h₁
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
⊢ ¬coeff p (n + 1) ≠ 0 → coeff p (n + 1) * (↑n + 1) = 0

Next tactic:
intro h
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · intro b
    cases b
    · intros
      rw [Nat.cast_zero, mul_zero, zero_mul]
    · intro _ H
      rw [Nat.add_one_sub_one, if_neg (mt (congr_arg Nat.succ) H.symm), mul_zero]
  · rw [if_pos (add_tsub_cancel_right n 1).symm, mul_one, Nat.cast_add, Nat.cast_one,
      mem_support_iff]
    intro h
    

Proof state:
case h₁
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
h : ¬coeff p (n + 1) ≠ 0
⊢ coeff p (n + 1) * (↑n + 1) = 0

Next tactic:
push_neg at h
theorem coeff_derivative (p : R[X]) (n : ℕ) :
    coeff (derivative p) n = coeff p (n + 1) * (n + 1) := by
  rw [derivative_apply]
  simp only [coeff_X_pow, coeff_sum, coeff_C_mul]
  rw [sum, Finset.sum_eq_single (n + 1)]
  simp only [Nat.add_succ_sub_one, add_zero, mul_one, if_true, eq_self_iff_true]; norm_cast
  · intro b
    cases b
    · intros
      rw [Nat.cast_zero, mul_zero, zero_mul]
    · intro _ H
      rw [Nat.add_one_sub_one, if_neg (mt (congr_arg Nat.succ) H.symm), mul_zero]
  · rw [if_pos (add_tsub_cancel_right n 1).symm, mul_one, Nat.cast_add, Nat.cast_one,
      mem_support_iff]
    intro h
    push_neg at h
    

Proof state:
case h₁
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
p : R[X]
n : ℕ
h : coeff p (n + 1) = 0
⊢ coeff p (n + 1) * (↑n + 1) = 0

Next tactic:
simp [h]
@[simp]
theorem iterate_derivative_zero {k : ℕ} : derivative^[k] (0 : R[X]) = 0 := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
k : ℕ
⊢ (⇑derivative)^[k] 0 = 0

Next tactic:
induction' k with k ih
@[simp]
theorem iterate_derivative_zero {k : ℕ} : derivative^[k] (0 : R[X]) = 0 := by
  induction' k with k ih
  · 

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
⊢ (⇑derivative)^[Nat.zero] 0 = 0

Next tactic:
simp
@[simp]
theorem iterate_derivative_zero {k : ℕ} : derivative^[k] (0 : R[X]) = 0 := by
  induction' k with k ih
  · simp
  · 

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
k : ℕ
ih : (⇑derivative)^[k] 0 = 0
⊢ (⇑derivative)^[Nat.succ k] 0 = 0

Next tactic:
simp [ih]
@[simp]
theorem derivative_monomial (a : R) (n : ℕ) :
    derivative (monomial n a) = monomial (n - 1) (a * n) := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Semiring R
a : R
n : ℕ
⊢ derivative ((monomial n) a) = (monomial (n - 1)) (a * ↑n)

Next tactic:
rw [derivative_apply, sum_monomial_index, C_mul_X_pow_eq_monomial]
@[simp]
theorem derivative_monomial (a : R) (n : ℕ) :
    derivative (monomial n a) = monomial (n - 1) (a * n) := by
  rw [derivative_apply, sum_monomial_index, C_mul_X_pow_eq_monomial]
  

Proof state:
case hf
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n✝ : ℕ
inst✝ : Semiring R
a : R
n : ℕ
⊢ C (0 * ↑n) * X ^ (n - 1) = 0

Next tactic:
simp
theorem derivative_C_mul_X (a : R) : derivative (C a * X) = C a := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝ : Semiring R
a : R
⊢ derivative (C a * X) = C a

Next tactic:
simp [C_mul_X_eq_monomial, derivative_monomial, Nat.cast_one, mul_one]
theorem derivative_C_mul_X_pow (a : R) (n : ℕ) :
    derivative (C a * X ^ n) = C (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
a : R
n : ℕ
⊢ derivative (C a * X ^ n) = C (a * ↑n) * X ^ (n - 1)

Next tactic:
rw [C_mul_X_pow_eq_monomial, C_mul_X_pow_eq_monomial, derivative_monomial]
theorem derivative_C_mul_X_sq (a : R) : derivative (C a * X ^ 2) = C (a * 2) * X := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝ : Semiring R
a : R
⊢ derivative (C a * X ^ 2) = C (a * 2) * X

Next tactic:
rw [derivative_C_mul_X_pow, Nat.cast_two, pow_one]
@[simp]
theorem derivative_X_pow (n : ℕ) : derivative (X ^ n : R[X]) = C (n : R) * 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
n : ℕ
⊢ derivative (X ^ n) = C ↑n * X ^ (n - 1)

Next tactic:
convert derivative_C_mul_X_pow (1 : R) n
@[simp]
theorem derivative_X_pow (n : ℕ) : derivative (X ^ n : R[X]) = C (n : R) * X ^ (n - 1) := by
  convert derivative_C_mul_X_pow (1 : R) n <;> 

Proof state:
case h.e'_2.h.e'_6
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
n : ℕ
⊢ X ^ n = C 1 * X ^ n

Next tactic:
simp
@[simp]
theorem derivative_X_pow (n : ℕ) : derivative (X ^ n : R[X]) = C (n : R) * X ^ (n - 1) := by
  convert derivative_C_mul_X_pow (1 : R) n <;> 

Proof state:
case h.e'_3.h.e'_5.h.e'_6
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n✝ : ℕ
inst✝ : Semiring R
n : ℕ
⊢ ↑n = 1 * ↑n

Next tactic:
simp
theorem derivative_X_sq : derivative (X ^ 2 : R[X]) = C 2 * X := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
⊢ derivative (X ^ 2) = C 2 * X

Next tactic:
rw [derivative_X_pow, Nat.cast_two, pow_one]
@[simp]
theorem derivative_C {a : R} : derivative (C a) = 0 := by 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝ : Semiring R
a : R
⊢ derivative (C a) = 0

Next tactic:
simp [derivative_apply]
theorem derivative_of_natDegree_zero {p : R[X]} (hp : p.natDegree = 0) : derivative p = 0 := 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]
hp : natDegree p = 0
⊢ derivative p = 0

Next tactic:
rw [eq_C_of_natDegree_eq_zero hp, derivative_C]
@[simp]
theorem derivative_X : derivative (X : R[X]) = 1 :=
  (derivative_monomial _ _).trans <| by 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
⊢ (monomial (1 - 1)) (1 * ↑1) = 1

Next tactic:
simp
set_option linter.deprecated false in
--Porting note: removed `simp`: `simp` can prove it.
theorem derivative_bit0 {a : R[X]} : derivative (bit0 a) = bit0 (derivative a) := by 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝ : Semiring R
a : R[X]
⊢ derivative (bit0 a) = bit0 (derivative a)

Next tactic:
simp [bit0]
set_option linter.deprecated false in
--Porting note: removed `simp`: `simp` can prove it.
theorem derivative_bit1 {a : R[X]} : derivative (bit1 a) = bit0 (derivative a) := by 

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝ : Semiring R
a : R[X]
⊢ derivative (bit1 a) = bit0 (derivative a)

Next tactic:
simp [bit1]
theorem derivative_X_add_C (c : R) : derivative (X + C c) = 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
c : R
⊢ derivative (X + C c) = 1

Next tactic:
rw [derivative_add, derivative_X, derivative_C, add_zero]
@[simp]
theorem iterate_derivative_smul {S : Type*} [Monoid S] [DistribMulAction S R] [IsScalarTower S R R]
    (s : S) (p : R[X]) (k : ℕ) : derivative^[k] (s • p) = s • derivative^[k] p := by
  

Proof state:
R : Type u
S✝ : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝³ : Semiring R
S : Type u_1
inst✝² : Monoid S
inst✝¹ : DistribMulAction S R
inst✝ : IsScalarTower S R R
s : S
p : R[X]
k : ℕ
⊢ (⇑derivative)^[k] (s • p) = s • (⇑derivative)^[k] p

Next tactic:
induction' k with k ih generalizing p
@[simp]
theorem iterate_derivative_smul {S : Type*} [Monoid S] [DistribMulAction S R] [IsScalarTower S R R]
    (s : S) (p : R[X]) (k : ℕ) : derivative^[k] (s • p) = s • derivative^[k] p := by
  induction' k with k ih generalizing p
  · 

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
S : Type u_1
inst✝² : Monoid S
inst✝¹ : DistribMulAction S R
inst✝ : IsScalarTower S R R
s : S
p : R[X]
⊢ (⇑derivative)^[Nat.zero] (s • p) = s • (⇑derivative)^[Nat.zero] p

Next tactic:
simp
@[simp]
theorem iterate_derivative_smul {S : Type*} [Monoid S] [DistribMulAction S R] [IsScalarTower S R R]
    (s : S) (p : R[X]) (k : ℕ) : derivative^[k] (s • p) = s • derivative^[k] p := by
  induction' k with k ih generalizing p
  · simp
  · 

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
S : Type u_1
inst✝² : Monoid S
inst✝¹ : DistribMulAction S R
inst✝ : IsScalarTower S R R
s : S
k : ℕ
ih : ∀ (p : R[X]), (⇑derivative)^[k] (s • p) = s • (⇑derivative)^[k] p
p : R[X]
⊢ (⇑derivative)^[Nat.succ k] (s • p) = s • (⇑derivative)^[Nat.succ k] p

Next tactic:
simp [ih]
@[simp]
theorem iterate_derivative_C_mul (a : R) (p : R[X]) (k : ℕ) :
    derivative^[k] (C a * p) = C a * derivative^[k] p := by
  

Proof state:
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a✝ b : R
n : ℕ
inst✝ : Semiring R
a : R
p : R[X]
k : ℕ
⊢ (⇑derivative)^[k] (C a * p) = C a * (⇑derivative)^[k] p

Next tactic:
simp_rw [← smul_eq_C_mul, iterate_derivative_smul]
theorem of_mem_support_derivative {p : R[X]} {n : ℕ} (h : n ∈ p.derivative.support) :
    n + 1 ∈ p.support :=
  mem_support_iff.2 fun h1 : p.coeff (n + 1) = 0 =>
    mem_support_iff.1 h <| show p.derivative.coeff n = 0 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]
n : ℕ
h : n ∈ support (derivative p)
h1 : coeff p (n + 1) = 0
⊢ coeff (derivative p) n = 0

Next tactic:
rw [coeff_derivative, h1, zero_mul]
theorem degree_derivative_le {p : R[X]} : p.derivative.degree ≤ p.degree :=
  letI := Classical.decEq R
  if H : p = 0 then le_of_eq <| 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]
this : DecidableEq R := Classical.decEq R
H : p = 0
⊢ degree (derivative p) = degree p

Next tactic:
rw [H, derivative_zero]
theorem natDegree_derivative_lt {p : R[X]} (hp : p.natDegree ≠ 0) :
    p.derivative.natDegree < p.natDegree := 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]
hp : natDegree p ≠ 0
⊢ natDegree (derivative p) < natDegree p

Next tactic:
rcases eq_or_ne (derivative p) 0 with hp' | hp'
theorem natDegree_derivative_lt {p : R[X]} (hp : p.natDegree ≠ 0) :
    p.derivative.natDegree < p.natDegree := by
  rcases eq_or_ne (derivative p) 0 with hp' | hp'
  · 

Proof state:
case inl
R : Type u
S : Type v
T : Type w
ι : Type y
A : Type z
a b : R
n : ℕ
inst✝ : Semiring R
p : R[X]
hp : natDegree p ≠ 0
hp' : derivative p = 0
⊢ natDegree (derivative p) < natDegree p

Next tactic:
rw [hp', Polynomial.natDegree_zero]