import Mathlib
import Optlib


open Filter Topology Set InnerProductSpace Finset

open Finset

theorem extracted_formal_statement_38.{u_1} {E : Type u_1} [inst : NormedAddCommGroup E] [inst_1 : InnerProductSpace ℝ E]
  {f : E → ℝ} (xm x₀ : E) {alg : subgradient_method f x₀} (hm : IsMinOn f Set.univ xm)
  (ha'' :
    ∀ (s : Set ℝ) (x : ℝ),
      (∀ (b : ℝ), x ≤ b → b ∈ s) → ∃ a, ∀ (b : ℕ), a ≤ b → (Finset.range (b + 1)).sum (subgradient_method.a f x₀) ∈ s)
  (s : Set ℝ)
  (ha' :
    ∀ (s x : Set ℝ),
      x ⊆ s →
        (∀ x_1 ∈ x, ∃ ε, 0 < ε ∧ Metric.ball x_1 ε ⊆ x) →
          0 ∈ x → ∃ a, ∀ (b : ℕ), a ≤ b → subgradient_method.a f x₀ b ∈ s)
  (t : Set ℝ) (hs₁ : t ⊆ s) (hs₂ : ∀ x ∈ t, ∃ ε, 0 < ε ∧ Metric.ball x ε ⊆ t) (hs₀ : 0 ∈ t) (ε : ℝ) (εpos : 0 < ε)
  (hs₂₀ : Metric.ball 0 ε ⊆ t)
  (ha₁ : ∃ a₁, ∀ (b : ℕ), a₁ ≤ b → ‖x₀ - xm‖ ^ 2 / (2 * (Finset.range (b + 1)).sum (subgradient_method.a f x₀)) < ε / 2)
  (hG : ¬subgradient_method.G f x₀ = 0) (hpos' : ↑(subgradient_method.G f x₀) ^ 2 > 0) (a₂ : ℕ)
  (ha₂ : ∀ (b : ℕ), a₂ ≤ b → |subgradient_method.a f x₀ b| < ε / (2 * ↑(subgradient_method.G f x₀) ^ 2)) :
  let A :=
    (2 * ↑(subgradient_method.G f x₀) ^ 2 * ∑ x ∈ Finset.range (a₂ + 1), subgradient_method.a f x₀ x ^ 2) / ε + 1;
  let s₁ :=
    {x | x > (2 * ↑(subgradient_method.G f x₀) ^ 2 * ∑ x ∈ Finset.range (a₂ + 1), subgradient_method.a f x₀ x ^ 2) / ε};
  (∀ (b : ℝ), A ≤ b → b ∈ s₁) →
    ∀ (a₁ : ℕ),
      (∀ (b : ℕ), a₁ ≤ b → (Finset.range (b + 1)).sum (subgradient_method.a f x₀) ∈ s₁) →
        ∀ (b : ℕ),
          a₁ ⊔ (a₂ + 1) ≤ b →
            b ≥ a₁ →
              b ≥ a₂ + 1 →
                b ≥ a₂ →
                  2 * (Finset.range (b + 1)).sum (subgradient_method.a f x₀) > 0 →
                    (Finset.range (b + 1)).sum (subgradient_method.a f x₀) > 0 →
                      ↑(subgradient_method.G f x₀) ^ 2 * (ε / (2 * ↑(subgradient_method.G f x₀) ^ 2)) > 0 →
                        (↑(subgradient_method.G f x₀) ^ 2 *
                                ∑ x ∈ Finset.range (a₂ + 1), subgradient_method.a f x₀ x ^ 2) /
                              (2 * (Finset.range (b + 1)).sum (subgradient_method.a f x₀)) +
                            (↑(subgradient_method.G f x₀) ^ 2 *
                                ∑ x ∈ Finset.range (b - a₂), subgradient_method.a f x₀ (a₂ + 1 + x) ^ 2) /
                              (2 * (Finset.range (b + 1)).sum (subgradient_method.a f x₀)) <
                          ε / 4 + ε / 4 := sorry

Tactic state before:
E : Type u_1
inst✝¹ : NormedAddCommGroup E
inst✝ : InnerProductSpace ℝ E
f : E → ℝ
xm x₀ : E
alg : subgradient_method f x₀
hm : IsMinOn f Set.univ xm
ha'' :
  ∀ (s : Set ℝ) (x : ℝ),
    (∀ (b : ℝ), x ≤ b → b ∈ s) → ∃ a, ∀ (b : ℕ), a ≤ b → (Finset.range (b + 1)).sum (subgradient_method.a f x₀) ∈ s
s✝ : Set ℝ
ha' :
  ∀ (s x : Set ℝ),
    x ⊆ s →
      (∀ x_1 ∈ x, ∃ ε, 0 < ε ∧ Metric.ball x_1 ε ⊆ x) → 0 ∈ x → ∃ a, ∀ (b : ℕ), a ≤ b → subgradient_method.a f x₀ b ∈ s
t : Set ℝ
hs₁ : t ⊆ s✝
hs₂ : ∀ x ∈ t, ∃ ε, 0 < ε ∧ Metric.ball x ε ⊆ t
hs₀ : 0 ∈ t
ε : ℝ
εpos : 0 < ε
hs₂₀ : Metric.ball 0 ε ⊆ t
ha₁ : ∃ a₁, ∀ (b : ℕ), a₁ ≤ b → ‖x₀ - xm‖ ^ 2 / (2 * (Finset.range (b + 1)).sum (subgradient_method.a f x₀)) < ε / 2
hG : ¬subgradient_method.G f x₀ = 0
hpos' : ↑(subgradient_method.G f x₀) ^ 2 > 0
s : Set ℝ := {x | |x| < ε / (2 * ↑(subgradient_method.G f x₀) ^ 2)}
c₁ : ∀ x_1 ∈ s, x_1 ∈ s
c₂ : ∀ x_1 ∈ s, ∃ ε, 0 < ε ∧ ∀ (x_2 : ℝ), dist x_2 x_1 < ε → x_2 ∈ s
c₃ : 0 ∈ s
a₂ : ℕ
ha₂ : ∀ (b : ℕ), a₂ ≤ b → |subgradient_method.a f x₀ b| < ε / (2 * ↑(subgradient_method.G f x₀) ^ 2)
A : ℝ := (2 * ↑(subgradient_method.G f x₀) ^ 2 * ∑ x ∈ Finset.range (a₂ + 1), subgradient_method.a f x₀ x ^ 2) / ε + 1
s₁ : Set ℝ :=
  {x | x > (2 * ↑(subgradient_method.G f x₀) ^ 2 * ∑ x ∈ Finset.range (a₂ + 1), subgradient_method.a f x₀ x ^ 2) / ε}
this : ∀ (b : ℝ), A ≤ b → b ∈ s₁
a₁ : ℕ
hasA : ∀ (b : ℕ), a₁ ≤ b → (Finset.range (b + 1)).sum (subgradient_method.a f x₀) ∈ s₁
b : ℕ
hb : a₁ ⊔ (a₂ + 1) ≤ b
hba₁ : b ≥ a₁
hba₂' : b ≥ a₂ + 1
hba₂ : b ≥ a₂
hpos : 2 * (Finset.range (b + 1)).sum (subgradient_method.a f x₀) > 0
hpos'' : (Finset.range (b + 1)).sum (subgradient_method.a f x₀) > 0
hposG : ↑(subgradient_method.G f x₀) ^ 2 * (ε / (2 * ↑(subgradient_method.G f x₀) ^ 2)) > 0
⊢ (↑(subgradient_method.G f x₀) ^ 2 * ∑ x ∈ Finset.range (a₂ + 1), subgradient_method.a f x₀ x ^ 2) /
        (2 * (Finset.range (b + 1)).sum (subgradient_method.a f x₀)) +
      (↑(subgradient_method.G f x₀) ^ 2 * ∑ x ∈ Finset.range (b - a₂), subgradient_method.a f x₀ (a₂ + 1 + x) ^ 2) /
        (2 * (Finset.range (b + 1)).sum (subgradient_method.a f x₀)) <
    ε / 4 + ε / 4

Tactic:
apply add_lt_add
    ·
  rcases hasA b hba₁ with h₃; simp [s₁] at h₃
  obtain h₃₁ := (div_lt_iff₀ εpos).mp h₃
  obtain h₃₂ := (div_lt_iff₀' hpos'').mpr h₃₁
  obtain h₃₃ := (div_lt_div_iff_of_pos_right zero_lt_four).mpr h₃₂
  calc
    _ =
        (2 * ↑alg.G ^ 2 * Finset.sum (Finset.range (a₂ + 1)) fun x => alg.a x ^ 2) /
            Finset.sum (Finset.range (b + 1)) alg.a /
          4 :=
      by field_simp; ring
    _ < ε / 4 := by apply h₃₃
    ·
  apply (div_lt_iff₀ hpos).mpr
  calc
    _ ≤ ↑alg.G ^ 2 * Finset.sum (Finset.range (b - a₂)) (fun x => (ε / (2 * ↑alg.G ^ 2)) * alg.a (a₂ + 1 + x)) :=
      by
      to_theorem apply (mul_le_mul_left hpos').mpr;apply Finset.sum_le_sum;intro i _
      have hposi : alg.a (a₂ + 1 + i) > 0 := by apply (alg.ha (a₂ + 1 + i))
      to_theorem
        rw [pow_two];apply
          (mul_le_mul_right hposi).mpr have : a₂ + 1 + i ≥ a₂ := by rw [Nat.add_assoc]; apply Nat.le_add_right
      rcases ha₂ (a₂ + 1 + i) this with hai₂
      apply le_trans _ (le_of_lt hai₂); apply le_abs_self
    _ = ↑alg.G ^ 2 * (ε / (2 * ↑alg.G ^ 2)) * Finset.sum (Finset.range (b - a₂)) fun x => alg.a (a₂ + 1 + x) :=
      by
      rw [mul_assoc]
      to_theorem apply (mul_eq_mul_left_iff).mpr left rw [← Finset.mul_sum]
    _ < ↑alg.G ^ 2 * (ε / (2 * ↑alg.G ^ 2)) * Finset.sum (Finset.range (b + 1)) (fun x => alg.a x) :=
      by
      to_theorem
        apply
          (mul_lt_mul_left hposG).mpr
            obtain heq :=
          Finset.sum_range_add (fun x => alg.a x) (a₂ + 1)
            (b -
              a₂)have h₃' : (b + 1) = a₂ + 1 + (b - a₂) := by
          rw [Nat.add_comm a₂, Nat.add_assoc, (Nat.add_sub_cancel' hba₂), Nat.add_comm]
      to_theorem rw [h₃', heq]simp apply Finset.sum_pos
      · intro i _
        apply (alg.ha i)
      · simp
    _ = ε / 4 * (2 * Finset.sum (Finset.range (b + 1)) alg.a) := by field_simp; ring

Tactic state after: