-
Notifications
You must be signed in to change notification settings - Fork 251
/
Topology.lean
421 lines (342 loc) · 21.7 KB
/
Topology.lean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
/-
Copyright (c) 2020 Yury Kudryashov. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Alexander Bentkamp, Yury Kudryashov
-/
import Mathlib.Analysis.Convex.Combination
import Mathlib.Analysis.Convex.Strict
import Mathlib.Topology.Connected.PathConnected
import Mathlib.Topology.Algebra.Affine
import Mathlib.Topology.Algebra.Module.Basic
#align_import analysis.convex.topology from "leanprover-community/mathlib"@"0e3aacdc98d25e0afe035c452d876d28cbffaa7e"
/-!
# Topological properties of convex sets
We prove the following facts:
* `Convex.interior` : interior of a convex set is convex;
* `Convex.closure` : closure of a convex set is convex;
* `Set.Finite.isCompact_convexHull` : convex hull of a finite set is compact;
* `Set.Finite.isClosed_convexHull` : convex hull of a finite set is closed.
-/
assert_not_exists Norm
open Metric Bornology Set Pointwise Convex
variable {ι 𝕜 E : Type*}
theorem Real.convex_iff_isPreconnected {s : Set ℝ} : Convex ℝ s ↔ IsPreconnected s :=
convex_iff_ordConnected.trans isPreconnected_iff_ordConnected.symm
#align real.convex_iff_is_preconnected Real.convex_iff_isPreconnected
alias ⟨_, IsPreconnected.convex⟩ := Real.convex_iff_isPreconnected
#align is_preconnected.convex IsPreconnected.convex
/-! ### Standard simplex -/
section stdSimplex
variable [Fintype ι]
/-- Every vector in `stdSimplex 𝕜 ι` has `max`-norm at most `1`. -/
theorem stdSimplex_subset_closedBall : stdSimplex ℝ ι ⊆ Metric.closedBall 0 1 := fun f hf ↦ by
rw [Metric.mem_closedBall, dist_pi_le_iff zero_le_one]
intro x
rw [Pi.zero_apply, Real.dist_0_eq_abs, abs_of_nonneg <| hf.1 x]
exact (mem_Icc_of_mem_stdSimplex hf x).2
#align std_simplex_subset_closed_ball stdSimplex_subset_closedBall
variable (ι)
/-- `stdSimplex ℝ ι` is bounded. -/
theorem bounded_stdSimplex : IsBounded (stdSimplex ℝ ι) :=
(Metric.isBounded_iff_subset_closedBall 0).2 ⟨1, stdSimplex_subset_closedBall⟩
#align bounded_std_simplex bounded_stdSimplex
/-- `stdSimplex ℝ ι` is closed. -/
theorem isClosed_stdSimplex : IsClosed (stdSimplex ℝ ι) :=
(stdSimplex_eq_inter ℝ ι).symm ▸
IsClosed.inter (isClosed_iInter fun i => isClosed_le continuous_const (continuous_apply i))
(isClosed_eq (continuous_finset_sum _ fun x _ => continuous_apply x) continuous_const)
#align is_closed_std_simplex isClosed_stdSimplex
/-- `stdSimplex ℝ ι` is compact. -/
theorem isCompact_stdSimplex : IsCompact (stdSimplex ℝ ι) :=
Metric.isCompact_iff_isClosed_bounded.2 ⟨isClosed_stdSimplex ι, bounded_stdSimplex ι⟩
#align is_compact_std_simplex isCompact_stdSimplex
instance stdSimplex.instCompactSpace_coe : CompactSpace ↥(stdSimplex ℝ ι) :=
isCompact_iff_compactSpace.mp <| isCompact_stdSimplex _
/-- The standard one-dimensional simplex in `ℝ² = Fin 2 → ℝ`
is homeomorphic to the unit interval. -/
@[simps! (config := .asFn)]
def stdSimplexHomeomorphUnitInterval : stdSimplex ℝ (Fin 2) ≃ₜ unitInterval where
toEquiv := stdSimplexEquivIcc ℝ
continuous_toFun := .subtype_mk ((continuous_apply 0).comp continuous_subtype_val) _
continuous_invFun := by
apply Continuous.subtype_mk
exact (continuous_pi <| Fin.forall_fin_two.2
⟨continuous_subtype_val, continuous_const.sub continuous_subtype_val⟩)
end stdSimplex
/-! ### Topological vector spaces -/
section TopologicalSpace
variable [LinearOrderedRing 𝕜] [DenselyOrdered 𝕜] [TopologicalSpace 𝕜] [OrderTopology 𝕜]
[AddCommGroup E] [TopologicalSpace E] [ContinuousAdd E] [Module 𝕜 E] [ContinuousSMul 𝕜 E]
{x y : E}
theorem segment_subset_closure_openSegment : [x -[𝕜] y] ⊆ closure (openSegment 𝕜 x y) := by
rw [segment_eq_image, openSegment_eq_image, ← closure_Ioo (zero_ne_one' 𝕜)]
exact image_closure_subset_closure_image (by fun_prop)
#align segment_subset_closure_open_segment segment_subset_closure_openSegment
end TopologicalSpace
section PseudoMetricSpace
variable [LinearOrderedRing 𝕜] [DenselyOrdered 𝕜] [PseudoMetricSpace 𝕜] [OrderTopology 𝕜]
[ProperSpace 𝕜] [CompactIccSpace 𝕜] [AddCommGroup E] [TopologicalSpace E] [T2Space E]
[ContinuousAdd E] [Module 𝕜 E] [ContinuousSMul 𝕜 E]
@[simp]
theorem closure_openSegment (x y : E) : closure (openSegment 𝕜 x y) = [x -[𝕜] y] := by
rw [segment_eq_image, openSegment_eq_image, ← closure_Ioo (zero_ne_one' 𝕜)]
exact (image_closure_of_isCompact (isBounded_Ioo _ _).isCompact_closure <|
Continuous.continuousOn <| by fun_prop).symm
#align closure_open_segment closure_openSegment
end PseudoMetricSpace
section ContinuousConstSMul
variable [LinearOrderedField 𝕜] [AddCommGroup E] [Module 𝕜 E] [TopologicalSpace E]
[TopologicalAddGroup E] [ContinuousConstSMul 𝕜 E]
/-- If `s` is a convex set, then `a • interior s + b • closure s ⊆ interior s` for all `0 < a`,
`0 ≤ b`, `a + b = 1`. See also `Convex.combo_interior_self_subset_interior` for a weaker version. -/
theorem Convex.combo_interior_closure_subset_interior {s : Set E} (hs : Convex 𝕜 s) {a b : 𝕜}
(ha : 0 < a) (hb : 0 ≤ b) (hab : a + b = 1) : a • interior s + b • closure s ⊆ interior s :=
interior_smul₀ ha.ne' s ▸
calc
interior (a • s) + b • closure s ⊆ interior (a • s) + closure (b • s) :=
add_subset_add Subset.rfl (smul_closure_subset b s)
_ = interior (a • s) + b • s := by rw [isOpen_interior.add_closure (b • s)]
_ ⊆ interior (a • s + b • s) := subset_interior_add_left
_ ⊆ interior s := interior_mono <| hs.set_combo_subset ha.le hb hab
#align convex.combo_interior_closure_subset_interior Convex.combo_interior_closure_subset_interior
/-- If `s` is a convex set, then `a • interior s + b • s ⊆ interior s` for all `0 < a`, `0 ≤ b`,
`a + b = 1`. See also `Convex.combo_interior_closure_subset_interior` for a stronger version. -/
theorem Convex.combo_interior_self_subset_interior {s : Set E} (hs : Convex 𝕜 s) {a b : 𝕜}
(ha : 0 < a) (hb : 0 ≤ b) (hab : a + b = 1) : a • interior s + b • s ⊆ interior s :=
calc
a • interior s + b • s ⊆ a • interior s + b • closure s :=
add_subset_add Subset.rfl <| image_subset _ subset_closure
_ ⊆ interior s := hs.combo_interior_closure_subset_interior ha hb hab
#align convex.combo_interior_self_subset_interior Convex.combo_interior_self_subset_interior
/-- If `s` is a convex set, then `a • closure s + b • interior s ⊆ interior s` for all `0 ≤ a`,
`0 < b`, `a + b = 1`. See also `Convex.combo_self_interior_subset_interior` for a weaker version. -/
theorem Convex.combo_closure_interior_subset_interior {s : Set E} (hs : Convex 𝕜 s) {a b : 𝕜}
(ha : 0 ≤ a) (hb : 0 < b) (hab : a + b = 1) : a • closure s + b • interior s ⊆ interior s := by
rw [add_comm]
exact hs.combo_interior_closure_subset_interior hb ha (add_comm a b ▸ hab)
#align convex.combo_closure_interior_subset_interior Convex.combo_closure_interior_subset_interior
/-- If `s` is a convex set, then `a • s + b • interior s ⊆ interior s` for all `0 ≤ a`, `0 < b`,
`a + b = 1`. See also `Convex.combo_closure_interior_subset_interior` for a stronger version. -/
theorem Convex.combo_self_interior_subset_interior {s : Set E} (hs : Convex 𝕜 s) {a b : 𝕜}
(ha : 0 ≤ a) (hb : 0 < b) (hab : a + b = 1) : a • s + b • interior s ⊆ interior s := by
rw [add_comm]
exact hs.combo_interior_self_subset_interior hb ha (add_comm a b ▸ hab)
#align convex.combo_self_interior_subset_interior Convex.combo_self_interior_subset_interior
theorem Convex.combo_interior_closure_mem_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E}
(hx : x ∈ interior s) (hy : y ∈ closure s) {a b : 𝕜} (ha : 0 < a) (hb : 0 ≤ b)
(hab : a + b = 1) : a • x + b • y ∈ interior s :=
hs.combo_interior_closure_subset_interior ha hb hab <|
add_mem_add (smul_mem_smul_set hx) (smul_mem_smul_set hy)
#align convex.combo_interior_closure_mem_interior Convex.combo_interior_closure_mem_interior
theorem Convex.combo_interior_self_mem_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E}
(hx : x ∈ interior s) (hy : y ∈ s) {a b : 𝕜} (ha : 0 < a) (hb : 0 ≤ b) (hab : a + b = 1) :
a • x + b • y ∈ interior s :=
hs.combo_interior_closure_mem_interior hx (subset_closure hy) ha hb hab
#align convex.combo_interior_self_mem_interior Convex.combo_interior_self_mem_interior
theorem Convex.combo_closure_interior_mem_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E}
(hx : x ∈ closure s) (hy : y ∈ interior s) {a b : 𝕜} (ha : 0 ≤ a) (hb : 0 < b)
(hab : a + b = 1) : a • x + b • y ∈ interior s :=
hs.combo_closure_interior_subset_interior ha hb hab <|
add_mem_add (smul_mem_smul_set hx) (smul_mem_smul_set hy)
#align convex.combo_closure_interior_mem_interior Convex.combo_closure_interior_mem_interior
theorem Convex.combo_self_interior_mem_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E} (hx : x ∈ s)
(hy : y ∈ interior s) {a b : 𝕜} (ha : 0 ≤ a) (hb : 0 < b) (hab : a + b = 1) :
a • x + b • y ∈ interior s :=
hs.combo_closure_interior_mem_interior (subset_closure hx) hy ha hb hab
#align convex.combo_self_interior_mem_interior Convex.combo_self_interior_mem_interior
theorem Convex.openSegment_interior_closure_subset_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E}
(hx : x ∈ interior s) (hy : y ∈ closure s) : openSegment 𝕜 x y ⊆ interior s := by
rintro _ ⟨a, b, ha, hb, hab, rfl⟩
exact hs.combo_interior_closure_mem_interior hx hy ha hb.le hab
#align convex.open_segment_interior_closure_subset_interior Convex.openSegment_interior_closure_subset_interior
theorem Convex.openSegment_interior_self_subset_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E}
(hx : x ∈ interior s) (hy : y ∈ s) : openSegment 𝕜 x y ⊆ interior s :=
hs.openSegment_interior_closure_subset_interior hx (subset_closure hy)
#align convex.open_segment_interior_self_subset_interior Convex.openSegment_interior_self_subset_interior
theorem Convex.openSegment_closure_interior_subset_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E}
(hx : x ∈ closure s) (hy : y ∈ interior s) : openSegment 𝕜 x y ⊆ interior s := by
rintro _ ⟨a, b, ha, hb, hab, rfl⟩
exact hs.combo_closure_interior_mem_interior hx hy ha.le hb hab
#align convex.open_segment_closure_interior_subset_interior Convex.openSegment_closure_interior_subset_interior
theorem Convex.openSegment_self_interior_subset_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E}
(hx : x ∈ s) (hy : y ∈ interior s) : openSegment 𝕜 x y ⊆ interior s :=
hs.openSegment_closure_interior_subset_interior (subset_closure hx) hy
#align convex.open_segment_self_interior_subset_interior Convex.openSegment_self_interior_subset_interior
/-- If `x ∈ closure s` and `y ∈ interior s`, then the segment `(x, y]` is included in `interior s`.
-/
theorem Convex.add_smul_sub_mem_interior' {s : Set E} (hs : Convex 𝕜 s) {x y : E}
(hx : x ∈ closure s) (hy : y ∈ interior s) {t : 𝕜} (ht : t ∈ Ioc (0 : 𝕜) 1) :
x + t • (y - x) ∈ interior s := by
simpa only [sub_smul, smul_sub, one_smul, add_sub, add_comm] using
hs.combo_interior_closure_mem_interior hy hx ht.1 (sub_nonneg.mpr ht.2)
(add_sub_cancel _ _)
#align convex.add_smul_sub_mem_interior' Convex.add_smul_sub_mem_interior'
/-- If `x ∈ s` and `y ∈ interior s`, then the segment `(x, y]` is included in `interior s`. -/
theorem Convex.add_smul_sub_mem_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E} (hx : x ∈ s)
(hy : y ∈ interior s) {t : 𝕜} (ht : t ∈ Ioc (0 : 𝕜) 1) : x + t • (y - x) ∈ interior s :=
hs.add_smul_sub_mem_interior' (subset_closure hx) hy ht
#align convex.add_smul_sub_mem_interior Convex.add_smul_sub_mem_interior
/-- If `x ∈ closure s` and `x + y ∈ interior s`, then `x + t y ∈ interior s` for `t ∈ (0, 1]`. -/
theorem Convex.add_smul_mem_interior' {s : Set E} (hs : Convex 𝕜 s) {x y : E} (hx : x ∈ closure s)
(hy : x + y ∈ interior s) {t : 𝕜} (ht : t ∈ Ioc (0 : 𝕜) 1) : x + t • y ∈ interior s := by
simpa only [add_sub_cancel_left] using hs.add_smul_sub_mem_interior' hx hy ht
#align convex.add_smul_mem_interior' Convex.add_smul_mem_interior'
/-- If `x ∈ s` and `x + y ∈ interior s`, then `x + t y ∈ interior s` for `t ∈ (0, 1]`. -/
theorem Convex.add_smul_mem_interior {s : Set E} (hs : Convex 𝕜 s) {x y : E} (hx : x ∈ s)
(hy : x + y ∈ interior s) {t : 𝕜} (ht : t ∈ Ioc (0 : 𝕜) 1) : x + t • y ∈ interior s :=
hs.add_smul_mem_interior' (subset_closure hx) hy ht
#align convex.add_smul_mem_interior Convex.add_smul_mem_interior
/-- In a topological vector space, the interior of a convex set is convex. -/
protected theorem Convex.interior {s : Set E} (hs : Convex 𝕜 s) : Convex 𝕜 (interior s) :=
convex_iff_openSegment_subset.mpr fun _ hx _ hy =>
hs.openSegment_closure_interior_subset_interior (interior_subset_closure hx) hy
#align convex.interior Convex.interior
/-- In a topological vector space, the closure of a convex set is convex. -/
protected theorem Convex.closure {s : Set E} (hs : Convex 𝕜 s) : Convex 𝕜 (closure s) :=
fun x hx y hy a b ha hb hab =>
let f : E → E → E := fun x' y' => a • x' + b • y'
have hf : Continuous (Function.uncurry f) :=
(continuous_fst.const_smul _).add (continuous_snd.const_smul _)
show f x y ∈ closure s from map_mem_closure₂ hf hx hy fun _ hx' _ hy' => hs hx' hy' ha hb hab
#align convex.closure Convex.closure
open AffineMap
/-- A convex set `s` is strictly convex provided that for any two distinct points of
`s \ interior s`, the line passing through these points has nonempty intersection with
`interior s`. -/
protected theorem Convex.strictConvex' {s : Set E} (hs : Convex 𝕜 s)
(h : (s \ interior s).Pairwise fun x y => ∃ c : 𝕜, lineMap x y c ∈ interior s) :
StrictConvex 𝕜 s := by
refine strictConvex_iff_openSegment_subset.2 ?_
intro x hx y hy hne
by_cases hx' : x ∈ interior s
· exact hs.openSegment_interior_self_subset_interior hx' hy
by_cases hy' : y ∈ interior s
· exact hs.openSegment_self_interior_subset_interior hx hy'
rcases h ⟨hx, hx'⟩ ⟨hy, hy'⟩ hne with ⟨c, hc⟩
refine (openSegment_subset_union x y ⟨c, rfl⟩).trans
(insert_subset_iff.2 ⟨hc, union_subset ?_ ?_⟩)
exacts [hs.openSegment_self_interior_subset_interior hx hc,
hs.openSegment_interior_self_subset_interior hc hy]
#align convex.strict_convex' Convex.strictConvex'
/-- A convex set `s` is strictly convex provided that for any two distinct points `x`, `y` of
`s \ interior s`, the segment with endpoints `x`, `y` has nonempty intersection with
`interior s`. -/
protected theorem Convex.strictConvex {s : Set E} (hs : Convex 𝕜 s)
(h : (s \ interior s).Pairwise fun x y => ([x -[𝕜] y] \ frontier s).Nonempty) :
StrictConvex 𝕜 s := by
refine hs.strictConvex' <| h.imp_on fun x hx y hy _ => ?_
simp only [segment_eq_image_lineMap, ← self_diff_frontier]
rintro ⟨_, ⟨⟨c, hc, rfl⟩, hcs⟩⟩
refine ⟨c, hs.segment_subset hx.1 hy.1 ?_, hcs⟩
exact (segment_eq_image_lineMap 𝕜 x y).symm ▸ mem_image_of_mem _ hc
#align convex.strict_convex Convex.strictConvex
end ContinuousConstSMul
section ContinuousSMul
variable [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] [TopologicalAddGroup E]
[ContinuousSMul ℝ E]
/-- Convex hull of a finite set is compact. -/
theorem Set.Finite.isCompact_convexHull {s : Set E} (hs : s.Finite) :
IsCompact (convexHull ℝ s) := by
rw [hs.convexHull_eq_image]
apply (@isCompact_stdSimplex _ hs.fintype).image
haveI := hs.fintype
apply LinearMap.continuous_on_pi
#align set.finite.compact_convex_hull Set.Finite.isCompact_convexHull
/-- Convex hull of a finite set is closed. -/
theorem Set.Finite.isClosed_convexHull [T2Space E] {s : Set E} (hs : s.Finite) :
IsClosed (convexHull ℝ s) :=
hs.isCompact_convexHull.isClosed
#align set.finite.is_closed_convex_hull Set.Finite.isClosed_convexHull
open AffineMap
/-- If we dilate the interior of a convex set about a point in its interior by a scale `t > 1`,
the result includes the closure of the original set.
TODO Generalise this from convex sets to sets that are balanced / star-shaped about `x`. -/
theorem Convex.closure_subset_image_homothety_interior_of_one_lt {s : Set E} (hs : Convex ℝ s)
{x : E} (hx : x ∈ interior s) (t : ℝ) (ht : 1 < t) :
closure s ⊆ homothety x t '' interior s := by
intro y hy
have hne : t ≠ 0 := (one_pos.trans ht).ne'
refine
⟨homothety x t⁻¹ y, hs.openSegment_interior_closure_subset_interior hx hy ?_,
(AffineEquiv.homothetyUnitsMulHom x (Units.mk0 t hne)).apply_symm_apply y⟩
rw [openSegment_eq_image_lineMap, ← inv_one, ← inv_Ioi (zero_lt_one' ℝ), ← image_inv, image_image,
homothety_eq_lineMap]
exact mem_image_of_mem _ ht
#align convex.closure_subset_image_homothety_interior_of_one_lt Convex.closure_subset_image_homothety_interior_of_one_lt
/-- If we dilate a convex set about a point in its interior by a scale `t > 1`, the interior of
the result includes the closure of the original set.
TODO Generalise this from convex sets to sets that are balanced / star-shaped about `x`. -/
theorem Convex.closure_subset_interior_image_homothety_of_one_lt {s : Set E} (hs : Convex ℝ s)
{x : E} (hx : x ∈ interior s) (t : ℝ) (ht : 1 < t) :
closure s ⊆ interior (homothety x t '' s) :=
(hs.closure_subset_image_homothety_interior_of_one_lt hx t ht).trans <|
(homothety_isOpenMap x t (one_pos.trans ht).ne').image_interior_subset _
#align convex.closure_subset_interior_image_homothety_of_one_lt Convex.closure_subset_interior_image_homothety_of_one_lt
/-- If we dilate a convex set about a point in its interior by a scale `t > 1`, the interior of
the result includes the closure of the original set.
TODO Generalise this from convex sets to sets that are balanced / star-shaped about `x`. -/
theorem Convex.subset_interior_image_homothety_of_one_lt {s : Set E} (hs : Convex ℝ s) {x : E}
(hx : x ∈ interior s) (t : ℝ) (ht : 1 < t) : s ⊆ interior (homothety x t '' s) :=
subset_closure.trans <| hs.closure_subset_interior_image_homothety_of_one_lt hx t ht
#align convex.subset_interior_image_homothety_of_one_lt Convex.subset_interior_image_homothety_of_one_lt
theorem JoinedIn.of_segment_subset {E : Type*} [AddCommGroup E] [Module ℝ E]
[TopologicalSpace E] [ContinuousAdd E] [ContinuousSMul ℝ E]
{x y : E} {s : Set E} (h : [x -[ℝ] y] ⊆ s) : JoinedIn s x y := by
have A : Continuous (fun t ↦ (1 - t) • x + t • y : ℝ → E) := by fun_prop
apply JoinedIn.ofLine A.continuousOn (by simp) (by simp)
convert h
rw [segment_eq_image ℝ x y]
/-- A nonempty convex set is path connected. -/
protected theorem Convex.isPathConnected {s : Set E} (hconv : Convex ℝ s) (hne : s.Nonempty) :
IsPathConnected s := by
refine isPathConnected_iff.mpr ⟨hne, ?_⟩
intro x x_in y y_in
exact JoinedIn.of_segment_subset ((segment_subset_iff ℝ).2 (hconv x_in y_in))
#align convex.is_path_connected Convex.isPathConnected
/-- A nonempty convex set is connected. -/
protected theorem Convex.isConnected {s : Set E} (h : Convex ℝ s) (hne : s.Nonempty) :
IsConnected s :=
(h.isPathConnected hne).isConnected
#align convex.is_connected Convex.isConnected
/-- A convex set is preconnected. -/
protected theorem Convex.isPreconnected {s : Set E} (h : Convex ℝ s) : IsPreconnected s :=
s.eq_empty_or_nonempty.elim (fun h => h.symm ▸ isPreconnected_empty) fun hne =>
(h.isConnected hne).isPreconnected
#align convex.is_preconnected Convex.isPreconnected
/-- Every topological vector space over ℝ is path connected.
Not an instance, because it creates enormous TC subproblems (turn on `pp.all`).
-/
protected theorem TopologicalAddGroup.pathConnectedSpace : PathConnectedSpace E :=
pathConnectedSpace_iff_univ.mpr <| convex_univ.isPathConnected ⟨(0 : E), trivial⟩
#align topological_add_group.path_connected TopologicalAddGroup.pathConnectedSpace
end ContinuousSMul
section ComplementsConnected
variable {E : Type*} [AddCommGroup E] [Module ℝ E] [TopologicalSpace E] [TopologicalAddGroup E]
local notation "π" => Submodule.linearProjOfIsCompl _ _
attribute [local instance 100] TopologicalAddGroup.pathConnectedSpace
/-- Given two complementary subspaces `p` and `q` in `E`, if the complement of `{0}`
is path connected in `p` then the complement of `q` is path connected in `E`. -/
theorem isPathConnected_compl_of_isPathConnected_compl_zero [ContinuousSMul ℝ E]
{p q : Submodule ℝ E} (hpq : IsCompl p q) (hpc : IsPathConnected ({0}ᶜ : Set p)) :
IsPathConnected (qᶜ : Set E) := by
rw [isPathConnected_iff] at hpc ⊢
constructor
· rcases hpc.1 with ⟨a, ha⟩
exact ⟨a, mt (Submodule.eq_zero_of_coe_mem_of_disjoint hpq.disjoint) ha⟩
· intro x hx y hy
have : π hpq x ≠ 0 ∧ π hpq y ≠ 0 := by
constructor <;> intro h <;> rw [Submodule.linearProjOfIsCompl_apply_eq_zero_iff hpq] at h <;>
[exact hx h; exact hy h]
rcases hpc.2 (π hpq x) this.1 (π hpq y) this.2 with ⟨γ₁, hγ₁⟩
let γ₂ := PathConnectedSpace.somePath (π hpq.symm x) (π hpq.symm y)
let γ₁' : Path (_ : E) _ := γ₁.map continuous_subtype_val
let γ₂' : Path (_ : E) _ := γ₂.map continuous_subtype_val
refine ⟨(γ₁'.add γ₂').cast (Submodule.linear_proj_add_linearProjOfIsCompl_eq_self hpq x).symm
(Submodule.linear_proj_add_linearProjOfIsCompl_eq_self hpq y).symm, fun t ↦ ?_⟩
rw [Path.cast_coe, Path.add_apply]
change γ₁ t + (γ₂ t : E) ∉ q
rw [← Submodule.linearProjOfIsCompl_apply_eq_zero_iff hpq, LinearMap.map_add,
Submodule.linearProjOfIsCompl_apply_right, add_zero,
Submodule.linearProjOfIsCompl_apply_eq_zero_iff]
exact mt (Submodule.eq_zero_of_coe_mem_of_disjoint hpq.disjoint) (hγ₁ t)
end ComplementsConnected