-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Expand file tree
/
Copy pathOrder.lean
More file actions
369 lines (271 loc) · 12.9 KB
/
Copy pathOrder.lean
File metadata and controls
369 lines (271 loc) · 12.9 KB
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
/-
Copyright (c) 2021 Peter Nelson. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
Authors: Peter Nelson, Yaël Dillies
-/
module
public import Mathlib.Data.Finset.Lattice.Fold
public import Mathlib.Data.Finset.Order
public import Mathlib.Data.Set.Finite.Basic -- shake: keep (IsAtomic α), cf. lean#13417
public import Mathlib.Data.Set.Finite.Range
public import Mathlib.Order.Atoms
import Mathlib.Data.Finite.Prod
import Mathlib.Order.ConditionallyCompleteLattice.Finset
/-!
# Order structures on finite types
This file provides order instances on fintypes.
## Computable instances
On a `Fintype`, we can construct
* an `OrderBot` from `SemilatticeInf`.
* an `OrderTop` from `SemilatticeSup`.
* a `BoundedOrder` from `Lattice`.
Those are marked as `def` to avoid defeqness issues.
## Completion instances
Those instances are noncomputable because the definitions of `sSup` and `sInf` use `Set.toFinset`
and set membership is undecidable in general.
On a `Fintype`, we can promote:
* a `Lattice` to a `CompleteLattice`.
* a `DistribLattice` to a `CompleteDistribLattice`.
* a `LinearOrder` to a `CompleteLinearOrder`.
* a `BooleanAlgebra` to a `CompleteAtomicBooleanAlgebra`.
Those are marked as `def` to avoid typeclass loops.
## Concrete instances
We provide a few instances for concrete types:
* `Fin.completeLinearOrder`
* `Bool.completeLinearOrder`
* `Bool.completeBooleanAlgebra`
-/
public section
open Finset
namespace Fintype
variable {ι α : Type*} [Fintype ι] [Fintype α]
section Nonempty
variable (α) [Nonempty α]
-- See note [reducible non-instances]
/-- Constructs the `⊥` of a finite nonempty `SemilatticeInf`. -/
abbrev toOrderBot [SemilatticeInf α] : OrderBot α where
bot := univ.inf' univ_nonempty id
bot_le a := inf'_le _ <| mem_univ a
-- See note [reducible non-instances]
/-- Constructs the `⊤` of a finite nonempty `SemilatticeSup` -/
abbrev toOrderTop [SemilatticeSup α] : OrderTop α where
top := univ.sup' univ_nonempty id
le_top a := le_sup' id <| mem_univ a
-- See note [reducible non-instances]
/-- Constructs the `⊤` and `⊥` of a finite nonempty `Lattice`. -/
abbrev toBoundedOrder [Lattice α] : BoundedOrder α :=
{ toOrderBot α, toOrderTop α with }
end Nonempty
section BoundedOrder
variable (α)
open scoped Classical in
-- See note [reducible non-instances]
/-- A finite bounded lattice is complete. -/
noncomputable abbrev toCompleteLattice [Lattice α] [BoundedOrder α] : CompleteLattice α where
__ := ‹Lattice α›
__ := ‹BoundedOrder α›
sSup := fun s => s.toFinset.sup id
sInf := fun s => s.toFinset.inf id
isLUB_sSup s := Set.coe_toFinset s ▸ Finset.isLUB_sup_id
isGLB_sInf s := Set.coe_toFinset s ▸ Finset.isGLB_inf_id
-- See note [reducible non-instances]
/-- A finite bounded distributive lattice is completely distributive. -/
noncomputable abbrev toCompleteDistribLatticeMinimalAxioms [DistribLattice α] [BoundedOrder α] :
CompleteDistribLattice.MinimalAxioms α where
__ := toCompleteLattice α
iInf_sup_le_sup_sInf := fun a s => by
convert! (Finset.inf_sup_distrib_left s.toFinset id a).ge using 1
rw [Finset.inf_eq_iInf]
simp_rw [Set.mem_toFinset]
rfl
inf_sSup_le_iSup_inf := fun a s => by
convert! (Finset.sup_inf_distrib_left s.toFinset id a).le using 1
rw [Finset.sup_eq_iSup]
simp_rw [Set.mem_toFinset]
rfl
-- See note [reducible non-instances]
/-- A finite bounded distributive lattice is completely distributive. -/
noncomputable abbrev toCompleteDistribLattice [DistribLattice α] [BoundedOrder α] :
CompleteDistribLattice α := .ofMinimalAxioms (toCompleteDistribLatticeMinimalAxioms _)
-- See note [reducible non-instances]
/-- A finite bounded linear order is complete.
If the `α` is already a `BiheytingAlgebra`, then prefer to construct this instance manually using
`Fintype.toCompleteLattice` instead, to avoid creating a diamond with
`LinearOrder.toBiheytingAlgebra`. -/
noncomputable abbrev toCompleteLinearOrder
[LinearOrder α] [BoundedOrder α] : CompleteLinearOrder α :=
{ toCompleteLattice α, ‹LinearOrder α›, LinearOrder.toBiheytingAlgebra _ with }
-- See note [reducible non-instances]
/-- A finite Boolean algebra is complete. -/
noncomputable abbrev toCompleteBooleanAlgebra [BooleanAlgebra α] : CompleteBooleanAlgebra α where
__ := ‹BooleanAlgebra α›
__ := Fintype.toCompleteDistribLattice α
-- See note [reducible non-instances]
/-- A finite Boolean algebra is complete and atomic. -/
noncomputable abbrev toCompleteAtomicBooleanAlgebra [BooleanAlgebra α] :
CompleteAtomicBooleanAlgebra α :=
(toCompleteBooleanAlgebra α).toCompleteAtomicBooleanAlgebra
end BoundedOrder
section Nonempty
variable (α) [Nonempty α]
-- See note [reducible non-instances]
/-- A nonempty finite lattice is complete. If the lattice is already a `BoundedOrder`, then use
`Fintype.toCompleteLattice` instead, as this gives definitional equality for `⊥` and `⊤`. -/
noncomputable abbrev toCompleteLatticeOfNonempty [Lattice α] : CompleteLattice α :=
@toCompleteLattice _ _ _ <| toBoundedOrder α
-- See note [reducible non-instances]
/-- A nonempty finite linear order is complete. If the linear order is already a `BoundedOrder`,
then use `Fintype.toCompleteLinearOrder` instead, as this gives definitional equality for `⊥` and
`⊤`. -/
noncomputable abbrev toCompleteLinearOrderOfNonempty [LinearOrder α] : CompleteLinearOrder α :=
@toCompleteLinearOrder _ _ _ <| toBoundedOrder α
end Nonempty
end Fintype
/-! ### Concrete instances -/
noncomputable instance Fin.completeLinearOrder {n : ℕ} [NeZero n] : CompleteLinearOrder (Fin n) :=
Fintype.toCompleteLinearOrder _
noncomputable instance Bool.completeBooleanAlgebra : CompleteBooleanAlgebra Bool :=
Fintype.toCompleteBooleanAlgebra _
noncomputable instance Bool.completeLinearOrder : CompleteLinearOrder Bool where
__ := Fintype.toCompleteLattice _
__ : BiheytingAlgebra Bool := inferInstance
__ : LinearOrder Bool := inferInstance
noncomputable instance Bool.completeAtomicBooleanAlgebra : CompleteAtomicBooleanAlgebra Bool :=
Fintype.toCompleteAtomicBooleanAlgebra _
/-! ### Directed Orders -/
section DirectedOrders
variable {α : Type*} {r : α → α → Prop} [IsTrans α r] {β γ : Type*} [Nonempty γ] {f : γ → α}
[Finite β]
theorem Directed.finite_set_le (D : Directed r f) {s : Set γ} (hs : s.Finite) :
∃ z, ∀ i ∈ s, r (f i) (f z) := by
convert! D.finset_le hs.toFinset using 3; rw [Set.Finite.mem_toFinset]
lemma Directed.finite_le {ι κ : Sort*} [Nonempty ι] [Finite κ] {f : ι → α} (hf : Directed r f)
(g : κ → ι) : ∃ z, ∀ i, r (f (g i)) (f z) := by
classical
simpa using
(hf.comp_of_surjective PLift.down_surjective).finite_set_le (Set.finite_range (PLift.up ∘ g))
theorem DirectedOn.finite_le {s : Set α} (hs₀ : s.Nonempty) (D : DirectedOn r s)
(hs : s.Finite) : ∃ z ∈ s, ∀ i ∈ s, r i z := by
have := hs₀.to_subtype
have := hs.to_subtype
obtain ⟨⟨z, hzs⟩, hz⟩ := D.directed_val.finite_le id
use z, hzs
simpa using hz
variable [Nonempty α] [Preorder α]
theorem Finite.exists_le [IsDirectedOrder α] (f : β → α) : ∃ M, ∀ i, f i ≤ M :=
directed_id.finite_le _
theorem Finite.exists_ge [IsCodirectedOrder α] (f : β → α) : ∃ M, ∀ i, M ≤ f i :=
directed_id.finite_le (r := (· ≥ ·)) _
theorem Set.Finite.exists_le [IsDirectedOrder α] {s : Set α} (hs : s.Finite) :
∃ M, ∀ i ∈ s, i ≤ M :=
directed_id.finite_set_le hs
theorem Set.Finite.exists_ge [IsCodirectedOrder α] {s : Set α} (hs : s.Finite) :
∃ M, ∀ i ∈ s, M ≤ i :=
directed_id.finite_set_le (r := (· ≥ ·)) hs
@[simp]
theorem Finite.bddAbove_range [IsDirectedOrder α] (f : β → α) : BddAbove (Set.range f) := by
obtain ⟨M, hM⟩ := Finite.exists_le f
refine ⟨M, fun a ha => ?_⟩
obtain ⟨b, rfl⟩ := ha
exact hM b
@[simp]
theorem Finite.bddBelow_range [IsCodirectedOrder α] (f : β → α) : BddBelow (Set.range f) := by
obtain ⟨M, hM⟩ := Finite.exists_ge f
refine ⟨M, fun a ha => ?_⟩
obtain ⟨b, rfl⟩ := ha
exact hM b
end DirectedOrders
section
variable {ι : Sort*} {α : Type*} [CompleteLattice α] {s : Set α} {a : α} {f : ι → α}
lemma le_iSup_iff_of_directed [Nonempty ι] [Finite ι] (hf : Directed (· ≤ ·) f) :
a ≤ ⨆ i, f i ↔ ∃ i, a ≤ f i where
mp ha := by obtain ⟨i, hi⟩ := hf.finite_le id; exact ⟨i, ha.trans <| iSup_le hi⟩
mpr := by rintro ⟨i, hai⟩; exact le_iSup_of_le i hai
lemma le_sSup_iff_of_directedOn (hs : s.Nonempty) (hs' : s.Finite) (hs'' : DirectedOn (· ≤ ·) s) :
a ≤ sSup s ↔ ∃ b ∈ s, a ≤ b := by
have := hs.to_subtype
have := hs'.to_subtype
simp [sSup_eq_iSup', le_iSup_iff_of_directed hs''.directed_val]
end
namespace Set
variable {ι : Sort*} {α : Type*} {S : Set (Set α)} {s : Set α} {f : ι → Set α}
lemma subset_iUnion_iff_of_directed [Nonempty ι] [Finite ι] (hf : Directed (· ≤ ·) f) :
s ⊆ ⋃ i, f i ↔ ∃ i, s ⊆ f i := le_iSup_iff_of_directed hf
lemma subset_sUnion_iff_of_directed (hS : S.Nonempty) (hS' : S.Finite)
(hS'' : DirectedOn (· ≤ ·) S) : s ⊆ sSup S ↔ ∃ t ∈ S, s ⊆ t :=
le_sSup_iff_of_directedOn hS hS' hS''
end Set
/-!
### Suprema and infima over finite types
We state simplified versions of `le_ciSup_if_le` and `ciSup_mono` when the indexing type
is finite. This avoids having to explicitly use `Finite.bddAbove_range`.
Similarly for `ciInf`.
-/
section ciSup
namespace Finite
section CCL
variable {α ι ι' : Type*} [Finite ι] [Finite ι'] [ConditionallyCompleteLattice α]
lemma le_ciSup_of_le {a : α} {f : ι → α} (c : ι) (h : a ≤ f c) : a ≤ iSup f :=
_root_.le_ciSup_of_le (bddAbove_range f) c h
lemma ciInf_le_of_le {a : α} {f : ι → α} (c : ι) (h : f c ≤ a) : iInf f ≤ a :=
_root_.ciInf_le_of_le (bddBelow_range f) c h
lemma ciSup_mono {f g : ι → α} (H : ∀ (x : ι), f x ≤ g x) : iSup f ≤ iSup g :=
_root_.ciSup_mono (bddAbove_range g) H
lemma ciInf_mono {f g : ι → α} (H : ∀ (x : ι), f x ≤ g x) : iInf f ≤ iInf g :=
_root_.ciInf_mono (bddBelow_range f) H
lemma le_ciSup (f : ι → α) (i : ι) : f i ≤ ⨆ j, f j :=
le_ciSup_of_le i le_rfl
lemma ciInf_le (f : ι → α) (i : ι) : ⨅ j, f j ≤ f i :=
le_ciSup (α := αᵒᵈ) f i
lemma ciSup_sup [Nonempty ι] {f : ι → α} {a : α} :
(⨆ i, f i) ⊔ a = ⨆ i, f i ⊔ a := by
refine le_antisymm (sup_le ?_ ?_) <| ciSup_le fun i ↦ sup_le_sup_right (le_ciSup f i) a
· exact ciSup_le fun i ↦ le_ciSup_of_le i le_sup_left
· exact le_ciSup_of_le (Classical.arbitrary ι) le_sup_right
lemma ciInf_inf [Nonempty ι] {f : ι → α} {a : α} :
(⨅ i, f i) ⊓ a = ⨅ i, f i ⊓ a :=
ciSup_sup (α := αᵒᵈ) ..
lemma ciSup_prod (f : ι × ι' → α) :
⨆ a, f a = ⨆ i, ⨆ i', f (i, i') :=
_root_.ciSup_prod (bddAbove_range f)
lemma ciInf_prod (f : ι × ι' → α) :
⨅ a, f a = ⨅ i, ⨅ i', f (i, i') :=
ciSup_prod (α := αᵒᵈ) f
end CCL
section CCLO
variable {α β ι : Type*} [ConditionallyCompleteLinearOrder α] [ConditionallyCompleteLattice β]
[Finite ι] [Nonempty ι]
lemma map_iSup_of_monotoneOn {s : Set α} {f : ι → α} {g : α → β} (hg : MonotoneOn g s)
(hs : ∀ i, f i ∈ s) :
g (⨆ i, f i) = ⨆ i, g (f i) := by
obtain ⟨j, hj⟩ : ∃ j, f j = ⨆ i, f i := exists_eq_ciSup_of_finite
rw [← hj]
exact le_antisymm (le_ciSup_of_le j le_rfl) <|
ciSup_le fun i ↦ hg (hs i) (hs j) (hj ▸ le_ciSup f i)
lemma map_iInf_of_monotoneOn {s : Set α} {f : ι → α} {g : α → β} (hg : MonotoneOn g s)
(hs : ∀ i, f i ∈ s) :
g (⨅ i, f i) = ⨅ i, g (f i) :=
map_iSup_of_monotoneOn (α := αᵒᵈ) (β := βᵒᵈ) (fun _ hi _ hj h ↦ hg hj hi h) hs
lemma map_iSup_of_antitoneOn {s : Set α} {f : ι → α} {g : α → β} (hg : AntitoneOn g s)
(hs : ∀ i, f i ∈ s) :
g (⨆ i, f i) = ⨅ i, g (f i) :=
map_iSup_of_monotoneOn (β := βᵒᵈ) hg hs
lemma map_iInf_of_antitoneOn {s : Set α} {f : ι → α} {g : α → β} (hg : AntitoneOn g s)
(hs : ∀ i, f i ∈ s) :
g (⨅ i, f i) = ⨆ i, g (f i) :=
map_iInf_of_monotoneOn (β := βᵒᵈ) hg hs
lemma map_iSup_of_monotone (f : ι → α) {g : α → β} (hg : Monotone g) :
g (⨆ i, f i) = ⨆ i, g (f i) :=
map_iSup_of_monotoneOn (monotoneOn_univ.mpr hg) (fun i ↦ Set.mem_univ (f i))
lemma map_iInf_of_monotone (f : ι → α) {g : α → β} (hg : Monotone g) :
g (⨅ i, f i) = ⨅ i, g (f i) :=
map_iSup_of_monotone (α := αᵒᵈ) (β := βᵒᵈ) f fun _ _ h ↦ hg h
lemma map_iSup_of_antitone (f : ι → α) {g : α → β} (hg : Antitone g) :
g (⨆ i, f i) = ⨅ i, g (f i) :=
map_iSup_of_monotone (β := βᵒᵈ) f hg
lemma map_iInf_of_antitone (f : ι → α) {g : α → β} (hg : Antitone g) :
g (⨅ i, f i) = ⨆ i, g (f i) :=
map_iInf_of_monotone (β := βᵒᵈ) f hg
end CCLO
end Finite
end ciSup