l3lab/ntp-mathlib huggingface dataset:
/-- If the Hausdorff distance is `< r`, then any point in one of the sets is at distance
`< r` of a point in the other set -/
theorem exists_dist_lt_of_hausdorffDist_lt' {r : ℝ} (h : y ∈ t) (H : hausdorffDist s t < r)
    (fin : hausdorffEdist s t ≠ ⊤) : ∃ x ∈ s, dist x y < r := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
r : ℝ
h : y ∈ t
H : hausdorffDist s t < r
fin : hausdorffEdist s t ≠ ⊤
⊢ ∃ x ∈ s, dist x y < r

Next tactic:
rw [hausdorffDist_comm] at H
/-- If the Hausdorff distance is `< r`, then any point in one of the sets is at distance
`< r` of a point in the other set -/
theorem exists_dist_lt_of_hausdorffDist_lt' {r : ℝ} (h : y ∈ t) (H : hausdorffDist s t < r)
    (fin : hausdorffEdist s t ≠ ⊤) : ∃ x ∈ s, dist x y < r := by
  rw [hausdorffDist_comm] at H
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
r : ℝ
h : y ∈ t
H : hausdorffDist t s < r
fin : hausdorffEdist s t ≠ ⊤
⊢ ∃ x ∈ s, dist x y < r

Next tactic:
rw [hausdorffEdist_comm] at fin
/-- If the Hausdorff distance is `< r`, then any point in one of the sets is at distance
`< r` of a point in the other set -/
theorem exists_dist_lt_of_hausdorffDist_lt' {r : ℝ} (h : y ∈ t) (H : hausdorffDist s t < r)
    (fin : hausdorffEdist s t ≠ ⊤) : ∃ x ∈ s, dist x y < r := by
  rw [hausdorffDist_comm] at H
  rw [hausdorffEdist_comm] at fin
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
r : ℝ
h : y ∈ t
H : hausdorffDist t s < r
fin : hausdorffEdist t s ≠ ⊤
⊢ ∃ x ∈ s, dist x y < r

Next tactic:
simpa [dist_comm] using exists_dist_lt_of_hausdorffDist_lt h H fin
/-- The infimum distance to `s` and `t` are the same, up to the Hausdorff distance
between `s` and `t` -/
theorem infDist_le_infDist_add_hausdorffDist (fin : hausdorffEdist s t ≠ ⊤) :
    infDist x t ≤ infDist x s + hausdorffDist s t := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist s t ≠ ⊤
⊢ infDist x t ≤ infDist x s + hausdorffDist s t

Next tactic:
refine toReal_le_add' infEdist_le_infEdist_add_hausdorffEdist (fun h ↦ ?_) (flip absurd fin)
/-- The infimum distance to `s` and `t` are the same, up to the Hausdorff distance
between `s` and `t` -/
theorem infDist_le_infDist_add_hausdorffDist (fin : hausdorffEdist s t ≠ ⊤) :
    infDist x t ≤ infDist x s + hausdorffDist s t := by
  refine toReal_le_add' infEdist_le_infEdist_add_hausdorffEdist (fun h ↦ ?_) (flip absurd fin)
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist s t ≠ ⊤
h : infEdist x s = ⊤
⊢ infEdist x t = ⊤

Next tactic:
rw [infEdist_eq_top_iff, ← not_nonempty_iff_eq_empty] at h ⊢
/-- The infimum distance to `s` and `t` are the same, up to the Hausdorff distance
between `s` and `t` -/
theorem infDist_le_infDist_add_hausdorffDist (fin : hausdorffEdist s t ≠ ⊤) :
    infDist x t ≤ infDist x s + hausdorffDist s t := by
  refine toReal_le_add' infEdist_le_infEdist_add_hausdorffEdist (fun h ↦ ?_) (flip absurd fin)
  rw [infEdist_eq_top_iff, ← not_nonempty_iff_eq_empty] at h ⊢
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist s t ≠ ⊤
h : ¬Set.Nonempty s
⊢ ¬Set.Nonempty t

Next tactic:
rw [hausdorffEdist_comm] at fin
/-- The infimum distance to `s` and `t` are the same, up to the Hausdorff distance
between `s` and `t` -/
theorem infDist_le_infDist_add_hausdorffDist (fin : hausdorffEdist s t ≠ ⊤) :
    infDist x t ≤ infDist x s + hausdorffDist s t := by
  refine toReal_le_add' infEdist_le_infEdist_add_hausdorffEdist (fun h ↦ ?_) (flip absurd fin)
  rw [infEdist_eq_top_iff, ← not_nonempty_iff_eq_empty] at h ⊢
  rw [hausdorffEdist_comm] at fin
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist t s ≠ ⊤
h : ¬Set.Nonempty s
⊢ ¬Set.Nonempty t

Next tactic:
exact mt (nonempty_of_hausdorffEdist_ne_top · fin) h
/-- The Hausdorff distance is invariant under isometries -/
theorem hausdorffDist_image (h : Isometry Φ) :
    hausdorffDist (Φ '' s) (Φ '' t) = hausdorffDist s t := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
h : Isometry Φ
⊢ hausdorffDist (Φ '' s) (Φ '' t) = hausdorffDist s t

Next tactic:
simp [hausdorffDist, hausdorffEdist_image h]
/-- The Hausdorff distance satisfies the triangular inequality -/
theorem hausdorffDist_triangle (fin : hausdorffEdist s t ≠ ⊤) :
    hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist s t ≠ ⊤
⊢ hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u

Next tactic:
refine toReal_le_add' hausdorffEdist_triangle (flip absurd fin) (not_imp_not.1 fun h ↦ ?_)
/-- The Hausdorff distance satisfies the triangular inequality -/
theorem hausdorffDist_triangle (fin : hausdorffEdist s t ≠ ⊤) :
    hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u := by
  refine toReal_le_add' hausdorffEdist_triangle (flip absurd fin) (not_imp_not.1 fun h ↦ ?_)
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist s t ≠ ⊤
h : ¬hausdorffEdist s u = ⊤
⊢ ¬hausdorffEdist t u = ⊤

Next tactic:
rw [hausdorffEdist_comm] at fin
/-- The Hausdorff distance satisfies the triangular inequality -/
theorem hausdorffDist_triangle (fin : hausdorffEdist s t ≠ ⊤) :
    hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u := by
  refine toReal_le_add' hausdorffEdist_triangle (flip absurd fin) (not_imp_not.1 fun h ↦ ?_)
  rw [hausdorffEdist_comm] at fin
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist t s ≠ ⊤
h : ¬hausdorffEdist s u = ⊤
⊢ ¬hausdorffEdist t u = ⊤

Next tactic:
exact ne_top_of_le_ne_top (add_ne_top.2 ⟨fin, h⟩) hausdorffEdist_triangle
/-- The Hausdorff distance satisfies the triangular inequality -/
theorem hausdorffDist_triangle' (fin : hausdorffEdist t u ≠ ⊤) :
    hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist t u ≠ ⊤
⊢ hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u

Next tactic:
rw [hausdorffEdist_comm] at fin
/-- The Hausdorff distance satisfies the triangular inequality -/
theorem hausdorffDist_triangle' (fin : hausdorffEdist t u ≠ ⊤) :
    hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u := by
  rw [hausdorffEdist_comm] at fin
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist u t ≠ ⊤
⊢ hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u

Next tactic:
have I : hausdorffDist u s ≤ hausdorffDist u t + hausdorffDist t s :=
    hausdorffDist_triangle fin
/-- The Hausdorff distance satisfies the triangular inequality -/
theorem hausdorffDist_triangle' (fin : hausdorffEdist t u ≠ ⊤) :
    hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u := by
  rw [hausdorffEdist_comm] at fin
  have I : hausdorffDist u s ≤ hausdorffDist u t + hausdorffDist t s :=
    hausdorffDist_triangle fin
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist u t ≠ ⊤
I : hausdorffDist u s ≤ hausdorffDist u t + hausdorffDist t s
⊢ hausdorffDist s u ≤ hausdorffDist s t + hausdorffDist t u

Next tactic:
simpa [add_comm, hausdorffDist_comm] using I
/-- The Hausdorff distance between a set and its closure vanish -/
@[simp]
theorem hausdorffDist_self_closure : hausdorffDist s (closure s) = 0 := by 

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
⊢ hausdorffDist s (closure s) = 0

Next tactic:
simp [hausdorffDist]
/-- Replacing a set by its closure does not change the Hausdorff distance. -/
@[simp]
theorem hausdorffDist_closure₁ : hausdorffDist (closure s) t = hausdorffDist s t := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
⊢ hausdorffDist (closure s) t = hausdorffDist s t

Next tactic:
simp [hausdorffDist]
/-- Replacing a set by its closure does not change the Hausdorff distance. -/
@[simp]
theorem hausdorffDist_closure₂ : hausdorffDist s (closure t) = hausdorffDist s t := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
⊢ hausdorffDist s (closure t) = hausdorffDist s t

Next tactic:
simp [hausdorffDist]
/-- The Hausdorff distance between two sets and their closures coincide -/
-- @[simp] -- Porting note: simp can prove this
theorem hausdorffDist_closure : hausdorffDist (closure s) (closure t) = hausdorffDist s t := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
⊢ hausdorffDist (closure s) (closure t) = hausdorffDist s t

Next tactic:
simp [hausdorffDist]
/-- Two sets are at zero Hausdorff distance if and only if they have the same closures -/
theorem hausdorffDist_zero_iff_closure_eq_closure (fin : hausdorffEdist s t ≠ ⊤) :
    hausdorffDist s t = 0 ↔ closure s = closure t := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
fin : hausdorffEdist s t ≠ ⊤
⊢ hausdorffDist s t = 0 ↔ closure s = closure t

Next tactic:
simp [← hausdorffEdist_zero_iff_closure_eq_closure, hausdorffDist,
    ENNReal.toReal_eq_zero_iff, fin]
/-- Two closed sets are at zero Hausdorff distance if and only if they coincide -/
theorem _root_.IsClosed.hausdorffDist_zero_iff_eq (hs : IsClosed s) (ht : IsClosed t)
    (fin : hausdorffEdist s t ≠ ⊤) : hausdorffDist s t = 0 ↔ s = t := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoMetricSpace α
inst✝ : PseudoMetricSpace β
s t u : Set α
x y : α
Φ : α → β
hs : IsClosed s
ht : IsClosed t
fin : hausdorffEdist s t ≠ ⊤
⊢ hausdorffDist s t = 0 ↔ s = t

Next tactic:
simp [← hausdorffEdist_zero_iff_eq_of_closed hs ht, hausdorffDist, ENNReal.toReal_eq_zero_iff,
    fin]
/-- An exterior point of a subset `E` (i.e., a point outside the closure of `E`) is not in the
(open) `δ`-thickening of `E` for small enough positive `δ`. -/
lemma eventually_not_mem_thickening_of_infEdist_pos {E : Set α} {x : α} (h : x ∉ closure E) :
    ∀ᶠ δ in 𝓝 (0 : ℝ), x ∉ Metric.thickening δ E := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x✝ : α
E : Set α
x : α
h : x ∉ closure E
⊢ ∀ᶠ (δ : ℝ) in 𝓝 0, x ∉ thickening δ E

Next tactic:
obtain ⟨ε, ⟨ε_pos, ε_lt⟩⟩ := exists_real_pos_lt_infEdist_of_not_mem_closure h
/-- An exterior point of a subset `E` (i.e., a point outside the closure of `E`) is not in the
(open) `δ`-thickening of `E` for small enough positive `δ`. -/
lemma eventually_not_mem_thickening_of_infEdist_pos {E : Set α} {x : α} (h : x ∉ closure E) :
    ∀ᶠ δ in 𝓝 (0 : ℝ), x ∉ Metric.thickening δ E := by
  obtain ⟨ε, ⟨ε_pos, ε_lt⟩⟩ := exists_real_pos_lt_infEdist_of_not_mem_closure h
  

Proof state:
case intro.intro
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x✝ : α
E : Set α
x : α
h : x ∉ closure E
ε : ℝ
ε_pos : 0 < ε
ε_lt : ENNReal.ofReal ε < infEdist x E
⊢ ∀ᶠ (δ : ℝ) in 𝓝 0, x ∉ thickening δ E

Next tactic:
filter_upwards [eventually_lt_nhds ε_pos] with δ hδ
/-- An exterior point of a subset `E` (i.e., a point outside the closure of `E`) is not in the
(open) `δ`-thickening of `E` for small enough positive `δ`. -/
lemma eventually_not_mem_thickening_of_infEdist_pos {E : Set α} {x : α} (h : x ∉ closure E) :
    ∀ᶠ δ in 𝓝 (0 : ℝ), x ∉ Metric.thickening δ E := by
  obtain ⟨ε, ⟨ε_pos, ε_lt⟩⟩ := exists_real_pos_lt_infEdist_of_not_mem_closure h
  filter_upwards [eventually_lt_nhds ε_pos] with δ hδ
  

Proof state:
case h
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x✝ : α
E : Set α
x : α
h : x ∉ closure E
ε : ℝ
ε_pos : 0 < ε
ε_lt : ENNReal.ofReal ε < infEdist x E
δ : ℝ
hδ : δ < ε
⊢ x ∉ thickening δ E

Next tactic:
simp only [thickening, mem_setOf_eq, not_lt]
/-- An exterior point of a subset `E` (i.e., a point outside the closure of `E`) is not in the
(open) `δ`-thickening of `E` for small enough positive `δ`. -/
lemma eventually_not_mem_thickening_of_infEdist_pos {E : Set α} {x : α} (h : x ∉ closure E) :
    ∀ᶠ δ in 𝓝 (0 : ℝ), x ∉ Metric.thickening δ E := by
  obtain ⟨ε, ⟨ε_pos, ε_lt⟩⟩ := exists_real_pos_lt_infEdist_of_not_mem_closure h
  filter_upwards [eventually_lt_nhds ε_pos] with δ hδ
  simp only [thickening, mem_setOf_eq, not_lt]
  

Proof state:
case h
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x✝ : α
E : Set α
x : α
h : x ∉ closure E
ε : ℝ
ε_pos : 0 < ε
ε_lt : ENNReal.ofReal ε < infEdist x E
δ : ℝ
hδ : δ < ε
⊢ ENNReal.ofReal δ ≤ infEdist x E

Next tactic:
exact (ENNReal.ofReal_le_ofReal hδ.le).trans ε_lt.le
/-- The (open) thickening of the empty set is empty. -/
@[simp]
theorem thickening_empty (δ : ℝ) : thickening δ (∅ : Set α) = ∅ := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x : α
δ : ℝ
⊢ thickening δ ∅ = ∅

Next tactic:
simp only [thickening, setOf_false, infEdist_empty, not_top_lt]
theorem frontier_thickening_disjoint (A : Set α) :
    Pairwise (Disjoint on fun r : ℝ => frontier (thickening r A)) := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x : α
A : Set α
⊢ Pairwise (Disjoint on fun r => frontier (thickening r A))

Next tactic:
refine' (pairwise_disjoint_on _).2 fun r₁ r₂ hr => _
theorem frontier_thickening_disjoint (A : Set α) :
    Pairwise (Disjoint on fun r : ℝ => frontier (thickening r A)) := by
  refine' (pairwise_disjoint_on _).2 fun r₁ r₂ hr => _
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x : α
A : Set α
r₁ r₂ : ℝ
hr : r₁ < r₂
⊢ Disjoint (frontier (thickening r₁ A)) (frontier (thickening r₂ A))

Next tactic:
rcases le_total r₁ 0 with h₁ | h₁
theorem frontier_thickening_disjoint (A : Set α) :
    Pairwise (Disjoint on fun r : ℝ => frontier (thickening r A)) := by
  refine' (pairwise_disjoint_on _).2 fun r₁ r₂ hr => _
  rcases le_total r₁ 0 with h₁ | h₁
  · 

Proof state:
case inl
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x : α
A : Set α
r₁ r₂ : ℝ
hr : r₁ < r₂
h₁ : r₁ ≤ 0
⊢ Disjoint (frontier (thickening r₁ A)) (frontier (thickening r₂ A))

Next tactic:
simp [thickening_of_nonpos h₁]
theorem frontier_thickening_disjoint (A : Set α) :
    Pairwise (Disjoint on fun r : ℝ => frontier (thickening r A)) := by
  refine' (pairwise_disjoint_on _).2 fun r₁ r₂ hr => _
  rcases le_total r₁ 0 with h₁ | h₁
  · simp [thickening_of_nonpos h₁]
  

Proof state:
case inr
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x : α
A : Set α
r₁ r₂ : ℝ
hr : r₁ < r₂
h₁ : 0 ≤ r₁
⊢ Disjoint (frontier (thickening r₁ A)) (frontier (thickening r₂ A))

Next tactic:
refine' ((disjoint_singleton.2 fun h => hr.ne _).preimage _).mono (frontier_thickening_subset _)
    (frontier_thickening_subset _)
theorem frontier_thickening_disjoint (A : Set α) :
    Pairwise (Disjoint on fun r : ℝ => frontier (thickening r A)) := by
  refine' (pairwise_disjoint_on _).2 fun r₁ r₂ hr => _
  rcases le_total r₁ 0 with h₁ | h₁
  · simp [thickening_of_nonpos h₁]
  refine' ((disjoint_singleton.2 fun h => hr.ne _).preimage _).mono (frontier_thickening_subset _)
    (frontier_thickening_subset _)
  

Proof state:
case inr
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x : α
A : Set α
r₁ r₂ : ℝ
hr : r₁ < r₂
h₁ : 0 ≤ r₁
h : ENNReal.ofReal r₁ = ENNReal.ofReal r₂
⊢ r₁ = r₂

Next tactic:
apply_fun ENNReal.toReal at h
theorem frontier_thickening_disjoint (A : Set α) :
    Pairwise (Disjoint on fun r : ℝ => frontier (thickening r A)) := by
  refine' (pairwise_disjoint_on _).2 fun r₁ r₂ hr => _
  rcases le_total r₁ 0 with h₁ | h₁
  · simp [thickening_of_nonpos h₁]
  refine' ((disjoint_singleton.2 fun h => hr.ne _).preimage _).mono (frontier_thickening_subset _)
    (frontier_thickening_subset _)
  apply_fun ENNReal.toReal at h
  

Proof state:
case inr
ι : Sort u_1
α : Type u
β : Type v
inst✝ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x : α
A : Set α
r₁ r₂ : ℝ
hr : r₁ < r₂
h₁ : 0 ≤ r₁
h : ENNReal.toReal (ENNReal.ofReal r₁) = ENNReal.toReal (ENNReal.ofReal r₂)
⊢ r₁ = r₂

Next tactic:
rwa [ENNReal.toReal_ofReal h₁, ENNReal.toReal_ofReal (h₁.trans hr.le)] at h
/-- A point in a metric space belongs to the (open) `δ`-thickening of a subset `E` if and only if
it is at distance less than `δ` from some point of `E`. -/
theorem mem_thickening_iff {E : Set X} {x : X} : x ∈ thickening δ E ↔ ∃ z ∈ E, dist x z < δ := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x✝ : α
X : Type u
inst✝ : PseudoMetricSpace X
E : Set X
x : X
⊢ x ∈ thickening δ E ↔ ∃ z ∈ E, dist x z < δ

Next tactic:
have key_iff : ∀ z : X, edist x z < ENNReal.ofReal δ ↔ dist x z < δ := fun z ↦ by
    rw [dist_edist, lt_ofReal_iff_toReal_lt (edist_ne_top _ _)]
/-- A point in a metric space belongs to the (open) `δ`-thickening of a subset `E` if and only if
it is at distance less than `δ` from some point of `E`. -/
theorem mem_thickening_iff {E : Set X} {x : X} : x ∈ thickening δ E ↔ ∃ z ∈ E, dist x z < δ := by
  have key_iff : ∀ z : X, edist x z < ENNReal.ofReal δ ↔ dist x z < δ := fun z ↦ by
    

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x✝ : α
X : Type u
inst✝ : PseudoMetricSpace X
E : Set X
x z : X
⊢ edist x z < ENNReal.ofReal δ ↔ dist x z < δ

Next tactic:
rw [dist_edist, lt_ofReal_iff_toReal_lt (edist_ne_top _ _)]
/-- A point in a metric space belongs to the (open) `δ`-thickening of a subset `E` if and only if
it is at distance less than `δ` from some point of `E`. -/
theorem mem_thickening_iff {E : Set X} {x : X} : x ∈ thickening δ E ↔ ∃ z ∈ E, dist x z < δ := by
  have key_iff : ∀ z : X, edist x z < ENNReal.ofReal δ ↔ dist x z < δ := fun z ↦ by
    rw [dist_edist, lt_ofReal_iff_toReal_lt (edist_ne_top _ _)]
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ : ℝ
s : Set α
x✝ : α
X : Type u
inst✝ : PseudoMetricSpace X
E : Set X
x : X
key_iff : ∀ (z : X), edist x z < ENNReal.ofReal δ ↔ dist x z < δ
⊢ x ∈ thickening δ E ↔ ∃ z ∈ E, dist x z < δ

Next tactic:
simp_rw [mem_thickening_iff_exists_edist_lt, key_iff]
@[simp]
theorem thickening_singleton (δ : ℝ) (x : X) : thickening δ ({x} : Set X) = ball x δ := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x✝ : α
X : Type u
inst✝ : PseudoMetricSpace X
δ : ℝ
x : X
⊢ thickening δ {x} = ball x δ

Next tactic:
ext
@[simp]
theorem thickening_singleton (δ : ℝ) (x : X) : thickening δ ({x} : Set X) = ball x δ := by
  ext
  

Proof state:
case h
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x✝¹ : α
X : Type u
inst✝ : PseudoMetricSpace X
δ : ℝ
x x✝ : X
⊢ x✝ ∈ thickening δ {x} ↔ x✝ ∈ ball x δ

Next tactic:
simp [mem_thickening_iff]
theorem ball_subset_thickening {x : X} {E : Set X} (hx : x ∈ E) (δ : ℝ) :
    ball x δ ⊆ thickening δ E :=
  Subset.trans (by 

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x✝ : α
X : Type u
inst✝ : PseudoMetricSpace X
x : X
E : Set X
hx : x ∈ E
δ : ℝ
⊢ ball x δ ⊆ thickening δ {x}

Next tactic:
simp [Subset.rfl]
/-- The (open) `δ`-thickening `Metric.thickening δ E` of a subset `E` in a metric space equals the
union of balls of radius `δ` centered at points of `E`. -/
theorem thickening_eq_biUnion_ball {δ : ℝ} {E : Set X} : thickening δ E = ⋃ x ∈ E, ball x δ := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x : α
X : Type u
inst✝ : PseudoMetricSpace X
δ : ℝ
E : Set X
⊢ thickening δ E = ⋃ x ∈ E, ball x δ

Next tactic:
ext x
/-- The (open) `δ`-thickening `Metric.thickening δ E` of a subset `E` in a metric space equals the
union of balls of radius `δ` centered at points of `E`. -/
theorem thickening_eq_biUnion_ball {δ : ℝ} {E : Set X} : thickening δ E = ⋃ x ∈ E, ball x δ := by
  ext x
  

Proof state:
case h
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x✝ : α
X : Type u
inst✝ : PseudoMetricSpace X
δ : ℝ
E : Set X
x : X
⊢ x ∈ thickening δ E ↔ x ∈ ⋃ x ∈ E, ball x δ

Next tactic:
simp only [mem_iUnion₂, exists_prop]
/-- The (open) `δ`-thickening `Metric.thickening δ E` of a subset `E` in a metric space equals the
union of balls of radius `δ` centered at points of `E`. -/
theorem thickening_eq_biUnion_ball {δ : ℝ} {E : Set X} : thickening δ E = ⋃ x ∈ E, ball x δ := by
  ext x
  simp only [mem_iUnion₂, exists_prop]
  

Proof state:
case h
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x✝ : α
X : Type u
inst✝ : PseudoMetricSpace X
δ : ℝ
E : Set X
x : X
⊢ x ∈ thickening δ E ↔ ∃ i ∈ E, x ∈ ball i δ

Next tactic:
exact mem_thickening_iff
protected theorem _root_.Bornology.IsBounded.thickening {δ : ℝ} {E : Set X} (h : IsBounded E) :
    IsBounded (thickening δ E) := by
  

Proof state:
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x : α
X : Type u
inst✝ : PseudoMetricSpace X
δ : ℝ
E : Set X
h : Bornology.IsBounded E
⊢ Bornology.IsBounded (thickening δ E)

Next tactic:
rcases E.eq_empty_or_nonempty with rfl | ⟨x, hx⟩
protected theorem _root_.Bornology.IsBounded.thickening {δ : ℝ} {E : Set X} (h : IsBounded E) :
    IsBounded (thickening δ E) := by
  rcases E.eq_empty_or_nonempty with rfl | ⟨x, hx⟩
  · 

Proof state:
case inl
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x : α
X : Type u
inst✝ : PseudoMetricSpace X
δ : ℝ
h : Bornology.IsBounded ∅
⊢ Bornology.IsBounded (thickening δ ∅)

Next tactic:
simp
protected theorem _root_.Bornology.IsBounded.thickening {δ : ℝ} {E : Set X} (h : IsBounded E) :
    IsBounded (thickening δ E) := by
  rcases E.eq_empty_or_nonempty with rfl | ⟨x, hx⟩
  · simp
  · 

Proof state:
case inr.intro
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x✝ : α
X : Type u
inst✝ : PseudoMetricSpace X
δ : ℝ
E : Set X
h : Bornology.IsBounded E
x : X
hx : x ∈ E
⊢ Bornology.IsBounded (thickening δ E)

Next tactic:
refine (isBounded_iff_subset_closedBall x).2 ⟨δ + diam E, fun y hy ↦ ?_⟩
protected theorem _root_.Bornology.IsBounded.thickening {δ : ℝ} {E : Set X} (h : IsBounded E) :
    IsBounded (thickening δ E) := by
  rcases E.eq_empty_or_nonempty with rfl | ⟨x, hx⟩
  · simp
  · refine (isBounded_iff_subset_closedBall x).2 ⟨δ + diam E, fun y hy ↦ ?_⟩
    

Proof state:
case inr.intro
ι : Sort u_1
α : Type u
β : Type v
inst✝¹ : PseudoEMetricSpace α
δ✝ : ℝ
s : Set α
x✝ : α
X : Type u
inst✝ : PseudoMetricSpace X
δ : ℝ
E : Set X
h : Bornology.IsBounded E
x : X
hx : x ∈ E
y : X
hy : y ∈ thickening δ E
⊢ y ∈ closedBall x (δ + diam E)

Next tactic:
calc
      dist y x ≤ infDist y E + diam E := dist_le_infDist_add_diam (x := y) h hx
      _ ≤ δ + diam E := add_le_add_right ((mem_thickening_iff_infDist_lt ⟨x, hx⟩).1 hy).le _