/
Extreme.lean
295 lines (237 loc) · 13 KB
/
Extreme.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
/-
Copyright (c) 2021 Yaël Dillies, Bhavik Mehta. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies, Bhavik Mehta
-/
import Mathlib.Analysis.Convex.Hull
#align_import analysis.convex.extreme from "leanprover-community/mathlib"@"c5773405394e073885e2a144c9ca14637e8eb963"
/-!
# Extreme sets
This file defines extreme sets and extreme points for sets in a module.
An extreme set of `A` is a subset of `A` that is as far as it can get in any outward direction: If
point `x` is in it and point `y ∈ A`, then the line passing through `x` and `y` leaves `A` at `x`.
This is an analytic notion of "being on the side of". It is weaker than being exposed (see
`IsExposed.isExtreme`).
## Main declarations
* `IsExtreme 𝕜 A B`: States that `B` is an extreme set of `A` (in the literature, `A` is often
implicit).
* `Set.extremePoints 𝕜 A`: Set of extreme points of `A` (corresponding to extreme singletons).
* `Convex.mem_extremePoints_iff_convex_diff`: A useful equivalent condition to being an extreme
point: `x` is an extreme point iff `A \ {x}` is convex.
## Implementation notes
The exact definition of extremeness has been carefully chosen so as to make as many lemmas
unconditional (in particular, the Krein-Milman theorem doesn't need the set to be convex!).
In practice, `A` is often assumed to be a convex set.
## References
See chapter 8 of [Barry Simon, *Convexity*][simon2011]
## TODO
Prove lemmas relating extreme sets and points to the intrinsic frontier.
More not-yet-PRed stuff is available on the mathlib3 branch `sperner_again`.
-/
open Function Set
open scoped Classical
open Affine
variable {𝕜 E F ι : Type*} {π : ι → Type*}
section SMul
variable (𝕜) [OrderedSemiring 𝕜] [AddCommMonoid E] [SMul 𝕜 E]
/-- A set `B` is an extreme subset of `A` if `B ⊆ A` and all points of `B` only belong to open
segments whose ends are in `B`. -/
def IsExtreme (A B : Set E) : Prop :=
B ⊆ A ∧ ∀ ⦃x₁⦄, x₁ ∈ A → ∀ ⦃x₂⦄, x₂ ∈ A → ∀ ⦃x⦄, x ∈ B → x ∈ openSegment 𝕜 x₁ x₂ → x₁ ∈ B ∧ x₂ ∈ B
#align is_extreme IsExtreme
/-- A point `x` is an extreme point of a set `A` if `x` belongs to no open segment with ends in
`A`, except for the obvious `openSegment x x`. -/
def Set.extremePoints (A : Set E) : Set E :=
{ x ∈ A | ∀ ⦃x₁⦄, x₁ ∈ A → ∀ ⦃x₂⦄, x₂ ∈ A → x ∈ openSegment 𝕜 x₁ x₂ → x₁ = x ∧ x₂ = x }
#align set.extreme_points Set.extremePoints
@[refl]
protected theorem IsExtreme.refl (A : Set E) : IsExtreme 𝕜 A A :=
⟨Subset.rfl, fun _ hx₁A _ hx₂A _ _ _ ↦ ⟨hx₁A, hx₂A⟩⟩
#align is_extreme.refl IsExtreme.refl
variable {𝕜} {A B C : Set E} {x : E}
protected theorem IsExtreme.rfl : IsExtreme 𝕜 A A :=
IsExtreme.refl 𝕜 A
#align is_extreme.rfl IsExtreme.rfl
@[trans]
protected theorem IsExtreme.trans (hAB : IsExtreme 𝕜 A B) (hBC : IsExtreme 𝕜 B C) :
IsExtreme 𝕜 A C := by
refine' ⟨Subset.trans hBC.1 hAB.1, fun x₁ hx₁A x₂ hx₂A x hxC hx ↦ _⟩
obtain ⟨hx₁B, hx₂B⟩ := hAB.2 hx₁A hx₂A (hBC.1 hxC) hx
exact hBC.2 hx₁B hx₂B hxC hx
#align is_extreme.trans IsExtreme.trans
protected theorem IsExtreme.antisymm : AntiSymmetric (IsExtreme 𝕜 : Set E → Set E → Prop) :=
fun _ _ hAB hBA ↦ Subset.antisymm hBA.1 hAB.1
#align is_extreme.antisymm IsExtreme.antisymm
instance : IsPartialOrder (Set E) (IsExtreme 𝕜) where
refl := IsExtreme.refl 𝕜
trans _ _ _ := IsExtreme.trans
antisymm := IsExtreme.antisymm
theorem IsExtreme.inter (hAB : IsExtreme 𝕜 A B) (hAC : IsExtreme 𝕜 A C) :
IsExtreme 𝕜 A (B ∩ C) := by
use Subset.trans (inter_subset_left _ _) hAB.1
rintro x₁ hx₁A x₂ hx₂A x ⟨hxB, hxC⟩ hx
obtain ⟨hx₁B, hx₂B⟩ := hAB.2 hx₁A hx₂A hxB hx
obtain ⟨hx₁C, hx₂C⟩ := hAC.2 hx₁A hx₂A hxC hx
exact ⟨⟨hx₁B, hx₁C⟩, hx₂B, hx₂C⟩
#align is_extreme.inter IsExtreme.inter
protected theorem IsExtreme.mono (hAC : IsExtreme 𝕜 A C) (hBA : B ⊆ A) (hCB : C ⊆ B) :
IsExtreme 𝕜 B C :=
⟨hCB, fun _ hx₁B _ hx₂B _ hxC hx ↦ hAC.2 (hBA hx₁B) (hBA hx₂B) hxC hx⟩
#align is_extreme.mono IsExtreme.mono
theorem isExtreme_iInter {ι : Sort*} [Nonempty ι] {F : ι → Set E}
(hAF : ∀ i : ι, IsExtreme 𝕜 A (F i)) : IsExtreme 𝕜 A (⋂ i : ι, F i) := by
obtain i := Classical.arbitrary ι
refine' ⟨iInter_subset_of_subset i (hAF i).1, fun x₁ hx₁A x₂ hx₂A x hxF hx ↦ _⟩
simp_rw [mem_iInter] at hxF ⊢
have h := fun i ↦ (hAF i).2 hx₁A hx₂A (hxF i) hx
exact ⟨fun i ↦ (h i).1, fun i ↦ (h i).2⟩
#align is_extreme_Inter isExtreme_iInter
theorem isExtreme_biInter {F : Set (Set E)} (hF : F.Nonempty) (hA : ∀ B ∈ F, IsExtreme 𝕜 A B) :
IsExtreme 𝕜 A (⋂ B ∈ F, B) := by
haveI := hF.to_subtype
simpa only [iInter_subtype] using isExtreme_iInter fun i : F ↦ hA _ i.2
#align is_extreme_bInter isExtreme_biInter
theorem isExtreme_sInter {F : Set (Set E)} (hF : F.Nonempty) (hAF : ∀ B ∈ F, IsExtreme 𝕜 A B) :
IsExtreme 𝕜 A (⋂₀ F) := by simpa [sInter_eq_biInter] using isExtreme_biInter hF hAF
#align is_extreme_sInter isExtreme_sInter
theorem mem_extremePoints : x ∈ A.extremePoints 𝕜 ↔
x ∈ A ∧ ∀ᵉ (x₁ ∈ A) (x₂ ∈ A), x ∈ openSegment 𝕜 x₁ x₂ → x₁ = x ∧ x₂ = x :=
Iff.rfl
#align mem_extreme_points mem_extremePoints
/-- x is an extreme point to A iff {x} is an extreme set of A. -/
@[simp] lemma isExtreme_singleton : IsExtreme 𝕜 A {x} ↔ x ∈ A.extremePoints 𝕜 := by
refine ⟨fun hx ↦ ⟨singleton_subset_iff.1 hx.1, fun x₁ hx₁ x₂ hx₂ ↦ hx.2 hx₁ hx₂ rfl⟩, ?_⟩
rintro ⟨hxA, hAx⟩
use singleton_subset_iff.2 hxA
rintro x₁ hx₁A x₂ hx₂A y (rfl : y = x)
exact hAx hx₁A hx₂A
#align mem_extreme_points_iff_extreme_singleton isExtreme_singleton
alias ⟨IsExtreme.mem_extremePoints, _⟩ := isExtreme_singleton
theorem extremePoints_subset : A.extremePoints 𝕜 ⊆ A :=
fun _ hx ↦ hx.1
#align extreme_points_subset extremePoints_subset
@[simp]
theorem extremePoints_empty : (∅ : Set E).extremePoints 𝕜 = ∅ :=
subset_empty_iff.1 extremePoints_subset
#align extreme_points_empty extremePoints_empty
@[simp]
theorem extremePoints_singleton : ({x} : Set E).extremePoints 𝕜 = {x} :=
extremePoints_subset.antisymm <|
singleton_subset_iff.2 ⟨mem_singleton x, fun _ hx₁ _ hx₂ _ ↦ ⟨hx₁, hx₂⟩⟩
#align extreme_points_singleton extremePoints_singleton
theorem inter_extremePoints_subset_extremePoints_of_subset (hBA : B ⊆ A) :
B ∩ A.extremePoints 𝕜 ⊆ B.extremePoints 𝕜 :=
fun _ ⟨hxB, hxA⟩ ↦ ⟨hxB, fun _ hx₁ _ hx₂ hx ↦ hxA.2 (hBA hx₁) (hBA hx₂) hx⟩
#align inter_extreme_points_subset_extreme_points_of_subset inter_extremePoints_subset_extremePoints_of_subset
theorem IsExtreme.extremePoints_subset_extremePoints (hAB : IsExtreme 𝕜 A B) :
B.extremePoints 𝕜 ⊆ A.extremePoints 𝕜 :=
fun _ ↦ by simpa only [← isExtreme_singleton] using hAB.trans
#align is_extreme.extreme_points_subset_extreme_points IsExtreme.extremePoints_subset_extremePoints
theorem IsExtreme.extremePoints_eq (hAB : IsExtreme 𝕜 A B) :
B.extremePoints 𝕜 = B ∩ A.extremePoints 𝕜 :=
Subset.antisymm (fun _ hx ↦ ⟨hx.1, hAB.extremePoints_subset_extremePoints hx⟩)
(inter_extremePoints_subset_extremePoints_of_subset hAB.1)
#align is_extreme.extreme_points_eq IsExtreme.extremePoints_eq
end SMul
section OrderedSemiring
variable [OrderedSemiring 𝕜] [AddCommGroup E] [AddCommGroup F] [∀ i, AddCommGroup (π i)]
[Module 𝕜 E] [Module 𝕜 F] [∀ i, Module 𝕜 (π i)] {A B : Set E} {x : E}
theorem IsExtreme.convex_diff (hA : Convex 𝕜 A) (hAB : IsExtreme 𝕜 A B) : Convex 𝕜 (A \ B) :=
convex_iff_openSegment_subset.2 fun _ ⟨hx₁A, hx₁B⟩ _ ⟨hx₂A, _⟩ _ hx ↦
⟨hA.openSegment_subset hx₁A hx₂A hx, fun hxB ↦ hx₁B (hAB.2 hx₁A hx₂A hxB hx).1⟩
#align is_extreme.convex_diff IsExtreme.convex_diff
@[simp]
theorem extremePoints_prod (s : Set E) (t : Set F) :
(s ×ˢ t).extremePoints 𝕜 = s.extremePoints 𝕜 ×ˢ t.extremePoints 𝕜 := by
ext
refine' (and_congr_right fun hx ↦ ⟨fun h ↦ _, fun h ↦ _⟩).trans and_and_and_comm
constructor
· rintro x₁ hx₁ x₂ hx₂ hx_fst
refine' (h (mk_mem_prod hx₁ hx.2) (mk_mem_prod hx₂ hx.2) _).imp (congr_arg Prod.fst)
(congr_arg Prod.fst)
rw [← Prod.image_mk_openSegment_left]
exact ⟨_, hx_fst, rfl⟩
· rintro x₁ hx₁ x₂ hx₂ hx_snd
refine' (h (mk_mem_prod hx.1 hx₁) (mk_mem_prod hx.1 hx₂) _).imp (congr_arg Prod.snd)
(congr_arg Prod.snd)
rw [← Prod.image_mk_openSegment_right]
exact ⟨_, hx_snd, rfl⟩
· rintro x₁ hx₁ x₂ hx₂ ⟨a, b, ha, hb, hab, hx'⟩
simp_rw [Prod.ext_iff]
exact and_and_and_comm.1
⟨h.1 hx₁.1 hx₂.1 ⟨a, b, ha, hb, hab, congr_arg Prod.fst hx'⟩,
h.2 hx₁.2 hx₂.2 ⟨a, b, ha, hb, hab, congr_arg Prod.snd hx'⟩⟩
#align extreme_points_prod extremePoints_prod
@[simp]
theorem extremePoints_pi (s : ∀ i, Set (π i)) :
(univ.pi s).extremePoints 𝕜 = univ.pi fun i ↦ (s i).extremePoints 𝕜 := by
ext x
simp only [mem_extremePoints, mem_pi, mem_univ, true_imp_iff, @forall_and ι]
refine' and_congr_right fun hx ↦ ⟨fun h i ↦ _, fun h ↦ _⟩
· rintro x₁ hx₁ x₂ hx₂ hi
refine' (h (update x i x₁) _ (update x i x₂) _ _).imp (fun h₁ ↦ by rw [← h₁, update_same])
fun h₂ ↦ by rw [← h₂, update_same]
iterate 2
rintro j
obtain rfl | hji := eq_or_ne j i
· rwa [update_same]
· rw [update_noteq hji]
exact hx _
rw [← Pi.image_update_openSegment]
exact ⟨_, hi, update_eq_self _ _⟩
· rintro x₁ hx₁ x₂ hx₂ ⟨a, b, ha, hb, hab, hx'⟩
simp_rw [funext_iff, ← forall_and]
exact fun i ↦ h _ _ (hx₁ _) _ (hx₂ _) ⟨a, b, ha, hb, hab, congr_fun hx' _⟩
#align extreme_points_pi extremePoints_pi
end OrderedSemiring
section OrderedRing
variable {L : Type*} [OrderedRing 𝕜] [AddCommGroup E] [Module 𝕜 E] [AddCommGroup F] [Module 𝕜 F]
[EquivLike L E F] [LinearEquivClass L 𝕜 E F]
lemma image_extremePoints (f : L) (s : Set E) :
f '' extremePoints 𝕜 s = extremePoints 𝕜 (f '' s) := by
ext b
obtain ⟨a, rfl⟩ := EquivLike.surjective f b
have : ∀ x y, f '' openSegment 𝕜 x y = openSegment 𝕜 (f x) (f y) :=
image_openSegment _ (LinearMapClass.linearMap f).toAffineMap
simp only [mem_extremePoints, (EquivLike.surjective f).forall,
(EquivLike.injective f).mem_set_image, (EquivLike.injective f).eq_iff, ← this]
end OrderedRing
section LinearOrderedRing
variable [LinearOrderedRing 𝕜] [AddCommGroup E] [Module 𝕜 E]
variable [DenselyOrdered 𝕜] [NoZeroSMulDivisors 𝕜 E] {A B : Set E} {x : E}
/-- A useful restatement using `segment`: `x` is an extreme point iff the only (closed) segments
that contain it are those with `x` as one of their endpoints. -/
theorem mem_extremePoints_iff_forall_segment : x ∈ A.extremePoints 𝕜 ↔
x ∈ A ∧ ∀ᵉ (x₁ ∈ A) (x₂ ∈ A), x ∈ segment 𝕜 x₁ x₂ → x₁ = x ∨ x₂ = x := by
refine' and_congr_right fun hxA ↦ forall₄_congr fun x₁ h₁ x₂ h₂ ↦ _
constructor
· rw [← insert_endpoints_openSegment]
rintro H (rfl | rfl | hx)
exacts [Or.inl rfl, Or.inr rfl, Or.inl <| (H hx).1]
· intro H hx
rcases H (openSegment_subset_segment _ _ _ hx) with (rfl | rfl)
exacts [⟨rfl, (left_mem_openSegment_iff.1 hx).symm⟩, ⟨right_mem_openSegment_iff.1 hx, rfl⟩]
#align mem_extreme_points_iff_forall_segment mem_extremePoints_iff_forall_segment
theorem Convex.mem_extremePoints_iff_convex_diff (hA : Convex 𝕜 A) :
x ∈ A.extremePoints 𝕜 ↔ x ∈ A ∧ Convex 𝕜 (A \ {x}) := by
use fun hx ↦ ⟨hx.1, (isExtreme_singleton.2 hx).convex_diff hA⟩
rintro ⟨hxA, hAx⟩
refine' mem_extremePoints_iff_forall_segment.2 ⟨hxA, fun x₁ hx₁ x₂ hx₂ hx ↦ _⟩
rw [convex_iff_segment_subset] at hAx
by_contra! h
exact (hAx ⟨hx₁, fun hx₁ ↦ h.1 (mem_singleton_iff.2 hx₁)⟩
⟨hx₂, fun hx₂ ↦ h.2 (mem_singleton_iff.2 hx₂)⟩ hx).2 rfl
#align convex.mem_extreme_points_iff_convex_diff Convex.mem_extremePoints_iff_convex_diff
theorem Convex.mem_extremePoints_iff_mem_diff_convexHull_diff (hA : Convex 𝕜 A) :
x ∈ A.extremePoints 𝕜 ↔ x ∈ A \ convexHull 𝕜 (A \ {x}) := by
rw [hA.mem_extremePoints_iff_convex_diff, hA.convex_remove_iff_not_mem_convexHull_remove,
mem_diff]
#align convex.mem_extreme_points_iff_mem_diff_convex_hull_diff Convex.mem_extremePoints_iff_mem_diff_convexHull_diff
theorem extremePoints_convexHull_subset : (convexHull 𝕜 A).extremePoints 𝕜 ⊆ A := by
rintro x hx
rw [(convex_convexHull 𝕜 _).mem_extremePoints_iff_convex_diff] at hx
by_contra h
exact (convexHull_min (subset_diff.2 ⟨subset_convexHull 𝕜 _, disjoint_singleton_right.2 h⟩) hx.2
hx.1).2 rfl
#align extreme_points_convex_hull_subset extremePoints_convexHull_subset
end LinearOrderedRing