-
Notifications
You must be signed in to change notification settings - Fork 259
/
Sups.lean
439 lines (327 loc) · 14.9 KB
/
Sups.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
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
/-
Copyright (c) 2022 Yaël Dillies. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Yaël Dillies
-/
import Mathlib.Data.Set.NAry
import Mathlib.Order.UpperLower.Basic
import Mathlib.Order.SupClosed
#align_import data.set.sups from "leanprover-community/mathlib"@"20715f4ac6819ef2453d9e5106ecd086a5dc2a5e"
/-!
# Set family operations
This file defines a few binary operations on `Set α` for use in set family combinatorics.
## Main declarations
* `s ⊻ t`: Set of elements of the form `a ⊔ b` where `a ∈ s`, `b ∈ t`.
* `s ⊼ t`: Set of elements of the form `a ⊓ b` where `a ∈ s`, `b ∈ t`.
## Notation
We define the following notation in locale `SetFamily`:
* `s ⊻ t`
* `s ⊼ t`
## References
[B. Bollobás, *Combinatorics*][bollobas1986]
-/
open Function
variable {F α β : Type*}
/-- Notation typeclass for pointwise supremum `⊻`. -/
class HasSups (α : Type*) where
/-- The point-wise supremum `a ⊔ b` of `a, b : α`. -/
sups : α → α → α
#align has_sups HasSups
/-- Notation typeclass for pointwise infimum `⊼`. -/
class HasInfs (α : Type*) where
/-- The point-wise infimum `a ⊓ b` of `a, b : α`. -/
infs : α → α → α
#align has_infs HasInfs
-- This notation is meant to have higher precedence than `⊔` and `⊓`, but still within the
-- realm of other binary notation.
@[inherit_doc]
infixl:74 " ⊻ " => HasSups.sups
@[inherit_doc]
infixl:75 " ⊼ " => HasInfs.infs
namespace Set
section Sups
variable [SemilatticeSup α] [SemilatticeSup β] [FunLike F α β] [SupHomClass F α β]
variable (s s₁ s₂ t t₁ t₂ u v : Set α)
/-- `s ⊻ t` is the set of elements of the form `a ⊔ b` where `a ∈ s`, `b ∈ t`. -/
protected def hasSups : HasSups (Set α) :=
⟨image2 (· ⊔ ·)⟩
#align set.has_sups Set.hasSups
scoped[SetFamily] attribute [instance] Set.hasSups
-- Porting note: opening SetFamily, because otherwise the Set.hasSups does not seem to be an
-- instance
open SetFamily
variable {s s₁ s₂ t t₁ t₂ u} {a b c : α}
@[simp]
theorem mem_sups : c ∈ s ⊻ t ↔ ∃ a ∈ s, ∃ b ∈ t, a ⊔ b = c := by simp [(· ⊻ ·)]
#align set.mem_sups Set.mem_sups
theorem sup_mem_sups : a ∈ s → b ∈ t → a ⊔ b ∈ s ⊻ t :=
mem_image2_of_mem
#align set.sup_mem_sups Set.sup_mem_sups
theorem sups_subset : s₁ ⊆ s₂ → t₁ ⊆ t₂ → s₁ ⊻ t₁ ⊆ s₂ ⊻ t₂ :=
image2_subset
#align set.sups_subset Set.sups_subset
theorem sups_subset_left : t₁ ⊆ t₂ → s ⊻ t₁ ⊆ s ⊻ t₂ :=
image2_subset_left
#align set.sups_subset_left Set.sups_subset_left
theorem sups_subset_right : s₁ ⊆ s₂ → s₁ ⊻ t ⊆ s₂ ⊻ t :=
image2_subset_right
#align set.sups_subset_right Set.sups_subset_right
theorem image_subset_sups_left : b ∈ t → (fun a => a ⊔ b) '' s ⊆ s ⊻ t :=
image_subset_image2_left
#align set.image_subset_sups_left Set.image_subset_sups_left
theorem image_subset_sups_right : a ∈ s → (· ⊔ ·) a '' t ⊆ s ⊻ t :=
image_subset_image2_right
#align set.image_subset_sups_right Set.image_subset_sups_right
theorem forall_sups_iff {p : α → Prop} : (∀ c ∈ s ⊻ t, p c) ↔ ∀ a ∈ s, ∀ b ∈ t, p (a ⊔ b) :=
forall_image2_iff
#align set.forall_sups_iff Set.forall_sups_iff
@[simp]
theorem sups_subset_iff : s ⊻ t ⊆ u ↔ ∀ a ∈ s, ∀ b ∈ t, a ⊔ b ∈ u :=
image2_subset_iff
#align set.sups_subset_iff Set.sups_subset_iff
@[simp]
theorem sups_nonempty : (s ⊻ t).Nonempty ↔ s.Nonempty ∧ t.Nonempty :=
image2_nonempty_iff
#align set.sups_nonempty Set.sups_nonempty
protected theorem Nonempty.sups : s.Nonempty → t.Nonempty → (s ⊻ t).Nonempty :=
Nonempty.image2
#align set.nonempty.sups Set.Nonempty.sups
theorem Nonempty.of_sups_left : (s ⊻ t).Nonempty → s.Nonempty :=
Nonempty.of_image2_left
#align set.nonempty.of_sups_left Set.Nonempty.of_sups_left
theorem Nonempty.of_sups_right : (s ⊻ t).Nonempty → t.Nonempty :=
Nonempty.of_image2_right
#align set.nonempty.of_sups_right Set.Nonempty.of_sups_right
@[simp]
theorem empty_sups : ∅ ⊻ t = ∅ :=
image2_empty_left
#align set.empty_sups Set.empty_sups
@[simp]
theorem sups_empty : s ⊻ ∅ = ∅ :=
image2_empty_right
#align set.sups_empty Set.sups_empty
@[simp]
theorem sups_eq_empty : s ⊻ t = ∅ ↔ s = ∅ ∨ t = ∅ :=
image2_eq_empty_iff
#align set.sups_eq_empty Set.sups_eq_empty
@[simp]
theorem singleton_sups : {a} ⊻ t = t.image fun b => a ⊔ b :=
image2_singleton_left
#align set.singleton_sups Set.singleton_sups
@[simp]
theorem sups_singleton : s ⊻ {b} = s.image fun a => a ⊔ b :=
image2_singleton_right
#align set.sups_singleton Set.sups_singleton
theorem singleton_sups_singleton : ({a} ⊻ {b} : Set α) = {a ⊔ b} :=
image2_singleton
#align set.singleton_sups_singleton Set.singleton_sups_singleton
theorem sups_union_left : (s₁ ∪ s₂) ⊻ t = s₁ ⊻ t ∪ s₂ ⊻ t :=
image2_union_left
#align set.sups_union_left Set.sups_union_left
theorem sups_union_right : s ⊻ (t₁ ∪ t₂) = s ⊻ t₁ ∪ s ⊻ t₂ :=
image2_union_right
#align set.sups_union_right Set.sups_union_right
theorem sups_inter_subset_left : (s₁ ∩ s₂) ⊻ t ⊆ s₁ ⊻ t ∩ s₂ ⊻ t :=
image2_inter_subset_left
#align set.sups_inter_subset_left Set.sups_inter_subset_left
theorem sups_inter_subset_right : s ⊻ (t₁ ∩ t₂) ⊆ s ⊻ t₁ ∩ s ⊻ t₂ :=
image2_inter_subset_right
#align set.sups_inter_subset_right Set.sups_inter_subset_right
lemma image_sups (f : F) (s t : Set α) : f '' (s ⊻ t) = f '' s ⊻ f '' t :=
image_image2_distrib <| map_sup f
lemma subset_sups_self : s ⊆ s ⊻ s := fun _a ha ↦ mem_sups.2 ⟨_, ha, _, ha, sup_idem _⟩
lemma sups_subset_self : s ⊻ s ⊆ s ↔ SupClosed s := sups_subset_iff
@[simp] lemma sups_eq_self : s ⊻ s = s ↔ SupClosed s :=
subset_sups_self.le.le_iff_eq.symm.trans sups_subset_self
lemma sep_sups_le (s t : Set α) (a : α) :
{b ∈ s ⊻ t | b ≤ a} = {b ∈ s | b ≤ a} ⊻ {b ∈ t | b ≤ a} := by ext; aesop
variable (s t u)
theorem iUnion_image_sup_left : ⋃ a ∈ s, (· ⊔ ·) a '' t = s ⊻ t :=
iUnion_image_left _
#align set.Union_image_sup_left Set.iUnion_image_sup_left
theorem iUnion_image_sup_right : ⋃ b ∈ t, (· ⊔ b) '' s = s ⊻ t :=
iUnion_image_right _
#align set.Union_image_sup_right Set.iUnion_image_sup_right
@[simp]
theorem image_sup_prod (s t : Set α) : Set.image2 (· ⊔ ·) s t = s ⊻ t := rfl
#align set.image_sup_prod Set.image_sup_prod
theorem sups_assoc : s ⊻ t ⊻ u = s ⊻ (t ⊻ u) := image2_assoc sup_assoc
#align set.sups_assoc Set.sups_assoc
theorem sups_comm : s ⊻ t = t ⊻ s := image2_comm sup_comm
#align set.sups_comm Set.sups_comm
theorem sups_left_comm : s ⊻ (t ⊻ u) = t ⊻ (s ⊻ u) :=
image2_left_comm sup_left_comm
#align set.sups_left_comm Set.sups_left_comm
theorem sups_right_comm : s ⊻ t ⊻ u = s ⊻ u ⊻ t :=
image2_right_comm sup_right_comm
#align set.sups_right_comm Set.sups_right_comm
theorem sups_sups_sups_comm : s ⊻ t ⊻ (u ⊻ v) = s ⊻ u ⊻ (t ⊻ v) :=
image2_image2_image2_comm sup_sup_sup_comm
#align set.sups_sups_sups_comm Set.sups_sups_sups_comm
end Sups
section Infs
variable [SemilatticeInf α] [SemilatticeInf β] [FunLike F α β] [InfHomClass F α β]
variable (s s₁ s₂ t t₁ t₂ u v : Set α)
/-- `s ⊼ t` is the set of elements of the form `a ⊓ b` where `a ∈ s`, `b ∈ t`. -/
protected def hasInfs : HasInfs (Set α) :=
⟨image2 (· ⊓ ·)⟩
#align set.has_infs Set.hasInfs
scoped[SetFamily] attribute [instance] Set.hasInfs
-- Porting note: opening SetFamily, because otherwise the Set.hasSups does not seem to be an
-- instance
open SetFamily
variable {s s₁ s₂ t t₁ t₂ u} {a b c : α}
@[simp]
theorem mem_infs : c ∈ s ⊼ t ↔ ∃ a ∈ s, ∃ b ∈ t, a ⊓ b = c := by simp [(· ⊼ ·)]
#align set.mem_infs Set.mem_infs
theorem inf_mem_infs : a ∈ s → b ∈ t → a ⊓ b ∈ s ⊼ t :=
mem_image2_of_mem
#align set.inf_mem_infs Set.inf_mem_infs
theorem infs_subset : s₁ ⊆ s₂ → t₁ ⊆ t₂ → s₁ ⊼ t₁ ⊆ s₂ ⊼ t₂ :=
image2_subset
#align set.infs_subset Set.infs_subset
theorem infs_subset_left : t₁ ⊆ t₂ → s ⊼ t₁ ⊆ s ⊼ t₂ :=
image2_subset_left
#align set.infs_subset_left Set.infs_subset_left
theorem infs_subset_right : s₁ ⊆ s₂ → s₁ ⊼ t ⊆ s₂ ⊼ t :=
image2_subset_right
#align set.infs_subset_right Set.infs_subset_right
theorem image_subset_infs_left : b ∈ t → (fun a => a ⊓ b) '' s ⊆ s ⊼ t :=
image_subset_image2_left
#align set.image_subset_infs_left Set.image_subset_infs_left
theorem image_subset_infs_right : a ∈ s → (a ⊓ ·) '' t ⊆ s ⊼ t :=
image_subset_image2_right
#align set.image_subset_infs_right Set.image_subset_infs_right
theorem forall_infs_iff {p : α → Prop} : (∀ c ∈ s ⊼ t, p c) ↔ ∀ a ∈ s, ∀ b ∈ t, p (a ⊓ b) :=
forall_image2_iff
#align set.forall_infs_iff Set.forall_infs_iff
@[simp]
theorem infs_subset_iff : s ⊼ t ⊆ u ↔ ∀ a ∈ s, ∀ b ∈ t, a ⊓ b ∈ u :=
image2_subset_iff
#align set.infs_subset_iff Set.infs_subset_iff
@[simp]
theorem infs_nonempty : (s ⊼ t).Nonempty ↔ s.Nonempty ∧ t.Nonempty :=
image2_nonempty_iff
#align set.infs_nonempty Set.infs_nonempty
protected theorem Nonempty.infs : s.Nonempty → t.Nonempty → (s ⊼ t).Nonempty :=
Nonempty.image2
#align set.nonempty.infs Set.Nonempty.infs
theorem Nonempty.of_infs_left : (s ⊼ t).Nonempty → s.Nonempty :=
Nonempty.of_image2_left
#align set.nonempty.of_infs_left Set.Nonempty.of_infs_left
theorem Nonempty.of_infs_right : (s ⊼ t).Nonempty → t.Nonempty :=
Nonempty.of_image2_right
#align set.nonempty.of_infs_right Set.Nonempty.of_infs_right
@[simp]
theorem empty_infs : ∅ ⊼ t = ∅ :=
image2_empty_left
#align set.empty_infs Set.empty_infs
@[simp]
theorem infs_empty : s ⊼ ∅ = ∅ :=
image2_empty_right
#align set.infs_empty Set.infs_empty
@[simp]
theorem infs_eq_empty : s ⊼ t = ∅ ↔ s = ∅ ∨ t = ∅ :=
image2_eq_empty_iff
#align set.infs_eq_empty Set.infs_eq_empty
@[simp]
theorem singleton_infs : {a} ⊼ t = t.image fun b => a ⊓ b :=
image2_singleton_left
#align set.singleton_infs Set.singleton_infs
@[simp]
theorem infs_singleton : s ⊼ {b} = s.image fun a => a ⊓ b :=
image2_singleton_right
#align set.infs_singleton Set.infs_singleton
theorem singleton_infs_singleton : ({a} ⊼ {b} : Set α) = {a ⊓ b} :=
image2_singleton
#align set.singleton_infs_singleton Set.singleton_infs_singleton
theorem infs_union_left : (s₁ ∪ s₂) ⊼ t = s₁ ⊼ t ∪ s₂ ⊼ t :=
image2_union_left
#align set.infs_union_left Set.infs_union_left
theorem infs_union_right : s ⊼ (t₁ ∪ t₂) = s ⊼ t₁ ∪ s ⊼ t₂ :=
image2_union_right
#align set.infs_union_right Set.infs_union_right
theorem infs_inter_subset_left : (s₁ ∩ s₂) ⊼ t ⊆ s₁ ⊼ t ∩ s₂ ⊼ t :=
image2_inter_subset_left
#align set.infs_inter_subset_left Set.infs_inter_subset_left
theorem infs_inter_subset_right : s ⊼ (t₁ ∩ t₂) ⊆ s ⊼ t₁ ∩ s ⊼ t₂ :=
image2_inter_subset_right
#align set.infs_inter_subset_right Set.infs_inter_subset_right
lemma image_infs (f : F) (s t : Set α) : f '' (s ⊼ t) = f '' s ⊼ f '' t :=
image_image2_distrib <| map_inf f
lemma subset_infs_self : s ⊆ s ⊼ s := fun _a ha ↦ mem_infs.2 ⟨_, ha, _, ha, inf_idem _⟩
lemma infs_self_subset : s ⊼ s ⊆ s ↔ InfClosed s := infs_subset_iff
@[simp] lemma infs_self : s ⊼ s = s ↔ InfClosed s :=
subset_infs_self.le.le_iff_eq.symm.trans infs_self_subset
lemma sep_infs_le (s t : Set α) (a : α) :
{b ∈ s ⊼ t | a ≤ b} = {b ∈ s | a ≤ b} ⊼ {b ∈ t | a ≤ b} := by ext; aesop
variable (s t u)
theorem iUnion_image_inf_left : ⋃ a ∈ s, (a ⊓ ·) '' t = s ⊼ t :=
iUnion_image_left _
#align set.Union_image_inf_left Set.iUnion_image_inf_left
theorem iUnion_image_inf_right : ⋃ b ∈ t, (· ⊓ b) '' s = s ⊼ t :=
iUnion_image_right _
#align set.Union_image_inf_right Set.iUnion_image_inf_right
@[simp]
theorem image_inf_prod (s t : Set α) : Set.image2 (fun x x_1 => x ⊓ x_1) s t = s ⊼ t := by
have : (s ×ˢ t).image (uncurry (· ⊓ ·)) = Set.image2 (fun x x_1 => x ⊓ x_1) s t := by
simp only [@ge_iff_le, @Set.image_uncurry_prod]
rw [← this]
exact image_uncurry_prod _ _ _
#align set.image_inf_prod Set.image_inf_prod
theorem infs_assoc : s ⊼ t ⊼ u = s ⊼ (t ⊼ u) := image2_assoc inf_assoc
#align set.infs_assoc Set.infs_assoc
theorem infs_comm : s ⊼ t = t ⊼ s := image2_comm inf_comm
#align set.infs_comm Set.infs_comm
theorem infs_left_comm : s ⊼ (t ⊼ u) = t ⊼ (s ⊼ u) :=
image2_left_comm inf_left_comm
#align set.infs_left_comm Set.infs_left_comm
theorem infs_right_comm : s ⊼ t ⊼ u = s ⊼ u ⊼ t :=
image2_right_comm inf_right_comm
#align set.infs_right_comm Set.infs_right_comm
theorem infs_infs_infs_comm : s ⊼ t ⊼ (u ⊼ v) = s ⊼ u ⊼ (t ⊼ v) :=
image2_image2_image2_comm inf_inf_inf_comm
#align set.infs_infs_infs_comm Set.infs_infs_infs_comm
end Infs
open SetFamily
section DistribLattice
variable [DistribLattice α] (s t u : Set α)
theorem sups_infs_subset_left : s ⊻ t ⊼ u ⊆ (s ⊻ t) ⊼ (s ⊻ u) :=
image2_distrib_subset_left sup_inf_left
#align set.sups_infs_subset_left Set.sups_infs_subset_left
theorem sups_infs_subset_right : t ⊼ u ⊻ s ⊆ (t ⊻ s) ⊼ (u ⊻ s) :=
image2_distrib_subset_right sup_inf_right
#align set.sups_infs_subset_right Set.sups_infs_subset_right
theorem infs_sups_subset_left : s ⊼ (t ⊻ u) ⊆ s ⊼ t ⊻ s ⊼ u :=
image2_distrib_subset_left inf_sup_left
#align set.infs_sups_subset_left Set.infs_sups_subset_left
theorem infs_sups_subset_right : (t ⊻ u) ⊼ s ⊆ t ⊼ s ⊻ u ⊼ s :=
image2_distrib_subset_right inf_sup_right
#align set.infs_sups_subset_right Set.infs_sups_subset_right
end DistribLattice
end Set
open SetFamily
@[simp]
theorem upperClosure_sups [SemilatticeSup α] (s t : Set α) :
upperClosure (s ⊻ t) = upperClosure s ⊔ upperClosure t := by
ext a
simp only [SetLike.mem_coe, mem_upperClosure, Set.mem_sups, exists_and_left, exists_prop,
UpperSet.coe_sup, Set.mem_inter_iff]
constructor
· rintro ⟨_, ⟨b, hb, c, hc, rfl⟩, ha⟩
exact ⟨⟨b, hb, le_sup_left.trans ha⟩, c, hc, le_sup_right.trans ha⟩
· rintro ⟨⟨b, hb, hab⟩, c, hc, hac⟩
exact ⟨_, ⟨b, hb, c, hc, rfl⟩, sup_le hab hac⟩
#align upper_closure_sups upperClosure_sups
@[simp]
theorem lowerClosure_infs [SemilatticeInf α] (s t : Set α) :
lowerClosure (s ⊼ t) = lowerClosure s ⊓ lowerClosure t := by
ext a
simp only [SetLike.mem_coe, mem_lowerClosure, Set.mem_infs, exists_and_left, exists_prop,
LowerSet.coe_sup, Set.mem_inter_iff]
constructor
· rintro ⟨_, ⟨b, hb, c, hc, rfl⟩, ha⟩
exact ⟨⟨b, hb, ha.trans inf_le_left⟩, c, hc, ha.trans inf_le_right⟩
· rintro ⟨⟨b, hb, hab⟩, c, hc, hac⟩
exact ⟨_, ⟨b, hb, c, hc, rfl⟩, le_inf hab hac⟩
#align lower_closure_infs lowerClosure_infs