l3lab/ntp-mathlib huggingface dataset:
/-- The Bernstein approximations
```
∑ k : Fin (n+1), f (k/n : ℝ) * n.choose k * x^k * (1-x)^(n-k)
```
for a continuous function `f : C([0,1], ℝ)` converge uniformly to `f` as `n` tends to infinity.

This is the proof given in [Richard Beals' *Analysis, an introduction*][beals-analysis], §7D,
and reproduced on wikipedia.
-/
theorem bernsteinApproximation_uniform (f : C(I, ℝ)) :
    Tendsto (fun n : ℕ => bernsteinApproximation n f) atTop (𝓝 f) := by
  simp only [Metric.nhds_basis_ball.tendsto_right_iff, Metric.mem_ball, dist_eq_norm]
  intro ε h
  let δ := δ f ε h
  have nhds_zero := tendsto_const_div_atTop_nhds_0_nat (2 * ‖f‖ * δ ^ (-2 : ℤ))
  filter_upwards [nhds_zero.eventually (gt_mem_nhds (half_pos h)), eventually_gt_atTop 0] with n nh
    npos'
  have npos : 0 < (n : ℝ) := by positivity
  -- As `[0,1]` is compact, it suffices to check the inequality pointwise.
  rw [ContinuousMap.norm_lt_iff _ h]
  intro x
  -- The idea is to split up the sum over `k` into two sets,
  -- `S`, where `x - k/n < δ`, and its complement.
  let S := S f ε h n x
  calc
    |(bernsteinApproximation n f - f) x| = |bernsteinApproximation n f x - f x| := rfl
    _ = |bernsteinApproximation n f x - f x * 1| := by rw [mul_one]
    _ = |bernsteinApproximation n f x - f x * ∑ k : Fin (n + 1), bernstein n k x| := by
      rw [bernstein.probability]
    _ = |∑ k : Fin (n + 1), (f k/ₙ - f x) * bernstein n k x| := by
      simp [bernsteinApproximation, Finset.mul_sum, sub_mul]
    _ ≤ ∑ k : Fin (n + 1), |(f k/ₙ - f x) * bernstein n k x| := (Finset.abs_sum_le_sum_abs _ _)
    _ = ∑ k : Fin (n + 1), |f k/ₙ - f x| * bernstein n k x := by
      simp_rw [abs_mul, abs_eq_self.mpr bernstein_nonneg]
    _ = (∑ k in S, |f k/ₙ - f x| * bernstein n k x) + ∑ k in Sᶜ, |f k/ₙ - f x| * bernstein n k x :=
      (S.sum_add_sum_compl _).symm
    -- We'll now deal with the terms in `S` and the terms in `Sᶜ` in separate calc blocks.
    _ < ε / 2 + ε / 2 :=
      (add_lt_add_of_le_of_lt ?_ ?_)
    _ = ε := add_halves ε
  · -- We now work on the terms in `S`: uniform continuity and `bernstein.probability`
    -- quickly give us a bound.
    calc
      ∑ k in S, |f k/ₙ - f x| * bernstein n k x ≤ ∑ k in S, ε / 2 * bernstein n k x := by
        gcongr with _ m
        exact le_of_lt (lt_of_mem_S m)
      _ = ε / 2 * ∑ k in S, bernstein n k x := by rw [Finset.mul_sum]
      -- In this step we increase the sum over `S` back to a sum over all of `Fin (n+1)`,
      -- so that we can use `bernstein.probability`.
      _ ≤ ε / 2 * ∑ k : Fin (n + 1), bernstein n k x := by
        gcongr
        

Proof state:
case h
f : C(↑I, ℝ)
ε : ℝ
h : 0 < ε
δ : ℝ := bernsteinApproximation.δ f ε h
nhds_zero : Tendsto (fun n => 2 * ‖f‖ * δ ^ (-2) / ↑n) atTop (𝓝 0)
n : ℕ
nh : 2 * ‖f‖ * δ ^ (-2) / ↑n < ε / 2
npos' : 0 < n
npos : 0 < ↑n
x : ↑I
S : Finset (Fin (n + 1)) := bernsteinApproximation.S f ε h n x
⊢ ∑ k in S, (bernstein n ↑k) x ≤ ∑ k : Fin (n + 1), (bernstein n ↑k) x

Next tactic:
exact Finset.sum_le_univ_sum_of_nonneg fun k => bernstein_nonneg
/-- The Bernstein approximations
```
∑ k : Fin (n+1), f (k/n : ℝ) * n.choose k * x^k * (1-x)^(n-k)
```
for a continuous function `f : C([0,1], ℝ)` converge uniformly to `f` as `n` tends to infinity.

This is the proof given in [Richard Beals' *Analysis, an introduction*][beals-analysis], §7D,
and reproduced on wikipedia.
-/
theorem bernsteinApproximation_uniform (f : C(I, ℝ)) :
    Tendsto (fun n : ℕ => bernsteinApproximation n f) atTop (𝓝 f) := by
  simp only [Metric.nhds_basis_ball.tendsto_right_iff, Metric.mem_ball, dist_eq_norm]
  intro ε h
  let δ := δ f ε h
  have nhds_zero := tendsto_const_div_atTop_nhds_0_nat (2 * ‖f‖ * δ ^ (-2 : ℤ))
  filter_upwards [nhds_zero.eventually (gt_mem_nhds (half_pos h)), eventually_gt_atTop 0] with n nh
    npos'
  have npos : 0 < (n : ℝ) := by positivity
  -- As `[0,1]` is compact, it suffices to check the inequality pointwise.
  rw [ContinuousMap.norm_lt_iff _ h]
  intro x
  -- The idea is to split up the sum over `k` into two sets,
  -- `S`, where `x - k/n < δ`, and its complement.
  let S := S f ε h n x
  calc
    |(bernsteinApproximation n f - f) x| = |bernsteinApproximation n f x - f x| := rfl
    _ = |bernsteinApproximation n f x - f x * 1| := by rw [mul_one]
    _ = |bernsteinApproximation n f x - f x * ∑ k : Fin (n + 1), bernstein n k x| := by
      rw [bernstein.probability]
    _ = |∑ k : Fin (n + 1), (f k/ₙ - f x) * bernstein n k x| := by
      simp [bernsteinApproximation, Finset.mul_sum, sub_mul]
    _ ≤ ∑ k : Fin (n + 1), |(f k/ₙ - f x) * bernstein n k x| := (Finset.abs_sum_le_sum_abs _ _)
    _ = ∑ k : Fin (n + 1), |f k/ₙ - f x| * bernstein n k x := by
      simp_rw [abs_mul, abs_eq_self.mpr bernstein_nonneg]
    _ = (∑ k in S, |f k/ₙ - f x| * bernstein n k x) + ∑ k in Sᶜ, |f k/ₙ - f x| * bernstein n k x :=
      (S.sum_add_sum_compl _).symm
    -- We'll now deal with the terms in `S` and the terms in `Sᶜ` in separate calc blocks.
    _ < ε / 2 + ε / 2 :=
      (add_lt_add_of_le_of_lt ?_ ?_)
    _ = ε := add_halves ε
  · -- We now work on the terms in `S`: uniform continuity and `bernstein.probability`
    -- quickly give us a bound.
    calc
      ∑ k in S, |f k/ₙ - f x| * bernstein n k x ≤ ∑ k in S, ε / 2 * bernstein n k x := by
        gcongr with _ m
        exact le_of_lt (lt_of_mem_S m)
      _ = ε / 2 * ∑ k in S, bernstein n k x := by rw [Finset.mul_sum]
      -- In this step we increase the sum over `S` back to a sum over all of `Fin (n+1)`,
      -- so that we can use `bernstein.probability`.
      _ ≤ ε / 2 * ∑ k : Fin (n + 1), bernstein n k x := by
        gcongr
        exact Finset.sum_le_univ_sum_of_nonneg fun k => bernstein_nonneg
      _ = ε / 2 := by 

Proof state:
f : C(↑I, ℝ)
ε : ℝ
h : 0 < ε
δ : ℝ := bernsteinApproximation.δ f ε h
nhds_zero : Tendsto (fun n => 2 * ‖f‖ * δ ^ (-2) / ↑n) atTop (𝓝 0)
n : ℕ
nh : 2 * ‖f‖ * δ ^ (-2) / ↑n < ε / 2
npos' : 0 < n
npos : 0 < ↑n
x : ↑I
S : Finset (Fin (n + 1)) := bernsteinApproximation.S f ε h n x
⊢ ε / 2 * ∑ k : Fin (n + 1), (bernstein n ↑k) x = ε / 2

Next tactic:
rw [bernstein.probability, mul_one]
theorem le_stepBound : id ≤ stepBound := fun n => Nat.le_mul_of_pos_right <| pow_pos (by 

Proof state:
n : ℕ
⊢ 0 < 4

Next tactic:
norm_num
theorem stepBound_mono : Monotone stepBound := fun a b h =>
  Nat.mul_le_mul h <| Nat.pow_le_pow_of_le_right (by 

Proof state:
a b : ℕ
h : a ≤ b
⊢ 4 > 0

Next tactic:
norm_num
theorem stepBound_pos_iff {n : ℕ} : 0 < stepBound n ↔ 0 < n :=
  zero_lt_mul_right <| by 

Proof state:
n : ℕ
⊢ 0 < 4 ^ n

Next tactic:
positivity
private theorem eps_pos {ε : ℝ} {n : ℕ} (h : 100 ≤ (4 : ℝ) ^ n * ε ^ 5) : 0 < ε :=
  (Odd.pow_pos_iff (by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε✝ ε : ℝ
n : ℕ
h : 100 ≤ 4 ^ n * ε ^ 5
⊢ Odd 5

Next tactic:
decide
private theorem eps_pos {ε : ℝ} {n : ℕ} (h : 100 ≤ (4 : ℝ) ^ n * ε ^ 5) : 0 < ε :=
  (Odd.pow_pos_iff (by decide)).mp
    (pos_of_mul_pos_right ((show 0 < (100 : ℝ) by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε✝ ε : ℝ
n : ℕ
h : 100 ≤ 4 ^ n * ε ^ 5
⊢ 0 < 100

Next tactic:
norm_num
private theorem eps_pos {ε : ℝ} {n : ℕ} (h : 100 ≤ (4 : ℝ) ^ n * ε ^ 5) : 0 < ε :=
  (Odd.pow_pos_iff (by decide)).mp
    (pos_of_mul_pos_right ((show 0 < (100 : ℝ) by norm_num).trans_le h) (by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε✝ ε : ℝ
n : ℕ
h : 100 ≤ 4 ^ n * ε ^ 5
⊢ 0 ≤ 4 ^ n

Next tactic:
positivity
private theorem m_pos [Nonempty α] (hPα : P.parts.card * 16 ^ P.parts.card ≤ card α) : 0 < m :=
  Nat.div_pos ((Nat.mul_le_mul_left _ <| Nat.pow_le_pow_left (by 

Proof state:
α : Type u_1
inst✝² : DecidableEq α
inst✝¹ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
inst✝ : Nonempty α
hPα : Finset.card P.parts * 16 ^ Finset.card P.parts ≤ Fintype.card α
⊢ 4 ≤ 16

Next tactic:
norm_num
theorem m_pos [Nonempty α] (hPα : P.parts.card * 16 ^ P.parts.card ≤ card α) : 0 < m := by
  

Proof state:
α : Type u_1
inst✝² : DecidableEq α
inst✝¹ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
inst✝ : Nonempty α
hPα : Finset.card P.parts * 16 ^ Finset.card P.parts ≤ Fintype.card α
⊢ 0 < m

Next tactic:
sz_positivity
theorem coe_m_add_one_pos : 0 < (m : ℝ) + 1 := by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
⊢ 0 < ↑m + 1

Next tactic:
positivity
theorem eps_pow_five_pos (hPε : 100 ≤ (4 : ℝ) ^ P.parts.card * ε ^ 5) : ↑0 < ε ^ 5 :=
  pos_of_mul_pos_right ((by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hPε : 100 ≤ 4 ^ Finset.card P.parts * ε ^ 5
⊢ 0 < 100

Next tactic:
norm_num
theorem eps_pow_five_pos (hPε : 100 ≤ (4 : ℝ) ^ P.parts.card * ε ^ 5) : ↑0 < ε ^ 5 :=
  pos_of_mul_pos_right ((by norm_num : (0 : ℝ) < 100).trans_le hPε) <| pow_nonneg (by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hPε : 100 ≤ 4 ^ Finset.card P.parts * ε ^ 5
⊢ 0 ≤ 4

Next tactic:
norm_num
theorem eps_pos (hPε : 100 ≤ (4 : ℝ) ^ P.parts.card * ε ^ 5) : 0 < ε :=
  (Odd.pow_pos_iff (by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hPε : 100 ≤ 4 ^ Finset.card P.parts * ε ^ 5
⊢ Odd 5

Next tactic:
decide
theorem hundred_div_ε_pow_five_le_m [Nonempty α] (hPα : P.parts.card * 16 ^ P.parts.card ≤ card α)
    (hPε : 100 ≤ (4 : ℝ) ^ P.parts.card * ε ^ 5) : 100 / ε ^ 5 ≤ m :=
  (div_le_of_nonneg_of_le_mul (eps_pow_five_pos hPε).le (by 

Proof state:
α : Type u_1
inst✝² : DecidableEq α
inst✝¹ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
inst✝ : Nonempty α
hPα : Finset.card P.parts * 16 ^ Finset.card P.parts ≤ Fintype.card α
hPε : 100 ≤ 4 ^ Finset.card P.parts * ε ^ 5
⊢ 0 ≤ 4 ^ Finset.card P.parts

Next tactic:
positivity
theorem hundred_div_ε_pow_five_le_m [Nonempty α] (hPα : P.parts.card * 16 ^ P.parts.card ≤ card α)
    (hPε : 100 ≤ (4 : ℝ) ^ P.parts.card * ε ^ 5) : 100 / ε ^ 5 ≤ m :=
  (div_le_of_nonneg_of_le_mul (eps_pow_five_pos hPε).le (by positivity) hPε).trans
    (by
      

Proof state:
α : Type u_1
inst✝² : DecidableEq α
inst✝¹ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
inst✝ : Nonempty α
hPα : Finset.card P.parts * 16 ^ Finset.card P.parts ≤ Fintype.card α
hPε : 100 ≤ 4 ^ Finset.card P.parts * ε ^ 5
⊢ 4 ^ Finset.card P.parts ≤ ↑m

Next tactic:
norm_cast
theorem hundred_div_ε_pow_five_le_m [Nonempty α] (hPα : P.parts.card * 16 ^ P.parts.card ≤ card α)
    (hPε : 100 ≤ (4 : ℝ) ^ P.parts.card * ε ^ 5) : 100 / ε ^ 5 ≤ m :=
  (div_le_of_nonneg_of_le_mul (eps_pow_five_pos hPε).le (by positivity) hPε).trans
    (by
      norm_cast
      

Proof state:
α : Type u_1
inst✝² : DecidableEq α
inst✝¹ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
inst✝ : Nonempty α
hPα : Finset.card P.parts * 16 ^ Finset.card P.parts ≤ Fintype.card α
hPε : 100 ≤ 4 ^ Finset.card P.parts * ε ^ 5
⊢ 4 ^ Finset.card P.parts ≤ m

Next tactic:
rwa [Nat.le_div_iff_mul_le' (stepBound_pos (P.parts_nonempty <|
        univ_nonempty.ne_empty).card_pos), stepBound, mul_left_comm, ← mul_pow]
theorem hundred_le_m [Nonempty α] (hPα : P.parts.card * 16 ^ P.parts.card ≤ card α)
    (hPε : 100 ≤ (4 : ℝ) ^ P.parts.card * ε ^ 5) (hε : ε ≤ 1) : 100 ≤ m :=
  mod_cast
    (hundred_div_ε_pow_five_le_m hPα hPε).trans'
      (le_div_self (by 

Proof state:
α : Type u_1
inst✝² : DecidableEq α
inst✝¹ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
inst✝ : Nonempty α
hPα : Finset.card P.parts * 16 ^ Finset.card P.parts ≤ Fintype.card α
hPε : 100 ≤ 4 ^ Finset.card P.parts * ε ^ 5
hε : ε ≤ 1
⊢ 0 ≤ 100

Next tactic:
norm_num
theorem hundred_le_m [Nonempty α] (hPα : P.parts.card * 16 ^ P.parts.card ≤ card α)
    (hPε : 100 ≤ (4 : ℝ) ^ P.parts.card * ε ^ 5) (hε : ε ≤ 1) : 100 ≤ m :=
  mod_cast
    (hundred_div_ε_pow_five_le_m hPα hPε).trans'
      (le_div_self (by norm_num) (by 

Proof state:
α : Type u_1
inst✝² : DecidableEq α
inst✝¹ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
inst✝ : Nonempty α
hPα : Finset.card P.parts * 16 ^ Finset.card P.parts ≤ Fintype.card α
hPε : 100 ≤ 4 ^ Finset.card P.parts * ε ^ 5
hε : ε ≤ 1
⊢ 0 < ε ^ 5

Next tactic:
sz_positivity
theorem hundred_le_m [Nonempty α] (hPα : P.parts.card * 16 ^ P.parts.card ≤ card α)
    (hPε : 100 ≤ (4 : ℝ) ^ P.parts.card * ε ^ 5) (hε : ε ≤ 1) : 100 ≤ m :=
  mod_cast
    (hundred_div_ε_pow_five_le_m hPα hPε).trans'
      (le_div_self (by norm_num) (by sz_positivity) <| pow_le_one _ (by 

Proof state:
α : Type u_1
inst✝² : DecidableEq α
inst✝¹ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
inst✝ : Nonempty α
hPα : Finset.card P.parts * 16 ^ Finset.card P.parts ≤ Fintype.card α
hPε : 100 ≤ 4 ^ Finset.card P.parts * ε ^ 5
hε : ε ≤ 1
⊢ 0 ≤ ε

Next tactic:
sz_positivity
theorem a_add_one_le_four_pow_parts_card : a + 1 ≤ 4 ^ P.parts.card := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
⊢ a + 1 ≤ 4 ^ Finset.card P.parts

Next tactic:
have h : 1 ≤ 4 ^ P.parts.card := one_le_pow_of_one_le (by norm_num) _
theorem a_add_one_le_four_pow_parts_card : a + 1 ≤ 4 ^ P.parts.card := by
  have h : 1 ≤ 4 ^ P.parts.card := one_le_pow_of_one_le (by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
⊢ 1 ≤ 4

Next tactic:
norm_num
theorem a_add_one_le_four_pow_parts_card : a + 1 ≤ 4 ^ P.parts.card := by
  have h : 1 ≤ 4 ^ P.parts.card := one_le_pow_of_one_le (by norm_num) _
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
h : 1 ≤ 4 ^ Finset.card P.parts
⊢ a + 1 ≤ 4 ^ Finset.card P.parts

Next tactic:
rw [stepBound, ← Nat.div_div_eq_div_mul]
theorem a_add_one_le_four_pow_parts_card : a + 1 ≤ 4 ^ P.parts.card := by
  have h : 1 ≤ 4 ^ P.parts.card := one_le_pow_of_one_le (by norm_num) _
  rw [stepBound, ← Nat.div_div_eq_div_mul]
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
h : 1 ≤ 4 ^ Finset.card P.parts
⊢ Fintype.card α / Finset.card P.parts -
        Fintype.card α / Finset.card P.parts / 4 ^ Finset.card P.parts * 4 ^ Finset.card P.parts +
      1 ≤
    4 ^ Finset.card P.parts

Next tactic:
conv_rhs => rw [← Nat.sub_add_cancel h]
theorem a_add_one_le_four_pow_parts_card : a + 1 ≤ 4 ^ P.parts.card := by
  have h : 1 ≤ 4 ^ P.parts.card := one_le_pow_of_one_le (by norm_num) _
  rw [stepBound, ← Nat.div_div_eq_div_mul]
  conv_rhs => 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
h : 1 ≤ 4 ^ Finset.card P.parts
| 4 ^ Finset.card P.parts

Next tactic:
rw [← Nat.sub_add_cancel h]
theorem a_add_one_le_four_pow_parts_card : a + 1 ≤ 4 ^ P.parts.card := by
  have h : 1 ≤ 4 ^ P.parts.card := one_le_pow_of_one_le (by norm_num) _
  rw [stepBound, ← Nat.div_div_eq_div_mul]
  conv_rhs => rw [← Nat.sub_add_cancel h]
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
h : 1 ≤ 4 ^ Finset.card P.parts
⊢ Fintype.card α / Finset.card P.parts -
        Fintype.card α / Finset.card P.parts / 4 ^ Finset.card P.parts * 4 ^ Finset.card P.parts +
      1 ≤
    4 ^ Finset.card P.parts - 1 + 1

Next tactic:
rw [add_le_add_iff_right, tsub_le_iff_left, ← Nat.add_sub_assoc h]
theorem a_add_one_le_four_pow_parts_card : a + 1 ≤ 4 ^ P.parts.card := by
  have h : 1 ≤ 4 ^ P.parts.card := one_le_pow_of_one_le (by norm_num) _
  rw [stepBound, ← Nat.div_div_eq_div_mul]
  conv_rhs => rw [← Nat.sub_add_cancel h]
  rw [add_le_add_iff_right, tsub_le_iff_left, ← Nat.add_sub_assoc h]
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
h : 1 ≤ 4 ^ Finset.card P.parts
⊢ Fintype.card α / Finset.card P.parts ≤
    Fintype.card α / Finset.card P.parts / 4 ^ Finset.card P.parts * 4 ^ Finset.card P.parts + 4 ^ Finset.card P.parts -
      1

Next tactic:
exact Nat.le_sub_one_of_lt (Nat.lt_div_mul_add h)
theorem card_aux₁ (hucard : u.card = m * 4 ^ P.parts.card + a) :
    (4 ^ P.parts.card - a) * m + a * (m + 1) = u.card := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hucard : Finset.card u = m * 4 ^ Finset.card P.parts + a
⊢ (4 ^ Finset.card P.parts - a) * m + a * (m + 1) = Finset.card u

Next tactic:
rw [hucard, mul_add, mul_one, ← add_assoc, ← add_mul,
    Nat.sub_add_cancel ((Nat.le_succ _).trans a_add_one_le_four_pow_parts_card), mul_comm]
theorem card_aux₂ (hP : P.IsEquipartition) (hu : u ∈ P.parts)
    (hucard : ¬u.card = m * 4 ^ P.parts.card + a) :
    (4 ^ P.parts.card - (a + 1)) * m + (a + 1) * (m + 1) = u.card := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hP : Finpartition.IsEquipartition P
hu : u ∈ P.parts
hucard : ¬Finset.card u = m * 4 ^ Finset.card P.parts + a
⊢ (4 ^ Finset.card P.parts - (a + 1)) * m + (a + 1) * (m + 1) = Finset.card u

Next tactic:
have : m * 4 ^ P.parts.card ≤ card α / P.parts.card := by
    rw [stepBound, ← Nat.div_div_eq_div_mul]
    exact Nat.div_mul_le_self _ _
theorem card_aux₂ (hP : P.IsEquipartition) (hu : u ∈ P.parts)
    (hucard : ¬u.card = m * 4 ^ P.parts.card + a) :
    (4 ^ P.parts.card - (a + 1)) * m + (a + 1) * (m + 1) = u.card := by
  have : m * 4 ^ P.parts.card ≤ card α / P.parts.card := by
    

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hP : Finpartition.IsEquipartition P
hu : u ∈ P.parts
hucard : ¬Finset.card u = m * 4 ^ Finset.card P.parts + a
⊢ m * 4 ^ Finset.card P.parts ≤ Fintype.card α / Finset.card P.parts

Next tactic:
rw [stepBound, ← Nat.div_div_eq_div_mul]
theorem card_aux₂ (hP : P.IsEquipartition) (hu : u ∈ P.parts)
    (hucard : ¬u.card = m * 4 ^ P.parts.card + a) :
    (4 ^ P.parts.card - (a + 1)) * m + (a + 1) * (m + 1) = u.card := by
  have : m * 4 ^ P.parts.card ≤ card α / P.parts.card := by
    rw [stepBound, ← Nat.div_div_eq_div_mul]
    

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hP : Finpartition.IsEquipartition P
hu : u ∈ P.parts
hucard : ¬Finset.card u = m * 4 ^ Finset.card P.parts + a
⊢ Fintype.card α / Finset.card P.parts / 4 ^ Finset.card P.parts * 4 ^ Finset.card P.parts ≤
    Fintype.card α / Finset.card P.parts

Next tactic:
exact Nat.div_mul_le_self _ _
theorem card_aux₂ (hP : P.IsEquipartition) (hu : u ∈ P.parts)
    (hucard : ¬u.card = m * 4 ^ P.parts.card + a) :
    (4 ^ P.parts.card - (a + 1)) * m + (a + 1) * (m + 1) = u.card := by
  have : m * 4 ^ P.parts.card ≤ card α / P.parts.card := by
    rw [stepBound, ← Nat.div_div_eq_div_mul]
    exact Nat.div_mul_le_self _ _
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hP : Finpartition.IsEquipartition P
hu : u ∈ P.parts
hucard : ¬Finset.card u = m * 4 ^ Finset.card P.parts + a
this : m * 4 ^ Finset.card P.parts ≤ Fintype.card α / Finset.card P.parts
⊢ (4 ^ Finset.card P.parts - (a + 1)) * m + (a + 1) * (m + 1) = Finset.card u

Next tactic:
rw [Nat.add_sub_of_le this] at hucard
theorem card_aux₂ (hP : P.IsEquipartition) (hu : u ∈ P.parts)
    (hucard : ¬u.card = m * 4 ^ P.parts.card + a) :
    (4 ^ P.parts.card - (a + 1)) * m + (a + 1) * (m + 1) = u.card := by
  have : m * 4 ^ P.parts.card ≤ card α / P.parts.card := by
    rw [stepBound, ← Nat.div_div_eq_div_mul]
    exact Nat.div_mul_le_self _ _
  rw [Nat.add_sub_of_le this] at hucard
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hP : Finpartition.IsEquipartition P
hu : u ∈ P.parts
hucard : ¬Finset.card u = Fintype.card α / Finset.card P.parts
this : m * 4 ^ Finset.card P.parts ≤ Fintype.card α / Finset.card P.parts
⊢ (4 ^ Finset.card P.parts - (a + 1)) * m + (a + 1) * (m + 1) = Finset.card u

Next tactic:
rw [(hP.card_parts_eq_average hu).resolve_left hucard, mul_add, mul_one, ← add_assoc, ← add_mul,
    Nat.sub_add_cancel a_add_one_le_four_pow_parts_card, ← add_assoc, mul_comm,
    Nat.add_sub_of_le this, card_univ]
theorem pow_mul_m_le_card_part (hP : P.IsEquipartition) (hu : u ∈ P.parts) :
    (4 : ℝ) ^ P.parts.card * m ≤ u.card := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hP : Finpartition.IsEquipartition P
hu : u ∈ P.parts
⊢ 4 ^ Finset.card P.parts * ↑m ≤ ↑(Finset.card u)

Next tactic:
norm_cast
theorem pow_mul_m_le_card_part (hP : P.IsEquipartition) (hu : u ∈ P.parts) :
    (4 : ℝ) ^ P.parts.card * m ≤ u.card := by
  norm_cast
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hP : Finpartition.IsEquipartition P
hu : u ∈ P.parts
⊢ 4 ^ Finset.card P.parts * m ≤ Finset.card u

Next tactic:
rw [stepBound, ← Nat.div_div_eq_div_mul]
theorem pow_mul_m_le_card_part (hP : P.IsEquipartition) (hu : u ∈ P.parts) :
    (4 : ℝ) ^ P.parts.card * m ≤ u.card := by
  norm_cast
  rw [stepBound, ← Nat.div_div_eq_div_mul]
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε : ℝ
hP : Finpartition.IsEquipartition P
hu : u ∈ P.parts
⊢ 4 ^ Finset.card P.parts * (Fintype.card α / Finset.card P.parts / 4 ^ Finset.card P.parts) ≤ Finset.card u

Next tactic:
exact (Nat.mul_div_le _ _).trans (hP.average_le_card_part hu)
theorem hundred_lt_pow_initialBound_mul {ε : ℝ} (hε : 0 < ε) (l : ℕ) :
    100 < ↑4 ^ initialBound ε l * ε ^ 5 := by
  

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε✝ : ℝ
l✝ : ℕ
ε : ℝ
hε : 0 < ε
l : ℕ
⊢ 100 < 4 ^ initialBound ε l * ε ^ 5

Next tactic:
rw [← rpow_nat_cast 4, ← div_lt_iff (pow_pos hε 5), lt_rpow_iff_log_lt _ zero_lt_four, ←
    div_lt_iff, initialBound, Nat.cast_max, Nat.cast_max]
theorem hundred_lt_pow_initialBound_mul {ε : ℝ} (hε : 0 < ε) (l : ℕ) :
    100 < ↑4 ^ initialBound ε l * ε ^ 5 := by
  rw [← rpow_nat_cast 4, ← div_lt_iff (pow_pos hε 5), lt_rpow_iff_log_lt _ zero_lt_four, ←
    div_lt_iff, initialBound, Nat.cast_max, Nat.cast_max]
  · 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε✝ : ℝ
l✝ : ℕ
ε : ℝ
hε : 0 < ε
l : ℕ
⊢ log (100 / ε ^ 5) / log 4 < max (↑7) (max ↑l ↑(⌊log (100 / ε ^ 5) / log 4⌋₊ + 1))

Next tactic:
push_cast
theorem hundred_lt_pow_initialBound_mul {ε : ℝ} (hε : 0 < ε) (l : ℕ) :
    100 < ↑4 ^ initialBound ε l * ε ^ 5 := by
  rw [← rpow_nat_cast 4, ← div_lt_iff (pow_pos hε 5), lt_rpow_iff_log_lt _ zero_lt_four, ←
    div_lt_iff, initialBound, Nat.cast_max, Nat.cast_max]
  · push_cast
    

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε✝ : ℝ
l✝ : ℕ
ε : ℝ
hε : 0 < ε
l : ℕ
⊢ log (100 / ε ^ 5) / log 4 < max 7 (max (↑l) (↑⌊log (100 / ε ^ 5) / log 4⌋₊ + 1))

Next tactic:
exact lt_max_of_lt_right (lt_max_of_lt_right <| Nat.lt_floor_add_one _)
theorem hundred_lt_pow_initialBound_mul {ε : ℝ} (hε : 0 < ε) (l : ℕ) :
    100 < ↑4 ^ initialBound ε l * ε ^ 5 := by
  rw [← rpow_nat_cast 4, ← div_lt_iff (pow_pos hε 5), lt_rpow_iff_log_lt _ zero_lt_four, ←
    div_lt_iff, initialBound, Nat.cast_max, Nat.cast_max]
  · push_cast
    exact lt_max_of_lt_right (lt_max_of_lt_right <| Nat.lt_floor_add_one _)
  · 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε✝ : ℝ
l✝ : ℕ
ε : ℝ
hε : 0 < ε
l : ℕ
⊢ 0 < log 4

Next tactic:
exact log_pos (by norm_num)
theorem hundred_lt_pow_initialBound_mul {ε : ℝ} (hε : 0 < ε) (l : ℕ) :
    100 < ↑4 ^ initialBound ε l * ε ^ 5 := by
  rw [← rpow_nat_cast 4, ← div_lt_iff (pow_pos hε 5), lt_rpow_iff_log_lt _ zero_lt_four, ←
    div_lt_iff, initialBound, Nat.cast_max, Nat.cast_max]
  · push_cast
    exact lt_max_of_lt_right (lt_max_of_lt_right <| Nat.lt_floor_add_one _)
  · exact log_pos (by 

Proof state:
α : Type u_1
inst✝¹ : DecidableEq α
inst✝ : Fintype α
P : Finpartition univ
u : Finset α
ε✝ : ℝ
l✝ : ℕ
ε : ℝ
hε : 0 < ε
l : ℕ
⊢ 1 < 4

Next tactic:
norm_num