|
| 1 | +/- |
| 2 | +Copyright (c) 2026 Yury Kudryashov. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Yury Kudryashov |
| 5 | +-/ |
| 6 | +module |
| 7 | + |
| 8 | +public import Mathlib.Topology.Covering.Basic |
| 9 | +public import Mathlib.Topology.Sheaves.Stalks |
| 10 | + |
| 11 | +/-! |
| 12 | +# Etale space of a presheaf |
| 13 | +
|
| 14 | +Given a presheaf `F` on a topological space `X`, |
| 15 | +its *etale space* is the space of pairs `(base, germ)`, |
| 16 | +where `base` is a point of `X`, and `germ` is an element of the stalk of `F` at `base`. |
| 17 | +
|
| 18 | +This space is equipped with the following topology. |
| 19 | +For each open set `U` and a section `s` of `F` over `U`, |
| 20 | +the set of germs of `s` at points `x ∈ U` is an open set in the etale space. |
| 21 | +
|
| 22 | +## Main results |
| 23 | +
|
| 24 | +- `TopCat.Presheaf.EtaleSpace.eventually_nhds`. If `s` is a section of `F` over `U` |
| 25 | + with germ at `g.base` equal to `g.germ`, |
| 26 | + then a neighborhood of `g` consists of germs of `s` at points `x ∈ U`. |
| 27 | +
|
| 28 | +- `TopCat.Presheaf.EtaleSpace.isCoveringMap_base`. |
| 29 | + Let `F` be a presheaf with the following property. |
| 30 | +
|
| 31 | + For each `x`, there exists an open neighborhood `U ∋ x` such that for each `y ∈ U`, |
| 32 | + the map `Presheaf.germ F U y hyU` from sections of `F` over `U` to the stalk at `y` |
| 33 | + is bijective. |
| 34 | +
|
| 35 | + Then the projection from the etale space of `F` to the base is a covering map. |
| 36 | +-/ |
| 37 | + |
| 38 | +public section |
| 39 | + |
| 40 | +open Function Set CategoryTheory TopologicalSpace Opposite Filter |
| 41 | +open scoped Topology |
| 42 | + |
| 43 | +namespace TopCat.Presheaf |
| 44 | + |
| 45 | +universe v u w |
| 46 | +variable {X : TopCat.{v}} {C : Type u} [Category.{v} C] {CC : C → Type v} {FC : C → C → Type w} |
| 47 | + [∀ X Y, FunLike (FC X Y) (CC X) (CC Y)] [ConcreteCategory C FC] [Limits.HasColimits.{v} C] |
| 48 | + |
| 49 | +/-- Etale space of a presheaf. -/ |
| 50 | +structure EtaleSpace (F : Presheaf C X) where |
| 51 | + /-- The base point. -/ |
| 52 | + base : X |
| 53 | + /-- A germ at `base` (formally, an element of the stalk of `F` at `base`). -/ |
| 54 | + germ : ToType (F.stalk base) |
| 55 | + |
| 56 | +namespace EtaleSpace |
| 57 | + |
| 58 | +instance (F : Presheaf C X) : TopologicalSpace F.EtaleSpace := |
| 59 | + .generateFrom |
| 60 | + {{g | ∃ h, g.germ = F.germ U g.base h f} | (U : Opens X) (f : ToType (F.obj <| op U))} |
| 61 | + |
| 62 | +variable {F : Presheaf C X} |
| 63 | + |
| 64 | +/-- If `s` is a section of a presheaf `F` over `U` with germ at `g.base` equal to `g.germ`, |
| 65 | +then a neighborhood of `g` consists of germs of `s` at points `x ∈ U`. -/ |
| 66 | +protected theorem eventually_nhds (g : EtaleSpace F) {U : Opens X} (h : g.base ∈ U) |
| 67 | + (s : ToType (F.obj (op U))) (hs : F.germ U g.base h s = g.germ) : |
| 68 | + ∀ᶠ g' : EtaleSpace F in 𝓝 g, ∃ hgU : g'.base ∈ U, g'.germ = F.germ U g'.base hgU s := by |
| 69 | + simp only [nhds_generateFrom, Filter.Eventually, mem_setOf_eq, iInf_and, iInf_exists] |
| 70 | + refine mem_iInf_of_mem _ <| mem_iInf_of_mem ?_ <| mem_iInf_of_mem U <| mem_iInf_of_mem s <| |
| 71 | + mem_iInf_of_mem rfl <| mem_principal_self _ |
| 72 | + simp [*] |
| 73 | + |
| 74 | +variable [Limits.PreservesFilteredColimits (forget C)] |
| 75 | + |
| 76 | +variable (F) in |
| 77 | +@[fun_prop] |
| 78 | +theorem continuous_base : Continuous (base (F := F)) := by |
| 79 | + rw [continuous_iff_continuousAt] |
| 80 | + intro x |
| 81 | + rw [ContinuousAt, (nhds_basis_opens _).tendsto_right_iff] |
| 82 | + rintro U ⟨hxU, hUo⟩ |
| 83 | + lift U to Opens X using hUo |
| 84 | + rcases F.exists_le_germ_eq x.germ hxU with ⟨V, hVU, hxV, f, hf⟩ |
| 85 | + refine x.eventually_nhds hxV f hf |>.mono ?_ |
| 86 | + aesop |
| 87 | + |
| 88 | +theorem exists_section_of_tendsto {α : Type*} {l : Filter α} {g : α → F.EtaleSpace} |
| 89 | + {g₀ : F.EtaleSpace} (h : Tendsto g l (𝓝 g₀)) : |
| 90 | + ∃ (U : Opens X), g₀.base ∈ U ∧ ∃ (f : ToType (F.obj (op U))), |
| 91 | + ∀ᶠ a in l, ∃ ha : (g a).base ∈ U, (g a).germ = F.germ U (g a).base ha f := by |
| 92 | + rcases F.exists_germ_eq g₀.germ with ⟨U, hU, s, hs⟩ |
| 93 | + use U, hU, s |
| 94 | + exact h.eventually <| g₀.eventually_nhds hU s hs |
| 95 | + |
| 96 | +/-- Let `F` be a `C`-valued presheaf on `X`. |
| 97 | +Let `U` be an open set on `X` such that for each `x ∈ U`, the `germ` map is bijective, i.e., |
| 98 | +every germ can be extended to a unique section over `U`. |
| 99 | +
|
| 100 | +Then for each `x ∈ U`, the preimage of `U` under `EtaleSpace.base` |
| 101 | +is homeomorphic to the product of `U` and the stalk of `F` at `x` with discrete topology. |
| 102 | +-/ |
| 103 | +@[expose, simps apply_fst] |
| 104 | +noncomputable def homeomorph (U : Opens X) |
| 105 | + (hF_bij : ∀ (x : X) (hx : x ∈ U), Bijective (F.germ U x hx)) |
| 106 | + (x : X) (hx : x ∈ U) : |
| 107 | + (base (F := F) ⁻¹' U) ≃ₜ U × WithDiscreteTopology (ToType (F.stalk x)) where |
| 108 | + toFun s := (⟨s.1.base, s.2⟩, |
| 109 | + .toTopology ⊥ <| F.germ U x hx <| surjInv (hF_bij s.1.base s.2).surjective s.1.germ) |
| 110 | + invFun |
| 111 | + | (⟨y, hy⟩, .toTopology _ g) => ⟨⟨y, F.germ U y hy <| surjInv (hF_bij x hx).surjective g⟩, hy⟩ |
| 112 | + left_inv := by |
| 113 | + rintro ⟨⟨base, s⟩, hs⟩ |
| 114 | + simp only |
| 115 | + congr 2 |
| 116 | + rw [leftInverse_surjInv (hF_bij _ _), surjInv_eq (hF_bij _ _).surjective] |
| 117 | + right_inv := by |
| 118 | + rintro ⟨⟨y, hy⟩, ⟨g⟩⟩ |
| 119 | + simp only |
| 120 | + congr |
| 121 | + rw [leftInverse_surjInv (hF_bij _ _), surjInv_eq (hF_bij _ _).surjective] |
| 122 | + continuous_toFun := by |
| 123 | + refine .prodMk (by fun_prop) ?_ |
| 124 | + simp_rw [continuous_iff_continuousAt, ContinuousAt, nhds_discrete, tendsto_pure, nhds_subtype, |
| 125 | + eventually_comap] |
| 126 | + rintro ⟨g, hg⟩ |
| 127 | + rcases hF_bij _ hg |>.surjective g.germ with ⟨f, hf⟩ |
| 128 | + filter_upwards [g.eventually_nhds hg f hf] |
| 129 | + rintro _ ⟨hgU, hgf⟩ g' rfl |
| 130 | + congr 1 |
| 131 | + rw [hgf, ← hf, leftInverse_surjInv (hF_bij _ _), leftInverse_surjInv (hF_bij _ _)] |
| 132 | + continuous_invFun := by |
| 133 | + simp_rw [continuous_iff_continuousAt, continuousAt_prod_of_discrete_right] |
| 134 | + rintro ⟨y, ⟨g⟩⟩ |
| 135 | + simp only [ContinuousAt, nhds_subtype_eq_comap, tendsto_comap_iff, comp_def, |
| 136 | + nhds_generateFrom, tendsto_iInf, mem_setOf_eq, tendsto_principal] |
| 137 | + rintro _ ⟨hmem, V, f, rfl⟩ |
| 138 | + simp only [mem_setOf_eq] at hmem |
| 139 | + rcases hmem with ⟨hyV, hgf⟩ |
| 140 | + rcases F.germ_eq _ _ _ _ _ hgf with ⟨W, hyW, ιWU, ιWV, hW⟩ |
| 141 | + filter_upwards [W.isOpen.preimage continuous_subtype_val |>.mem_nhds hyW] with z hz |
| 142 | + use ιWV.le hz |
| 143 | + rw [← F.germ_res_apply ιWU z hz, hW, F.germ_res_apply] |
| 144 | + |
| 145 | +/-- Let `F` be a presheaf with the following property. |
| 146 | +
|
| 147 | +For each `x`, there exists an open neighborhood `U ∋ x` such that for each `y ∈ U`, |
| 148 | +the map `Presheaf.germ F U y hyU` from sections of `F` over `U` to the stalk at `y` |
| 149 | +is bijective. |
| 150 | +
|
| 151 | +Then the projection from the etale space of `F` to the base is a covering map. -/ |
| 152 | +theorem isCoveringMap_base |
| 153 | + (hF_bij : ∀ x, ∃ (U : Opens X), x ∈ U ∧ ∀ y (hyU : y ∈ U), Bijective (F.germ U y hyU)) : |
| 154 | + IsCoveringMap (base (F := F)) := by |
| 155 | + refine fun x ↦ .to_isEvenlyCovered_preimage (I := WithDiscreteTopology (ToType (F.stalk x))) ?_ |
| 156 | + use inferInstance |
| 157 | + rcases hF_bij x with ⟨U, hxU, hU_bij⟩ |
| 158 | + use U, hxU, U.isOpen, U.isOpen.preimage (continuous_base F), homeomorph U hU_bij x hxU |
| 159 | + simp |
| 160 | + |
| 161 | +end EtaleSpace |
| 162 | + |
| 163 | +end TopCat.Presheaf |
0 commit comments