Skip to content

Commit 9ab1fcc

Browse files
feat(Topology): countable product of extended metric spaces (#30822)
We already have a (highly non-canonical) (pseudo) metric space structure on a countable product of (pseudo) metric spaces. This PR factors that construction to first provide a (still highly non-canonical) (pseudo) extended metric space structure on a countable product of (pseudo) extended metric spaces. Co-authored-by: Yaël Dillies <yael.dillies@gmail.com>
1 parent 33700d7 commit 9ab1fcc

File tree

2 files changed

+149
-94
lines changed

2 files changed

+149
-94
lines changed

Mathlib/Topology/Instances/ENNReal/Lemmas.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,11 @@ protected theorem tsum_comm {f : α → β → ℝ≥0∞} : ∑' a, ∑' b, f a
611611
protected theorem tsum_add : ∑' a, (f a + g a) = ∑' a, f a + ∑' a, g a :=
612612
ENNReal.summable.tsum_add ENNReal.summable
613613

614+
protected lemma sum_add_tsum_compl {ι : Type*} (s : Finset ι) (f : ι → ℝ≥0∞) :
615+
∑ i ∈ s, f i + ∑' i : ↥(s : Set ι)ᶜ, f i = ∑' i, f i := by
616+
rw [tsum_subtype, sum_eq_tsum_indicator]
617+
simp [← ENNReal.tsum_add]
618+
614619
protected theorem tsum_le_tsum (h : ∀ a, f a ≤ g a) : ∑' a, f a ≤ ∑' a, g a :=
615620
ENNReal.summable.tsum_le_tsum h ENNReal.summable
616621

Mathlib/Topology/MetricSpace/PiNat.lean

Lines changed: 144 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -763,124 +763,174 @@ namespace PiCountable
763763
### Products of (possibly non-discrete) metric spaces
764764
-/
765765

766+
variable {ι : Type*} [Encodable ι] {F : ι → Type*}
767+
open Encodable ENNReal
768+
section EDist
769+
variable [∀ i, EDist (F i)] {x y : ∀ i, F i} {i : ι} {r : ℝ≥0∞}
766770

767-
variable {ι : Type*} [Encodable ι] {F : ι → Type*} [∀ i, MetricSpace (F i)]
771+
/-- Given a countable family of extended metric spaces,
772+
one may put an extended distance on their product `Π i, E i`.
768773
769-
open Encodable
770-
771-
/-- Given a countable family of metric spaces, one may put a distance on their product `Π i, E i`.
772774
It is highly non-canonical, though, and therefore not registered as a global instance.
773-
The distance we use here is `dist x y = ∑' i, min (1/2)^(encode i) (dist (x i) (y i))`. -/
774-
protected def dist : Dist (∀ i, F i) :=
775-
fun x y => ∑' i : ι, min ((1 / 2) ^ encode i) (dist (x i) (y i))
775+
The distance we use here is `edist x y = ∑' i, min (1/2)^(encode i) (edist (x i) (y i))`. -/
776+
protected def edist : EDist (∀ i, F i) where
777+
edist x y := ∑' i, min (2⁻¹ ^ encode i) (edist (x i) (y i))
776778

777-
attribute [local instance] PiCountable.dist
779+
attribute [scoped instance] PiCountable.edist
778780

779-
theorem dist_eq_tsum (x y : ∀ i, F i) :
780-
dist x y = ∑' i : ι, min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i)) :=
781-
rfl
781+
lemma edist_eq_tsum (x y : ∀ i, F i) :
782+
edist x y = ∑' i, min (2⁻¹ ^ encode i) (edist (x i) (y i)) := rfl
782783

783-
theorem dist_summable (x y : ∀ i, F i) :
784-
Summable fun i : ι => min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i)) := by
785-
refine .of_nonneg_of_le (fun i => ?_) (fun i => min_le_left _ _)
786-
summable_geometric_two_encode
787-
exact le_min (pow_nonneg (by simp) _) dist_nonneg
784+
lemma min_edist_le_edist_pi (x y : ∀ i, F i) (i : ι) :
785+
min (2⁻¹ ^ encode i) (edist (x i) (y i)) ≤ edist x y := ENNReal.le_tsum _
788786

789-
theorem min_dist_le_dist_pi (x y : ∀ i, F i) (i : ι) :
790-
min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i)) ≤ dist x y :=
791-
(dist_summable x y).le_tsum i fun j _ => le_min (by simp) dist_nonneg
787+
lemma edist_le_two : edist x y ≤ 2 :=
788+
(ENNReal.tsum_geometric_two_encode_le_two).trans' <| by
789+
rw [edist_eq_tsum]; gcongr; exact min_le_left ..
792790

793-
theorem dist_le_dist_pi_of_dist_lt {x y : ∀ i, F i} {i : ι} (h : dist x y < (1 / 2) ^ encode i) :
794-
dist (x i) (y i) ≤ dist x y := by
795-
simpa only [not_le.2 h, false_or] using min_le_iff.1 (min_dist_le_dist_pi x y i)
791+
lemma edist_lt_top : edist x y < ∞ := edist_le_two.trans_lt (by simp)
796792

797-
open Topology Filter NNReal
793+
lemma edist_le_edist_pi_of_edist_lt (h : edist x y < 2⁻¹ ^ encode i) :
794+
edist (x i) (y i) ≤ edist x y := by
795+
simpa only [not_le.2 h, false_or] using min_le_iff.1 (min_edist_le_edist_pi x y i)
798796

799-
variable (E)
797+
end EDist
800798

801-
/-- Given a countable family of metric spaces, one may put a distance on their product `Π i, E i`,
802-
defining the right topology and uniform structure. It is highly non-canonical, though, and therefore
803-
not registered as a global instance.
804-
The distance we use here is `dist x y = ∑' n, min (1/2)^(encode i) (dist (x n) (y n))`. -/
805-
protected def metricSpace : MetricSpace (∀ i, F i) where
806-
dist_self x := by simp [dist_eq_tsum]
807-
dist_comm x y := by simp [dist_eq_tsum, dist_comm]
808-
dist_triangle x y z :=
809-
have I : ∀ i, min ((1 / 2) ^ encode i : ℝ) (dist (x i) (z i)) ≤
810-
min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i)) +
811-
min ((1 / 2) ^ encode i : ℝ) (dist (y i) (z i)) := fun i =>
812-
calc
813-
min ((1 / 2) ^ encode i : ℝ) (dist (x i) (z i)) ≤
814-
min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i) + dist (y i) (z i)) :=
815-
min_le_min le_rfl (dist_triangle _ _ _)
816-
_ = min ((1 / 2) ^ encode i : ℝ) (min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i)) +
817-
min ((1 / 2) ^ encode i : ℝ) (dist (y i) (z i))) := by
818-
convert congr_arg ((↑) : ℝ≥0 → ℝ)
819-
(min_add_distrib ((1 / 2 : ℝ≥0) ^ encode i) (nndist (x i) (y i))
820-
(nndist (y i) (z i)))
821-
_ ≤ min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i)) +
822-
min ((1 / 2) ^ encode i : ℝ) (dist (y i) (z i)) :=
823-
min_le_right _ _
824-
calc dist x z ≤ ∑' i, (min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i)) +
825-
min ((1 / 2) ^ encode i : ℝ) (dist (y i) (z i))) :=
826-
(dist_summable x z).tsum_le_tsum I ((dist_summable x y).add (dist_summable y z))
827-
_ = dist x y + dist y z := (dist_summable x y).tsum_add (dist_summable y z)
828-
eq_of_dist_eq_zero hxy := by
829-
ext1 n
830-
rw [← dist_le_zero, ← hxy]
831-
apply dist_le_dist_pi_of_dist_lt
832-
rw [hxy]
833-
simp
799+
attribute [scoped instance] PiCountable.edist
800+
801+
section PseudoEMetricSpace
802+
variable [∀ i, PseudoEMetricSpace (F i)]
803+
804+
/-- Given a countable family of extended pseudo metric spaces,
805+
one may put an extended distance on their product `Π i, E i`.
806+
807+
It is highly non-canonical, though, and therefore not registered as a global instance.
808+
The distance we use here is `edist x y = ∑' i, min (1/2)^(encode i) (edist (x i) (y i))`. -/
809+
protected def pseudoEMetricSpace : PseudoEMetricSpace (∀ i, F i) where
810+
edist_self x := by simp [edist_eq_tsum]
811+
edist_comm x y := by simp [edist_eq_tsum, edist_comm]
812+
edist_triangle x y z := calc
813+
∑' i, min (2⁻¹ ^ encode i) (edist (x i) (z i))
814+
_ ≤ ∑' i, (min (2⁻¹ ^ encode i) (edist (x i) (y i)) +
815+
min (2⁻¹ ^ encode i) (edist (y i) (z i))) := by
816+
gcongr with n; grw [edist_triangle _ (y n), min_add_distrib, min_le_right]
817+
_ = _ := ENNReal.tsum_add ..
834818
toUniformSpace := Pi.uniformSpace _
835-
uniformity_dist := by
819+
uniformity_edist := by
836820
simp only [Pi.uniformity, comap_iInf, gt_iff_lt, preimage_setOf_eq, comap_principal,
837-
PseudoMetricSpace.uniformity_dist]
838-
apply le_antisymm
839-
· simp only [le_iInf_iff, le_principal_iff]
840-
intro ε εpos
821+
PseudoEMetricSpace.uniformity_edist, le_antisymm_iff, le_iInf_iff, le_principal_iff]
822+
constructor
823+
· intro ε hε
841824
classical
842-
obtain ⟨K, hK⟩ :
843-
∃ K : Finset ι, (∑' i : { j // j ∉ K }, (1 / 2 : ℝ) ^ encode (i : ι)) < ε / 2 :=
844-
((tendsto_order.1 (tendsto_tsum_compl_atTop_zero fun i : ι => (1 / 2 : ℝ) ^ encode i)).2 _
845-
(half_pos εpos)).exists
846-
obtain ⟨δ, δpos, hδ⟩ : ∃ δ : ℝ, 0 < δ ∧ (K.card : ℝ) * δ < ε / 2 :=
847-
exists_pos_mul_lt (half_pos εpos) _
825+
obtain ⟨K, hK⟩ : ∃ K : Finset ι, ∑' i : {j // j ∉ K}, 2⁻¹ ^ encode (i : ι) < ε / 2 :=
826+
((tendsto_order.1 <| ENNReal.tendsto_tsum_compl_atTop_zero
827+
(tsum_geometric_encode_lt_top ENNReal.one_half_lt_one).ne).2 _
828+
<| by simpa using hε.ne').exists
829+
obtain ⟨δ, δpos, hδ⟩ : ∃ δ, 0 < δ ∧ δ * K.card < ε / 2 :=
830+
ENNReal.exists_pos_mul_lt (by simp) (by simpa using hε.ne')
848831
apply @mem_iInf_of_iInter _ _ _ _ _ K.finite_toSet fun i =>
849-
{ p : (∀ i : ι, F i) × ∀ i : ι, F i | dist (p.fst i) (p.snd i) < δ }
832+
{p : (∀ i : ι, F i) × ∀ i : ι, F i | edist (p.fst i) (p.snd i) < δ}
850833
· rintro ⟨i, hi⟩
851834
refine mem_iInf_of_mem δ (mem_iInf_of_mem δpos ?_)
852835
simp only [mem_principal, Subset.rfl]
853836
· rintro ⟨x, y⟩ hxy
854837
simp only [mem_iInter, mem_setOf_eq, SetCoe.forall, Finset.mem_coe] at hxy
855838
calc
856-
dist x y = ∑' i : ι, min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i)) := rfl
857-
_ = (∑ i ∈ K, min ((1 / 2) ^ encode i : ℝ) (dist (x i) (y i))) +
858-
∑' i : ↑(K : Set ι)ᶜ, min ((1 / 2) ^ encode (i : ι) : ℝ) (dist (x i) (y i)) :=
859-
(Summable.sum_add_tsum_compl (dist_summable _ _)).symm
860-
_ ≤ (∑ i ∈ K, dist (x i) (y i)) +
861-
∑' i : ↑(K : Set ι)ᶜ, ((1 / 2) ^ encode (i : ι) : ℝ) := by
839+
edist x y = ∑' i : ι, min (2⁻¹ ^ encode i) (edist (x i) (y i)) := rfl
840+
_ = ∑ i ∈ K, min (2⁻¹ ^ encode i) (edist (x i) (y i)) +
841+
∑' i : ↑(K : Set ι)ᶜ, min (2⁻¹ ^ encode (i : ι)) (edist (x i) (y i)) :=
842+
(ENNReal.sum_add_tsum_compl ..).symm
843+
_ ≤ ∑ i ∈ K, edist (x i) (y i) + ∑' i : ↑(K : Set ι)ᶜ, 2⁻¹ ^ encode (i : ι) := by
862844
gcongr
863845
· apply min_le_right
864-
· apply Summable.subtype (dist_summable x y) (↑K : Set ι)ᶜ
865-
· apply Summable.subtype summable_geometric_two_encode (↑K : Set ι)ᶜ
866846
· apply min_le_left
867-
_ < (∑ _i ∈ K, δ) + ε / 2 := by
868-
apply add_lt_add_of_le_of_lt _ hK
869-
refine Finset.sum_le_sum fun i hi => (hxy i ?_).le
870-
simpa using hi
871-
_ ≤ ε / 2 + ε / 2 := by
872-
gcongr
873-
simpa using hδ.le
874-
_ = ε := add_halves _
875-
· simp only [le_iInf_iff, le_principal_iff]
876-
intro i ε εpos
877-
refine mem_iInf_of_mem (min ((1 / 2) ^ encode i : ℝ) ε) ?_
878-
have : 0 < min ((1 / 2) ^ encode i : ℝ) ε := lt_min (by simp) εpos
879-
refine mem_iInf_of_mem this ?_
847+
_ < ∑ _i ∈ K, δ + ε / 2 := by
848+
refine ENNReal.add_lt_add_of_le_of_lt (by simpa using fun i hi ↦ (hxy i hi).ne_top) ?_
849+
hK
850+
gcongr with i hi
851+
exact (hxy i hi).le
852+
_ ≤ ε / 2 + ε / 2 := by gcongr; simpa [mul_comm] using hδ.le
853+
_ = ε := ENNReal.add_halves _
854+
· intro i ε hε₀
855+
have : (0 : ℝ≥0∞) < 2⁻¹ ^ encode i := ENNReal.pow_pos (by norm_num) _
856+
refine mem_iInf_of_mem (min (2⁻¹ ^ encode i) ε) <| mem_iInf_of_mem (by positivity) ?_
880857
simp only [and_imp, Prod.forall, setOf_subset_setOf, lt_min_iff, mem_principal]
881-
intro x y hn hε
882-
calc
883-
dist (x i) (y i) ≤ dist x y := dist_le_dist_pi_of_dist_lt hn
884-
_ < ε := hε
858+
intro x y hn
859+
exact (edist_le_edist_pi_of_edist_lt hn).trans_lt
860+
861+
end PseudoEMetricSpace
862+
863+
attribute [scoped instance] PiCountable.pseudoEMetricSpace
864+
865+
section EMetricSpace
866+
variable [∀ i, EMetricSpace (F i)]
867+
868+
/-- Given a countable family of extended metric spaces,
869+
one may put an extended distance on their product `Π i, E i`.
870+
871+
It is highly non-canonical, though, and therefore not registered as a global instance.
872+
The distance we use here is `edist x y = ∑' i, min (1/2)^(encode i) (edist (x i) (y i))`. -/
873+
protected def emetricSpace : EMetricSpace (∀ i, F i) where
874+
eq_of_edist_eq_zero := by simp [edist_eq_tsum, funext_iff]
875+
876+
end EMetricSpace
877+
878+
attribute [scoped instance] PiCountable.emetricSpace
879+
880+
section PseudoMetricSpace
881+
variable [∀ i, PseudoMetricSpace (F i)] {x y : ∀ i, F i} {i : ι}
882+
883+
884+
/-- Given a countable family of metric spaces, one may put a distance on their product `Π i, E i`.
885+
886+
It is highly non-canonical, though, and therefore not registered as a global instance.
887+
The distance we use here is `dist x y = ∑' i, min (1/2)^(encode i) (dist (x i) (y i))`. -/
888+
protected def dist : Dist (∀ i, F i) where
889+
dist x y := ∑' i, min (2⁻¹ ^ encode i) (dist (x i) (y i))
890+
891+
attribute [scoped instance] PiCountable.dist
892+
893+
lemma dist_eq_tsum (x y : ∀ i, F i) : dist x y = ∑' i, min (2⁻¹ ^ encode i) (dist (x i) (y i)) :=
894+
rfl
895+
896+
lemma dist_summable (x y : ∀ i, F i) :
897+
Summable fun i ↦ min (2⁻¹ ^ encode i) (dist (x i) (y i)) := by
898+
refine .of_nonneg_of_le (fun i => ?_) (fun i => min_le_left _ _) <| by
899+
simpa [one_div] using summable_geometric_two_encode
900+
exact le_min (by positivity) dist_nonneg
901+
902+
lemma min_dist_le_dist_pi (x y : ∀ i, F i) (i : ι) :
903+
min (2⁻¹ ^ encode i) (dist (x i) (y i)) ≤ dist x y :=
904+
(dist_summable x y).le_tsum i fun j _ => le_min (by simp) dist_nonneg
905+
906+
lemma dist_le_dist_pi_of_dist_lt (h : dist x y < 2⁻¹ ^ encode i) : dist (x i) (y i) ≤ dist x y := by
907+
simpa only [not_le.2 h, false_or] using min_le_iff.1 (min_dist_le_dist_pi x y i)
908+
909+
/-- Given a countable family of metric spaces, one may put a distance on their product `Π i, E i`.
910+
911+
It is highly non-canonical, though, and therefore not registered as a global instance.
912+
The distance we use here is `dist x y = ∑' i, min (1/2)^(encode i) (dist (x i) (y i))`. -/
913+
protected def pseudoMetricSpace : PseudoMetricSpace (∀ i, F i) :=
914+
PseudoEMetricSpace.toPseudoMetricSpaceOfDist dist
915+
(fun x y ↦ by simp [dist_eq_tsum]; positivity) fun x y ↦ by
916+
rw [edist_eq_tsum, dist_eq_tsum,
917+
ENNReal.ofReal_tsum_of_nonneg (fun _ ↦ by positivity) (dist_summable ..)]
918+
simp [edist, ENNReal.inv_pow]
919+
congr! with a
920+
exact PseudoMetricSpace.edist_dist (x a) (y a)
921+
922+
end PseudoMetricSpace
923+
924+
attribute [scoped instance] PiCountable.pseudoMetricSpace
925+
926+
section MetricSpace
927+
variable [∀ i, MetricSpace (F i)]
928+
/-- Given a countable family of metric spaces, one may put a distance on their product `Π i, E i`.
929+
930+
It is highly non-canonical, though, and therefore not registered as a global instance.
931+
The distance we use here is edist x y = ∑' i, min (1/2)^(encode i) (edist (x i) (y i))`. -/
932+
protected def metricSpace : MetricSpace (∀ i, F i) :=
933+
EMetricSpace.toMetricSpaceOfDist dist (by simp) (by simp [edist_dist])
885934

935+
end MetricSpace
886936
end PiCountable

0 commit comments

Comments
 (0)