l3lab/ntp-mathlib huggingface dataset:
theorem rank_eq :
    hwf.rank a = Ordinal.sup.{u, u} fun b : { b // r b a } => Order.succ <| hwf.rank b := by
  rw [rank, Acc.rank_eq]
  

Proof state:
α : Type u
r : α → α → Prop
a b : α
hwf : WellFounded r
⊢ (sup fun b => succ (Acc.rank (_ : Acc r ↑b))) = sup fun b => succ (rank hwf ↑b)

Next tactic:
rfl
theorem hasseDeriv_apply :
    hasseDeriv k f = f.sum fun i r => monomial (i - k) (↑(i.choose k) * r) := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
⊢ (hasseDeriv k) f = sum f fun i r => (monomial (i - k)) (↑(choose i k) * r)

Next tactic:
dsimp [hasseDeriv]
theorem hasseDeriv_apply :
    hasseDeriv k f = f.sum fun i r => monomial (i - k) (↑(i.choose k) * r) := by
  dsimp [hasseDeriv]
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
⊢ (sum f fun x x_1 => (monomial (x - k)) (choose x k • x_1)) = sum f fun i r => (monomial (i - k)) (↑(choose i k) * r)

Next tactic:
congr
theorem hasseDeriv_apply :
    hasseDeriv k f = f.sum fun i r => monomial (i - k) (↑(i.choose k) * r) := by
  dsimp [hasseDeriv]
  congr; 

Proof state:
case e_f
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
⊢ (fun x x_1 => (monomial (x - k)) (choose x k • x_1)) = fun i r => (monomial (i - k)) (↑(choose i k) * r)

Next tactic:
ext
theorem hasseDeriv_apply :
    hasseDeriv k f = f.sum fun i r => monomial (i - k) (↑(i.choose k) * r) := by
  dsimp [hasseDeriv]
  congr; ext; 

Proof state:
case e_f.h.h.a
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
x✝¹ : ℕ
x✝ : R
n✝ : ℕ
⊢ coeff ((monomial (x✝¹ - k)) (choose x✝¹ k • x✝)) n✝ = coeff ((monomial (x✝¹ - k)) (↑(choose x✝¹ k) * x✝)) n✝

Next tactic:
congr
theorem hasseDeriv_apply :
    hasseDeriv k f = f.sum fun i r => monomial (i - k) (↑(i.choose k) * r) := by
  dsimp [hasseDeriv]
  congr; ext; congr
  

Proof state:
case e_f.h.h.a.e_a.h.e_6.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
x✝¹ : ℕ
x✝ : R
n✝ : ℕ
⊢ choose x✝¹ k • x✝ = ↑(choose x✝¹ k) * x✝

Next tactic:
apply nsmul_eq_mul
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
⊢ coeff ((hasseDeriv k) f) n = ↑(choose (n + k) k) * coeff f (n + k)

Next tactic:
rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · 

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
⊢ (if n + k - k = n then ↑(choose (n + k) k) * coeff f (n + k) else 0) = ↑(choose (n + k) k) * coeff f (n + k)

Next tactic:
simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · 

Proof state:
case h₀
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
⊢ ∀ b ∈ support f, b ≠ n + k → coeff ((monomial (b - k)) (↑(choose b k) * coeff f b)) n = 0

Next tactic:
intro i _hi hink
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · intro i _hi hink
    

Proof state:
case h₀
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n i : ℕ
_hi : i ∈ support f
hink : i ≠ n + k
⊢ coeff ((monomial (i - k)) (↑(choose i k) * coeff f i)) n = 0

Next tactic:
rw [coeff_monomial]
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · intro i _hi hink
    rw [coeff_monomial]
    

Proof state:
case h₀
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n i : ℕ
_hi : i ∈ support f
hink : i ≠ n + k
⊢ (if i - k = n then ↑(choose i k) * coeff f i else 0) = 0

Next tactic:
by_cases hik : i < k
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · intro i _hi hink
    rw [coeff_monomial]
    by_cases hik : i < k
    · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n i : ℕ
_hi : i ∈ support f
hink : i ≠ n + k
hik : i < k
⊢ (if i - k = n then ↑(choose i k) * coeff f i else 0) = 0

Next tactic:
simp only [Nat.choose_eq_zero_of_lt hik, ite_self, Nat.cast_zero, zero_mul]
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · intro i _hi hink
    rw [coeff_monomial]
    by_cases hik : i < k
    · simp only [Nat.choose_eq_zero_of_lt hik, ite_self, Nat.cast_zero, zero_mul]
    · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n i : ℕ
_hi : i ∈ support f
hink : i ≠ n + k
hik : ¬i < k
⊢ (if i - k = n then ↑(choose i k) * coeff f i else 0) = 0

Next tactic:
push_neg at hik
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · intro i _hi hink
    rw [coeff_monomial]
    by_cases hik : i < k
    · simp only [Nat.choose_eq_zero_of_lt hik, ite_self, Nat.cast_zero, zero_mul]
    · push_neg at hik
      

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n i : ℕ
_hi : i ∈ support f
hink : i ≠ n + k
hik : k ≤ i
⊢ (if i - k = n then ↑(choose i k) * coeff f i else 0) = 0

Next tactic:
rw [if_neg]
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · intro i _hi hink
    rw [coeff_monomial]
    by_cases hik : i < k
    · simp only [Nat.choose_eq_zero_of_lt hik, ite_self, Nat.cast_zero, zero_mul]
    · push_neg at hik
      rw [if_neg]
      

Proof state:
case neg.hnc
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n i : ℕ
_hi : i ∈ support f
hink : i ≠ n + k
hik : k ≤ i
⊢ ¬i - k = n

Next tactic:
contrapose! hink
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · intro i _hi hink
    rw [coeff_monomial]
    by_cases hik : i < k
    · simp only [Nat.choose_eq_zero_of_lt hik, ite_self, Nat.cast_zero, zero_mul]
    · push_neg at hik
      rw [if_neg]
      contrapose! hink
      

Proof state:
case neg.hnc
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n i : ℕ
_hi : i ∈ support f
hik : k ≤ i
hink : i - k = n
⊢ i = n + k

Next tactic:
exact (tsub_eq_iff_eq_add_of_le hik).mp hink
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · intro i _hi hink
    rw [coeff_monomial]
    by_cases hik : i < k
    · simp only [Nat.choose_eq_zero_of_lt hik, ite_self, Nat.cast_zero, zero_mul]
    · push_neg at hik
      rw [if_neg]
      contrapose! hink
      exact (tsub_eq_iff_eq_add_of_le hik).mp hink
  · 

Proof state:
case h₁
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
⊢ n + k ∉ support f → coeff ((monomial (n + k - k)) (↑(choose (n + k) k) * coeff f (n + k))) n = 0

Next tactic:
intro h
theorem hasseDeriv_coeff (n : ℕ) :
    (hasseDeriv k f).coeff n = (n + k).choose k * f.coeff (n + k) := by
  rw [hasseDeriv_apply, coeff_sum, sum_def, Finset.sum_eq_single (n + k), coeff_monomial]
  · simp only [if_true, add_tsub_cancel_right, eq_self_iff_true]
  · intro i _hi hink
    rw [coeff_monomial]
    by_cases hik : i < k
    · simp only [Nat.choose_eq_zero_of_lt hik, ite_self, Nat.cast_zero, zero_mul]
    · push_neg at hik
      rw [if_neg]
      contrapose! hink
      exact (tsub_eq_iff_eq_add_of_le hik).mp hink
  · intro h
    

Proof state:
case h₁
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
h : n + k ∉ support f
⊢ coeff ((monomial (n + k - k)) (↑(choose (n + k) k) * coeff f (n + k))) n = 0

Next tactic:
simp only [not_mem_support_iff.mp h, monomial_zero_right, mul_zero, coeff_zero]
theorem hasseDeriv_zero' : hasseDeriv 0 f = f := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
⊢ (hasseDeriv 0) f = f

Next tactic:
simp only [hasseDeriv_apply, tsub_zero, Nat.choose_zero_right, Nat.cast_one, one_mul,
    sum_monomial_eq]
theorem hasseDeriv_eq_zero_of_lt_natDegree (p : R[X]) (n : ℕ) (h : p.natDegree < n) :
    hasseDeriv n p = 0 := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f p : R[X]
n : ℕ
h : natDegree p < n
⊢ (hasseDeriv n) p = 0

Next tactic:
rw [hasseDeriv_apply, sum_def]
theorem hasseDeriv_eq_zero_of_lt_natDegree (p : R[X]) (n : ℕ) (h : p.natDegree < n) :
    hasseDeriv n p = 0 := by
  rw [hasseDeriv_apply, sum_def]
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f p : R[X]
n : ℕ
h : natDegree p < n
⊢ ∑ n_1 in support p, (monomial (n_1 - n)) (↑(choose n_1 n) * coeff p n_1) = 0

Next tactic:
refine' Finset.sum_eq_zero fun x hx => _
theorem hasseDeriv_eq_zero_of_lt_natDegree (p : R[X]) (n : ℕ) (h : p.natDegree < n) :
    hasseDeriv n p = 0 := by
  rw [hasseDeriv_apply, sum_def]
  refine' Finset.sum_eq_zero fun x hx => _
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f p : R[X]
n : ℕ
h : natDegree p < n
x : ℕ
hx : x ∈ support p
⊢ (monomial (x - n)) (↑(choose x n) * coeff p x) = 0

Next tactic:
simp [Nat.choose_eq_zero_of_lt ((le_natDegree_of_mem_supp _ hx).trans_lt h)]
theorem hasseDeriv_one' : hasseDeriv 1 f = derivative f := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
⊢ (hasseDeriv 1) f = derivative f

Next tactic:
simp only [hasseDeriv_apply, derivative_apply, ← C_mul_X_pow_eq_monomial, Nat.choose_one_right,
    (Nat.cast_commute _ _).eq]
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
⊢ (hasseDeriv k) ((monomial n) r) = (monomial (n - k)) (↑(choose n k) * r)

Next tactic:
ext i
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  

Proof state:
case a
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
⊢ coeff ((hasseDeriv k) ((monomial n) r)) i = coeff ((monomial (n - k)) (↑(choose n k) * r)) i

Next tactic:
simp only [hasseDeriv_coeff, coeff_monomial]
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  

Proof state:
case a
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
⊢ (↑(choose (i + k) k) * if n = i + k then r else 0) = if n - k = i then ↑(choose n k) * r else 0

Next tactic:
by_cases hnik : n = i + k
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  by_cases hnik : n = i + k
  · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
hnik : n = i + k
⊢ (↑(choose (i + k) k) * if n = i + k then r else 0) = if n - k = i then ↑(choose n k) * r else 0

Next tactic:
rw [if_pos hnik, if_pos, ← hnik]
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  by_cases hnik : n = i + k
  · rw [if_pos hnik, if_pos, ← hnik]
    

Proof state:
case pos.hc
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
hnik : n = i + k
⊢ n - k = i

Next tactic:
apply tsub_eq_of_eq_add_rev
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  by_cases hnik : n = i + k
  · rw [if_pos hnik, if_pos, ← hnik]
    apply tsub_eq_of_eq_add_rev
    

Proof state:
case pos.hc.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
hnik : n = i + k
⊢ n = k + i

Next tactic:
rwa [add_comm]
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  by_cases hnik : n = i + k
  · rw [if_pos hnik, if_pos, ← hnik]
    apply tsub_eq_of_eq_add_rev
    rwa [add_comm]
  · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
hnik : ¬n = i + k
⊢ (↑(choose (i + k) k) * if n = i + k then r else 0) = if n - k = i then ↑(choose n k) * r else 0

Next tactic:
rw [if_neg hnik, mul_zero]
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  by_cases hnik : n = i + k
  · rw [if_pos hnik, if_pos, ← hnik]
    apply tsub_eq_of_eq_add_rev
    rwa [add_comm]
  · rw [if_neg hnik, mul_zero]
    

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
hnik : ¬n = i + k
⊢ 0 = if n - k = i then ↑(choose n k) * r else 0

Next tactic:
by_cases hkn : k ≤ n
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  by_cases hnik : n = i + k
  · rw [if_pos hnik, if_pos, ← hnik]
    apply tsub_eq_of_eq_add_rev
    rwa [add_comm]
  · rw [if_neg hnik, mul_zero]
    by_cases hkn : k ≤ n
    · 

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
hnik : ¬n = i + k
hkn : k ≤ n
⊢ 0 = if n - k = i then ↑(choose n k) * r else 0

Next tactic:
rw [← tsub_eq_iff_eq_add_of_le hkn] at hnik
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  by_cases hnik : n = i + k
  · rw [if_pos hnik, if_pos, ← hnik]
    apply tsub_eq_of_eq_add_rev
    rwa [add_comm]
  · rw [if_neg hnik, mul_zero]
    by_cases hkn : k ≤ n
    · rw [← tsub_eq_iff_eq_add_of_le hkn] at hnik
      

Proof state:
case pos
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
hnik : ¬n - k = i
hkn : k ≤ n
⊢ 0 = if n - k = i then ↑(choose n k) * r else 0

Next tactic:
rw [if_neg hnik]
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  by_cases hnik : n = i + k
  · rw [if_pos hnik, if_pos, ← hnik]
    apply tsub_eq_of_eq_add_rev
    rwa [add_comm]
  · rw [if_neg hnik, mul_zero]
    by_cases hkn : k ≤ n
    · rw [← tsub_eq_iff_eq_add_of_le hkn] at hnik
      rw [if_neg hnik]
    · 

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
hnik : ¬n = i + k
hkn : ¬k ≤ n
⊢ 0 = if n - k = i then ↑(choose n k) * r else 0

Next tactic:
push_neg at hkn
@[simp]
theorem hasseDeriv_monomial (n : ℕ) (r : R) :
    hasseDeriv k (monomial n r) = monomial (n - k) (↑(n.choose k) * r) := by
  ext i
  simp only [hasseDeriv_coeff, coeff_monomial]
  by_cases hnik : n = i + k
  · rw [if_pos hnik, if_pos, ← hnik]
    apply tsub_eq_of_eq_add_rev
    rwa [add_comm]
  · rw [if_neg hnik, mul_zero]
    by_cases hkn : k ≤ n
    · rw [← tsub_eq_iff_eq_add_of_le hkn] at hnik
      rw [if_neg hnik]
    · push_neg at hkn
      

Proof state:
case neg
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
n : ℕ
r : R
i : ℕ
hnik : ¬n = i + k
hkn : n < k
⊢ 0 = if n - k = i then ↑(choose n k) * r else 0

Next tactic:
rw [Nat.choose_eq_zero_of_lt hkn, Nat.cast_zero, zero_mul, ite_self]
theorem hasseDeriv_C (r : R) (hk : 0 < k) : hasseDeriv k (C r) = 0 := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
r : R
hk : 0 < k
⊢ (hasseDeriv k) (C r) = 0

Next tactic:
rw [← monomial_zero_left, hasseDeriv_monomial, Nat.choose_eq_zero_of_lt hk, Nat.cast_zero,
    zero_mul, monomial_zero_right]
theorem hasseDeriv_apply_one (hk : 0 < k) : hasseDeriv k (1 : R[X]) = 0 := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
hk : 0 < k
⊢ (hasseDeriv k) 1 = 0

Next tactic:
rw [← C_1, hasseDeriv_C k _ hk]
theorem hasseDeriv_X (hk : 1 < k) : hasseDeriv k (X : R[X]) = 0 := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
hk : 1 < k
⊢ (hasseDeriv k) X = 0

Next tactic:
rw [← monomial_one_one_eq_X, hasseDeriv_monomial, Nat.choose_eq_zero_of_lt hk, Nat.cast_zero,
    zero_mul, monomial_zero_right]
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  

Proof state:
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
⊢ ⇑(k ! • hasseDeriv k) = (⇑derivative)^[k]

Next tactic:
induction' k with k ih
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  induction' k with k ih
  · 

Proof state:
case zero
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
⊢ ⇑(Nat.zero ! • hasseDeriv Nat.zero) = (⇑derivative)^[Nat.zero]

Next tactic:
rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe]
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  induction' k with k ih
  · rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe]
  

Proof state:
case succ
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k : ℕ
ih : ⇑(k ! • hasseDeriv k) = (⇑derivative)^[k]
⊢ ⇑((succ k)! • hasseDeriv (succ k)) = (⇑derivative)^[succ k]

Next tactic:
ext f n : 2
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  induction' k with k ih
  · rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe]
  ext f n : 2
  

Proof state:
case succ.h.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f✝ : R[X]
k : ℕ
ih : ⇑(k ! • hasseDeriv k) = (⇑derivative)^[k]
f : R[X]
n : ℕ
⊢ coeff (((succ k)! • hasseDeriv (succ k)) f) n = coeff ((⇑derivative)^[succ k] f) n

Next tactic:
rw [iterate_succ_apply', ← ih]
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  induction' k with k ih
  · rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe]
  ext f n : 2
  rw [iterate_succ_apply', ← ih]
  

Proof state:
case succ.h.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f✝ : R[X]
k : ℕ
ih : ⇑(k ! • hasseDeriv k) = (⇑derivative)^[k]
f : R[X]
n : ℕ
⊢ coeff (((succ k)! • hasseDeriv (succ k)) f) n = coeff (derivative ((k ! • hasseDeriv k) f)) n

Next tactic:
simp only [LinearMap.smul_apply, coeff_smul, LinearMap.map_smul_of_tower, coeff_derivative,
    hasseDeriv_coeff, ← @choose_symm_add _ k]
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  induction' k with k ih
  · rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe]
  ext f n : 2
  rw [iterate_succ_apply', ← ih]
  simp only [LinearMap.smul_apply, coeff_smul, LinearMap.map_smul_of_tower, coeff_derivative,
    hasseDeriv_coeff, ← @choose_symm_add _ k]
  

Proof state:
case succ.h.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f✝ : R[X]
k : ℕ
ih : ⇑(k ! • hasseDeriv k) = (⇑derivative)^[k]
f : R[X]
n : ℕ
⊢ (succ k)! • (↑(choose (n + succ k) (succ k)) * coeff f (n + succ k)) =
    k ! • (↑(choose (n + 1 + k) (n + 1)) * coeff f (n + 1 + k) * (↑n + 1))

Next tactic:
simp only [nsmul_eq_mul, factorial_succ, mul_assoc, succ_eq_add_one, ← add_assoc,
    add_right_comm n 1 k, ← cast_succ]
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  induction' k with k ih
  · rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe]
  ext f n : 2
  rw [iterate_succ_apply', ← ih]
  simp only [LinearMap.smul_apply, coeff_smul, LinearMap.map_smul_of_tower, coeff_derivative,
    hasseDeriv_coeff, ← @choose_symm_add _ k]
  simp only [nsmul_eq_mul, factorial_succ, mul_assoc, succ_eq_add_one, ← add_assoc,
    add_right_comm n 1 k, ← cast_succ]
  

Proof state:
case succ.h.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f✝ : R[X]
k : ℕ
ih : ⇑(k ! • hasseDeriv k) = (⇑derivative)^[k]
f : R[X]
n : ℕ
⊢ ↑((k + 1) * k !) * (↑(choose (n + k + 1) (k + 1)) * coeff f (n + k + 1)) =
    ↑k ! * (↑(choose (n + k + 1) (n + 1)) * (coeff f (n + k + 1) * ↑(n + 1)))

Next tactic:
rw [← (cast_commute (n + 1) (f.coeff (n + k + 1))).eq]
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  induction' k with k ih
  · rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe]
  ext f n : 2
  rw [iterate_succ_apply', ← ih]
  simp only [LinearMap.smul_apply, coeff_smul, LinearMap.map_smul_of_tower, coeff_derivative,
    hasseDeriv_coeff, ← @choose_symm_add _ k]
  simp only [nsmul_eq_mul, factorial_succ, mul_assoc, succ_eq_add_one, ← add_assoc,
    add_right_comm n 1 k, ← cast_succ]
  rw [← (cast_commute (n + 1) (f.coeff (n + k + 1))).eq]
  

Proof state:
case succ.h.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f✝ : R[X]
k : ℕ
ih : ⇑(k ! • hasseDeriv k) = (⇑derivative)^[k]
f : R[X]
n : ℕ
⊢ ↑((k + 1) * k !) * (↑(choose (n + k + 1) (k + 1)) * coeff f (n + k + 1)) =
    ↑k ! * (↑(choose (n + k + 1) (n + 1)) * (↑(n + 1) * coeff f (n + k + 1)))

Next tactic:
simp only [← mul_assoc]
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  induction' k with k ih
  · rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe]
  ext f n : 2
  rw [iterate_succ_apply', ← ih]
  simp only [LinearMap.smul_apply, coeff_smul, LinearMap.map_smul_of_tower, coeff_derivative,
    hasseDeriv_coeff, ← @choose_symm_add _ k]
  simp only [nsmul_eq_mul, factorial_succ, mul_assoc, succ_eq_add_one, ← add_assoc,
    add_right_comm n 1 k, ← cast_succ]
  rw [← (cast_commute (n + 1) (f.coeff (n + k + 1))).eq]
  simp only [← mul_assoc]
  

Proof state:
case succ.h.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f✝ : R[X]
k : ℕ
ih : ⇑(k ! • hasseDeriv k) = (⇑derivative)^[k]
f : R[X]
n : ℕ
⊢ ↑((k + 1) * k !) * ↑(choose (n + k + 1) (k + 1)) * coeff f (n + k + 1) =
    ↑k ! * ↑(choose (n + k + 1) (n + 1)) * ↑(n + 1) * coeff f (n + k + 1)

Next tactic:
norm_cast
theorem factorial_smul_hasseDeriv : ⇑(k ! • @hasseDeriv R _ k) = (@derivative R _)^[k] := by
  induction' k with k ih
  · rw [hasseDeriv_zero, factorial_zero, iterate_zero, one_smul, LinearMap.id_coe]
  ext f n : 2
  rw [iterate_succ_apply', ← ih]
  simp only [LinearMap.smul_apply, coeff_smul, LinearMap.map_smul_of_tower, coeff_derivative,
    hasseDeriv_coeff, ← @choose_symm_add _ k]
  simp only [nsmul_eq_mul, factorial_succ, mul_assoc, succ_eq_add_one, ← add_assoc,
    add_right_comm n 1 k, ← cast_succ]
  rw [← (cast_commute (n + 1) (f.coeff (n + k + 1))).eq]
  simp only [← mul_assoc]
  norm_cast
  

Proof state:
case succ.h.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f✝ : R[X]
k : ℕ
ih : ⇑(k ! • hasseDeriv k) = (⇑derivative)^[k]
f : R[X]
n : ℕ
⊢ ↑((k + 1) * k ! * choose (n + k + 1) (k + 1)) * coeff f (n + k + 1) =
    ↑(k ! * choose (n + k + 1) (n + 1) * (n + 1)) * coeff f (n + k + 1)

Next tactic:
congr 2