-- Mathlib/Topology/MetricSpace/Lipschitz.lean
theorem LipschitzOnWith.extend_real {f : α → ℝ} {s : Set α} {K : ℝ≥0} (hf : LipschitzOnWith K f s) :
    ∃ g : α → ℝ, LipschitzWith K g ∧ EqOn f g s

Proof state:
case inr
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
B : ∀ (y : α), BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)
⊢ ∃ g, LipschitzWith K g ∧ EqOn f g s

Tactic:
have E : EqOn f g s := fun x hx => by
  refine le_antisymm (le_ciInf fun y => hf.le_add_mul hx y.2) ?_
  simpa only [add_zero, Subtype.coe_mk, mul_zero, dist_self] using ciInf_le (B x) ⟨x, hx⟩

Result:
case inr
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
B : ∀ (y : α), BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)
E : EqOn f g s
⊢ ∃ g, LipschitzWith K g ∧ EqOn f g s

Proof state:
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
B : ∀ (y : α), BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)
E : EqOn f g s
x y : α
z : ↑s
⊢ f ↑z + ↑K * dist x ↑z ≤ f ↑z + ↑K * (dist x y + dist y ↑z)

Tactic:
gcongr

Result:
case bc.h
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
B : ∀ (y : α), BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)
E : EqOn f g s
x y : α
z : ↑s
⊢ dist x ↑z ≤ dist x y + dist y ↑z

Proof state:
case intro
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
⊢ BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)

Tactic:
refine ⟨f z - K * dist y z, ?_⟩

Result:
case intro
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
⊢ f z - ↑K * dist y z ∈ lowerBounds (range fun x => f ↑x + ↑K * dist y ↑x)

Proof state:
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
⊢ Nonempty ↑s

Tactic:
simp only [hs, nonempty_coe_sort]

Result:
no goals

Proof state:
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
B : ∀ (y : α), BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)
x : α
hx : x ∈ s
⊢ f x = g x

Tactic:
refine le_antisymm (le_ciInf fun y => hf.le_add_mul hx y.2) ?_

Result:
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
B : ∀ (y : α), BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)
x : α
hx : x ∈ s
⊢ g x ≤ f x

Proof state:
case intro.intro
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
t : ↑s
⊢ f z ≤ f ↑t + ↑K * (dist y z + dist y ↑t)

Tactic:
calc
  f z ≤ f t + K * dist z t := hf.le_add_mul hz t.2
  _ ≤ f t + K * (dist y z + dist y t) := by gcongr; apply dist_triangle_left

Result:
no goals

Proof state:
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
t : ↑s
⊢ f ↑t + ↑K * dist z ↑t ≤ f ↑t + ↑K * (dist y z + dist y ↑t)

Tactic:
gcongr

Result:
case bc.h
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
t : ↑s
⊢ dist z ↑t ≤ dist y z + dist y ↑t

Proof state:
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
B : ∀ (y : α), BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)
x : α
hx : x ∈ s
⊢ g x ≤ f x

Tactic:
simpa only [add_zero, Subtype.coe_mk, mul_zero, dist_self] using ciInf_le (B x) ⟨x, hx⟩

Result:
no goals

Proof state:
case bc.h
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
B : ∀ (y : α), BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)
E : EqOn f g s
x y : α
z : ↑s
⊢ dist x ↑z ≤ dist x y + dist y ↑z

Tactic:
apply dist_triangle

Result:
no goals

Proof state:
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
⊢ ∃ g, LipschitzWith K g ∧ EqOn f g s

Tactic:
rcases eq_empty_or_nonempty s with (rfl | hs)

Result:
case inl
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
K : ℝ≥0
hf : LipschitzOnWith K f ∅
⊢ ∃ g, LipschitzWith K g ∧ EqOn f g ∅

case inr
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
⊢ ∃ g, LipschitzWith K g ∧ EqOn f g s

Proof state:
case inr
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : s.Nonempty
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
B : ∀ (y : α), BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)
E : EqOn f g s
x y : α
z : ↑s
⊢ g x ≤ f ↑z + ↑K * dist y ↑z + ↑K * dist x y

Tactic:
calc
  g x ≤ f z + K * dist x z := ciInf_le (B x) _
  _ ≤ f z + K * dist y z + K * dist x y := by
    rw [add_assoc, ← mul_add, add_comm (dist y z)]
    gcongr
    apply dist_triangle

Result:
no goals

Proof state:
case intro
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
⊢ f z - ↑K * dist y z ∈ lowerBounds (range fun x => f ↑x + ↑K * dist y ↑x)

Tactic:
rintro w ⟨t, rfl⟩

Result:
case intro.intro
α : Type u
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ x, f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
t : ↑s
⊢ f z - ↑K * dist y z ≤ (fun x => f ↑x + ↑K * dist y ↑x) t