/-- This theorem establishes **Leibniz's series for `π`**: The alternating sum of the reciprocals
  of the odd numbers is `π/4`. Note that this is a conditionally rather than absolutely convergent
  series. The main tool that this proof uses is the Mean Value Theorem (specifically avoiding the
  Fundamental Theorem of Calculus).

  Intuitively, the theorem holds because Leibniz's series is the Taylor series of `arctan x`
  centered about `0` and evaluated at the value `x = 1`. Therefore, much of this proof consists of
  reasoning about a function
    `f := arctan x - ∑ i in Finset.range k, (-(1:ℝ))^i * x^(2*i+1) / (2*i+1)`,
  the difference between `arctan` and the `k`-th partial sum of its Taylor series. Some ingenuity is
  required due to the fact that the Taylor series is not absolutely convergent at `x = 1`.

  This proof requires a bound on `f 1`, the key idea being that `f 1` can be split as the sum of
  `f 1 - f u` and `f u`, where `u` is a sequence of values in [0,1], carefully chosen such that
  each of these two terms can be controlled (in different ways).

  We begin the proof by (1) introducing that sequence `u` and then proving that another sequence
  constructed from `u` tends to `0` at `+∞`. After (2) converting the limit in our goal to an
  inequality, we (3) introduce the auxiliary function `f` defined above. Next, we (4) compute the
  derivative of `f`, denoted by `f'`, first generally and then on each of two subintervals of [0,1].
  We then (5) prove a bound for `f'`, again both generally as well as on each of the two
  subintervals. Finally, we (6) apply the Mean Value Theorem twice, obtaining bounds on `f 1 - f u`
  and `f u - f 0` from the bounds on `f'` (note that `f 0 = 0`). -/
theorem tendsto_sum_pi_div_four :
    Tendsto (fun k => ∑ i in Finset.range k, (-(1 : ℝ)) ^ i / (2 * i + 1)) atTop (𝓝 (π / 4)) := by
  rw [tendsto_iff_norm_sub_tendsto_zero, ← tendsto_zero_iff_norm_tendsto_zero]
  -- (1) We introduce a useful sequence `u` of values in [0,1], then prove that another sequence
  --     constructed from `u` tends to `0` at `+∞`
  let u := fun k : ℕ => (k : NNReal) ^ (-1 / (2 * (k : ℝ) + 1))
  have H : Tendsto (fun k : ℕ => (1 : ℝ) - u k + u k ^ (2 * (k : ℝ) + 1)) atTop (𝓝 0) := by
    convert (((tendsto_rpow_div_mul_add (-1) 2 1 two_ne_zero.symm).neg.const_add 1).add
        tendsto_inv_atTop_zero).comp tendsto_nat_cast_atTop_atTop using 1
    · ext k
      simp only [NNReal.coe_nat_cast, Function.comp_apply, NNReal.coe_rpow]
      rw [← rpow_mul (Nat.cast_nonneg k) (-1 / (2 * (k : ℝ) + 1)) (2 * (k : ℝ) + 1),
        @div_mul_cancel _ _ (2 * (k : ℝ) + 1) _
          (by norm_cast; simp only [Nat.succ_ne_zero, not_false_iff]),
        rpow_neg_one k, sub_eq_add_neg]
    · simp only [add_zero, add_right_neg]
  -- (2) We convert the limit in our goal to an inequality
  refine' squeeze_zero_norm _ H
  intro k
  -- Since `k` is now fixed, we henceforth denote `u k` as `U`
  let U := u k
  -- (3) We introduce an auxiliary function `f`
  let b (i : ℕ) x := (-(1 : ℝ)) ^ i * x ^ (2 * i + 1) / (2 * i + 1)
  let f x := arctan x - ∑ i in Finset.range k, b i x
  suffices f_bound : |f 1 - f 0| ≤ (1 : ℝ) - U + U ^ (2 * (k : ℝ) + 1)
  · rw [← norm_neg]
    convert f_bound using 1
    simp
  -- We show that `U` is indeed in [0,1]
  have hU1 : (U : ℝ) ≤ 1 := by
    by_cases hk : k = 0
    · simp [hk]
    · exact rpow_le_one_of_one_le_of_nonpos
        (by norm_cast; exact Nat.succ_le_iff.mpr (Nat.pos_of_ne_zero hk)) (le_of_lt
          (@div_neg_of_neg_of_pos _ _ (-(1 : ℝ)) (2 * k + 1) (neg_neg_iff_pos.mpr zero_lt_one)
            (by norm_cast; exact Nat.succ_pos')))
  have hU2 := NNReal.coe_nonneg U
  -- (4) We compute the derivative of `f`, denoted by `f'`
  let f' := fun x : ℝ => (-x ^ 2) ^ k / (1 + x ^ 2)
  have has_deriv_at_f : ∀ x, HasDerivAt f (f' x) x := by
    intro x
    have has_deriv_at_b : ∀ i ∈ Finset.range k, HasDerivAt (b i) ((-x ^ 2) ^ i) x := by
      intro i _
      convert HasDerivAt.const_mul ((-1 : ℝ) ^ i / (2 * i + 1))
          (HasDerivAt.pow (2 * i + 1) (hasDerivAt_id x)) using 1
      · ext y
        simp only [id.def]
        ring
      · simp
        rw [← mul_assoc, @div_mul_cancel _ _ (2 * (i : ℝ) + 1) _ (by norm_cast; linarith),
          pow_mul x 2 i, ← mul_pow (-1 : ℝ) (x ^ 2) i]
        ring_nf
    convert (hasDerivAt_arctan x).sub (HasDerivAt.sum has_deriv_at_b) using 1
    

Proof state:
case h.e'_7
u : ℕ → NNReal := fun k => ↑k ^ (-1 / (2 * ↑k + 1))
H : Tendsto (fun k => 1 - ↑(u k) + ↑(u k) ^ (2 * ↑k + 1)) atTop (𝓝 0)
k : ℕ
U : NNReal := u k
b : ℕ → ℝ → ℝ := fun i x => (-1) ^ i * x ^ (2 * i + 1) / (2 * ↑i + 1)
f : ℝ → ℝ := fun x => arctan x - ∑ i in Finset.range k, b i x
hU1 : ↑U ≤ 1
hU2 : 0 ≤ ↑U
f' : ℝ → ℝ := fun x => (-x ^ 2) ^ k / (1 + x ^ 2)
x : ℝ
has_deriv_at_b : ∀ i ∈ Finset.range k, HasDerivAt (b i) ((-x ^ 2) ^ i) x
⊢ f' x = 1 / (1 + x ^ 2) - ∑ i in Finset.range k, (-x ^ 2) ^ i

Next tactic:
have g_sum :=
      @geom_sum_eq _ _ (-x ^ 2) ((neg_nonpos.mpr (sq_nonneg x)).trans_lt zero_lt_one).ne k