Theorem: bernsteinPolynomial.sum_mul_smul
File: Mathlib/RingTheory/Polynomial/Bernstein.lean

tactic: let x : MvPolynomial Bool R := MvPolynomial.X true
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
⊢ ∑ ν in Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν = (n * (n - 1)) • X ^ 2

tactic: let y : MvPolynomial Bool R := MvPolynomial.X false
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
⊢ ∑ ν in Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν = (n * (n - 1)) • X ^ 2

tactic: have pderiv_true_x : pderiv true x = 1 := by rw [pderiv_X]; rfl
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
⊢ ∑ ν in Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν = (n * (n - 1)) • X ^ 2

tactic: have pderiv_true_y : pderiv true y = 0 := by rw [pderiv_X]; rfl
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
⊢ ∑ ν in Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν = (n * (n - 1)) • X ^ 2

tactic: let e : Bool → R[X] := fun i => cond i X (1 - X)
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
⊢ ∑ ν in Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν = (n * (n - 1)) • X ^ 2

tactic: trans MvPolynomial.aeval e (pderiv true (pderiv true ((x + y) ^ n))) * X ^ 2
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
⊢ ∑ ν in Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν = (n * (n - 1)) • X ^ 2

tactic: rw [pderiv_X]
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
⊢ ↑(pderiv true) x = 1

tactic: rfl
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
⊢ Pi.single true 1 true = 1

tactic: rw [pderiv_X]
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
⊢ ↑(pderiv true) y = 0

tactic: rfl
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
⊢ Pi.single true 1 false = 0

tactic: rw [add_pow, (pderiv true).map_sum, (pderiv true).map_sum, (MvPolynomial.aeval e).map_sum,
  Finset.sum_mul]
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
w :
  ∀ (k : ℕ),
    (k * (k - 1)) • bernsteinPolynomial R n k =
      ↑(choose n k) * ((1 - X) ^ (n - k) * (↑k * (↑(k - 1) * X ^ (k - 1 - 1)))) * X ^ 2
⊢ ∑ ν in Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν =
    ↑(MvPolynomial.aeval e) (↑(pderiv true) (↑(pderiv true) ((x + y) ^ n))) * X ^ 2

tactic: refine' Finset.sum_congr rfl fun k _ => (w k).trans _
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
w :
  ∀ (k : ℕ),
    (k * (k - 1)) • bernsteinPolynomial R n k =
      ↑(choose n k) * ((1 - X) ^ (n - k) * (↑k * (↑(k - 1) * X ^ (k - 1 - 1)))) * X ^ 2
⊢ ∑ ν in Finset.range (n + 1), (ν * (ν - 1)) • bernsteinPolynomial R n ν =
    ∑ x_1 in Finset.range (n + 1),
      ↑(MvPolynomial.aeval e) (↑(pderiv true) (↑(pderiv true) (x ^ x_1 * y ^ (n - x_1) * ↑(choose n x_1)))) * X ^ 2

tactic: simp only [pderiv_true_x, pderiv_true_y, Algebra.id.smul_eq_mul, nsmul_eq_mul, Bool.cond_true,
  Bool.cond_false, add_zero, zero_add, MulZeroClass.mul_zero, smul_zero, mul_one,
  MvPolynomial.aeval_X, MvPolynomial.pderiv_X_self, MvPolynomial.pderiv_X_of_ne,
  Derivation.leibniz_pow, Derivation.leibniz, Derivation.map_coe_nat, map_natCast, map_pow,
  map_mul, map_add]
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
w :
  ∀ (k : ℕ),
    (k * (k - 1)) • bernsteinPolynomial R n k =
      ↑(choose n k) * ((1 - X) ^ (n - k) * (↑k * (↑(k - 1) * X ^ (k - 1 - 1)))) * X ^ 2
k : ℕ
x✝ : k ∈ Finset.range (n + 1)
⊢ ↑(choose n k) * ((1 - X) ^ (n - k) * (↑k * (↑(k - 1) * X ^ (k - 1 - 1)))) * X ^ 2 =
    ↑(MvPolynomial.aeval e) (↑(pderiv true) (↑(pderiv true) (x ^ k * y ^ (n - k) * ↑(choose n k)))) * X ^ 2

tactic: rintro (_ | _ | k)
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
⊢ ∀ (k : ℕ),
    (k * (k - 1)) • bernsteinPolynomial R n k =
      ↑(choose n k) * ((1 - X) ^ (n - k) * (↑k * (↑(k - 1) * X ^ (k - 1 - 1)))) * X ^ 2

tactic: simp
state_before: case zero
R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
⊢ (Nat.zero * (Nat.zero - 1)) • bernsteinPolynomial R n Nat.zero =
    ↑(choose n Nat.zero) * ((1 - X) ^ (n - Nat.zero) * (↑Nat.zero * (↑(Nat.zero - 1) * X ^ (Nat.zero - 1 - 1)))) * X ^ 2

tactic: simp
state_before: case succ.zero
R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
⊢ (Nat.succ Nat.zero * (Nat.succ Nat.zero - 1)) • bernsteinPolynomial R n (Nat.succ Nat.zero) =
    ↑(choose n (Nat.succ Nat.zero)) *
        ((1 - X) ^ (n - Nat.succ Nat.zero) *
          (↑(Nat.succ Nat.zero) * (↑(Nat.succ Nat.zero - 1) * X ^ (Nat.succ Nat.zero - 1 - 1)))) *
      X ^ 2

tactic: rw [bernsteinPolynomial]
state_before: case succ.succ
R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
k : ℕ
⊢ (Nat.succ (Nat.succ k) * (Nat.succ (Nat.succ k) - 1)) • bernsteinPolynomial R n (Nat.succ (Nat.succ k)) =
    ↑(choose n (Nat.succ (Nat.succ k))) *
        ((1 - X) ^ (n - Nat.succ (Nat.succ k)) *
          (↑(Nat.succ (Nat.succ k)) * (↑(Nat.succ (Nat.succ k) - 1) * X ^ (Nat.succ (Nat.succ k) - 1 - 1)))) *
      X ^ 2

tactic: simp only [← nat_cast_mul, Nat.succ_eq_add_one, Nat.add_succ_sub_one, add_zero, pow_succ]
state_before: case succ.succ
R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
k : ℕ
⊢ (Nat.succ (Nat.succ k) * (Nat.succ (Nat.succ k) - 1)) •
      (↑(choose n (Nat.succ (Nat.succ k))) * X ^ Nat.succ (Nat.succ k) * (1 - X) ^ (n - Nat.succ (Nat.succ k))) =
    ↑(choose n (Nat.succ (Nat.succ k))) *
        ((1 - X) ^ (n - Nat.succ (Nat.succ k)) *
          (↑(Nat.succ (Nat.succ k)) * (↑(Nat.succ (Nat.succ k) - 1) * X ^ (Nat.succ (Nat.succ k) - 1 - 1)))) *
      X ^ 2

tactic: push_cast
state_before: case succ.succ
R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
k : ℕ
⊢ ↑((k + 1 + 1) * (k + 1)) * (↑(choose n (k + 1 + 1)) * (X * (X * X ^ k)) * (1 - X) ^ (n - (k + 1 + 1))) =
    ↑(choose n (k + 1 + 1)) * ((1 - X) ^ (n - (k + 1 + 1)) * (↑(k + 1 + 1) * (↑(k + 1) * X ^ k))) * (X * (X * X ^ 0))

tactic: ring
state_before: case succ.succ
R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
k : ℕ
⊢ (↑k + 1 + 1) * (↑k + 1) * (↑(choose n (k + 1 + 1)) * (X * (X * X ^ k)) * (1 - X) ^ (n - (k + 1 + 1))) =
    ↑(choose n (k + 1 + 1)) * ((1 - X) ^ (n - (k + 1 + 1)) * ((↑k + 1 + 1) * ((↑k + 1) * X ^ k))) * (X * (X * X ^ 0))

tactic: simp only [pderiv_one, pderiv_mul, (pderiv _).leibniz_pow, (pderiv _).map_coe_nat,
  (pderiv true).map_add, pderiv_true_x, pderiv_true_y, Algebra.id.smul_eq_mul, add_zero,
  mul_one, Derivation.map_smul_of_tower, map_nsmul, map_pow, map_add, Bool.cond_true,
  Bool.cond_false, MvPolynomial.aeval_X, add_sub_cancel'_right, one_pow, smul_smul,
  smul_one_mul]
state_before: R : Type u_1
inst✝ : CommRing R
n : ℕ
x : MvPolynomial Bool R := MvPolynomial.X true
y : MvPolynomial Bool R := MvPolynomial.X false
pderiv_true_x : ↑(pderiv true) x = 1
pderiv_true_y : ↑(pderiv true) y = 0
e : Bool → R[X] := fun i => bif i then X else 1 - X
⊢ ↑(MvPolynomial.aeval e) (↑(pderiv true) (↑(pderiv true) ((x + y) ^ n))) * X ^ 2 = (n * (n - 1)) • X ^ 2