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

Proof steps:
state_before: A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
⊢ (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1) = PowerSeries.X * (rescale t) (exp A)
state_after: case h
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ (PowerSeries.coeff A n) ((PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1)) =
    (PowerSeries.coeff A n) (PowerSeries.X * (rescale t) (exp A))
tactic: ext n
state_before: case h
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ (PowerSeries.coeff A n) ((PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1)) =
    (PowerSeries.coeff A n) (PowerSeries.X * (rescale t) (exp A))
state_after: case h.zero
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
⊢ (PowerSeries.coeff A 0) ((PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1)) =
    (PowerSeries.coeff A 0) (PowerSeries.X * (rescale t) (exp A))

case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ (PowerSeries.coeff A (n + 1)) ((PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1)) =
    (PowerSeries.coeff A (n + 1)) (PowerSeries.X * (rescale t) (exp A))
tactic: cases' n with n
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ (PowerSeries.coeff A (n + 1)) ((PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) * (exp A - 1)) =
    (PowerSeries.coeff A (n + 1)) (PowerSeries.X * (rescale t) (exp A))
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A (x, n + 1 - x).1) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (x, n + 1 - x).2) (exp A - 1) +
      (PowerSeries.coeff A (n + 1, n + 1 - (n + 1)).1) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
        (PowerSeries.coeff A (n + 1, n + 1 - (n + 1)).2) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (1 / ↑n !)
tactic: rw [coeff_succ_X_mul, coeff_rescale, coeff_exp, PowerSeries.coeff_mul,
    Nat.sum_antidiagonal_eq_sum_range_succ_mk, sum_range_succ]
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A (x, n + 1 - x).1) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (x, n + 1 - x).2) (exp A - 1) +
      (PowerSeries.coeff A (n + 1, n + 1 - (n + 1)).1) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
        (PowerSeries.coeff A (n + 1, n + 1 - (n + 1)).2) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (1 / ↑n !)
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ ∑ x ∈ range (n + 1),
      (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
        (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (1 / ↑n !)
tactic: simp only [RingHom.map_sub, tsub_self, constantCoeff_one, constantCoeff_exp,
    coeff_zero_eq_constantCoeff, mul_zero, sub_self, add_zero]
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
⊢ ∑ x ∈ range (n + 1),
      (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
        (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (1 / ↑n !)
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ∑ x ∈ range (n + 1),
      (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
        (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (1 / ↑n !)
tactic: have hnp1 : IsUnit ((n + 1)! : ℚ) := IsUnit.mk0 _ (mod_cast factorial_ne_zero (n + 1))
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ∑ x ∈ range (n + 1),
      (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
        (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (1 / ↑n !)
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    (algebraMap ℚ A) ↑(n + 1)! * (t ^ n * (algebraMap ℚ A) (1 / ↑n !))
tactic: rw [← (hnp1.map (algebraMap ℚ A)).mul_right_inj]
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    (algebraMap ℚ A) ↑(n + 1)! * (t ^ n * (algebraMap ℚ A) (1 / ↑n !))
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (↑(n + 1)! * (1 / ↑n !))
tactic: rw [mul_left_comm, ← RingHom.map_mul]
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (↑(n + 1)! * (1 / ↑n !))
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (↑((n + 1) * n !) * (1 / ↑n !))
tactic: change _ = t ^ n * algebraMap ℚ A (((n + 1) * n ! : ℕ) * (1 / n !))
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    t ^ n * (algebraMap ℚ A) (↑((n + 1) * n !) * (1 / ↑n !))
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    (aeval t) ((monomial n) (↑n + 1))
tactic: rw [cast_mul, mul_assoc,
    mul_one_div_cancel (show (n ! : ℚ) ≠ 0 from cast_ne_zero.2 (factorial_ne_zero n)), mul_one,
    mul_comm (t ^ n), ← aeval_monomial, cast_add, cast_one]
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ∑ x ∈ range (n + 1),
        (PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1) =
    (aeval t) ((monomial n) (↑n + 1))
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ∑ i ∈ range (n + 1),
      (algebraMap ℚ A) ↑(n + 1)! *
        ((PowerSeries.coeff A i) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - i)) (exp A - 1)) =
    ∑ x ∈ range (n + 1), (aeval t) (↑((n + 1).choose x) • bernoulli x)
tactic: rw [← sum_bernoulli, Finset.mul_sum, map_sum]
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ∑ i ∈ range (n + 1),
      (algebraMap ℚ A) ↑(n + 1)! *
        ((PowerSeries.coeff A i) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - i)) (exp A - 1)) =
    ∑ x ∈ range (n + 1), (aeval t) (↑((n + 1).choose x) • bernoulli x)
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ∀ x ∈ range (n + 1),
    (algebraMap ℚ A) ↑(n + 1)! *
        ((PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1)) =
      (aeval t) (↑((n + 1).choose x) • bernoulli x)
tactic: apply Finset.sum_congr rfl
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
⊢ ∀ x ∈ range (n + 1),
    (algebraMap ℚ A) ↑(n + 1)! *
        ((PowerSeries.coeff A x) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
          (PowerSeries.coeff A (n + 1 - x)) (exp A - 1)) =
      (aeval t) (↑((n + 1).choose x) • bernoulli x)
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
i : ℕ
hi : i ∈ range (n + 1)
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ((PowerSeries.coeff A i) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
        (PowerSeries.coeff A (n + 1 - i)) (exp A - 1)) =
    (aeval t) (↑((n + 1).choose i) • bernoulli i)
tactic: intro i hi
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
i : ℕ
hi : i ∈ range (n + 1)
⊢ (algebraMap ℚ A) ↑(n + 1)! *
      ((PowerSeries.coeff A i) (PowerSeries.mk fun n => (aeval t) ((1 / ↑n !) • bernoulli n)) *
        (PowerSeries.coeff A (n + 1 - i)) (exp A - 1)) =
    (aeval t) (↑((n + 1).choose i) • bernoulli i)
state_after: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
i : ℕ
hi : i ∈ range (n + 1)
⊢ (algebraMap ℚ A) (↑(n + 1)! * (↑i !)⁻¹ * (↑(n + 1 - i)!)⁻¹) * (aeval t) (bernoulli i) =
    (algebraMap ℚ A) (↑(n + 1)! / (↑i ! * ↑(n + 1 - i)!)) * (aeval t) (bernoulli i)
tactic: simp only [Nat.cast_choose ℚ (mem_range_le hi), coeff_mk, if_neg (mem_range_sub_ne_zero hi),
    one_div, map_smul, PowerSeries.coeff_one, coeff_exp, sub_zero, LinearMap.map_sub,
    Algebra.smul_mul_assoc, Algebra.smul_def, mul_right_comm _ ((aeval t) _), ← mul_assoc, ←
    RingHom.map_mul, succ_eq_add_one, ← Polynomial.C_eq_algebraMap, Polynomial.aeval_mul,
    Polynomial.aeval_C]
state_before: case h.succ
A : Type u_1
inst✝¹ : CommRing A
inst✝ : Algebra ℚ A
t : A
n : ℕ
hnp1 : IsUnit ↑(n + 1)!
i : ℕ
hi : i ∈ range (n + 1)
⊢ (algebraMap ℚ A) (↑(n + 1)! * (↑i !)⁻¹ * (↑(n + 1 - i)!)⁻¹) * (aeval t) (bernoulli i) =
    (algebraMap ℚ A) (↑(n + 1)! / (↑i ! * ↑(n + 1 - i)!)) * (aeval t) (bernoulli i)
state_after: no goals
tactic: field_simp