Skip to content

Commit 10d6486

Browse files
committed
refactor(Topology): split Topology.Perfect into two modules (#10272)
Splits `Topology.Perfect` into two modules: `Topology.Perfect`, where the existing definition of `Perfect` and `Preperfect` are kept, and `Topology.MetricSpace.Perfect`, in which the theorems specific to metric spaces are moved.
1 parent 9b6ad3c commit 10d6486

File tree

5 files changed

+152
-116
lines changed

5 files changed

+152
-116
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3806,6 +3806,7 @@ import Mathlib.Topology.MetricSpace.Kuratowski
38063806
import Mathlib.Topology.MetricSpace.Lipschitz
38073807
import Mathlib.Topology.MetricSpace.MetricSeparated
38083808
import Mathlib.Topology.MetricSpace.PartitionOfUnity
3809+
import Mathlib.Topology.MetricSpace.Perfect
38093810
import Mathlib.Topology.MetricSpace.PiNat
38103811
import Mathlib.Topology.MetricSpace.Polish
38113812
import Mathlib.Topology.MetricSpace.ProperSpace

Mathlib/MeasureTheory/Constructions/Polish.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Sébastien Gouëzel, Felix Weilacher
55
-/
66
import Mathlib.Data.Real.Cardinality
7-
import Mathlib.Topology.Perfect
7+
import Mathlib.Topology.MetricSpace.Perfect
88
import Mathlib.MeasureTheory.Constructions.BorelSpace.Basic
99

1010
#align_import measure_theory.constructions.polish from "leanprover-community/mathlib"@"9f55d0d4363ae59948c33864cbc52e0b12e0e8ce"

Mathlib/Topology/Algebra/Module/Cardinality.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Authors: Sébastien Gouëzel
66
import Mathlib.SetTheory.Cardinal.CountableCover
77
import Mathlib.SetTheory.Cardinal.Continuum
88
import Mathlib.Analysis.SpecificLimits.Normed
9-
import Mathlib.Topology.Perfect
9+
import Mathlib.Topology.MetricSpace.Perfect
1010

1111
/-!
1212
# Cardinality of open subsets of vector spaces
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/-
2+
Copyright (c) 2022 Felix Weilacher. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Felix Weilacher
5+
-/
6+
7+
import Mathlib.Topology.Perfect
8+
import Mathlib.Topology.MetricSpace.Polish
9+
import Mathlib.Topology.MetricSpace.CantorScheme
10+
11+
#align_import topology.perfect from "leanprover-community/mathlib"@"3905fa80e62c0898131285baab35559fbc4e5cda"
12+
13+
/-!
14+
# Perfect Sets
15+
16+
In this file we define properties of `Perfect` subsets of a metric space,
17+
including a version of the Cantor-Bendixson Theorem.
18+
19+
## Main Statements
20+
21+
* `Perfect.exists_nat_bool_injection`: A perfect nonempty set in a complete metric space
22+
admits an embedding from the Cantor space.
23+
24+
## References
25+
26+
* [kechris1995] (Chapters 6-7)
27+
28+
## Tags
29+
30+
accumulation point, perfect set, cantor-bendixson.
31+
32+
--/
33+
34+
open Set Filter
35+
36+
section CantorInjMetric
37+
38+
open Function ENNReal
39+
40+
variable {α : Type*} [MetricSpace α] {C : Set α} (hC : Perfect C) {ε : ℝ≥0∞}
41+
42+
private theorem Perfect.small_diam_aux (ε_pos : 0 < ε) {x : α} (xC : x ∈ C) :
43+
let D := closure (EMetric.ball x (ε / 2) ∩ C)
44+
Perfect D ∧ D.Nonempty ∧ D ⊆ C ∧ EMetric.diam D ≤ ε := by
45+
have : x ∈ EMetric.ball x (ε / 2) := by
46+
apply EMetric.mem_ball_self
47+
rw [ENNReal.div_pos_iff]
48+
exact ⟨ne_of_gt ε_pos, by norm_num⟩
49+
have := hC.closure_nhds_inter x xC this EMetric.isOpen_ball
50+
refine' ⟨this.1, this.2, _, _⟩
51+
· rw [IsClosed.closure_subset_iff hC.closed]
52+
apply inter_subset_right
53+
rw [EMetric.diam_closure]
54+
apply le_trans (EMetric.diam_mono (inter_subset_left _ _))
55+
convert EMetric.diam_ball (x := x)
56+
rw [mul_comm, ENNReal.div_mul_cancel] <;> norm_num
57+
58+
variable (hnonempty : C.Nonempty)
59+
60+
/-- A refinement of `Perfect.splitting` for metric spaces, where we also control
61+
the diameter of the new perfect sets. -/
62+
theorem Perfect.small_diam_splitting (ε_pos : 0 < ε) :
63+
∃ C₀ C₁ : Set α, (Perfect C₀ ∧ C₀.Nonempty ∧ C₀ ⊆ C ∧ EMetric.diam C₀ ≤ ε) ∧
64+
(Perfect C₁ ∧ C₁.Nonempty ∧ C₁ ⊆ C ∧ EMetric.diam C₁ ≤ ε) ∧ Disjoint C₀ C₁ := by
65+
rcases hC.splitting hnonempty with ⟨D₀, D₁, ⟨perf0, non0, sub0⟩, ⟨perf1, non1, sub1⟩, hdisj⟩
66+
cases' non0 with x₀ hx₀
67+
cases' non1 with x₁ hx₁
68+
rcases perf0.small_diam_aux ε_pos hx₀ with ⟨perf0', non0', sub0', diam0⟩
69+
rcases perf1.small_diam_aux ε_pos hx₁ with ⟨perf1', non1', sub1', diam1⟩
70+
refine'
71+
⟨closure (EMetric.ball x₀ (ε / 2) ∩ D₀), closure (EMetric.ball x₁ (ε / 2) ∩ D₁),
72+
⟨perf0', non0', sub0'.trans sub0, diam0⟩, ⟨perf1', non1', sub1'.trans sub1, diam1⟩, _⟩
73+
apply Disjoint.mono _ _ hdisj <;> assumption
74+
#align perfect.small_diam_splitting Perfect.small_diam_splitting
75+
76+
open CantorScheme
77+
78+
/-- Any nonempty perfect set in a complete metric space admits a continuous injection
79+
from the Cantor space, `ℕ → Bool`. -/
80+
theorem Perfect.exists_nat_bool_injection [CompleteSpace α] :
81+
∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Injective f := by
82+
obtain ⟨u, -, upos', hu⟩ := exists_seq_strictAnti_tendsto' (zero_lt_one' ℝ≥0∞)
83+
have upos := fun n => (upos' n).1
84+
let P := Subtype fun E : Set α => Perfect E ∧ E.Nonempty
85+
choose C0 C1 h0 h1 hdisj using
86+
fun {C : Set α} (hC : Perfect C) (hnonempty : C.Nonempty) {ε : ℝ≥0∞} (hε : 0 < ε) =>
87+
hC.small_diam_splitting hnonempty hε
88+
let DP : List Bool → P := fun l => by
89+
induction' l with a l ih; · exact ⟨C, ⟨hC, hnonempty⟩⟩
90+
cases a
91+
· use C0 ih.property.1 ih.property.2 (upos l.length.succ)
92+
exact ⟨(h0 _ _ _).1, (h0 _ _ _).2.1
93+
use C1 ih.property.1 ih.property.2 (upos l.length.succ)
94+
exact ⟨(h1 _ _ _).1, (h1 _ _ _).2.1
95+
let D : List Bool → Set α := fun l => (DP l).val
96+
have hanti : ClosureAntitone D := by
97+
refine' Antitone.closureAntitone _ fun l => (DP l).property.1.closed
98+
intro l a
99+
cases a
100+
· exact (h0 _ _ _).2.2.1
101+
exact (h1 _ _ _).2.2.1
102+
have hdiam : VanishingDiam D := by
103+
intro x
104+
apply tendsto_of_tendsto_of_tendsto_of_le_of_le' tendsto_const_nhds hu
105+
· simp
106+
rw [eventually_atTop]
107+
refine' ⟨1, fun m (hm : 1 ≤ m) => _⟩
108+
rw [Nat.one_le_iff_ne_zero] at hm
109+
rcases Nat.exists_eq_succ_of_ne_zero hm with ⟨n, rfl⟩
110+
dsimp
111+
cases x n
112+
· convert (h0 _ _ _).2.2.2
113+
rw [PiNat.res_length]
114+
convert (h1 _ _ _).2.2.2
115+
rw [PiNat.res_length]
116+
have hdisj' : CantorScheme.Disjoint D := by
117+
rintro l (a | a) (b | b) hab <;> try contradiction
118+
· exact hdisj _ _ _
119+
exact (hdisj _ _ _).symm
120+
have hdom : ∀ {x : ℕ → Bool}, x ∈ (inducedMap D).1 := fun {x} => by
121+
rw [hanti.map_of_vanishingDiam hdiam fun l => (DP l).property.2]
122+
apply mem_univ
123+
refine' ⟨fun x => (inducedMap D).2 ⟨x, hdom⟩, _, _, _⟩
124+
· rintro y ⟨x, rfl⟩
125+
exact map_mem ⟨_, hdom⟩ 0
126+
· apply hdiam.map_continuous.comp
127+
continuity
128+
intro x y hxy
129+
simpa only [← Subtype.val_inj] using hdisj'.map_injective hxy
130+
#align perfect.exists_nat_bool_injection Perfect.exists_nat_bool_injection
131+
132+
end CantorInjMetric
133+
134+
/-- Any closed uncountable subset of a Polish space admits a continuous injection
135+
from the Cantor space `ℕ → Bool`.-/
136+
theorem IsClosed.exists_nat_bool_injection_of_not_countable {α : Type*} [TopologicalSpace α]
137+
[PolishSpace α] {C : Set α} (hC : IsClosed C) (hunc : ¬C.Countable) :
138+
∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Function.Injective f := by
139+
letI := upgradePolishSpace α
140+
obtain ⟨D, hD, Dnonempty, hDC⟩ := exists_perfect_nonempty_of_isClosed_of_not_countable hC hunc
141+
obtain ⟨f, hfD, hf⟩ := hD.exists_nat_bool_injection Dnonempty
142+
exact ⟨f, hfD.trans hDC, hf⟩
143+
#align is_closed.exists_nat_bool_injection_of_not_countable IsClosed.exists_nat_bool_injection_of_not_countable

Mathlib/Topology/Perfect.lean

Lines changed: 6 additions & 114 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,8 @@ Copyright (c) 2022 Felix Weilacher. All rights reserved.
33
Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Felix Weilacher
55
-/
6-
import Mathlib.Topology.MetricSpace.Polish
7-
import Mathlib.Topology.MetricSpace.CantorScheme
86

9-
#align_import topology.perfect from "leanprover-community/mathlib"@"3905fa80e62c0898131285baab35559fbc4e5cda"
7+
import Mathlib.Topology.Separation
108

119
/-!
1210
# Perfect Sets
@@ -27,8 +25,6 @@ including a version of the Cantor-Bendixson Theorem.
2725
* `exists_countable_union_perfect_of_isClosed`: One version of the **Cantor-Bendixson Theorem**:
2826
A closed set in a second countable space can be written as the union of a countable set and a
2927
perfect set.
30-
* `Perfect.exists_nat_bool_injection`: A perfect nonempty set in a complete metric space
31-
admits an embedding from the Cantor space.
3228
3329
## Implementation Notes
3430
@@ -38,6 +34,11 @@ We define a nonstandard predicate, `Preperfect`, which drops the closed-ness req
3834
from the definition of perfect. In T1 spaces, this is equivalent to having a perfect closure,
3935
see `preperfect_iff_perfect_closure`.
4036
37+
## See also
38+
39+
`Mathlib.Topology.MetricSpace.Perfect`, for properties of perfect sets in metric spaces,
40+
namely Polish spaces.
41+
4142
## References
4243
4344
* [kechris1995] (Chapters 6-7)
@@ -214,112 +215,3 @@ theorem exists_perfect_nonempty_of_isClosed_of_not_countable [SecondCountableTop
214215
end Kernel
215216

216217
end Basic
217-
218-
section CantorInjMetric
219-
220-
open Function ENNReal
221-
222-
variable {α : Type*} [MetricSpace α] {C : Set α} (hC : Perfect C) {ε : ℝ≥0∞}
223-
224-
private theorem Perfect.small_diam_aux (ε_pos : 0 < ε) {x : α} (xC : x ∈ C) :
225-
let D := closure (EMetric.ball x (ε / 2) ∩ C)
226-
Perfect D ∧ D.Nonempty ∧ D ⊆ C ∧ EMetric.diam D ≤ ε := by
227-
have : x ∈ EMetric.ball x (ε / 2) := by
228-
apply EMetric.mem_ball_self
229-
rw [ENNReal.div_pos_iff]
230-
exact ⟨ne_of_gt ε_pos, by norm_num⟩
231-
have := hC.closure_nhds_inter x xC this EMetric.isOpen_ball
232-
refine' ⟨this.1, this.2, _, _⟩
233-
· rw [IsClosed.closure_subset_iff hC.closed]
234-
apply inter_subset_right
235-
rw [EMetric.diam_closure]
236-
apply le_trans (EMetric.diam_mono (inter_subset_left _ _))
237-
convert EMetric.diam_ball (x := x)
238-
rw [mul_comm, ENNReal.div_mul_cancel] <;> norm_num
239-
240-
variable (hnonempty : C.Nonempty)
241-
242-
/-- A refinement of `Perfect.splitting` for metric spaces, where we also control
243-
the diameter of the new perfect sets. -/
244-
theorem Perfect.small_diam_splitting (ε_pos : 0 < ε) :
245-
∃ C₀ C₁ : Set α, (Perfect C₀ ∧ C₀.Nonempty ∧ C₀ ⊆ C ∧ EMetric.diam C₀ ≤ ε) ∧
246-
(Perfect C₁ ∧ C₁.Nonempty ∧ C₁ ⊆ C ∧ EMetric.diam C₁ ≤ ε) ∧ Disjoint C₀ C₁ := by
247-
rcases hC.splitting hnonempty with ⟨D₀, D₁, ⟨perf0, non0, sub0⟩, ⟨perf1, non1, sub1⟩, hdisj⟩
248-
cases' non0 with x₀ hx₀
249-
cases' non1 with x₁ hx₁
250-
rcases perf0.small_diam_aux ε_pos hx₀ with ⟨perf0', non0', sub0', diam0⟩
251-
rcases perf1.small_diam_aux ε_pos hx₁ with ⟨perf1', non1', sub1', diam1⟩
252-
refine'
253-
⟨closure (EMetric.ball x₀ (ε / 2) ∩ D₀), closure (EMetric.ball x₁ (ε / 2) ∩ D₁),
254-
⟨perf0', non0', sub0'.trans sub0, diam0⟩, ⟨perf1', non1', sub1'.trans sub1, diam1⟩, _⟩
255-
apply Disjoint.mono _ _ hdisj <;> assumption
256-
#align perfect.small_diam_splitting Perfect.small_diam_splitting
257-
258-
open CantorScheme
259-
260-
/-- Any nonempty perfect set in a complete metric space admits a continuous injection
261-
from the Cantor space, `ℕ → Bool`. -/
262-
theorem Perfect.exists_nat_bool_injection [CompleteSpace α] :
263-
∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Injective f := by
264-
obtain ⟨u, -, upos', hu⟩ := exists_seq_strictAnti_tendsto' (zero_lt_one' ℝ≥0∞)
265-
have upos := fun n => (upos' n).1
266-
let P := Subtype fun E : Set α => Perfect E ∧ E.Nonempty
267-
choose C0 C1 h0 h1 hdisj using
268-
fun {C : Set α} (hC : Perfect C) (hnonempty : C.Nonempty) {ε : ℝ≥0∞} (hε : 0 < ε) =>
269-
hC.small_diam_splitting hnonempty hε
270-
let DP : List Bool → P := fun l => by
271-
induction' l with a l ih; · exact ⟨C, ⟨hC, hnonempty⟩⟩
272-
cases a
273-
· use C0 ih.property.1 ih.property.2 (upos l.length.succ)
274-
exact ⟨(h0 _ _ _).1, (h0 _ _ _).2.1
275-
use C1 ih.property.1 ih.property.2 (upos l.length.succ)
276-
exact ⟨(h1 _ _ _).1, (h1 _ _ _).2.1
277-
let D : List Bool → Set α := fun l => (DP l).val
278-
have hanti : ClosureAntitone D := by
279-
refine' Antitone.closureAntitone _ fun l => (DP l).property.1.closed
280-
intro l a
281-
cases a
282-
· exact (h0 _ _ _).2.2.1
283-
exact (h1 _ _ _).2.2.1
284-
have hdiam : VanishingDiam D := by
285-
intro x
286-
apply tendsto_of_tendsto_of_tendsto_of_le_of_le' tendsto_const_nhds hu
287-
· simp
288-
rw [eventually_atTop]
289-
refine' ⟨1, fun m (hm : 1 ≤ m) => _⟩
290-
rw [Nat.one_le_iff_ne_zero] at hm
291-
rcases Nat.exists_eq_succ_of_ne_zero hm with ⟨n, rfl⟩
292-
dsimp
293-
cases x n
294-
· convert (h0 _ _ _).2.2.2
295-
rw [PiNat.res_length]
296-
convert (h1 _ _ _).2.2.2
297-
rw [PiNat.res_length]
298-
have hdisj' : CantorScheme.Disjoint D := by
299-
rintro l (a | a) (b | b) hab <;> try contradiction
300-
· exact hdisj _ _ _
301-
exact (hdisj _ _ _).symm
302-
have hdom : ∀ {x : ℕ → Bool}, x ∈ (inducedMap D).1 := fun {x} => by
303-
rw [hanti.map_of_vanishingDiam hdiam fun l => (DP l).property.2]
304-
apply mem_univ
305-
refine' ⟨fun x => (inducedMap D).2 ⟨x, hdom⟩, _, _, _⟩
306-
· rintro y ⟨x, rfl⟩
307-
exact map_mem ⟨_, hdom⟩ 0
308-
· apply hdiam.map_continuous.comp
309-
continuity
310-
intro x y hxy
311-
simpa only [← Subtype.val_inj] using hdisj'.map_injective hxy
312-
#align perfect.exists_nat_bool_injection Perfect.exists_nat_bool_injection
313-
314-
end CantorInjMetric
315-
316-
/-- Any closed uncountable subset of a Polish space admits a continuous injection
317-
from the Cantor space `ℕ → Bool`.-/
318-
theorem IsClosed.exists_nat_bool_injection_of_not_countable {α : Type*} [TopologicalSpace α]
319-
[PolishSpace α] {C : Set α} (hC : IsClosed C) (hunc : ¬C.Countable) :
320-
∃ f : (ℕ → Bool) → α, range f ⊆ C ∧ Continuous f ∧ Function.Injective f := by
321-
letI := upgradePolishSpace α
322-
obtain ⟨D, hD, Dnonempty, hDC⟩ := exists_perfect_nonempty_of_isClosed_of_not_countable hC hunc
323-
obtain ⟨f, hfD, hf⟩ := hD.exists_nat_bool_injection Dnonempty
324-
exact ⟨f, hfD.trans hDC, hf⟩
325-
#align is_closed.exists_nat_bool_injection_of_not_countable IsClosed.exists_nat_bool_injection_of_not_countable

0 commit comments

Comments
 (0)