Skip to content
This repository was archived by the owner on Jul 24, 2024. It is now read-only.

Commit 7e20058

Browse files
adamtopazkmill
andcommitted
feat(topology/Profinite/cofiltered_limit): Locally constant functions from cofiltered limits (#7992)
This generalizes one of the main technical theorems from LTE about cofiltered limits of profinite sets. This theorem should be useful for a future proof of Stone duality. Co-authored-by: Kyle Miller <kmill31415@gmail.com>
1 parent 6e5de19 commit 7e20058

File tree

3 files changed

+165
-1
lines changed

3 files changed

+165
-1
lines changed

src/topology/category/Profinite/cofiltered_limit.lean

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Released under Apache 2.0 license as described in the file LICENSE.
44
Authors: Adam Topaz
55
-/
66
import topology.category.Profinite
7+
import topology.locally_constant.basic
8+
import topology.discrete_quotient
79

810
/-!
911
# Cofiltered limits of profinite sets.
@@ -14,6 +16,8 @@ This file contains some theorems about cofiltered limits of profinite sets.
1416
1517
- `exists_clopen_of_cofiltered` shows that any clopen set in a cofiltered limit of profinite
1618
sets is the pullback of a clopen set from one of the factors in the limit.
19+
- `exists_locally_constant` shows that any locally constant function from a cofiltered limit
20+
of profinite sets factors through one of the components.
1721
-/
1822

1923

@@ -110,4 +114,129 @@ begin
110114
rwa [dif_pos hs, ← set.preimage_comp, ← Profinite.coe_comp, C.w] at hx } }
111115
end
112116

117+
lemma exists_locally_constant_fin_two (f : locally_constant C.X (fin 2)) :
118+
∃ (j : J) (g : locally_constant (F.obj j) (fin 2)), f = g.comap (C.π.app _) :=
119+
begin
120+
let U := f ⁻¹' {0},
121+
have hU : is_clopen U := f.is_locally_constant.is_clopen_fiber _,
122+
obtain ⟨j,V,hV,h⟩ := exists_clopen_of_cofiltered C hC hU,
123+
use [j, locally_constant.of_clopen hV],
124+
apply locally_constant.locally_constant_eq_of_fiber_zero_eq,
125+
rw locally_constant.coe_comap _ _ (C.π.app j).continuous,
126+
conv_rhs { rw set.preimage_comp },
127+
rw [locally_constant.of_clopen_fiber_zero hV, ← h],
128+
end
129+
130+
theorem exists_locally_constant_fintype_aux {α : Type*} [fintype α] (f : locally_constant C.X α) :
131+
∃ (j : J) (g : locally_constant (F.obj j) (α → fin 2)),
132+
f.map (λ a b, if a = b then (0 : fin 2) else 1) = g.comap (C.π.app _) :=
133+
begin
134+
let ι : α → α → fin 2 := λ x y, if x = y then 0 else 1,
135+
let ff := (f.map ι).flip,
136+
have hff := λ (a : α), exists_locally_constant_fin_two _ hC (ff a),
137+
choose j g h using hff,
138+
let G : finset J := finset.univ.image j,
139+
obtain ⟨j0,hj0⟩ := is_cofiltered.inf_objs_exists G,
140+
have hj : ∀ a, j a ∈ G,
141+
{ intros a,
142+
simp [G] },
143+
let fs : Π (a : α), j0 ⟶ j a := λ a, (hj0 (hj a)).some,
144+
let gg : α → locally_constant (F.obj j0) (fin 2) := λ a, (g a).comap (F.map (fs _)),
145+
let ggg := locally_constant.unflip gg,
146+
refine ⟨j0, ggg, _⟩,
147+
have : f.map ι = locally_constant.unflip (f.map ι).flip, by simp,
148+
rw this, clear this,
149+
have : locally_constant.comap (C.π.app j0) ggg =
150+
locally_constant.unflip (locally_constant.comap (C.π.app j0) ggg).flip, by simp,
151+
rw this, clear this,
152+
congr' 1,
153+
ext1 a,
154+
change ff a = _,
155+
rw h,
156+
dsimp [ggg, gg],
157+
ext1,
158+
repeat {
159+
rw locally_constant.coe_comap,
160+
dsimp [locally_constant.flip, locally_constant.unflip] },
161+
{ congr' 1,
162+
change _ = ((C.π.app j0) ≫ (F.map (fs a))) x,
163+
rw C.w },
164+
all_goals { continuity },
165+
end
166+
167+
theorem exists_locally_constant_fintype_nonempty {α : Type*} [fintype α] [nonempty α]
168+
(f : locally_constant C.X α) :
169+
∃ (j : J) (g : locally_constant (F.obj j) α), f = g.comap (C.π.app _) :=
170+
begin
171+
inhabit α,
172+
obtain ⟨j,gg,h⟩ := exists_locally_constant_fintype_aux _ hC f,
173+
let ι : α → α → fin 2 := λ a b, if a = b then 0 else 1,
174+
let σ : (α → fin 2) → α := λ f, if h : ∃ (a : α), ι a = f then h.some else arbitrary _,
175+
refine ⟨j, gg.map σ, _⟩,
176+
ext,
177+
rw locally_constant.coe_comap _ _ (C.π.app j).continuous,
178+
dsimp [σ],
179+
have h1 : ι (f x) = gg (C.π.app j x),
180+
{ change f.map (λ a b, if a = b then (0 : fin 2) else 1) x = _,
181+
rw [h, locally_constant.coe_comap _ _ (C.π.app j).continuous] },
182+
have h2 : ∃ a : α, ι a = gg (C.π.app j x) := ⟨f x, h1⟩,
183+
rw dif_pos h2,
184+
apply_fun ι,
185+
{ rw h2.some_spec,
186+
exact h1 },
187+
{ intros a b hh,
188+
apply_fun (λ e, e a) at hh,
189+
dsimp [ι] at hh,
190+
rw if_pos rfl at hh,
191+
split_ifs at hh with hh1 hh1,
192+
{ exact hh1.symm },
193+
{ exact false.elim (bot_ne_top hh) } }
194+
end
195+
196+
/-- Any locally constant function from a cofiltered limit of profinite sets factors through
197+
one of the components. -/
198+
theorem exists_locally_constant {α : Type*} (f : locally_constant C.X α) :
199+
∃ (j : J) (g : locally_constant (F.obj j) α), f = g.comap (C.π.app _) :=
200+
begin
201+
let S := f.discrete_quotient,
202+
let ff : S → α := f.lift,
203+
by_cases hα : nonempty S,
204+
{ resetI,
205+
let f' : locally_constant C.X S := ⟨S.proj, S.proj_is_locally_constant⟩,
206+
obtain ⟨j,g',h⟩ := exists_locally_constant_fintype_nonempty _ hC f',
207+
use j,
208+
refine ⟨⟨ff ∘ g', g'.is_locally_constant.comp _⟩,_⟩,
209+
ext1 t,
210+
apply_fun (λ e, e t) at h,
211+
rw locally_constant.coe_comap _ _ (C.π.app j).continuous at h ⊢,
212+
dsimp at h ⊢,
213+
rw ← h,
214+
refl },
215+
{ suffices : ∃ j : J, ¬ nonempty (F.obj j),
216+
{ obtain ⟨j,hj⟩ := this,
217+
use j,
218+
refine ⟨⟨λ x, false.elim (hj ⟨x⟩), λ A, _⟩, _⟩,
219+
{ convert is_open_empty,
220+
rw set.eq_empty_iff_forall_not_mem,
221+
intros x,
222+
exact false.elim (hj ⟨x⟩) },
223+
{ ext x,
224+
exact false.elim (hj ⟨C.π.app j x⟩) } },
225+
rw ← not_forall,
226+
intros h,
227+
apply hα,
228+
haveI : ∀ j : J, nonempty ((F ⋙ Profinite_to_Top).obj j) := h,
229+
haveI : ∀ j : J, t2_space ((F ⋙ Profinite_to_Top).obj j) := λ j,
230+
(infer_instance : t2_space (F.obj j)),
231+
haveI : ∀ j : J, compact_space ((F ⋙ Profinite_to_Top).obj j) := λ j,
232+
(infer_instance : compact_space (F.obj j)),
233+
have cond := Top.nonempty_limit_cone_of_compact_t2_cofiltered_system
234+
(F ⋙ Profinite_to_Top),
235+
suffices : nonempty C.X, by exact nonempty.map S.proj this,
236+
let D := Profinite_to_Top.map_cone C,
237+
have hD : is_limit D := is_limit_of_preserves Profinite_to_Top hC,
238+
have CD := (hD.cone_point_unique_up_to_iso (Top.limit_cone_is_limit _)).inv,
239+
exact cond.map CD }
240+
end
241+
113242
end Profinite

src/topology/discrete_quotient.lean

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -326,3 +326,30 @@ begin
326326
end
327327

328328
end discrete_quotient
329+
330+
namespace locally_constant
331+
332+
variables {X} {α : Type*} (f : locally_constant X α)
333+
334+
/-- Any locally constant function induces a discrete quotient. -/
335+
def discrete_quotient : discrete_quotient X :=
336+
{ rel := λ a b, f b = f a,
337+
equiv := ⟨by tauto, by tauto, λ a b c h1 h2, by rw [h2, h1]⟩,
338+
clopen := λ x, f.is_locally_constant.is_clopen_fiber _ }
339+
340+
/-- The function from the discrete quotient associated to a locally constant function. -/
341+
def lift : f.discrete_quotient → α := λ a, quotient.lift_on' a f (λ a b h, h.symm)
342+
343+
lemma lift_is_locally_constant : _root_.is_locally_constant f.lift := λ A, trivial
344+
345+
/-- A locally constant version of `locally_constant.lift`. -/
346+
def locally_constant_lift : locally_constant f.discrete_quotient α :=
347+
⟨f.lift, f.lift_is_locally_constant⟩
348+
349+
@[simp]
350+
lemma lift_eq_coe : f.lift = f.locally_constant_lift := rfl
351+
352+
@[simp]
353+
lemma factors : f.locally_constant_lift ∘ f.discrete_quotient.proj = f := by { ext, refl }
354+
355+
end locally_constant

src/topology/locally_constant/basic.lean

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,14 @@ lemma is_open_fiber {f : X → Y} (hf : is_locally_constant f) (y : Y) :
6464
is_open {x | f x = y} :=
6565
hf {y}
6666

67+
lemma is_closed_fiber {f : X → Y} (hf : is_locally_constant f) (y : Y) :
68+
is_closed {x | f x = y} :=
69+
⟨hf {y}ᶜ⟩
70+
71+
lemma is_clopen_fiber {f : X → Y} (hf : is_locally_constant f) (y : Y) :
72+
is_clopen {x | f x = y} :=
73+
⟨is_open_fiber hf _, is_closed_fiber hf _⟩
74+
6775
lemma iff_exists_open (f : X → Y) :
6876
is_locally_constant f ↔ ∀ x, ∃ (U : set X) (hU : is_open U) (hx : x ∈ U), ∀ x' ∈ U, f x' = f x :=
6977
(is_locally_constant.tfae f).out 0 4
@@ -161,7 +169,7 @@ lemma div [has_div Y] ⦃f g : X → Y⦄ (hf : is_locally_constant f) (hg : is_
161169
is_locally_constant (f / g) :=
162170
hf.comp₂ hg (/)
163171

164-
/-- If a composition of a function `f` followed by an injection `g` is locally
172+
/-- If a composition of a function `f` followed by an injection `g` is locally
165173
constant, then the locally constant property descends to `f`. -/
166174
lemma desc {α β : Type*} (f : X → α) (g : α → β)
167175
(h : is_locally_constant (g ∘ f)) (inj : function.injective g) : is_locally_constant f :=

0 commit comments

Comments
 (0)