Skip to content

Commit 8387c03

Browse files
refactor(Topology): cleaner way to get metric spaces from emetric spaces (#29321)
Change EMetricSpace.toMetricSpaceOfDist in Mathlib/Topology/MetricSpace/Basic and PseudoEMetricSpace.toPseudoMetricSpaceOfDist in Mathlib/Topology/MetricSpace/Pseudo/Defs to require nonnegativity of given distance function rather than finiteness of old edistance.
1 parent a843d6c commit 8387c03

File tree

8 files changed

+72
-82
lines changed

8 files changed

+72
-82
lines changed

Mathlib/Analysis/Normed/Lp/PiLp.lean

Lines changed: 15 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ are equivalent on `ℝ^n` for abstract (norm equivalence) reasons. Instead, we g
6060
We also set up the theory for `PseudoEMetricSpace` and `PseudoMetricSpace`.
6161
-/
6262

63-
6463
open Module Real Set Filter RCLike Bornology Uniformity Topology NNReal ENNReal WithLp
6564

6665
noncomputable section
@@ -334,31 +333,25 @@ abbrev pseudoMetricAux : PseudoMetricSpace (PiLp p α) :=
334333
PseudoEMetricSpace.toPseudoMetricSpaceOfDist dist
335334
(fun f g => by
336335
rcases p.dichotomy with (rfl | h)
337-
· exact iSup_edist_ne_top_aux f g
338-
· rw [edist_eq_sum (zero_lt_one.trans_le h)]
339-
exact ENNReal.rpow_ne_top_of_nonneg (by positivity) <| ENNReal.sum_ne_top.2 fun _ _ ↦
340-
by finiteness)
336+
· simp only [dist, top_ne_zero, ↓reduceIte]
337+
exact Real.iSup_nonneg fun i ↦ dist_nonneg
338+
· simp only [dist]
339+
split_ifs with hp
340+
· linarith
341+
· exact Real.iSup_nonneg fun i ↦ dist_nonneg
342+
· exact rpow_nonneg (Fintype.sum_nonneg fun i ↦ by positivity) (1 / p.toReal))
341343
fun f g => by
342344
rcases p.dichotomy with (rfl | h)
343345
· rw [edist_eq_iSup, dist_eq_iSup]
344346
cases isEmpty_or_nonempty ι
345-
· simp only [Real.iSup_of_isEmpty, ciSup_of_empty, ENNReal.bot_eq_zero, ENNReal.toReal_zero]
346-
· refine le_antisymm (ciSup_le fun i => ?_) ?_
347-
· rw [← ENNReal.ofReal_le_iff_le_toReal (iSup_edist_ne_top_aux f g), ←
348-
PseudoMetricSpace.edist_dist]
349-
-- Porting note: `le_iSup` needed some help
350-
exact le_iSup (fun k => edist (f k) (g k)) i
351-
· refine ENNReal.toReal_le_of_le_ofReal (Real.sSup_nonneg ?_) (iSup_le fun i => ?_)
352-
· rintro - ⟨i, rfl⟩
353-
exact dist_nonneg
354-
· change PseudoMetricSpace.edist _ _ ≤ _
355-
rw [PseudoMetricSpace.edist_dist]
356-
-- Porting note: `le_ciSup` needed some help
357-
exact ENNReal.ofReal_le_ofReal
358-
(le_ciSup (Finite.bddAbove_range (fun k => dist (f k) (g k))) i)
359-
· have A (i) : edist (f i) (g i) ^ p.toReal ≠ ⊤ := by finiteness
360-
simp only [edist_eq_sum (zero_lt_one.trans_le h), dist_edist, ENNReal.toReal_rpow,
361-
dist_eq_sum (zero_lt_one.trans_le h), ← ENNReal.toReal_sum fun i _ => A i]
347+
· simp
348+
· refine ENNReal.eq_of_forall_le_nnreal_iff fun r ↦ ?_
349+
have : BddAbove <| .range fun i ↦ dist (f i) (g i) := Finite.bddAbove_range _
350+
simp [ciSup_le_iff this]
351+
· have : 0 < p.toReal := by rw [ENNReal.toReal_pos_iff_ne_top]; rintro rfl; norm_num at h
352+
simp only [edist_eq_sum, edist_dist, dist_eq_sum, this]
353+
rw [← ENNReal.ofReal_rpow_of_nonneg (by simp [Finset.sum_nonneg, Real.rpow_nonneg]) (by simp)]
354+
simp [Real.rpow_nonneg, ENNReal.ofReal_sum_of_nonneg, ← ENNReal.ofReal_rpow_of_nonneg]
362355

363356
attribute [local instance] PiLp.pseudoMetricAux
364357

Mathlib/Analysis/Normed/Lp/ProdLp.lean

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -342,26 +342,17 @@ abbrev prodPseudoMetricAux [PseudoMetricSpace α] [PseudoMetricSpace β] :
342342
PseudoEMetricSpace.toPseudoMetricSpaceOfDist dist
343343
(fun f g => by
344344
rcases p.dichotomy with (rfl | h)
345-
· exact prod_sup_edist_ne_top_aux f g
346-
· rw [prod_edist_eq_add (zero_lt_one.trans_le h)]
347-
finiteness)
345+
· simp [prod_dist_eq_sup]
346+
· simp only [dist, one_div, dite_eq_ite]
347+
split_ifs with hp' <;> positivity)
348348
fun f g => by
349349
rcases p.dichotomy with (rfl | h)
350-
· rw [prod_edist_eq_sup, prod_dist_eq_sup]
351-
refine le_antisymm (sup_le ?_ ?_) ?_
352-
· rw [← ENNReal.ofReal_le_iff_le_toReal (prod_sup_edist_ne_top_aux f g),
353-
← PseudoMetricSpace.edist_dist]
354-
exact le_sup_left
355-
· rw [← ENNReal.ofReal_le_iff_le_toReal (prod_sup_edist_ne_top_aux f g),
356-
← PseudoMetricSpace.edist_dist]
357-
exact le_sup_right
358-
· refine ENNReal.toReal_le_of_le_ofReal ?_ ?_
359-
· simp only [le_sup_iff, dist_nonneg, or_self]
360-
· simp [-ofReal_max]
361-
· have h1 : edist f.fst g.fst ^ p.toReal ≠ ⊤ := by finiteness
362-
have h2 : edist f.snd g.snd ^ p.toReal ≠ ⊤ := by finiteness
363-
simp only [prod_edist_eq_add (zero_lt_one.trans_le h), dist_edist, ENNReal.toReal_rpow,
364-
prod_dist_eq_add (zero_lt_one.trans_le h), ← ENNReal.toReal_add h1 h2]
350+
· refine ENNReal.eq_of_forall_le_nnreal_iff fun r ↦ ?_
351+
simp [prod_edist_eq_sup, prod_dist_eq_sup]
352+
· have : 0 < p.toReal := by rw [ENNReal.toReal_pos_iff_ne_top]; rintro rfl; norm_num at h
353+
simp only [prod_edist_eq_add, edist_dist, one_div, prod_dist_eq_add, this]
354+
rw [← ENNReal.ofReal_rpow_of_nonneg, ENNReal.ofReal_add, ← ENNReal.ofReal_rpow_of_nonneg,
355+
← ENNReal.ofReal_rpow_of_nonneg] <;> simp [Real.rpow_nonneg, add_nonneg]
365356

366357
attribute [local instance] WithLp.prodPseudoMetricAux
367358

Mathlib/Data/ENNReal/Real.lean

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,10 @@ theorem ofReal_le_ofReal_iff {p q : ℝ} (h : 0 ≤ q) :
147147
lemma ofReal_le_ofReal_iff' {p q : ℝ} : ENNReal.ofReal p ≤ .ofReal q ↔ p ≤ q ∨ p ≤ 0 :=
148148
coe_le_coe.trans Real.toNNReal_le_toNNReal_iff'
149149

150+
@[simp, norm_cast]
151+
lemma ofReal_le_coe {a : ℝ} {b : ℝ≥0} : ENNReal.ofReal a ≤ b ↔ a ≤ b := by
152+
simp [← ofReal_le_ofReal_iff]
153+
150154
lemma ofReal_lt_ofReal_iff' {p q : ℝ} : ENNReal.ofReal p < .ofReal q ↔ p < q ∧ 0 < q :=
151155
coe_lt_coe.trans Real.toNNReal_lt_toNNReal_iff'
152156

Mathlib/Topology/MetricSpace/Basic.lean

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -73,17 +73,17 @@ uniformity are defeq in the metric space and the emetric space. In this definiti
7373
is given separately, to be able to prescribe some expression which is not defeq to the push-forward
7474
of the edistance to reals. -/
7575
abbrev EMetricSpace.toMetricSpaceOfDist {α : Type u} [EMetricSpace α] (dist : α → α → ℝ)
76-
(edist_ne_top : ∀ x y : α, edist x y ≠ ⊤) (h : ∀ x y, dist x y = ENNReal.toReal (edist x y)) :
76+
(dist_nonneg : ∀ x y, 0 ≤ dist x y) (h : ∀ x y, edist x y = .ofReal (dist x y)) :
7777
MetricSpace α :=
78-
@MetricSpace.ofT0PseudoMetricSpace _
79-
(PseudoEMetricSpace.toPseudoMetricSpaceOfDist dist edist_ne_top h) _
78+
letI := PseudoEMetricSpace.toPseudoMetricSpaceOfDist dist dist_nonneg h
79+
MetricSpace.ofT0PseudoMetricSpace _
8080

8181
/-- One gets a metric space from an emetric space if the edistance
8282
is everywhere finite, by pushing the edistance to reals. We set it up so that the edist and the
8383
uniformity are defeq in the metric space and the emetric space. -/
84-
def EMetricSpace.toMetricSpace {α : Type u} [EMetricSpace α] (h : ∀ x y : α, edist x y ≠ ⊤) :
84+
abbrev EMetricSpace.toMetricSpace {α : Type u} [EMetricSpace α] (h : ∀ x y : α, edist x y ≠ ⊤) :
8585
MetricSpace α :=
86-
EMetricSpace.toMetricSpaceOfDist (fun x y => ENNReal.toReal (edist x y)) h fun _ _ => rfl
86+
EMetricSpace.toMetricSpaceOfDist (ENNReal.toReal <| edist · ·) (by simp) (by simp [h])
8787

8888
/-- Metric space structure pulled back by an injective function. Injectivity is necessary to
8989
ensure that `dist x y = 0` only if `x = y`. -/
@@ -186,8 +186,8 @@ theorem SeparationQuotient.dist_mk {α : Type u} [PseudoMetricSpace α] (p q :
186186

187187
instance SeparationQuotient.instMetricSpace {α : Type u} [PseudoMetricSpace α] :
188188
MetricSpace (SeparationQuotient α) :=
189-
EMetricSpace.toMetricSpaceOfDist dist (surjective_mk.forall₂.2 edist_ne_top) <|
190-
surjective_mk.forall₂.2 dist_edist
189+
EMetricSpace.toMetricSpaceOfDist dist (surjective_mk.forall₂.2 fun _ _ ↦ dist_nonneg) <|
190+
surjective_mk.forall₂.2 edist_dist
191191

192192
end EqRel
193193

Mathlib/Topology/MetricSpace/Pseudo/Constructions.lean

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,8 @@ variable [PseudoMetricSpace β]
143143
instance Prod.pseudoMetricSpaceMax : PseudoMetricSpace (α × β) :=
144144
let i := PseudoEMetricSpace.toPseudoMetricSpaceOfDist
145145
(fun x y : α × β => dist x.1 y.1 ⊔ dist x.2 y.2)
146-
(fun _ _ => (max_lt (edist_lt_top _ _) (edist_lt_top _ _)).ne) fun x y => by
147-
simp only [dist_edist, ← ENNReal.toReal_max (edist_ne_top _ _) (edist_ne_top _ _),
148-
Prod.edist_eq]
146+
(fun x y ↦ by positivity) fun x y => by
147+
simp only [ENNReal.ofReal_max, Prod.edist_eq, edist_dist]
149148
i.replaceBornology fun s => by
150149
simp only [← isBounded_image_fst_and_snd, isBounded_iff_eventually, forall_mem_image, ←
151150
eventually_and, ← forall_and, ← max_le_iff]

Mathlib/Topology/MetricSpace/Pseudo/Defs.lean

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -994,29 +994,27 @@ is everywhere finite, by pushing the edistance to reals. We set it up so that th
994994
uniformity are defeq in the pseudometric space and the pseudoemetric space. In this definition, the
995995
distance is given separately, to be able to prescribe some expression which is not defeq to the
996996
push-forward of the edistance to reals. See note [reducible non-instances]. -/
997-
abbrev PseudoEMetricSpace.toPseudoMetricSpaceOfDist {α : Type u} [e : PseudoEMetricSpace α]
998-
(dist : αα → ℝ) (edist_ne_top : ∀ x y : α, edist x y ≠ ⊤)
999-
(h : ∀ x y, dist x y = ENNReal.toReal (edist x y)) : PseudoMetricSpace α where
997+
abbrev PseudoEMetricSpace.toPseudoMetricSpaceOfDist {X : Type*} [e : PseudoEMetricSpace X]
998+
(dist : XX → ℝ) (dist_nonneg : ∀ x y, 0 ≤ dist x y)
999+
(h : ∀ x y, edist x y = .ofReal (dist x y)) : PseudoMetricSpace X where
10001000
dist := dist
1001-
dist_self x := by simp [h]
1002-
dist_comm x y := by simp [h, edist_comm]
1001+
dist_self x := by simpa [h, (dist_nonneg _ _).ge_iff_eq', -edist_self] using edist_self x
1002+
dist_comm x y := by simpa [h, dist_nonneg] using edist_comm x y
10031003
dist_triangle x y z := by
1004-
simp only [h]
1005-
exact ENNReal.toReal_le_add (edist_triangle _ _ _) (edist_ne_top _ _) (edist_ne_top _ _)
1004+
simpa [h, dist_nonneg, add_nonneg, ← ENNReal.ofReal_add] using edist_triangle x y z
10061005
edist := edist
1007-
edist_dist _ _ := by simp only [h, ENNReal.ofReal_toReal (edist_ne_top _ _)]
1008-
toUniformSpace := e.toUniformSpace
1006+
edist_dist _ _ := by simp only [h]
1007+
toUniformSpace := PseudoEMetricSpace.toUniformSpace
10091008
uniformity_dist := e.uniformity_edist.trans <| by
1010-
simpa only [ENNReal.coe_toNNReal (edist_ne_top _ _), h]
1011-
using (Metric.uniformity_edist_aux fun x y : α => (edist x y).toNNReal).symm
1009+
simpa [h, dist_nonneg, ENNReal.coe_toNNReal_eq_toReal]
1010+
using (Metric.uniformity_edist_aux fun x y : X => (edist x y).toNNReal).symm
10121011

10131012
/-- One gets a pseudometric space from an emetric space if the edistance
10141013
is everywhere finite, by pushing the edistance to reals. We set it up so that the edist and the
10151014
uniformity are defeq in the pseudometric space and the emetric space. -/
10161015
abbrev PseudoEMetricSpace.toPseudoMetricSpace {α : Type u} [PseudoEMetricSpace α]
10171016
(h : ∀ x y : α, edist x y ≠ ⊤) : PseudoMetricSpace α :=
1018-
PseudoEMetricSpace.toPseudoMetricSpaceOfDist (fun x y => ENNReal.toReal (edist x y)) h fun _ _ =>
1019-
rfl
1017+
PseudoEMetricSpace.toPseudoMetricSpaceOfDist (ENNReal.toReal <| edist · ·) (by simp) (by simp [h])
10201018

10211019
/-- Build a new pseudometric space from an old one where the bundled bornology structure is provably
10221020
(but typically non-definitionaly) equal to some given bornology structure.

Mathlib/Topology/MetricSpace/Pseudo/Pi.lean

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@ instance pseudoMetricSpacePi : PseudoMetricSpace (∀ b, X b) := by
3030
formula for the distance -/
3131
let i := PseudoEMetricSpace.toPseudoMetricSpaceOfDist
3232
(fun f g : ∀ b, X b => ((sup univ fun b => nndist (f b) (g b) : ℝ≥0) : ℝ))
33-
(fun f g => ((Finset.sup_lt_iff bot_lt_top).2 fun b _ => edist_lt_top _ _).ne)
34-
(fun f g => by
35-
simp only [edist_pi_def, edist_nndist, ← ENNReal.coe_finset_sup, ENNReal.coe_toReal])
33+
(fun f g => NNReal.zero_le_coe)
34+
(fun f g => by simp [edist_pi_def])
3635
refine i.replaceBornology fun s => ?_
3736
simp only [isBounded_iff_eventually, ← forall_isBounded_image_eval_iff,
3837
forall_mem_image, ← Filter.eventually_all, @dist_nndist (X _)]

Mathlib/Topology/MetricSpace/UniformConvergence.lean

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -130,11 +130,16 @@ variable [PseudoMetricSpace β]
130130
noncomputable instance [BoundedSpace β] : PseudoMetricSpace (α →ᵤ β) :=
131131
PseudoEMetricSpace.toPseudoMetricSpaceOfDist
132132
(fun f g ↦ ⨆ x, dist (toFun f x) (toFun g x))
133-
(fun _ _ ↦ by
134-
have := BoundedSpace.bounded_univ (α := β) |>.ediam_ne_top.lt_top
135-
refine (iSup_le fun x ↦ EMetric.edist_le_diam_of_mem ?_ ?_).trans_lt this |>.ne
136-
all_goals trivial)
137-
(fun _ _ ↦ by simp [edist_def, ENNReal.toReal_iSup (fun _ ↦ edist_ne_top _ _), dist_edist])
133+
(fun _ _ ↦ Real.iSup_nonneg fun i ↦ dist_nonneg)
134+
fun f g ↦ by
135+
cases isEmpty_or_nonempty α
136+
· simp [edist_def]
137+
have : BddAbove <| .range fun x ↦ dist (toFun f x) (toFun g x) := by
138+
use (EMetric.diam (.univ : Set β)).toReal
139+
simp +contextual [mem_upperBounds, eq_comm (a := dist _ _), ← edist_dist,
140+
← ENNReal.ofReal_le_iff_le_toReal BoundedSpace.bounded_univ.ediam_ne_top,
141+
EMetric.edist_le_diam_of_mem]
142+
exact ENNReal.eq_of_forall_le_nnreal_iff fun r ↦ by simp [edist_def, ciSup_le_iff this]
138143

139144
lemma dist_def [BoundedSpace β] (f g : α →ᵤ β) :
140145
dist f g = ⨆ x, dist (toFun f x) (toFun g x) :=
@@ -279,17 +284,18 @@ variable [Finite 𝔖] [PseudoMetricSpace β]
279284

280285
noncomputable instance [BoundedSpace β] : PseudoMetricSpace (α →ᵤ[𝔖] β) :=
281286
PseudoEMetricSpace.toPseudoMetricSpaceOfDist
282-
(fun f g ↦ ⨆ x ∈ ⋃₀ 𝔖, dist (toFun 𝔖 f x) (toFun 𝔖 g x))
283-
(fun _ _ ↦ by
284-
have := BoundedSpace.bounded_univ (α := β) |>.ediam_ne_top.lt_top
285-
exact (iSup₂_le fun x _ ↦ EMetric.edist_le_diam_of_mem (Set.mem_univ _) (Set.mem_univ _))
286-
|>.trans_lt this |>.ne)
287-
(fun _ _ ↦ by
288-
simp only [dist_edist, edist_def, ← ENNReal.toReal_iSup (fun _ ↦ edist_ne_top _ _)]
289-
rw [ENNReal.toReal_iSup]
290-
have := BoundedSpace.bounded_univ (α := β) |>.ediam_ne_top.lt_top
291-
refine fun x ↦ lt_of_le_of_lt (iSup_le fun hx ↦ ?_) this |>.ne
292-
exact EMetric.edist_le_diam_of_mem (Set.mem_univ _) (Set.mem_univ _))
287+
(fun f g ↦ ⨆ x : ⋃₀ 𝔖, dist (toFun 𝔖 f x) (toFun 𝔖 g x))
288+
(fun _ _ ↦ Real.iSup_nonneg fun i ↦ dist_nonneg)
289+
fun f g ↦ by
290+
cases isEmpty_or_nonempty (⋃₀ 𝔖)
291+
· simp_all [edist_def]
292+
have : BddAbove (.range fun x : ⋃₀ 𝔖 ↦ dist (toFun 𝔖 f x) (toFun 𝔖 g x)) := by
293+
use (EMetric.diam (.univ : Set β)).toReal
294+
simp +contextual [mem_upperBounds, eq_comm (a := dist _ _), ← edist_dist,
295+
← ENNReal.ofReal_le_iff_le_toReal BoundedSpace.bounded_univ.ediam_ne_top,
296+
EMetric.edist_le_diam_of_mem]
297+
refine ENNReal.eq_of_forall_le_nnreal_iff fun r ↦ ?_
298+
simp [edist_def, ciSup_le_iff this]
293299

294300
noncomputable instance [BoundedSpace β] : BoundedSpace (α →ᵤ[𝔖] β) where
295301
bounded_univ := by

0 commit comments

Comments
 (0)