Theorem: Polynomial.hasseDeriv_mul
File: Mathlib/Algebra/Polynomial/HasseDeriv.lean

Proof steps:
state_before: R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
⊢ (hasseDeriv k) (f * g) = ∑ ij ∈ antidiagonal k, (hasseDeriv ij.1) f * (hasseDeriv ij.2) g
state_after: R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
⊢ (hasseDeriv k) (f * g) = ∑ ij ∈ antidiagonal k, (hasseDeriv ij.1) f * (hasseDeriv ij.2) g
tactic: let D k := (@hasseDeriv R _ k).toAddMonoidHom
state_before: R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
⊢ (hasseDeriv k) (f * g) = ∑ ij ∈ antidiagonal k, (hasseDeriv ij.1) f * (hasseDeriv ij.2) g
state_after: R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (hasseDeriv k) (f * g) = ∑ ij ∈ antidiagonal k, (hasseDeriv ij.1) f * (hasseDeriv ij.2) g
tactic: let Φ := @AddMonoidHom.mul R[X] _
state_before: R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (hasseDeriv k) (f * g) = ∑ ij ∈ antidiagonal k, (hasseDeriv ij.1) f * (hasseDeriv ij.2) g
state_after: R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (((compHom (D k)).comp Φ) f) g = ∑ ij ∈ antidiagonal k, (((compHom.comp ((compHom Φ) (D ij.1))).flip (D ij.2)) f) g
tactic: show
    (compHom (D k)).comp Φ f g =
      ∑ ij ∈ antidiagonal k, ((compHom.comp ((compHom Φ) (D ij.1))).flip (D ij.2) f) g
state_before: R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (((compHom (D k)).comp Φ) f) g = ∑ ij ∈ antidiagonal k, (((compHom.comp ((compHom Φ) (D ij.1))).flip (D ij.2)) f) g
state_after: R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (((compHom (D k)).comp Φ) f) g = ((∑ x ∈ antidiagonal k, (compHom.comp ((compHom Φ) (D x.1))).flip (D x.2)) f) g
tactic: simp only [← finset_sum_apply]
state_before: R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (((compHom (D k)).comp Φ) f) g = ((∑ x ∈ antidiagonal k, (compHom.comp ((compHom Φ) (D x.1))).flip (D x.2)) f) g
state_after: case e_a.e_a
R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (compHom (D k)).comp Φ = ∑ x ∈ antidiagonal k, (compHom.comp ((compHom Φ) (D x.1))).flip (D x.2)
tactic: congr 2
state_before: case e_a.e_a
R : Type u_1
inst✝ : Semiring R
k : ℕ
f✝ f g : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (compHom (D k)).comp Φ = ∑ x ∈ antidiagonal k, (compHom.comp ((compHom Φ) (D x.1))).flip (D x.2)
state_after: case e_a.e_a
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (compHom (D k)).comp Φ = ∑ x ∈ antidiagonal k, (compHom.comp ((compHom Φ) (D x.1))).flip (D x.2)
tactic: clear f g
state_before: case e_a.e_a
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
⊢ (compHom (D k)).comp Φ = ∑ x ∈ antidiagonal k, (compHom.comp ((compHom Φ) (D x.1))).flip (D x.2)
state_after: case e_a.e_a.h.h.h.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
⊢ (((((compHom (D k)).comp Φ).comp (monomial m).toAddMonoidHom) r).comp (monomial n).toAddMonoidHom) s =
    ((((∑ x ∈ antidiagonal k, (compHom.comp ((compHom Φ) (D x.1))).flip (D x.2)).comp (monomial m).toAddMonoidHom)
            r).comp
        (monomial n).toAddMonoidHom)
      s
tactic: ext m r n s : 4
state_before: case e_a.e_a.h.h.h.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
⊢ (((((compHom (D k)).comp Φ).comp (monomial m).toAddMonoidHom) r).comp (monomial n).toAddMonoidHom) s =
    ((((∑ x ∈ antidiagonal k, (compHom.comp ((compHom Φ) (D x.1))).flip (D x.2)).comp (monomial m).toAddMonoidHom)
            r).comp
        (monomial n).toAddMonoidHom)
      s
state_after: case e_a.e_a.h.h.h.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
⊢ (monomial (m + n - k)) (↑((m + n).choose k) * (r * s)) =
    ∑ x ∈ antidiagonal k, (monomial (m - x.1 + (n - x.2))) (↑(m.choose x.1) * r * (↑(n.choose x.2) * s))
tactic: simp only [Φ, D, finset_sum_apply, coe_mulLeft, coe_comp, flip_apply, Function.comp_apply,
             hasseDeriv_monomial, LinearMap.toAddMonoidHom_coe, compHom_apply_apply,
             coe_mul, monomial_mul_monomial]
state_before: case e_a.e_a.h.h.h.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
aux :
  ∀ x ∈ antidiagonal k,
    (monomial (m - x.1 + (n - x.2))) (↑(m.choose x.1) * r * (↑(n.choose x.2) * s)) =
      (monomial (m + n - k)) (↑(m.choose x.1) * ↑(n.choose x.2) * (r * s))
⊢ (monomial (m + n - k)) (↑((m + n).choose k) * (r * s)) =
    ∑ x ∈ antidiagonal k, (monomial (m - x.1 + (n - x.2))) (↑(m.choose x.1) * r * (↑(n.choose x.2) * s))
state_after: case e_a.e_a.h.h.h.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
aux :
  ∀ x ∈ antidiagonal k,
    (monomial (m - x.1 + (n - x.2))) (↑(m.choose x.1) * r * (↑(n.choose x.2) * s)) =
      (monomial (m + n - k)) (↑(m.choose x.1) * ↑(n.choose x.2) * (r * s))
⊢ (monomial (m + n - k)) (↑((m + n).choose k) * (r * s)) =
    ∑ x ∈ antidiagonal k, (monomial (m + n - k)) (↑(m.choose x.1) * ↑(n.choose x.2) * (r * s))
tactic: rw [Finset.sum_congr rfl aux]
state_before: case e_a.e_a.h.h.h.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
aux :
  ∀ x ∈ antidiagonal k,
    (monomial (m - x.1 + (n - x.2))) (↑(m.choose x.1) * r * (↑(n.choose x.2) * s)) =
      (monomial (m + n - k)) (↑(m.choose x.1) * ↑(n.choose x.2) * (r * s))
⊢ (monomial (m + n - k)) (↑((m + n).choose k) * (r * s)) =
    ∑ x ∈ antidiagonal k, (monomial (m + n - k)) (↑(m.choose x.1) * ↑(n.choose x.2) * (r * s))
state_after: case e_a.e_a.h.h.h.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
aux :
  ∀ x ∈ antidiagonal k,
    (monomial (m - x.1 + (n - x.2))) (↑(m.choose x.1) * r * (↑(n.choose x.2) * s)) =
      (monomial (m + n - k)) (↑(m.choose x.1) * ↑(n.choose x.2) * (r * s))
⊢ (monomial (m + n - k)) (↑((m + n).choose k) * (r * s)) =
    (monomial (m + n - k)) ((∑ i ∈ antidiagonal k, ↑(m.choose i.1) * ↑(n.choose i.2)) * (r * s))
tactic: rw [← map_sum, ← Finset.sum_mul]
state_before: case e_a.e_a.h.h.h.h
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
aux :
  ∀ x ∈ antidiagonal k,
    (monomial (m - x.1 + (n - x.2))) (↑(m.choose x.1) * r * (↑(n.choose x.2) * s)) =
      (monomial (m + n - k)) (↑(m.choose x.1) * ↑(n.choose x.2) * (r * s))
⊢ (monomial (m + n - k)) (↑((m + n).choose k) * (r * s)) =
    (monomial (m + n - k)) ((∑ i ∈ antidiagonal k, ↑(m.choose i.1) * ↑(n.choose i.2)) * (r * s))
state_after: case e_a.e_a.h.h.h.h.h.e_6.h.e_a
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
aux :
  ∀ x ∈ antidiagonal k,
    (monomial (m - x.1 + (n - x.2))) (↑(m.choose x.1) * r * (↑(n.choose x.2) * s)) =
      (monomial (m + n - k)) (↑(m.choose x.1) * ↑(n.choose x.2) * (r * s))
⊢ ↑((m + n).choose k) = ∑ i ∈ antidiagonal k, ↑(m.choose i.1) * ↑(n.choose i.2)
tactic: congr
state_before: case e_a.e_a.h.h.h.h.h.e_6.h.e_a
R : Type u_1
inst✝ : Semiring R
k : ℕ
f : R[X]
D : ℕ → R[X] →+ R[X] := fun k => (hasseDeriv k).toAddMonoidHom
Φ : R[X] →+ R[X] →+ R[X] := mul
m : ℕ
r : R
n : ℕ
s : R
aux :
  ∀ x ∈ antidiagonal k,
    (monomial (m - x.1 + (n - x.2))) (↑(m.choose x.1) * r * (↑(n.choose x.2) * s)) =
      (monomial (m + n - k)) (↑(m.choose x.1) * ↑(n.choose x.2) * (r * s))
⊢ ↑((m + n).choose k) = ∑ i ∈ antidiagonal k, ↑(m.choose i.1) * ↑(n.choose i.2)
state_after: no goals
tactic: rw_mod_cast [← Nat.add_choose_eq]