|
| 1 | +/- |
| 2 | +Copyright (c) 2022 Yury Kudryashov. All rights reserved. |
| 3 | +Released under Apache 2.0 license as described in the file LICENSE. |
| 4 | +Authors: Yury Kudryashov |
| 5 | +
|
| 6 | +! This file was ported from Lean 3 source module data.set.intervals.ord_connected_component |
| 7 | +! leanprover-community/mathlib commit 1e05171a5e8cf18d98d9cf7b207540acb044acae |
| 8 | +! Please do not edit these lines, except to modify the commit id |
| 9 | +! if you have ported upstream changes. |
| 10 | +-/ |
| 11 | +import Mathlib.Data.Set.Intervals.OrdConnected |
| 12 | +import Mathlib.Tactic.SwapVar |
| 13 | +/-! |
| 14 | +# Order connected components of a set |
| 15 | +
|
| 16 | +In this file we define `Set.ordConnectedComponent s x` to be the set of `y` such that |
| 17 | +`Set.interval x y ⊆ s` and prove some basic facts about this definition. At the moment of writing, |
| 18 | +this construction is used only to prove that any linear order with order topology is a T₅ space, |
| 19 | +so we only add API needed for this lemma. |
| 20 | +-/ |
| 21 | + |
| 22 | + |
| 23 | +open Function OrderDual |
| 24 | + |
| 25 | +namespace Set |
| 26 | + |
| 27 | +variable {α : Type _} [LinearOrder α] {s t : Set α} {x y z : α} |
| 28 | + |
| 29 | +/-- Order-connected component of a point `x` in a set `s`. It is defined as the set of `y` such that |
| 30 | +`Set.interval x y ⊆ s`. Note that it is empty if and only if `x ∉ s`. -/ |
| 31 | +def ordConnectedComponent (s : Set α) (x : α) : Set α := |
| 32 | + { y | [[x, y]] ⊆ s } |
| 33 | +#align set.ord_connected_component Set.ordConnectedComponent |
| 34 | + |
| 35 | +theorem mem_ordConnectedComponent : y ∈ ordConnectedComponent s x ↔ [[x, y]] ⊆ s := |
| 36 | + Iff.rfl |
| 37 | +#align set.mem_ord_connected_component Set.mem_ordConnectedComponent |
| 38 | + |
| 39 | +theorem dual_ordConnectedComponent : |
| 40 | + ordConnectedComponent (ofDual ⁻¹' s) (toDual x) = ofDual ⁻¹' ordConnectedComponent s x := |
| 41 | + ext <| |
| 42 | + (Surjective.forall toDual.surjective).2 fun x => |
| 43 | + by |
| 44 | + rw [mem_ordConnectedComponent, dual_interval] |
| 45 | + rfl |
| 46 | +#align set.dual_ord_connected_component Set.dual_ordConnectedComponent |
| 47 | + |
| 48 | +theorem ordConnectedComponent_subset : ordConnectedComponent s x ⊆ s := fun _ hy => |
| 49 | + hy right_mem_interval |
| 50 | +#align set.ord_connected_component_subset Set.ordConnectedComponent_subset |
| 51 | + |
| 52 | +theorem subset_ordConnectedComponent {t} [h : OrdConnected s] (hs : x ∈ s) (ht : s ⊆ t) : |
| 53 | + s ⊆ ordConnectedComponent t x := fun _ hy => (h.interval_subset hs hy).trans ht |
| 54 | +#align set.subset_ord_connected_component Set.subset_ordConnectedComponent |
| 55 | + |
| 56 | +@[simp] |
| 57 | +theorem self_mem_ordConnectedComponent : x ∈ ordConnectedComponent s x ↔ x ∈ s := by |
| 58 | + rw [mem_ordConnectedComponent, interval_self, singleton_subset_iff] |
| 59 | +#align set.self_mem_ord_connected_component Set.self_mem_ordConnectedComponent |
| 60 | + |
| 61 | +@[simp] |
| 62 | +theorem nonempty_ordConnectedComponent : (ordConnectedComponent s x).Nonempty ↔ x ∈ s := |
| 63 | + ⟨fun ⟨_, hy⟩ => hy <| left_mem_interval, fun h => ⟨x, self_mem_ordConnectedComponent.2 h⟩⟩ |
| 64 | +#align set.nonempty_ord_connected_component Set.nonempty_ordConnectedComponent |
| 65 | + |
| 66 | +@[simp] |
| 67 | +theorem ordConnectedComponent_eq_empty : ordConnectedComponent s x = ∅ ↔ x ∉ s := by |
| 68 | + rw [← not_nonempty_iff_eq_empty, nonempty_ordConnectedComponent] |
| 69 | +#align set.ord_connected_component_eq_empty Set.ordConnectedComponent_eq_empty |
| 70 | + |
| 71 | +@[simp] |
| 72 | +theorem ordConnectedComponent_empty : ordConnectedComponent ∅ x = ∅ := |
| 73 | + ordConnectedComponent_eq_empty.2 (not_mem_empty x) |
| 74 | +#align set.ord_connected_component_empty Set.ordConnectedComponent_empty |
| 75 | + |
| 76 | +@[simp] |
| 77 | +theorem ordConnectedComponent_univ : ordConnectedComponent univ x = univ := by |
| 78 | + simp [ordConnectedComponent] |
| 79 | +#align set.ord_connected_component_univ Set.ordConnectedComponent_univ |
| 80 | + |
| 81 | +theorem ordConnectedComponent_inter (s t : Set α) (x : α) : |
| 82 | + ordConnectedComponent (s ∩ t) x = ordConnectedComponent s x ∩ ordConnectedComponent t x := by |
| 83 | + simp [ordConnectedComponent, setOf_and] |
| 84 | +#align set.ord_connected_component_inter Set.ordConnectedComponent_inter |
| 85 | + |
| 86 | +theorem mem_ordConnectedComponent_comm : |
| 87 | + y ∈ ordConnectedComponent s x ↔ x ∈ ordConnectedComponent s y := by |
| 88 | + rw [mem_ordConnectedComponent, mem_ordConnectedComponent, interval_swap] |
| 89 | +#align set.mem_ord_connected_component_comm Set.mem_ordConnectedComponent_comm |
| 90 | + |
| 91 | +theorem mem_ordConnectedComponent_trans (hxy : y ∈ ordConnectedComponent s x) |
| 92 | + (hyz : z ∈ ordConnectedComponent s y) : z ∈ ordConnectedComponent s x := |
| 93 | + calc |
| 94 | + [[x, z]] ⊆ [[x, y]] ∪ [[y, z]] := interval_subset_interval_union_interval |
| 95 | + _ ⊆ s := union_subset hxy hyz |
| 96 | + |
| 97 | +#align set.mem_ord_connected_component_trans Set.mem_ordConnectedComponent_trans |
| 98 | + |
| 99 | +theorem ordConnectedComponent_eq (h : [[x, y]] ⊆ s) : |
| 100 | + ordConnectedComponent s x = ordConnectedComponent s y := |
| 101 | + ext fun _ => |
| 102 | + ⟨mem_ordConnectedComponent_trans (mem_ordConnectedComponent_comm.2 h), |
| 103 | + mem_ordConnectedComponent_trans h⟩ |
| 104 | +#align set.ord_connected_component_eq Set.ordConnectedComponent_eq |
| 105 | + |
| 106 | +instance : OrdConnected (ordConnectedComponent s x) := |
| 107 | + ordConnected_of_interval_subset_left fun _ hy _ hz => (interval_subset_interval_left hz).trans hy |
| 108 | + |
| 109 | +/-- Projection from `s : Set α` to `α` sending each order connected component of `s` to a single |
| 110 | +point of this component. -/ |
| 111 | +noncomputable def ordConnectedProj (s : Set α) : s → α := fun x : s => |
| 112 | + (nonempty_ordConnectedComponent.2 x.2).some |
| 113 | +#align set.ord_connected_proj Set.ordConnectedProj |
| 114 | + |
| 115 | +theorem ordConnectedProj_mem_ordConnectedComponent (s : Set α) (x : s) : |
| 116 | + ordConnectedProj s x ∈ ordConnectedComponent s x := |
| 117 | + Nonempty.some_mem _ |
| 118 | +#align |
| 119 | + set.ord_connected_proj_mem_ord_connected_component |
| 120 | + Set.ordConnectedProj_mem_ordConnectedComponent |
| 121 | + |
| 122 | +theorem mem_ordConnectedComponent_ord_connected_proj (s : Set α) (x : s) : |
| 123 | + ↑x ∈ ordConnectedComponent s (ordConnectedProj s x) := |
| 124 | + mem_ordConnectedComponent_comm.2 <| ordConnectedProj_mem_ordConnectedComponent s x |
| 125 | +#align |
| 126 | + set.mem_ord_connected_component_ord_connected_proj |
| 127 | + Set.mem_ordConnectedComponent_ord_connected_proj |
| 128 | + |
| 129 | +@[simp] |
| 130 | +theorem ordConnectedComponent_ord_connected_proj (s : Set α) (x : s) : |
| 131 | + ordConnectedComponent s (ordConnectedProj s x) = ordConnectedComponent s x := |
| 132 | + ordConnectedComponent_eq <| mem_ordConnectedComponent_ord_connected_proj _ _ |
| 133 | +#align set.ord_connected_component_ord_connected_proj Set.ordConnectedComponent_ord_connected_proj |
| 134 | + |
| 135 | +@[simp] |
| 136 | +theorem ordConnectedProj_eq {x y : s} : |
| 137 | + ordConnectedProj s x = ordConnectedProj s y ↔ [[(x : α), y]] ⊆ s := |
| 138 | + by |
| 139 | + constructor <;> intro h |
| 140 | + · rw [← mem_ordConnectedComponent, ← ordConnectedComponent_ord_connected_proj, h, |
| 141 | + ordConnectedComponent_ord_connected_proj, self_mem_ordConnectedComponent] |
| 142 | + exact y.2 |
| 143 | + · simp only [ordConnectedProj] |
| 144 | + congr 1 |
| 145 | + exact ordConnectedComponent_eq h |
| 146 | +#align set.ord_connected_proj_eq Set.ordConnectedProj_eq |
| 147 | + |
| 148 | +/-- A set that intersects each order connected component of a set by a single point. Defined as the |
| 149 | +range of `Set.ordConnectedProj s`. -/ |
| 150 | +def ordConnectedSection (s : Set α) : Set α := |
| 151 | + range <| ordConnectedProj s |
| 152 | +#align set.ord_connected_section Set.ordConnectedSection |
| 153 | + |
| 154 | +theorem dual_ordConnectedSection (s : Set α) : |
| 155 | + ordConnectedSection (ofDual ⁻¹' s) = ofDual ⁻¹' ordConnectedSection s := by |
| 156 | + simp_rw [ordConnectedSection, ordConnectedProj] |
| 157 | + ext x |
| 158 | + simp [dual_ordConnectedComponent] |
| 159 | + tauto |
| 160 | + |
| 161 | +#align set.dual_ord_connected_section Set.dual_ordConnectedSection |
| 162 | + |
| 163 | +theorem ordConnectedSection_subset : ordConnectedSection s ⊆ s := |
| 164 | + range_subset_iff.2 fun _ => ordConnectedComponent_subset <| Nonempty.some_mem _ |
| 165 | +#align set.ord_connected_section_subset Set.ordConnectedSection_subset |
| 166 | + |
| 167 | +theorem eq_of_mem_ordConnectedSection_of_interval_subset (hx : x ∈ ordConnectedSection s) |
| 168 | + (hy : y ∈ ordConnectedSection s) (h : [[x, y]] ⊆ s) : x = y := |
| 169 | + by |
| 170 | + rcases hx with ⟨x, rfl⟩; rcases hy with ⟨y, rfl⟩ |
| 171 | + exact |
| 172 | + ordConnectedProj_eq.2 |
| 173 | + (mem_ordConnectedComponent_trans |
| 174 | + (mem_ordConnectedComponent_trans (ordConnectedProj_mem_ordConnectedComponent _ _) h) |
| 175 | + (mem_ordConnectedComponent_ord_connected_proj _ _)) |
| 176 | +#align |
| 177 | + set.eq_of_mem_ord_connected_section_of_interval_subset |
| 178 | + Set.eq_of_mem_ordConnectedSection_of_interval_subset |
| 179 | + |
| 180 | +/-- Given two sets `s t : Set α`, the set `Set.orderSeparatingSet s t` is the set of points that |
| 181 | +belong both to some `Set.ordConnectedComponent tᶜ x`, `x ∈ s`, and to some |
| 182 | +`Set.ordConnectedComponent sᶜ x`, `x ∈ t`. In the case of two disjoint closed sets, this is the |
| 183 | +union of all open intervals $(a, b)$ such that their endpoints belong to different sets. -/ |
| 184 | +def ordSeparatingSet (s t : Set α) : Set α := |
| 185 | + (⋃ x ∈ s, ordConnectedComponent (tᶜ) x) ∩ ⋃ x ∈ t, ordConnectedComponent (sᶜ) x |
| 186 | +#align set.ord_separating_set Set.ordSeparatingSet |
| 187 | + |
| 188 | +theorem ordSeparatingSet_comm (s t : Set α) : ordSeparatingSet s t = ordSeparatingSet t s := |
| 189 | + inter_comm _ _ |
| 190 | +#align set.ord_separating_set_comm Set.ordSeparatingSet_comm |
| 191 | + |
| 192 | +theorem disjoint_left_ordSeparatingSet : Disjoint s (ordSeparatingSet s t) := |
| 193 | + Disjoint.inter_right' _ <| |
| 194 | + disjoint_unionᵢ₂_right.2 fun _ _ => |
| 195 | + disjoint_compl_right.mono_right <| ordConnectedComponent_subset |
| 196 | +#align set.disjoint_left_ord_separating_set Set.disjoint_left_ordSeparatingSet |
| 197 | + |
| 198 | +theorem disjoint_right_ordSeparatingSet : Disjoint t (ordSeparatingSet s t) := |
| 199 | + ordSeparatingSet_comm t s ▸ disjoint_left_ordSeparatingSet |
| 200 | +#align set.disjoint_right_ord_separating_set Set.disjoint_right_ordSeparatingSet |
| 201 | + |
| 202 | +theorem dual_ordSeparatingSet : |
| 203 | + ordSeparatingSet (ofDual ⁻¹' s) (ofDual ⁻¹' t) = ofDual ⁻¹' ordSeparatingSet s t := by |
| 204 | + simp only [ordSeparatingSet, mem_preimage, ← toDual.surjective.unionᵢ_comp, ofDual_toDual, |
| 205 | + dual_ordConnectedComponent, ← preimage_compl, preimage_inter, preimage_unionᵢ] |
| 206 | +#align set.dual_ord_separating_set Set.dual_ordSeparatingSet |
| 207 | + |
| 208 | +/-- An auxiliary neighborhood that will be used in the proof of `OrderTopology.t5Space`. -/ |
| 209 | +def ordT5Nhd (s t : Set α) : Set α := |
| 210 | + ⋃ x ∈ s, ordConnectedComponent (tᶜ ∩ (ordConnectedSection <| ordSeparatingSet s t)ᶜ) x |
| 211 | +#align set.ord_t5_nhd Set.ordT5Nhd |
| 212 | + |
| 213 | +theorem disjoint_ordT5Nhd : Disjoint (ordT5Nhd s t) (ordT5Nhd t s) := |
| 214 | + by |
| 215 | + rw [disjoint_iff_inf_le] |
| 216 | + rintro x ⟨hx₁, hx₂⟩ |
| 217 | + rcases mem_unionᵢ₂.1 hx₁ with ⟨a, has, ha⟩ |
| 218 | + clear hx₁ |
| 219 | + rcases mem_unionᵢ₂.1 hx₂ with ⟨b, hbt, hb⟩ |
| 220 | + clear hx₂ |
| 221 | + rw [mem_ordConnectedComponent, subset_inter_iff] at ha hb |
| 222 | + cases' le_total a b with hab hab |
| 223 | + on_goal 2 => swap_var a ↔ b, s ↔ t, ha ↔ hb, has ↔ hbt |
| 224 | + all_goals |
| 225 | +-- porting note: wlog not implemented yet, the following replaces the three previous lines |
| 226 | +-- wlog (discharger := tactic.skip) hab : a ≤ b := le_total a b using a b s t, b a t s |
| 227 | + cases' ha with ha ha' |
| 228 | + cases' hb with hb hb' |
| 229 | + have hsub : [[a, b]] ⊆ (ordSeparatingSet s t).ordConnectedSectionᶜ := |
| 230 | + by |
| 231 | + rw [ordSeparatingSet_comm, interval_swap] at hb' |
| 232 | + calc |
| 233 | + [[a, b]] ⊆ [[a, x]] ∪ [[x, b]] := interval_subset_interval_union_interval |
| 234 | + _ ⊆ (ordSeparatingSet s t).ordConnectedSectionᶜ := union_subset ha' hb' |
| 235 | + clear ha' hb' |
| 236 | + cases' le_total x a with hxa hax |
| 237 | + · exact hb (Icc_subset_interval' ⟨hxa, hab⟩) has |
| 238 | + cases' le_total b x with hbx hxb |
| 239 | + · exact ha (Icc_subset_interval ⟨hab, hbx⟩) hbt |
| 240 | + have h' : x ∈ ordSeparatingSet s t := ⟨mem_unionᵢ₂.2 ⟨a, has, ha⟩, mem_unionᵢ₂.2 ⟨b, hbt, hb⟩⟩ |
| 241 | + -- porting note: lift not implemented yet |
| 242 | + -- lift x to ordSeparatingSet s t using this |
| 243 | + suffices : ordConnectedComponent (ordSeparatingSet s t) x ⊆ [[a, b]] |
| 244 | + exact hsub (this <| ordConnectedProj_mem_ordConnectedComponent _ ⟨x, h'⟩) (mem_range_self _) |
| 245 | + rintro y (hy : [[x, y]] ⊆ ordSeparatingSet s t) |
| 246 | + rw [interval_of_le hab, mem_Icc, ← not_lt, ← not_lt] |
| 247 | + have sol1 := fun (hya : y < a) => |
| 248 | + (disjoint_left (t := ordSeparatingSet s t)).1 disjoint_left_ordSeparatingSet has |
| 249 | + (hy <| Icc_subset_interval' ⟨hya.le, hax⟩) |
| 250 | + have sol2 := fun (hby : b < y) => |
| 251 | + (disjoint_left (t := ordSeparatingSet s t)).1 disjoint_right_ordSeparatingSet hbt |
| 252 | + (hy <| Icc_subset_interval ⟨hxb, hby.le⟩) |
| 253 | + exact ⟨sol1, sol2⟩ |
| 254 | +#align set.disjoint_ord_t5_nhd Set.disjoint_ordT5Nhd |
0 commit comments