l3lab/ntp-mathlib huggingface dataset:
/-- Given a cocone `t` of `F`, the induced monoid linear map from the colimit to the cocone point.
We already know that this is a morphism between additive groups. The only thing left to see is that
it is a linear map, i.e. preserves scalar multiplication.
-/
def colimitDesc (t : Cocone F) : colimit F ⟶ t.pt :=
  { (AddCommGroupCat.FilteredColimits.colimitCoconeIsColimit
          (F ⋙ forget₂ (ModuleCatMax.{v, u} R) AddCommGroupCat.{max v u})).desc
      ((forget₂ (ModuleCat R) AddCommGroupCat.{max v u}).mapCocone t) with
    map_smul' := fun r x => by
      refine' Quot.inductionOn x _; clear x; 

Proof state:
R : Type u
inst✝² : Ring R
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsFiltered J
F : J ⥤ ModuleCatMax R
t : Cocone F
src✝ : (AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt ⟶
  ((forget₂ (ModuleCat R) AddCommGroupCat).mapCocone t).pt :=
  IsColimit.desc
    (AddCommGroupCat.FilteredColimits.colimitCoconeIsColimit (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat))
    ((forget₂ (ModuleCat R) AddCommGroupCat).mapCocone t)
r : R
⊢ ∀
    (a :
      (j : J) ×
        ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
                forget₂ AddGroupCat AddMonCat) ⋙
              forget AddMonCat).obj
          j),
    AddHom.toFun
        { toFun := src✝.toFun,
          map_add' :=
            (_ :
              ∀
                (x y :
                  ↑(AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt),
                ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) }
        (r •
          Quot.mk
            (Types.Quot.Rel
              ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
                  forget₂ AddGroupCat AddMonCat) ⋙
                forget AddMonCat))
            a) =
      (RingHom.id R) r •
        AddHom.toFun
          { toFun := src✝.toFun,
            map_add' :=
              (_ :
                ∀
                  (x y :
                    ↑(AddCommGroupCat.FilteredColimits.colimitCocone
                          (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt),
                  ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) }
          (Quot.mk
            (Types.Quot.Rel
              ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
                  forget₂ AddGroupCat AddMonCat) ⋙
                forget AddMonCat))
            a)

Next tactic:
intro x
/-- Given a cocone `t` of `F`, the induced monoid linear map from the colimit to the cocone point.
We already know that this is a morphism between additive groups. The only thing left to see is that
it is a linear map, i.e. preserves scalar multiplication.
-/
def colimitDesc (t : Cocone F) : colimit F ⟶ t.pt :=
  { (AddCommGroupCat.FilteredColimits.colimitCoconeIsColimit
          (F ⋙ forget₂ (ModuleCatMax.{v, u} R) AddCommGroupCat.{max v u})).desc
      ((forget₂ (ModuleCat R) AddCommGroupCat.{max v u}).mapCocone t) with
    map_smul' := fun r x => by
      refine' Quot.inductionOn x _; clear x; intro x; 

Proof state:
R : Type u
inst✝² : Ring R
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsFiltered J
F : J ⥤ ModuleCatMax R
t : Cocone F
src✝ : (AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt ⟶
  ((forget₂ (ModuleCat R) AddCommGroupCat).mapCocone t).pt :=
  IsColimit.desc
    (AddCommGroupCat.FilteredColimits.colimitCoconeIsColimit (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat))
    ((forget₂ (ModuleCat R) AddCommGroupCat).mapCocone t)
r : R
x :
  (j : J) ×
    ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
            forget₂ AddGroupCat AddMonCat) ⋙
          forget AddMonCat).obj
      j
⊢ AddHom.toFun
      { toFun := src✝.toFun,
        map_add' :=
          (_ :
            ∀
              (x y :
                ↑(AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt),
              ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) }
      (r •
        Quot.mk
          (Types.Quot.Rel
            ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
                forget₂ AddGroupCat AddMonCat) ⋙
              forget AddMonCat))
          x) =
    (RingHom.id R) r •
      AddHom.toFun
        { toFun := src✝.toFun,
          map_add' :=
            (_ :
              ∀
                (x y :
                  ↑(AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt),
                ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) }
        (Quot.mk
          (Types.Quot.Rel
            ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
                forget₂ AddGroupCat AddMonCat) ⋙
              forget AddMonCat))
          x)

Next tactic:
cases' x with j x
/-- Given a cocone `t` of `F`, the induced monoid linear map from the colimit to the cocone point.
We already know that this is a morphism between additive groups. The only thing left to see is that
it is a linear map, i.e. preserves scalar multiplication.
-/
def colimitDesc (t : Cocone F) : colimit F ⟶ t.pt :=
  { (AddCommGroupCat.FilteredColimits.colimitCoconeIsColimit
          (F ⋙ forget₂ (ModuleCatMax.{v, u} R) AddCommGroupCat.{max v u})).desc
      ((forget₂ (ModuleCat R) AddCommGroupCat.{max v u}).mapCocone t) with
    map_smul' := fun r x => by
      refine' Quot.inductionOn x _; clear x; intro x; cases' x with j x
      

Proof state:
case mk
R : Type u
inst✝² : Ring R
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsFiltered J
F : J ⥤ ModuleCatMax R
t : Cocone F
src✝ : (AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt ⟶
  ((forget₂ (ModuleCat R) AddCommGroupCat).mapCocone t).pt :=
  IsColimit.desc
    (AddCommGroupCat.FilteredColimits.colimitCoconeIsColimit (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat))
    ((forget₂ (ModuleCat R) AddCommGroupCat).mapCocone t)
r : R
j : J
x :
  ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
          forget₂ AddGroupCat AddMonCat) ⋙
        forget AddMonCat).obj
    j
⊢ AddHom.toFun
      { toFun := src✝.toFun,
        map_add' :=
          (_ :
            ∀
              (x y :
                ↑(AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt),
              ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) }
      (r •
        Quot.mk
          (Types.Quot.Rel
            ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
                forget₂ AddGroupCat AddMonCat) ⋙
              forget AddMonCat))
          { fst := j, snd := x }) =
    (RingHom.id R) r •
      AddHom.toFun
        { toFun := src✝.toFun,
          map_add' :=
            (_ :
              ∀
                (x y :
                  ↑(AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt),
                ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) }
        (Quot.mk
          (Types.Quot.Rel
            ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
                forget₂ AddGroupCat AddMonCat) ⋙
              forget AddMonCat))
          { fst := j, snd := x })

Next tactic:
erw [colimit_smul_mk_eq]
/-- Given a cocone `t` of `F`, the induced monoid linear map from the colimit to the cocone point.
We already know that this is a morphism between additive groups. The only thing left to see is that
it is a linear map, i.e. preserves scalar multiplication.
-/
def colimitDesc (t : Cocone F) : colimit F ⟶ t.pt :=
  { (AddCommGroupCat.FilteredColimits.colimitCoconeIsColimit
          (F ⋙ forget₂ (ModuleCatMax.{v, u} R) AddCommGroupCat.{max v u})).desc
      ((forget₂ (ModuleCat R) AddCommGroupCat.{max v u}).mapCocone t) with
    map_smul' := fun r x => by
      refine' Quot.inductionOn x _; clear x; intro x; cases' x with j x
      erw [colimit_smul_mk_eq]
      

Proof state:
case mk
R : Type u
inst✝² : Ring R
J : Type v
inst✝¹ : SmallCategory J
inst✝ : IsFiltered J
F : J ⥤ ModuleCatMax R
t : Cocone F
src✝ : (AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt ⟶
  ((forget₂ (ModuleCat R) AddCommGroupCat).mapCocone t).pt :=
  IsColimit.desc
    (AddCommGroupCat.FilteredColimits.colimitCoconeIsColimit (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat))
    ((forget₂ (ModuleCat R) AddCommGroupCat).mapCocone t)
r : R
j : J
x :
  ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
          forget₂ AddGroupCat AddMonCat) ⋙
        forget AddMonCat).obj
    j
⊢ AddHom.toFun
      { toFun := src✝.toFun,
        map_add' :=
          (_ :
            ∀
              (x y :
                ↑(AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt),
              ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) }
      (M.mk F { fst := { fst := j, snd := x }.fst, snd := r • { fst := j, snd := x }.snd }) =
    (RingHom.id R) r •
      AddHom.toFun
        { toFun := src✝.toFun,
          map_add' :=
            (_ :
              ∀
                (x y :
                  ↑(AddCommGroupCat.FilteredColimits.colimitCocone (F ⋙ forget₂ (ModuleCatMax R) AddCommGroupCat)).pt),
                ZeroHom.toFun (↑src✝) (x + y) = ZeroHom.toFun (↑src✝) x + ZeroHom.toFun (↑src✝) y) }
        (Quot.mk
          (Types.Quot.Rel
            ((((F ⋙ forget₂ (ModuleCat R) AddCommGroupCat) ⋙ forget₂ AddCommGroupCat AddGroupCat) ⋙
                forget₂ AddGroupCat AddMonCat) ⋙
              forget AddMonCat))
          { fst := j, snd := x })

Next tactic:
exact LinearMap.map_smul (t.ι.app j) r x
/-- The norm on a real normed space is convex on any convex set. See also `Seminorm.convexOn`
and `convexOn_univ_norm`. -/
theorem convexOn_norm (hs : Convex ℝ s) : ConvexOn ℝ s norm :=
  ⟨hs, fun x _ y _ a b ha hb _ =>
    calc
      ‖a • x + b • y‖ ≤ ‖a • x‖ + ‖b • y‖ := norm_add_le _ _
      _ = a * ‖x‖ + b * ‖y‖ := by
        

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
hs : Convex ℝ s
x : E
x✝² : x ∈ s
y : E
x✝¹ : y ∈ s
a b : ℝ
ha : 0 ≤ a
hb : 0 ≤ b
x✝ : a + b = 1
⊢ ‖a • x‖ + ‖b • y‖ = a * ‖x‖ + b * ‖y‖

Next tactic:
rw [norm_smul, norm_smul, Real.norm_of_nonneg ha, Real.norm_of_nonneg hb]
theorem convexOn_dist (z : E) (hs : Convex ℝ s) : ConvexOn ℝ s fun z' => dist z' z := by
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
z : E
hs : Convex ℝ s
⊢ ConvexOn ℝ s fun z' => dist z' z

Next tactic:
simpa [dist_eq_norm, preimage_preimage] using
    (convexOn_norm (hs.translate (-z))).comp_affineMap (AffineMap.id ℝ E - AffineMap.const ℝ E z)
theorem convex_ball (a : E) (r : ℝ) : Convex ℝ (Metric.ball a r) := by
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
a : E
r : ℝ
⊢ Convex ℝ (ball a r)

Next tactic:
simpa only [Metric.ball, sep_univ] using (convexOn_univ_dist a).convex_lt r
theorem convex_closedBall (a : E) (r : ℝ) : Convex ℝ (Metric.closedBall a r) := by
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
a : E
r : ℝ
⊢ Convex ℝ (closedBall a r)

Next tactic:
simpa only [Metric.closedBall, sep_univ] using (convexOn_univ_dist a).convex_le r
theorem Convex.thickening (hs : Convex ℝ s) (δ : ℝ) : Convex ℝ (thickening δ s) := by
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
hs : Convex ℝ s
δ : ℝ
⊢ Convex ℝ (Metric.thickening δ s)

Next tactic:
rw [← add_ball_zero]
theorem Convex.thickening (hs : Convex ℝ s) (δ : ℝ) : Convex ℝ (thickening δ s) := by
  rw [← add_ball_zero]
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
hs : Convex ℝ s
δ : ℝ
⊢ Convex ℝ (s + ball 0 δ)

Next tactic:
exact hs.add (convex_ball 0 _)
theorem Convex.cthickening (hs : Convex ℝ s) (δ : ℝ) : Convex ℝ (cthickening δ s) := by
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
hs : Convex ℝ s
δ : ℝ
⊢ Convex ℝ (Metric.cthickening δ s)

Next tactic:
obtain hδ | hδ := le_total 0 δ
theorem Convex.cthickening (hs : Convex ℝ s) (δ : ℝ) : Convex ℝ (cthickening δ s) := by
  obtain hδ | hδ := le_total 0 δ
  · 

Proof state:
case inl
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
hs : Convex ℝ s
δ : ℝ
hδ : 0 ≤ δ
⊢ Convex ℝ (Metric.cthickening δ s)

Next tactic:
rw [cthickening_eq_iInter_thickening hδ]
theorem Convex.cthickening (hs : Convex ℝ s) (δ : ℝ) : Convex ℝ (cthickening δ s) := by
  obtain hδ | hδ := le_total 0 δ
  · rw [cthickening_eq_iInter_thickening hδ]
    

Proof state:
case inl
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
hs : Convex ℝ s
δ : ℝ
hδ : 0 ≤ δ
⊢ Convex ℝ (⋂ ε, ⋂ (_ : δ < ε), Metric.thickening ε s)

Next tactic:
exact convex_iInter₂ fun _ _ => hs.thickening _
theorem Convex.cthickening (hs : Convex ℝ s) (δ : ℝ) : Convex ℝ (cthickening δ s) := by
  obtain hδ | hδ := le_total 0 δ
  · rw [cthickening_eq_iInter_thickening hδ]
    exact convex_iInter₂ fun _ _ => hs.thickening _
  · 

Proof state:
case inr
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
hs : Convex ℝ s
δ : ℝ
hδ : δ ≤ 0
⊢ Convex ℝ (Metric.cthickening δ s)

Next tactic:
rw [cthickening_of_nonpos hδ]
theorem Convex.cthickening (hs : Convex ℝ s) (δ : ℝ) : Convex ℝ (cthickening δ s) := by
  obtain hδ | hδ := le_total 0 δ
  · rw [cthickening_eq_iInter_thickening hδ]
    exact convex_iInter₂ fun _ _ => hs.thickening _
  · rw [cthickening_of_nonpos hδ]
    

Proof state:
case inr
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s t : Set E
hs : Convex ℝ s
δ : ℝ
hδ : δ ≤ 0
⊢ Convex ℝ (closure s)

Next tactic:
exact hs.closure
/-- Given a point `x` in the convex hull of `s` and a point `y` in the convex hull of `t`,
there exist points `x' ∈ s` and `y' ∈ t` at distance at least `dist x y`. -/
theorem convexHull_exists_dist_ge2 {s t : Set E} {x y : E} (hx : x ∈ convexHull ℝ s)
    (hy : y ∈ convexHull ℝ t) : ∃ x' ∈ s, ∃ y' ∈ t, dist x y ≤ dist x' y' := by
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t✝ s t : Set E
x y : E
hx : x ∈ (convexHull ℝ) s
hy : y ∈ (convexHull ℝ) t
⊢ ∃ x' ∈ s, ∃ y' ∈ t, dist x y ≤ dist x' y'

Next tactic:
rcases convexHull_exists_dist_ge hx y with ⟨x', hx', Hx'⟩
/-- Given a point `x` in the convex hull of `s` and a point `y` in the convex hull of `t`,
there exist points `x' ∈ s` and `y' ∈ t` at distance at least `dist x y`. -/
theorem convexHull_exists_dist_ge2 {s t : Set E} {x y : E} (hx : x ∈ convexHull ℝ s)
    (hy : y ∈ convexHull ℝ t) : ∃ x' ∈ s, ∃ y' ∈ t, dist x y ≤ dist x' y' := by
  rcases convexHull_exists_dist_ge hx y with ⟨x', hx', Hx'⟩
  

Proof state:
case intro.intro
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t✝ s t : Set E
x y : E
hx : x ∈ (convexHull ℝ) s
hy : y ∈ (convexHull ℝ) t
x' : E
hx' : x' ∈ s
Hx' : dist x y ≤ dist x' y
⊢ ∃ x' ∈ s, ∃ y' ∈ t, dist x y ≤ dist x' y'

Next tactic:
rcases convexHull_exists_dist_ge hy x' with ⟨y', hy', Hy'⟩
/-- Given a point `x` in the convex hull of `s` and a point `y` in the convex hull of `t`,
there exist points `x' ∈ s` and `y' ∈ t` at distance at least `dist x y`. -/
theorem convexHull_exists_dist_ge2 {s t : Set E} {x y : E} (hx : x ∈ convexHull ℝ s)
    (hy : y ∈ convexHull ℝ t) : ∃ x' ∈ s, ∃ y' ∈ t, dist x y ≤ dist x' y' := by
  rcases convexHull_exists_dist_ge hx y with ⟨x', hx', Hx'⟩
  rcases convexHull_exists_dist_ge hy x' with ⟨y', hy', Hy'⟩
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t✝ s t : Set E
x y : E
hx : x ∈ (convexHull ℝ) s
hy : y ∈ (convexHull ℝ) t
x' : E
hx' : x' ∈ s
Hx' : dist x y ≤ dist x' y
y' : E
hy' : y' ∈ t
Hy' : dist y x' ≤ dist y' x'
⊢ ∃ x' ∈ s, ∃ y' ∈ t, dist x y ≤ dist x' y'

Next tactic:
use x', hx', y', hy'
/-- Given a point `x` in the convex hull of `s` and a point `y` in the convex hull of `t`,
there exist points `x' ∈ s` and `y' ∈ t` at distance at least `dist x y`. -/
theorem convexHull_exists_dist_ge2 {s t : Set E} {x y : E} (hx : x ∈ convexHull ℝ s)
    (hy : y ∈ convexHull ℝ t) : ∃ x' ∈ s, ∃ y' ∈ t, dist x y ≤ dist x' y' := by
  rcases convexHull_exists_dist_ge hx y with ⟨x', hx', Hx'⟩
  rcases convexHull_exists_dist_ge hy x' with ⟨y', hy', Hy'⟩
  use x', hx', y', hy'
  

Proof state:
case right
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t✝ s t : Set E
x y : E
hx : x ∈ (convexHull ℝ) s
hy : y ∈ (convexHull ℝ) t
x' : E
hx' : x' ∈ s
Hx' : dist x y ≤ dist x' y
y' : E
hy' : y' ∈ t
Hy' : dist y x' ≤ dist y' x'
⊢ dist x y ≤ dist x' y'

Next tactic:
exact le_trans Hx' (dist_comm y x' ▸ dist_comm y' x' ▸ Hy')
/-- Emetric diameter of the convex hull of a set `s` equals the emetric diameter of `s`. -/
@[simp]
theorem convexHull_ediam (s : Set E) : EMetric.diam (convexHull ℝ s) = EMetric.diam s := by
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t s : Set E
⊢ EMetric.diam ((convexHull ℝ) s) = EMetric.diam s

Next tactic:
refine' (EMetric.diam_le fun x hx y hy => _).antisymm (EMetric.diam_mono <| subset_convexHull ℝ s)
/-- Emetric diameter of the convex hull of a set `s` equals the emetric diameter of `s`. -/
@[simp]
theorem convexHull_ediam (s : Set E) : EMetric.diam (convexHull ℝ s) = EMetric.diam s := by
  refine' (EMetric.diam_le fun x hx y hy => _).antisymm (EMetric.diam_mono <| subset_convexHull ℝ s)
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t s : Set E
x : E
hx : x ∈ (convexHull ℝ) s
y : E
hy : y ∈ (convexHull ℝ) s
⊢ edist x y ≤ EMetric.diam s

Next tactic:
rcases convexHull_exists_dist_ge2 hx hy with ⟨x', hx', y', hy', H⟩
/-- Emetric diameter of the convex hull of a set `s` equals the emetric diameter of `s`. -/
@[simp]
theorem convexHull_ediam (s : Set E) : EMetric.diam (convexHull ℝ s) = EMetric.diam s := by
  refine' (EMetric.diam_le fun x hx y hy => _).antisymm (EMetric.diam_mono <| subset_convexHull ℝ s)
  rcases convexHull_exists_dist_ge2 hx hy with ⟨x', hx', y', hy', H⟩
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t s : Set E
x : E
hx : x ∈ (convexHull ℝ) s
y : E
hy : y ∈ (convexHull ℝ) s
x' : E
hx' : x' ∈ s
y' : E
hy' : y' ∈ s
H : dist x y ≤ dist x' y'
⊢ edist x y ≤ EMetric.diam s

Next tactic:
rw [edist_dist]
/-- Emetric diameter of the convex hull of a set `s` equals the emetric diameter of `s`. -/
@[simp]
theorem convexHull_ediam (s : Set E) : EMetric.diam (convexHull ℝ s) = EMetric.diam s := by
  refine' (EMetric.diam_le fun x hx y hy => _).antisymm (EMetric.diam_mono <| subset_convexHull ℝ s)
  rcases convexHull_exists_dist_ge2 hx hy with ⟨x', hx', y', hy', H⟩
  rw [edist_dist]
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t s : Set E
x : E
hx : x ∈ (convexHull ℝ) s
y : E
hy : y ∈ (convexHull ℝ) s
x' : E
hx' : x' ∈ s
y' : E
hy' : y' ∈ s
H : dist x y ≤ dist x' y'
⊢ ENNReal.ofReal (dist x y) ≤ EMetric.diam s

Next tactic:
apply le_trans (ENNReal.ofReal_le_ofReal H)
/-- Emetric diameter of the convex hull of a set `s` equals the emetric diameter of `s`. -/
@[simp]
theorem convexHull_ediam (s : Set E) : EMetric.diam (convexHull ℝ s) = EMetric.diam s := by
  refine' (EMetric.diam_le fun x hx y hy => _).antisymm (EMetric.diam_mono <| subset_convexHull ℝ s)
  rcases convexHull_exists_dist_ge2 hx hy with ⟨x', hx', y', hy', H⟩
  rw [edist_dist]
  apply le_trans (ENNReal.ofReal_le_ofReal H)
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t s : Set E
x : E
hx : x ∈ (convexHull ℝ) s
y : E
hy : y ∈ (convexHull ℝ) s
x' : E
hx' : x' ∈ s
y' : E
hy' : y' ∈ s
H : dist x y ≤ dist x' y'
⊢ ENNReal.ofReal (dist x' y') ≤ EMetric.diam s

Next tactic:
rw [← edist_dist]
/-- Emetric diameter of the convex hull of a set `s` equals the emetric diameter of `s`. -/
@[simp]
theorem convexHull_ediam (s : Set E) : EMetric.diam (convexHull ℝ s) = EMetric.diam s := by
  refine' (EMetric.diam_le fun x hx y hy => _).antisymm (EMetric.diam_mono <| subset_convexHull ℝ s)
  rcases convexHull_exists_dist_ge2 hx hy with ⟨x', hx', y', hy', H⟩
  rw [edist_dist]
  apply le_trans (ENNReal.ofReal_le_ofReal H)
  rw [← edist_dist]
  

Proof state:
case intro.intro.intro.intro
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t s : Set E
x : E
hx : x ∈ (convexHull ℝ) s
y : E
hy : y ∈ (convexHull ℝ) s
x' : E
hx' : x' ∈ s
y' : E
hy' : y' ∈ s
H : dist x y ≤ dist x' y'
⊢ edist x' y' ≤ EMetric.diam s

Next tactic:
exact EMetric.edist_le_diam_of_mem hx' hy'
/-- Diameter of the convex hull of a set `s` equals the emetric diameter of `s`. -/
@[simp]
theorem convexHull_diam (s : Set E) : Metric.diam (convexHull ℝ s) = Metric.diam s := by
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t s : Set E
⊢ diam ((convexHull ℝ) s) = diam s

Next tactic:
simp only [Metric.diam, convexHull_ediam]
/-- Convex hull of `s` is bounded if and only if `s` is bounded. -/
@[simp]
theorem isBounded_convexHull {s : Set E} :
    Bornology.IsBounded (convexHull ℝ s) ↔ Bornology.IsBounded s := by
  

Proof state:
ι : Type u_1
E : Type u_2
P : Type u_3
inst✝³ : SeminormedAddCommGroup E
inst✝² : NormedSpace ℝ E
inst✝¹ : PseudoMetricSpace P
inst✝ : NormedAddTorsor E P
s✝ t s : Set E
⊢ Bornology.IsBounded ((convexHull ℝ) s) ↔ Bornology.IsBounded s

Next tactic:
simp only [Metric.isBounded_iff_ediam_ne_top, convexHull_ediam]