import Mathlib
import Optlib


open Set Real

open Set Real PNat

theorem extracted_formal_statement_0.{u_1} {E : Type u_1} [inst : NormedAddCommGroup E] [inst_1 : InnerProductSpace ℝ E]
  [inst_2 : CompleteSpace E] {x0 : E} {f h : E → ℝ} {f' : E → E} {alg : Nesterov_second f h f' x0} {xm : E}
  (minφ : IsMinOn (f + h) univ xm) :
  let φ := fun z => f z + h z;
  (∀ (z : E), φ z = f z + h z) →
    ∀ (k : ℕ+),
      prox_prop ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h)
          (Nesterov_second.y f h f' x0 (↑k - 1) -
            (Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • f' (Nesterov_second.z f h f' x0 k))
          (Nesterov_second.y f h f' x0 ↑k) →
        Nesterov_second.γ f h f' x0 ↑k • (Nesterov_second.y f h f' x0 (↑k - 1) - Nesterov_second.y f h f' x0 ↑k) -
              Nesterov_second.t f h f' x0 ↑k • f' (Nesterov_second.z f h f' x0 k) ∈
            SubderivAt (Nesterov_second.t f h f' x0 ↑k • h) (Nesterov_second.y f h f' x0 ↑k) →
          Nesterov_second.y f h f' x0 (↑k - 1) -
                  (Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) •
                    f' (Nesterov_second.z f h f' x0 k) -
                Nesterov_second.y f h f' x0 ↑k ∈
              SubderivAt ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h)
                (Nesterov_second.y f h f' x0 ↑k) ∧
            (fun x => Nesterov_second.γ f h f' x0 ↑k • x)
                (Nesterov_second.y f h f' x0 (↑k - 1) -
                    (Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) •
                      f' (Nesterov_second.z f h f' x0 k) -
                  Nesterov_second.y f h f' x0 ↑k) =
              Nesterov_second.γ f h f' x0 ↑k • (Nesterov_second.y f h f' x0 (↑k - 1) - Nesterov_second.y f h f' x0 ↑k) -
                Nesterov_second.t f h f' x0 ↑k • f' (Nesterov_second.z f h f' x0 k) := sorry

Tactic state before:
E : Type u_1
inst✝² : NormedAddCommGroup E
inst✝¹ : InnerProductSpace ℝ E
inst✝ : CompleteSpace E
x0 : E
f h : E → ℝ
f' : E → E
alg : Nesterov_second f h f' x0
xm : E
minφ : IsMinOn (f + h) univ xm
φ : E → ℝ := fun z => f z + h z
φdef : ∀ (z : E), φ z = f z + h z
k : ℕ+
h1 :
  prox_prop ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h)
    (Nesterov_second.y f h f' x0 (↑k - 1) -
      (Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • f' (Nesterov_second.z f h f' x0 k))
    (Nesterov_second.y f h f' x0 ↑k)
⊢ Nesterov_second.γ f h f' x0 ↑k • (Nesterov_second.y f h f' x0 (↑k - 1) - Nesterov_second.y f h f' x0 ↑k) -
      Nesterov_second.t f h f' x0 ↑k • f' (Nesterov_second.z f h f' x0 k) ∈
    SubderivAt (Nesterov_second.t f h f' x0 ↑k • h) (Nesterov_second.y f h f' x0 ↑k)

Tactic:
rw [prox_iff_subderiv] at h1
    have upd2 := @SubderivAt.pos_smul _ _ _ ((alg.t k / alg.γ k) • h) (alg.y k) (alg.γ k) (alg.γbound k).1
    rw [← smul_assoc, smul_eq_mul, mul_div, mul_comm, ← mul_div, div_self, mul_one] at upd2
    rw [upd2]
    use (alg.y (↑k - 1) - (alg.t ↑k / alg.γ ↑k) • f' (alg.z k) - alg.y ↑k)

Tactic state after:
[case h
 E : Type u_1
 inst✝² : NormedAddCommGroup E
 inst✝¹ : InnerProductSpace ℝ E
 inst✝ : CompleteSpace E
 x0 : E
 f h : E → ℝ
 f' : E → E
 alg : Nesterov_second f h f' x0
 xm : E
 minφ : IsMinOn (f + h) univ xm
 φ : E → ℝ := fun z => f z + h z
 φdef : ∀ (z : E), φ z = f z + h z
 k : ℕ+
 h1 :
   Nesterov_second.y f h f' x0 (↑k - 1) -
         (Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • f' (Nesterov_second.z f h f' x0 k) -
       Nesterov_second.y f h f' x0 ↑k ∈
     SubderivAt ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h) (Nesterov_second.y f h f' x0 ↑k)
 upd2 :
   SubderivAt (Nesterov_second.t f h f' x0 ↑k • h) (Nesterov_second.y f h f' x0 ↑k) =
     Nesterov_second.γ f h f' x0 ↑k •
       SubderivAt ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h)
         (Nesterov_second.y f h f' x0 ↑k)
 ⊢ Nesterov_second.y f h f' x0 (↑k - 1) -
           (Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • f' (Nesterov_second.z f h f' x0 k) -
         Nesterov_second.y f h f' x0 ↑k ∈
       SubderivAt ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h)
         (Nesterov_second.y f h f' x0 ↑k) ∧
     (fun x => Nesterov_second.γ f h f' x0 ↑k • x)
         (Nesterov_second.y f h f' x0 (↑k - 1) -
             (Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • f' (Nesterov_second.z f h f' x0 k) -
           Nesterov_second.y f h f' x0 ↑k) =
       Nesterov_second.γ f h f' x0 ↑k • (Nesterov_second.y f h f' x0 (↑k - 1) - Nesterov_second.y f h f' x0 ↑k) -
         Nesterov_second.t f h f' x0 ↑k • f' (Nesterov_second.z f h f' x0 k),
 E : Type u_1
 inst✝² : NormedAddCommGroup E
 inst✝¹ : InnerProductSpace ℝ E
 inst✝ : CompleteSpace E
 x0 : E
 f h : E → ℝ
 f' : E → E
 alg : Nesterov_second f h f' x0
 xm : E
 minφ : IsMinOn (f + h) univ xm
 φ : E → ℝ := fun z => f z + h z
 φdef : ∀ (z : E), φ z = f z + h z
 k : ℕ+
 h1 :
   Nesterov_second.y f h f' x0 (↑k - 1) -
         (Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • f' (Nesterov_second.z f h f' x0 k) -
       Nesterov_second.y f h f' x0 ↑k ∈
     SubderivAt ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h) (Nesterov_second.y f h f' x0 ↑k)
 upd2 :
   SubderivAt ((Nesterov_second.t f h f' x0 ↑k * (Nesterov_second.γ f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k)) • h)
       (Nesterov_second.y f h f' x0 ↑k) =
     Nesterov_second.γ f h f' x0 ↑k •
       SubderivAt ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h)
         (Nesterov_second.y f h f' x0 ↑k)
 ⊢ Nesterov_second.γ f h f' x0 ↑k ≠ 0,
 case hfun
 E : Type u_1
 inst✝² : NormedAddCommGroup E
 inst✝¹ : InnerProductSpace ℝ E
 inst✝ : CompleteSpace E
 x0 : E
 f h : E → ℝ
 f' : E → E
 alg : Nesterov_second f h f' x0
 xm : E
 minφ : IsMinOn (f + h) univ xm
 φ : E → ℝ := fun z => f z + h z
 φdef : ∀ (z : E), φ z = f z + h z
 k : ℕ+
 h1 :
   prox_prop ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h)
     (Nesterov_second.y f h f' x0 (↑k - 1) -
       (Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • f' (Nesterov_second.z f h f' x0 k))
     (Nesterov_second.y f h f' x0 ↑k)
 ⊢ ConvexOn ℝ univ ((Nesterov_second.t f h f' x0 ↑k / Nesterov_second.γ f h f' x0 ↑k) • h)]