Skip to content

Commit acb5c0c

Browse files
committed
feat: port Data.Set.Intervals.OrdConnectedComponent (#1303)
1 parent cb1b0a6 commit acb5c0c

File tree

2 files changed

+255
-0
lines changed

2 files changed

+255
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,7 @@ import Mathlib.Data.Set.Intervals.Group
318318
import Mathlib.Data.Set.Intervals.Monoid
319319
import Mathlib.Data.Set.Intervals.Monotone
320320
import Mathlib.Data.Set.Intervals.OrdConnected
321+
import Mathlib.Data.Set.Intervals.OrdConnectedComponent
321322
import Mathlib.Data.Set.Intervals.OrderIso
322323
import Mathlib.Data.Set.Intervals.Pi
323324
import Mathlib.Data.Set.Intervals.ProjIcc
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
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

Comments
 (0)