Theorem: Polynomial.hasseDeriv_comp
File: Mathlib/Data/Polynomial/HasseDeriv.lean

tactic: ext i : 2
state_before: R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l : ℕ
⊢ LinearMap.comp (hasseDeriv k) (hasseDeriv l) = choose (k + l) k • hasseDeriv (k + l)

tactic: simp only [LinearMap.smul_apply, comp_apply, LinearMap.coe_comp, smul_monomial, hasseDeriv_apply,
  mul_one, monomial_eq_zero_iff, sum_monomial_index, mul_zero, ←
  tsub_add_eq_tsub_tsub, add_comm l k]
state_before: case h.h
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
⊢ ↑(LinearMap.comp (LinearMap.comp (hasseDeriv k) (hasseDeriv l)) (monomial i)) 1 =
    ↑(LinearMap.comp (choose (k + l) k • hasseDeriv (k + l)) (monomial i)) 1

tactic: rw_mod_cast [nsmul_eq_mul]
state_before: case h.h
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
⊢ ↑(monomial (i - (k + l))) (↑(choose (i - l) k) * ↑(choose i l)) =
    ↑(monomial (i - (k + l))) (choose (k + l) k • ↑(choose i (k + l)))

tactic: rw [←Nat.cast_mul]
state_before: case h.h
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
⊢ ↑(monomial (i - (k + l))) ↑(choose (i - l) k * choose i l) =
    ↑(monomial (i - (k + l))) (↑(choose (k + l) k) * ↑(choose i (k + l)))

tactic: congr 2
state_before: case h.h
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
⊢ ↑(monomial (i - (k + l))) ↑(choose (i - l) k * choose i l) =
    ↑(monomial (i - (k + l))) ↑(choose (k + l) k * choose i (k + l))

tactic: by_cases hikl : i < k + l
state_before: case h.h.h.e_6.h.e_a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
⊢ choose (i - l) k * choose i l = choose (k + l) k * choose i (k + l)

tactic: push_neg at hikl
state_before: case neg
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : ¬i < k + l
⊢ choose (i - l) k * choose i l = choose (k + l) k * choose i (k + l)

tactic: apply @cast_injective ℚ
state_before: case neg
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
⊢ choose (i - l) k * choose i l = choose (k + l) k * choose i (k + l)

tactic: have h1 : l ≤ i := le_of_add_le_right hikl
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
⊢ ↑(choose (i - l) k * choose i l) = ↑(choose (k + l) k * choose i (k + l))

tactic: have h2 : k ≤ i - l := le_tsub_of_add_le_right hikl
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
⊢ ↑(choose (i - l) k * choose i l) = ↑(choose (k + l) k * choose i (k + l))

tactic: have h3 : k ≤ k + l := le_self_add
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
⊢ ↑(choose (i - l) k * choose i l) = ↑(choose (k + l) k * choose i (k + l))

tactic: push_cast
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
⊢ ↑(choose (i - l) k * choose i l) = ↑(choose (k + l) k * choose i (k + l))

tactic: rw [cast_choose ℚ h1, cast_choose ℚ h2, cast_choose ℚ h3, cast_choose ℚ hikl]
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
⊢ ↑(choose (i - l) k) * ↑(choose i l) = ↑(choose (k + l) k) * ↑(choose i (k + l))

tactic: rw [show i - (k + l) = i - l - k by rw [add_comm]; apply tsub_add_eq_tsub_tsub]
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
⊢ ↑(i - l)! / (↑k ! * ↑(i - l - k)!) * (↑i ! / (↑l ! * ↑(i - l)!)) =
    ↑(k + l)! / (↑k ! * ↑(k + l - k)!) * (↑i ! / (↑(k + l)! * ↑(i - (k + l))!))

tactic: simp only [add_tsub_cancel_left]
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
⊢ ↑(i - l)! / (↑k ! * ↑(i - l - k)!) * (↑i ! / (↑l ! * ↑(i - l)!)) =
    ↑(k + l)! / (↑k ! * ↑(k + l - k)!) * (↑i ! / (↑(k + l)! * ↑(i - l - k)!))

tactic: have H : ∀ n : ℕ, (n ! : ℚ) ≠ 0 := by exact_mod_cast factorial_ne_zero
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
⊢ ↑(i - l)! / (↑k ! * ↑(i - l - k)!) * (↑i ! / (↑l ! * ↑(i - l)!)) =
    ↑(k + l)! / (↑k ! * ↑l !) * (↑i ! / (↑(k + l)! * ↑(i - l - k)!))

tactic: field_simp [H]
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
H : ∀ (n : ℕ), ↑n ! ≠ 0
⊢ ↑(i - l)! / (↑k ! * ↑(i - l - k)!) * (↑i ! / (↑l ! * ↑(i - l)!)) =
    ↑(k + l)! / (↑k ! * ↑l !) * (↑i ! / (↑(k + l)! * ↑(i - l - k)!))

tactic: ring
state_before: case neg.a
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
H : ∀ (n : ℕ), ↑n ! ≠ 0
⊢ ↑(i - l)! * ↑i ! * (↑k ! * ↑l ! * (↑(k + l)! * ↑(i - l - k)!)) =
    ↑(k + l)! * ↑i ! * (↑k ! * ↑(i - l - k)! * (↑l ! * ↑(i - l)!))

tactic: rw [choose_eq_zero_of_lt hikl, mul_zero]
state_before: case pos
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : i < k + l
⊢ choose (i - l) k * choose i l = choose (k + l) k * choose i (k + l)

tactic: by_cases hil : i < l
state_before: case pos
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : i < k + l
⊢ choose (i - l) k * choose i l = 0

tactic: rw [choose_eq_zero_of_lt hil, mul_zero]
state_before: case pos
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : i < k + l
hil : i < l
⊢ choose (i - l) k * choose i l = 0

tactic: push_neg at hil
state_before: case neg
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : i < k + l
hil : ¬i < l
⊢ choose (i - l) k * choose i l = 0

tactic: rw [← tsub_lt_iff_right hil] at hikl
state_before: case neg
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : i < k + l
hil : l ≤ i
⊢ choose (i - l) k * choose i l = 0

tactic: rw [choose_eq_zero_of_lt hikl, zero_mul]
state_before: case neg
R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : i - l < k
hil : l ≤ i
⊢ choose (i - l) k * choose i l = 0

tactic: rw [add_comm]
state_before: R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
⊢ i - (k + l) = i - l - k

tactic: apply tsub_add_eq_tsub_tsub
state_before: R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
⊢ i - (l + k) = i - l - k

tactic: exact_mod_cast factorial_ne_zero
state_before: R : Type u_1
inst✝ : Semiring R
k✝ : ℕ
f : R[X]
k l i : ℕ
hikl : k + l ≤ i
h1 : l ≤ i
h2 : k ≤ i - l
h3 : k ≤ k + l
⊢ ∀ (n : ℕ), ↑n ! ≠ 0