Theorem: LipschitzOnWith.extend_real
File: Mathlib/Topology/MetricSpace/Lipschitz.lean

tactic: rcases eq_empty_or_nonempty s with (rfl | hs)
state_before: α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
⊢ ∃ g, LipschitzWith K g ∧ EqOn f g s

tactic: have : Nonempty s := by simp only [hs, nonempty_coe_sort]
state_before: case inr
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
⊢ ∃ g, LipschitzWith K g ∧ EqOn f g s

tactic: let g := fun y : α => iInf fun x : s => f x + K * dist y x
state_before: case inr
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
⊢ ∃ g, LipschitzWith K g ∧ EqOn f g s

tactic: have B : ∀ y : α, BddBelow (range fun x : s => f x + K * dist y x) := fun y => by
  rcases hs with ⟨z, hz⟩
  refine' ⟨f z - K * dist y z, _⟩
  rintro w ⟨t, rfl⟩
  dsimp
  rw [sub_le_iff_le_add, add_assoc, ← mul_add, add_comm (dist y t)]
  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
state_before: case inr
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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⟩
state_before: case inr
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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: refine' ⟨g, LipschitzWith.of_le_add_mul K fun x y => _, E⟩
state_before: case inr
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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

tactic: rw [← sub_le_iff_le_add]
state_before: case inr
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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 : α
⊢ g x ≤ g y + ↑K * dist x y

tactic: refine' le_ciInf fun z => _
state_before: case inr
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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 : α
⊢ g x - ↑K * dist x y ≤ g y

tactic: rw [sub_le_iff_le_add]
state_before: case inr
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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 - ↑K * dist x y ≤ f ↑z + ↑K * dist y ↑z

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
state_before: case inr
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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: exact ⟨fun _ => 0, (LipschitzWith.const _).weaken (zero_le _), eqOn_empty _ _⟩
state_before: case inl
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
K : ℝ≥0
hf : LipschitzOnWith K f ∅
⊢ ∃ g, LipschitzWith K g ∧ EqOn f g ∅

tactic: simp only [hs, nonempty_coe_sort]
state_before: α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
⊢ Nonempty ↑s

tactic: rcases hs with ⟨z, hz⟩
state_before: α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), f ↑x + ↑K * dist y ↑x
y : α
⊢ BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)

tactic: refine' ⟨f z - K * dist y z, _⟩
state_before: case intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
⊢ BddBelow (range fun x => f ↑x + ↑K * dist y ↑x)

tactic: rintro w ⟨t, rfl⟩
state_before: case intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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: dsimp
state_before: case intro.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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

tactic: rw [sub_le_iff_le_add, add_assoc, ← mul_add, add_comm (dist y t)]
state_before: case intro.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
t : ↑s
⊢ f z - ↑K * dist y z ≤ f ↑t + ↑K * 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
state_before: case intro.intro
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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: gcongr
state_before: α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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: apply dist_triangle_left
state_before: case bc.h
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), f ↑x + ↑K * dist y ↑x
y z : α
hz : z ∈ s
t : ↑s
⊢ dist z ↑t ≤ dist y z + dist y ↑t

tactic: refine' le_antisymm (le_ciInf fun y => hf.le_add_mul hx y.2) _
state_before: α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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: simpa only [add_zero, Subtype.coe_mk, mul_zero, dist_self] using ciInf_le (B x) ⟨x, hx⟩
state_before: α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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: rw [add_assoc, ← mul_add, add_comm (dist y z)]
state_before: α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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 y ↑z + ↑K * dist x y

tactic: gcongr
state_before: α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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: apply dist_triangle
state_before: case bc.h
α : Type u
β : Type v
γ : Type w
ι : Type x
inst✝ : PseudoMetricSpace α
f : α → ℝ
s : Set α
K : ℝ≥0
hf : LipschitzOnWith K f s
hs : Set.Nonempty s
this : Nonempty ↑s
g : α → ℝ := fun y => ⨅ (x : ↑s), 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