Skip to content

Commit 53cb457

Browse files
gasparattilaocfnash
andcommitted
feat(Topology/UniformSpace): define the Hausdorff uniformity (#31031)
This PR defines the Hausdorff uniformity on `Closeds`, `Compacts` and `NonemptyCompacts`. Since `Closeds` and `NonemptyCompacts` already have metrics, they are changed to use the newly defined uniformity. Co-authored-by: Oliver Nash <github@olivernash.org>
1 parent 3830f92 commit 53cb457

File tree

6 files changed

+358
-31
lines changed

6 files changed

+358
-31
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7150,6 +7150,7 @@ public import Mathlib.Topology.UniformSpace.AbstractCompletion
71507150
public import Mathlib.Topology.UniformSpace.Ascoli
71517151
public import Mathlib.Topology.UniformSpace.Basic
71527152
public import Mathlib.Topology.UniformSpace.Cauchy
7153+
public import Mathlib.Topology.UniformSpace.Closeds
71537154
public import Mathlib.Topology.UniformSpace.Compact
71547155
public import Mathlib.Topology.UniformSpace.CompactConvergence
71557156
public import Mathlib.Topology.UniformSpace.CompareReals

Mathlib/Data/Rel.lean

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,15 @@ def preimage : Set α := {a | ∃ b ∈ t, a ~[R] b}
223223
@[gcongr] lemma image_subset_image (hs : s₁ ⊆ s₂) : image R s₁ ⊆ image R s₂ :=
224224
fun _ ⟨a, ha, hab⟩ ↦ ⟨a, hs ha, hab⟩
225225

226+
@[gcongr] lemma image_subset_image_left (hR : R₁ ⊆ R₂) : image R₁ s ⊆ image R₂ s :=
227+
fun _ ⟨a, ha, hab⟩ ↦ ⟨a, ha, hR hab⟩
228+
226229
@[gcongr] lemma preimage_subset_preimage (ht : t₁ ⊆ t₂) : preimage R t₁ ⊆ preimage R t₂ :=
227230
fun _ ⟨a, ha, hab⟩ ↦ ⟨a, ht ha, hab⟩
228231

232+
@[gcongr] lemma preimage_subset_preimage_left (hR : R₁ ⊆ R₂) : preimage R₁ t ⊆ preimage R₂ t :=
233+
fun _ ⟨a, ha, hab⟩ ↦ ⟨a, ha, hR hab⟩
234+
229235
variable (R t) in
230236
@[simp] lemma image_inv : R.inv.image t = preimage R t := rfl
231237

@@ -385,6 +391,12 @@ lemma subset_iterate_comp [R.IsRefl] {S : SetRel α β} : ∀ {n}, S ⊆ (R ○
385391
| 0 => .rfl
386392
| _n + 1 => right_subset_comp.trans subset_iterate_comp
387393

394+
lemma self_subset_image [R.IsRefl] (s : Set α) : s ⊆ R.image s :=
395+
fun x hx => ⟨x, hx, R.rfl⟩
396+
397+
lemma self_subset_preimage [R.IsRefl] (s : Set α) : s ⊆ R.preimage s :=
398+
fun x hx => ⟨x, hx, R.rfl⟩
399+
388400
lemma exists_eq_singleton_of_prod_subset_id {s t : Set α} (hs : s.Nonempty) (ht : t.Nonempty)
389401
(hst : s ×ˢ t ⊆ SetRel.id) : ∃ x, s = {x} ∧ t = {x} := by
390402
obtain ⟨a, ha⟩ := hs

Mathlib/Topology/MetricSpace/Closeds.lean

Lines changed: 61 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ module
77

88
public import Mathlib.Analysis.SpecificLimits.Basic
99
public import Mathlib.Topology.MetricSpace.HausdorffDistance
10-
public import Mathlib.Topology.Sets.Compacts
10+
public import Mathlib.Topology.UniformSpace.Closeds
1111

1212
/-!
1313
# Closed subsets
@@ -34,15 +34,60 @@ namespace EMetric
3434

3535
section
3636

37+
variable {α : Type*} [PseudoEMetricSpace α]
38+
39+
theorem mem_hausdorffEntourage_of_hausdorffEdist_lt {s t : Set α} {δ : ℝ≥0∞}
40+
(h : hausdorffEdist s t < δ) : (s, t) ∈ hausdorffEntourage {p | edist p.1 p.2 < δ} := by
41+
rw [hausdorffEdist, max_lt_iff] at h
42+
rw [hausdorffEntourage, Set.mem_setOf]
43+
conv => enter [2, 2, 1, 1, _]; rw [edist_comm]
44+
have {s t : Set α} (h : ⨆ x ∈ s, infEdist x t < δ) :
45+
s ⊆ SetRel.preimage {p | edist p.1 p.2 < δ} t := by
46+
intro x hx
47+
simpa only [infEdist, iInf_lt_iff, exists_prop] using (le_iSup₂ x hx).trans_lt h
48+
exact ⟨this h.1, this h.2
49+
50+
theorem hausdorffEdist_le_of_mem_hausdorffEntourage {s t : Set α} {δ : ℝ≥0∞}
51+
(h : (s, t) ∈ hausdorffEntourage {p | edist p.1 p.2 ≤ δ}) : hausdorffEdist s t ≤ δ := by
52+
rw [hausdorffEdist, max_le_iff]
53+
rw [hausdorffEntourage, Set.mem_setOf] at h
54+
conv at h => enter [2, 2, 1, 1, _]; rw [edist_comm]
55+
have {s t : Set α} (h : s ⊆ SetRel.preimage {p | edist p.1 p.2 ≤ δ} t) :
56+
⨆ x ∈ s, infEdist x t ≤ δ := by
57+
rw [iSup₂_le_iff]
58+
intro x hx
59+
obtain ⟨y, hy, hxy⟩ := h hx
60+
exact iInf₂_le_of_le y hy hxy
61+
exact ⟨this h.1, this h.2
62+
63+
/-- The Hausdorff pseudo emetric on the powerset of a pseudo emetric space.
64+
See note [reducible non-instances]. -/
65+
protected abbrev _root_.PseudoEMetricSpace.hausdorff : PseudoEMetricSpace (Set α) where
66+
edist s t := hausdorffEdist s t
67+
edist_self _ := hausdorffEdist_self
68+
edist_comm _ _ := hausdorffEdist_comm
69+
edist_triangle _ _ _ := hausdorffEdist_triangle
70+
toUniformSpace := .hausdorff α
71+
uniformity_edist := by
72+
refine le_antisymm
73+
(le_iInf₂ fun ε hε => Filter.le_principal_iff.mpr ?_)
74+
(uniformity_basis_edist.lift' monotone_hausdorffEntourage |>.ge_iff.mpr fun ε hε =>
75+
Filter.mem_iInf_of_mem ε <| Filter.mem_iInf_of_mem hε fun _ =>
76+
mem_hausdorffEntourage_of_hausdorffEdist_lt)
77+
obtain ⟨δ, hδ, hδε⟩ := exists_between hε
78+
filter_upwards [Filter.mem_lift' (uniformity_basis_edist_le.mem_of_mem hδ)]
79+
with _ h using hδε.trans_le' <| hausdorffEdist_le_of_mem_hausdorffEntourage h
80+
81+
end
82+
83+
section
84+
3785
variable {α β : Type*} [EMetricSpace α] [EMetricSpace β] {s : Set α}
3886

3987
/-- In emetric spaces, the Hausdorff edistance defines an emetric space structure
4088
on the type of closed subsets -/
4189
instance Closeds.emetricSpace : EMetricSpace (Closeds α) where
42-
edist s t := hausdorffEdist (s : Set α) t
43-
edist_self _ := hausdorffEdist_self
44-
edist_comm _ _ := hausdorffEdist_comm
45-
edist_triangle _ _ _ := hausdorffEdist_triangle
90+
__ := PseudoEMetricSpace.hausdorff.induced SetLike.coe
4691
eq_of_edist_eq_zero {s t} h :=
4792
Closeds.ext <| (hausdorffEdist_zero_iff_eq_of_closed s.isClosed t.isClosed).1 h
4893

@@ -63,20 +108,11 @@ theorem continuous_infEdist_hausdorffEdist :
63108
_ = infEdist y t + 2 * edist (x, s) (y, t) := by rw [← mul_two, mul_comm]
64109

65110
/-- Subsets of a given closed subset form a closed set -/
66-
theorem Closeds.isClosed_subsets_of_isClosed (hs : IsClosed s) :
67-
IsClosed { t : Closeds α | (t : Set α) ⊆ s } := by
68-
refine isClosed_of_closure_subset fun
69-
(t : Closeds α) (ht : t ∈ closure {t : Closeds α | (t : Set α) ⊆ s}) (x : α) (hx : x ∈ t) => ?_
70-
have : x ∈ closure s := by
71-
refine mem_closure_iff.2 fun ε εpos => ?_
72-
obtain ⟨u : Closeds α, hu : u ∈ {t : Closeds α | (t : Set α) ⊆ s}, Dtu : edist t u < ε⟩ :=
73-
mem_closure_iff.1 ht ε εpos
74-
obtain ⟨y : α, hy : y ∈ u, Dxy : edist x y < ε⟩ := exists_edist_lt_of_hausdorffEdist_lt hx Dtu
75-
exact ⟨y, hu hy, Dxy⟩
76-
rwa [hs.closure_eq] at this
111+
@[deprecated (since := "2025-11-19")]
112+
alias Closeds.isClosed_subsets_of_isClosed := TopologicalSpace.Closeds.isClosed_subsets_of_isClosed
77113

78114
@[deprecated (since := "2025-08-20")]
79-
alias isClosed_subsets_of_isClosed := Closeds.isClosed_subsets_of_isClosed
115+
alias isClosed_subsets_of_isClosed := TopologicalSpace.Closeds.isClosed_subsets_of_isClosed
80116

81117
/-- By definition, the edistance on `Closeds α` is given by the Hausdorff edistance -/
82118
theorem Closeds.edist_eq {s t : Closeds α} : edist s t = hausdorffEdist (s : Set α) t :=
@@ -235,10 +271,7 @@ namespace NonemptyCompacts
235271
/-- In an emetric space, the type of non-empty compact subsets is an emetric space,
236272
where the edistance is the Hausdorff edistance -/
237273
instance emetricSpace : EMetricSpace (NonemptyCompacts α) where
238-
edist s t := hausdorffEdist (s : Set α) t
239-
edist_self _ := hausdorffEdist_self
240-
edist_comm _ _ := hausdorffEdist_comm
241-
edist_triangle _ _ _ := hausdorffEdist_triangle
274+
__ := PseudoEMetricSpace.hausdorff.induced SetLike.coe
242275
eq_of_edist_eq_zero {s t} h := NonemptyCompacts.ext <| by
243276
have : closure (s : Set α) = closure t := hausdorffEdist_zero_iff_closure_eq_closure.1 h
244277
rwa [s.isCompact.isClosed.closure_eq, t.isCompact.isClosed.closure_eq] at this
@@ -248,21 +281,18 @@ theorem isometry_toCloseds : Isometry (@NonemptyCompacts.toCloseds α _ _) :=
248281
fun _ _ => rfl
249282

250283
/-- `NonemptyCompacts.toCloseds` is a uniform embedding (as it is an isometry) -/
251-
theorem isUniformEmbedding_toCloseds :
252-
IsUniformEmbedding (@NonemptyCompacts.toCloseds α _ _) :=
253-
isometry_toCloseds.isUniformEmbedding
284+
@[deprecated (since := "2025-11-19")]
285+
alias isUniformEmbedding_toCloseds := TopologicalSpace.NonemptyCompacts.isUniformEmbedding_toCloseds
254286

255287
@[deprecated (since := "2025-08-20")]
256-
alias ToCloseds.isUniformEmbedding := isUniformEmbedding_toCloseds
288+
alias ToCloseds.isUniformEmbedding := TopologicalSpace.NonemptyCompacts.isUniformEmbedding_toCloseds
257289

258290
/-- `NonemptyCompacts.toCloseds` is continuous (as it is an isometry) -/
259-
@[fun_prop]
260-
theorem continuous_toCloseds : Continuous (@NonemptyCompacts.toCloseds α _ _) :=
261-
isometry_toCloseds.continuous
291+
@[deprecated (since := "2025-11-19")]
292+
alias continuous_toCloseds := TopologicalSpace.NonemptyCompacts.continuous_toCloseds
262293

263-
lemma isClosed_subsets_of_isClosed (hs : IsClosed s) :
264-
IsClosed {A : NonemptyCompacts α | (A : Set α) ⊆ s} :=
265-
(Closeds.isClosed_subsets_of_isClosed hs).preimage continuous_toCloseds
294+
@[deprecated (since := "2025-11-19")]
295+
alias isClosed_subsets_of_isClosed := TopologicalSpace.NonemptyCompacts.isClosed_subsets_of_isClosed
266296

267297
/-- The range of `NonemptyCompacts.toCloseds` is closed in a complete space -/
268298
theorem isClosed_in_closeds [CompleteSpace α] :

Mathlib/Topology/Order.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -813,6 +813,10 @@ theorem isOpen_induced_eq {s : Set α} :
813813
theorem isOpen_induced {s : Set β} (h : IsOpen s) : IsOpen[induced f t] (f ⁻¹' s) :=
814814
⟨s, h, rfl⟩
815815

816+
theorem isClosed_induced {s : Set β} (h : IsClosed s) : IsClosed[induced f t] (f ⁻¹' s) := by
817+
simp_rw [← isOpen_compl_iff]
818+
exact isOpen_induced h.isOpen_compl
819+
816820
theorem map_nhds_induced_eq (a : α) : map f (@nhds α (induced f t) a) = 𝓝[range f] f a := by
817821
rw [nhds_induced, Filter.map_comap, nhdsWithin]
818822

Mathlib/Topology/Sets/Compacts.lean

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,9 @@ theorem mem_toCloseds [T2Space α] {x : α} {s : Compacts α} :
6767
x ∈ s.toCloseds ↔ x ∈ s :=
6868
Iff.rfl
6969

70+
theorem toCloseds_injective [T2Space α] : Function.Injective (toCloseds (α := α)) :=
71+
.of_comp (f := SetLike.coe) SetLike.coe_injective
72+
7073
instance : CanLift (Set α) (Compacts α) (↑) IsCompact where prf K hK := ⟨⟨K, hK⟩, rfl⟩
7174

7275
@[ext]
@@ -295,6 +298,9 @@ theorem mem_toCloseds [T2Space α] {x : α} {s : NonemptyCompacts α} :
295298
x ∈ s.toCloseds ↔ x ∈ s :=
296299
Iff.rfl
297300

301+
theorem toCloseds_injective [T2Space α] : Function.Injective (toCloseds (α := α)) :=
302+
.of_comp (f := SetLike.coe) SetLike.coe_injective
303+
298304
@[ext]
299305
protected theorem ext {s t : NonemptyCompacts α} (h : (s : Set α) = t) : s = t :=
300306
SetLike.ext' h
@@ -314,6 +320,9 @@ theorem mem_toCompacts {x : α} {s : NonemptyCompacts α} :
314320
x ∈ s.toCompacts ↔ x ∈ s :=
315321
Iff.rfl
316322

323+
theorem toCompacts_injective : Function.Injective (toCompacts (α := α)) :=
324+
.of_comp (f := SetLike.coe) SetLike.coe_injective
325+
317326
instance : Max (NonemptyCompacts α) :=
318327
fun s t => ⟨s.toCompacts ⊔ t.toCompacts, s.nonempty.mono subset_union_left⟩⟩
319328

0 commit comments

Comments
 (0)