Theorem: Polynomial.sum_range_pow_eq_bernoulli_sub
File: Mathlib/NumberTheory/BernoulliPolynomials.lean

tactic: rw [sum_range_pow, bernoulli_def, eval_finset_sum, ← sum_div, mul_div_cancel₀ _ _]
state_before: n p : ℕ
⊢ (↑p + 1) * ∑ k ∈ range n, ↑k ^ p = eval (↑n) (bernoulli p.succ) - _root_.bernoulli p.succ
state_after: n p : ℕ
⊢ ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i) =
    ∑ i ∈ range (p.succ + 1), eval (↑n) ((monomial i) (_root_.bernoulli (p.succ - i) * ↑(p.succ.choose i))) -
      _root_.bernoulli p.succ

n p : ℕ
⊢ ↑p + 1 ≠ 0

tactic: simp_rw [eval_monomial]
state_before: n p : ℕ
⊢ ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i) =
    ∑ i ∈ range (p.succ + 1), eval (↑n) ((monomial i) (_root_.bernoulli (p.succ - i) * ↑(p.succ.choose i))) -
      _root_.bernoulli p.succ
state_after: n p : ℕ
⊢ ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i) =
    ∑ x ∈ range (p.succ + 1), _root_.bernoulli (p.succ - x) * ↑(p.succ.choose x) * ↑n ^ x - _root_.bernoulli p.succ

tactic: symm
state_before: n p : ℕ
⊢ ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i) =
    ∑ x ∈ range (p.succ + 1), _root_.bernoulli (p.succ - x) * ↑(p.succ.choose x) * ↑n ^ x - _root_.bernoulli p.succ
state_after: n p : ℕ
⊢ ∑ x ∈ range (p.succ + 1), _root_.bernoulli (p.succ - x) * ↑(p.succ.choose x) * ↑n ^ x - _root_.bernoulli p.succ =
    ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i)

tactic: rw [← sum_flip _, sum_range_succ]
state_before: n p : ℕ
⊢ ∑ x ∈ range (p.succ + 1), _root_.bernoulli (p.succ - x) * ↑(p.succ.choose x) * ↑n ^ x - _root_.bernoulli p.succ =
    ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i)
state_after: n p : ℕ
⊢ ∑ x ∈ range (p + 1), _root_.bernoulli (p.succ - (p + 1 - x)) * ↑(p.succ.choose (p + 1 - x)) * ↑n ^ (p + 1 - x) +
        _root_.bernoulli (p.succ - (p + 1 - (p + 1))) * ↑(p.succ.choose (p + 1 - (p + 1))) * ↑n ^ (p + 1 - (p + 1)) -
      _root_.bernoulli p.succ =
    ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i)

tactic: simp only [tsub_self, tsub_zero, choose_zero_right, cast_one, mul_one, _root_.pow_zero,
  add_tsub_cancel_right]
state_before: n p : ℕ
⊢ ∑ x ∈ range (p + 1), _root_.bernoulli (p.succ - (p + 1 - x)) * ↑(p.succ.choose (p + 1 - x)) * ↑n ^ (p + 1 - x) +
        _root_.bernoulli (p.succ - (p + 1 - (p + 1))) * ↑(p.succ.choose (p + 1 - (p + 1))) * ↑n ^ (p + 1 - (p + 1)) -
      _root_.bernoulli p.succ =
    ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i)
state_after: n p : ℕ
⊢ ∑ x ∈ range (p + 1), _root_.bernoulli (p.succ - (p + 1 - x)) * ↑(p.succ.choose (p + 1 - x)) * ↑n ^ (p + 1 - x) =
    ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i)

tactic: apply sum_congr rfl fun x hx => _
state_before: n p : ℕ
⊢ ∑ x ∈ range (p + 1), _root_.bernoulli (p.succ - (p + 1 - x)) * ↑(p.succ.choose (p + 1 - x)) * ↑n ^ (p + 1 - x) =
    ∑ i ∈ range (p + 1), _root_.bernoulli i * ↑((p + 1).choose i) * ↑n ^ (p + 1 - i)
state_after: n p : ℕ
⊢ ∀ x ∈ range (p + 1),
    _root_.bernoulli (p.succ - (p + 1 - x)) * ↑(p.succ.choose (p + 1 - x)) * ↑n ^ (p + 1 - x) =
      _root_.bernoulli x * ↑((p + 1).choose x) * ↑n ^ (p + 1 - x)

tactic: intro x hx
state_before: n p : ℕ
⊢ ∀ x ∈ range (p + 1),
    _root_.bernoulli (p.succ - (p + 1 - x)) * ↑(p.succ.choose (p + 1 - x)) * ↑n ^ (p + 1 - x) =
      _root_.bernoulli x * ↑((p + 1).choose x) * ↑n ^ (p + 1 - x)
state_after: n p x : ℕ
hx : x ∈ range (p + 1)
⊢ _root_.bernoulli (p.succ - (p + 1 - x)) * ↑(p.succ.choose (p + 1 - x)) * ↑n ^ (p + 1 - x) =
    _root_.bernoulli x * ↑((p + 1).choose x) * ↑n ^ (p + 1 - x)

tactic: apply congr_arg₂ _ (congr_arg₂ _ _ _) rfl
state_before: n p x : ℕ
hx : x ∈ range (p + 1)
⊢ _root_.bernoulli (p.succ - (p + 1 - x)) * ↑(p.succ.choose (p + 1 - x)) * ↑n ^ (p + 1 - x) =
    _root_.bernoulli x * ↑((p + 1).choose x) * ↑n ^ (p + 1 - x)
state_after: n p x : ℕ
hx : x ∈ range (p + 1)
⊢ _root_.bernoulli (p.succ - (p + 1 - x)) = _root_.bernoulli x

n p x : ℕ
hx : x ∈ range (p + 1)
⊢ ↑(p.succ.choose (p + 1 - x)) = ↑((p + 1).choose x)

tactic: rw [Nat.sub_sub_self (mem_range_le hx)]
state_before: n p x : ℕ
hx : x ∈ range (p + 1)
⊢ _root_.bernoulli (p.succ - (p + 1 - x)) = _root_.bernoulli x
state_after: no goals

tactic: rw [← choose_symm (mem_range_le hx)]
state_before: n p x : ℕ
hx : x ∈ range (p + 1)
⊢ ↑(p.succ.choose (p + 1 - x)) = ↑((p + 1).choose x)
state_after: no goals

tactic: norm_cast
state_before: n p : ℕ
⊢ ↑p + 1 ≠ 0
state_after: no goals