|
| 1 | +/- |
| 2 | +Copyright (c) 2022 Anatole Dedecker. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Anatole Dedecker |
| 5 | +-/ |
| 6 | +import Mathlib.Topology.Connected.Basic |
| 7 | + |
| 8 | +/-! |
| 9 | +# Locally connected topological spaces |
| 10 | +
|
| 11 | +A topological space is **locally connected** if each neighborhood filter admits a basis |
| 12 | +of connected *open* sets. Local connectivity is equivalent to each point having a basis |
| 13 | +of connected (not necessarily open) sets --- but in a non-trivial way, so we choose this definition |
| 14 | +and prove the equivalence later in `locallyConnectedSpace_iff_connected_basis`. |
| 15 | +-/ |
| 16 | + |
| 17 | +open Set Topology |
| 18 | + |
| 19 | +universe u v |
| 20 | + |
| 21 | +variable {α : Type u} {β : Type v} {ι : Type*} {π : ι → Type*} [TopologicalSpace α] |
| 22 | + {s t u v : Set α} |
| 23 | + |
| 24 | +section LocallyConnectedSpace |
| 25 | + |
| 26 | +/-- A topological space is **locally connected** if each neighborhood filter admits a basis |
| 27 | +of connected *open* sets. Note that it is equivalent to each point having a basis of connected |
| 28 | +(non necessarily open) sets but in a non-trivial way, so we choose this definition and prove the |
| 29 | +equivalence later in `locallyConnectedSpace_iff_connected_basis`. -/ |
| 30 | +class LocallyConnectedSpace (α : Type*) [TopologicalSpace α] : Prop where |
| 31 | + /-- Open connected neighborhoods form a basis of the neighborhoods filter. -/ |
| 32 | + open_connected_basis : ∀ x, (𝓝 x).HasBasis (fun s : Set α => IsOpen s ∧ x ∈ s ∧ IsConnected s) id |
| 33 | +#align locally_connected_space LocallyConnectedSpace |
| 34 | + |
| 35 | +theorem locallyConnectedSpace_iff_open_connected_basis : |
| 36 | + LocallyConnectedSpace α ↔ |
| 37 | + ∀ x, (𝓝 x).HasBasis (fun s : Set α => IsOpen s ∧ x ∈ s ∧ IsConnected s) id := |
| 38 | + ⟨@LocallyConnectedSpace.open_connected_basis _ _, LocallyConnectedSpace.mk⟩ |
| 39 | +#align locally_connected_space_iff_open_connected_basis |
| 40 | + locallyConnectedSpace_iff_open_connected_basis |
| 41 | + |
| 42 | +theorem locallyConnectedSpace_iff_open_connected_subsets : |
| 43 | + LocallyConnectedSpace α ↔ |
| 44 | + ∀ x, ∀ U ∈ 𝓝 x, ∃ V : Set α, V ⊆ U ∧ IsOpen V ∧ x ∈ V ∧ IsConnected V := by |
| 45 | + simp_rw [locallyConnectedSpace_iff_open_connected_basis] |
| 46 | + refine forall_congr' fun _ => ?_ |
| 47 | + constructor |
| 48 | + · intro h U hU |
| 49 | + rcases h.mem_iff.mp hU with ⟨V, hV, hVU⟩ |
| 50 | + exact ⟨V, hVU, hV⟩ |
| 51 | + · exact fun h => ⟨fun U => ⟨fun hU => |
| 52 | + let ⟨V, hVU, hV⟩ := h U hU |
| 53 | + ⟨V, hV, hVU⟩, fun ⟨V, ⟨hV, hxV, _⟩, hVU⟩ => mem_nhds_iff.mpr ⟨V, hVU, hV, hxV⟩⟩⟩ |
| 54 | +#align locally_connected_space_iff_open_connected_subsets locallyConnectedSpace_iff_open_connected_subsets |
| 55 | + |
| 56 | +/-- A space with discrete topology is a locally connected space. -/ |
| 57 | +instance (priority := 100) DiscreteTopology.toLocallyConnectedSpace (α) [TopologicalSpace α] |
| 58 | + [DiscreteTopology α] : LocallyConnectedSpace α := |
| 59 | + locallyConnectedSpace_iff_open_connected_subsets.2 fun x _U hU => |
| 60 | + ⟨{x}, singleton_subset_iff.2 <| mem_of_mem_nhds hU, isOpen_discrete _, rfl, |
| 61 | + isConnected_singleton⟩ |
| 62 | +#align discrete_topology.to_locally_connected_space DiscreteTopology.toLocallyConnectedSpace |
| 63 | + |
| 64 | +theorem connectedComponentIn_mem_nhds [LocallyConnectedSpace α] {F : Set α} {x : α} (h : F ∈ 𝓝 x) : |
| 65 | + connectedComponentIn F x ∈ 𝓝 x := by |
| 66 | + rw [(LocallyConnectedSpace.open_connected_basis x).mem_iff] at h |
| 67 | + rcases h with ⟨s, ⟨h1s, hxs, h2s⟩, hsF⟩ |
| 68 | + exact mem_nhds_iff.mpr ⟨s, h2s.isPreconnected.subset_connectedComponentIn hxs hsF, h1s, hxs⟩ |
| 69 | +#align connected_component_in_mem_nhds connectedComponentIn_mem_nhds |
| 70 | + |
| 71 | +protected theorem IsOpen.connectedComponentIn [LocallyConnectedSpace α] {F : Set α} {x : α} |
| 72 | + (hF : IsOpen F) : IsOpen (connectedComponentIn F x) := by |
| 73 | + rw [isOpen_iff_mem_nhds] |
| 74 | + intro y hy |
| 75 | + rw [connectedComponentIn_eq hy] |
| 76 | + exact connectedComponentIn_mem_nhds (hF.mem_nhds <| connectedComponentIn_subset F x hy) |
| 77 | +#align is_open.connected_component_in IsOpen.connectedComponentIn |
| 78 | + |
| 79 | +theorem isOpen_connectedComponent [LocallyConnectedSpace α] {x : α} : |
| 80 | + IsOpen (connectedComponent x) := by |
| 81 | + rw [← connectedComponentIn_univ] |
| 82 | + exact isOpen_univ.connectedComponentIn |
| 83 | +#align is_open_connected_component isOpen_connectedComponent |
| 84 | + |
| 85 | +theorem isClopen_connectedComponent [LocallyConnectedSpace α] {x : α} : |
| 86 | + IsClopen (connectedComponent x) := |
| 87 | + ⟨isOpen_connectedComponent, isClosed_connectedComponent⟩ |
| 88 | +#align is_clopen_connected_component isClopen_connectedComponent |
| 89 | + |
| 90 | +theorem locallyConnectedSpace_iff_connectedComponentIn_open : |
| 91 | + LocallyConnectedSpace α ↔ |
| 92 | + ∀ F : Set α, IsOpen F → ∀ x ∈ F, IsOpen (connectedComponentIn F x) := by |
| 93 | + constructor |
| 94 | + · intro h |
| 95 | + exact fun F hF x _ => hF.connectedComponentIn |
| 96 | + · intro h |
| 97 | + rw [locallyConnectedSpace_iff_open_connected_subsets] |
| 98 | + refine' fun x U hU => |
| 99 | + ⟨connectedComponentIn (interior U) x, |
| 100 | + (connectedComponentIn_subset _ _).trans interior_subset, h _ isOpen_interior x _, |
| 101 | + mem_connectedComponentIn _, isConnected_connectedComponentIn_iff.mpr _⟩ <;> |
| 102 | + exact mem_interior_iff_mem_nhds.mpr hU |
| 103 | +#align locally_connected_space_iff_connected_component_in_open locallyConnectedSpace_iff_connectedComponentIn_open |
| 104 | + |
| 105 | +theorem locallyConnectedSpace_iff_connected_subsets : |
| 106 | + LocallyConnectedSpace α ↔ ∀ (x : α), ∀ U ∈ 𝓝 x, ∃ V ∈ 𝓝 x, IsPreconnected V ∧ V ⊆ U := by |
| 107 | + constructor |
| 108 | + · rw [locallyConnectedSpace_iff_open_connected_subsets] |
| 109 | + intro h x U hxU |
| 110 | + rcases h x U hxU with ⟨V, hVU, hV₁, hxV, hV₂⟩ |
| 111 | + exact ⟨V, hV₁.mem_nhds hxV, hV₂.isPreconnected, hVU⟩ |
| 112 | + · rw [locallyConnectedSpace_iff_connectedComponentIn_open] |
| 113 | + refine' fun h U hU x _ => isOpen_iff_mem_nhds.mpr fun y hy => _ |
| 114 | + rw [connectedComponentIn_eq hy] |
| 115 | + rcases h y U (hU.mem_nhds <| (connectedComponentIn_subset _ _) hy) with ⟨V, hVy, hV, hVU⟩ |
| 116 | + exact Filter.mem_of_superset hVy (hV.subset_connectedComponentIn (mem_of_mem_nhds hVy) hVU) |
| 117 | +#align locally_connected_space_iff_connected_subsets locallyConnectedSpace_iff_connected_subsets |
| 118 | + |
| 119 | +theorem locallyConnectedSpace_iff_connected_basis : |
| 120 | + LocallyConnectedSpace α ↔ |
| 121 | + ∀ x, (𝓝 x).HasBasis (fun s : Set α => s ∈ 𝓝 x ∧ IsPreconnected s) id := by |
| 122 | + rw [locallyConnectedSpace_iff_connected_subsets] |
| 123 | + exact forall_congr' <| fun x => Filter.hasBasis_self.symm |
| 124 | +#align locally_connected_space_iff_connected_basis locallyConnectedSpace_iff_connected_basis |
| 125 | + |
| 126 | +theorem locallyConnectedSpace_of_connected_bases {ι : Type*} (b : α → ι → Set α) (p : α → ι → Prop) |
| 127 | + (hbasis : ∀ x, (𝓝 x).HasBasis (p x) (b x)) |
| 128 | + (hconnected : ∀ x i, p x i → IsPreconnected (b x i)) : LocallyConnectedSpace α := by |
| 129 | + rw [locallyConnectedSpace_iff_connected_basis] |
| 130 | + exact fun x => |
| 131 | + (hbasis x).to_hasBasis |
| 132 | + (fun i hi => ⟨b x i, ⟨(hbasis x).mem_of_mem hi, hconnected x i hi⟩, subset_rfl⟩) fun s hs => |
| 133 | + ⟨(hbasis x).index s hs.1, ⟨(hbasis x).property_index hs.1, (hbasis x).set_index_subset hs.1⟩⟩ |
| 134 | +#align locally_connected_space_of_connected_bases locallyConnectedSpace_of_connected_bases |
| 135 | + |
| 136 | +theorem OpenEmbedding.locallyConnectedSpace [LocallyConnectedSpace α] [TopologicalSpace β] |
| 137 | + {f : β → α} (h : OpenEmbedding f) : LocallyConnectedSpace β := by |
| 138 | + refine locallyConnectedSpace_of_connected_bases (fun _ s ↦ f ⁻¹' s) |
| 139 | + (fun x s ↦ (IsOpen s ∧ f x ∈ s ∧ IsConnected s) ∧ s ⊆ range f) (fun x ↦ ?_) |
| 140 | + (fun x s hxs ↦ hxs.1.2.2.isPreconnected.preimage_of_open_map h.inj h.isOpenMap hxs.2) |
| 141 | + rw [h.nhds_eq_comap] |
| 142 | + exact LocallyConnectedSpace.open_connected_basis (f x) |>.restrict_subset |
| 143 | + (h.open_range.mem_nhds <| mem_range_self _) |>.comap _ |
| 144 | + |
| 145 | +theorem IsOpen.locallyConnectedSpace [LocallyConnectedSpace α] {U : Set α} (hU : IsOpen U) : |
| 146 | + LocallyConnectedSpace U := |
| 147 | + hU.openEmbedding_subtype_val.locallyConnectedSpace |
| 148 | + |
| 149 | +end LocallyConnectedSpace |
0 commit comments