Skip to content

Commit e07097c

Browse files
kim-empecherskyVierkantor
committed
feat: port Order.Max (#567)
mathlib3 hash: fd47bdf09e90f553519c712378e651975fe8c829 - [x] depends on: #566 - [x] depends on: #562 Co-authored-by: Yakov Pechersky <ypechersky@treeline.bio> Co-authored-by: Vierkantor <vierkantor@vierkantor.com> Co-authored-by: Anne Baanen <Vierkantor@users.noreply.github.com>
1 parent 25fc282 commit e07097c

File tree

2 files changed

+345
-0
lines changed

2 files changed

+345
-0
lines changed

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ import Mathlib.Mathport.Attributes
114114
import Mathlib.Mathport.Rename
115115
import Mathlib.Mathport.Syntax
116116
import Mathlib.Order.Basic
117+
import Mathlib.Order.Max
117118
import Mathlib.Order.Monotone
118119
import Mathlib.Order.RelClasses
119120
import Mathlib.Order.Synonym

Mathlib/Order/Max.lean

Lines changed: 344 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,344 @@
1+
/-
2+
Copyright (c) 2014 Jeremy Avigad. All rights reserved.
3+
Released under Apache 2.0 license as described in the file LICENSE.
4+
Authors: Jeremy Avigad, Yury Kudryashov, Yaël Dillies
5+
-/
6+
import Mathlib.Order.Synonym
7+
8+
/-!
9+
# Minimal/maximal and bottom/top elements
10+
11+
This file defines predicates for elements to be minimal/maximal or bottom/top and typeclasses
12+
saying that there are no such elements.
13+
14+
## Predicates
15+
16+
* `IsBot`: An element is *bottom* if all elements are greater than it.
17+
* `IsTop`: An element is *top* if all elements are less than it.
18+
* `IsMin`: An element is *minimal* if no element is strictly less than it.
19+
* `IsMax`: An element is *maximal* if no element is strictly greater than it.
20+
21+
See also `isBot_iff_isMin` and `isTop_iff_isMax` for the equivalences in a (co)directed order.
22+
23+
## Typeclasses
24+
25+
* `NoBotOrder`: An order without bottom elements.
26+
* `NoTopOrder`: An order without top elements.
27+
* `NoMinOrder`: An order without minimal elements.
28+
* `NoMaxOrder`: An order without maximal elements.
29+
-/
30+
31+
32+
open OrderDual
33+
34+
variable {α β : Type _}
35+
36+
/-- Order without bottom elements. -/
37+
class NoBotOrder (α : Type _) [LE α] : Prop where
38+
/-- For each term `a`, there is some `b` which is either incomparable or strictly smaller. -/
39+
exists_not_ge (a : α) : ∃ b, ¬a ≤ b
40+
41+
/-- Order without top elements. -/
42+
class NoTopOrder (α : Type _) [LE α] : Prop where
43+
/-- For each term `a`, there is some `b` which is either incomparable or strictly larger. -/
44+
exists_not_le (a : α) : ∃ b, ¬b ≤ a
45+
46+
/-- Order without minimal elements. Sometimes called coinitial or dense. -/
47+
class NoMinOrder (α : Type _) [LT α] : Prop where
48+
/-- For each term `a`, there is some strictly smaller `b`. -/
49+
exists_lt (a : α) : ∃ b, b < a
50+
51+
/-- Order without maximal elements. Sometimes called cofinal. -/
52+
class NoMaxOrder (α : Type _) [LT α] : Prop where
53+
/-- For each term `a`, there is some strictly greater `b`. -/
54+
exists_gt (a : α) : ∃ b, a < b
55+
56+
export NoBotOrder (exists_not_ge)
57+
58+
export NoTopOrder (exists_not_le)
59+
60+
export NoMinOrder (exists_lt)
61+
62+
export NoMaxOrder (exists_gt)
63+
64+
instance [LT α] [NoMinOrder α] (a : α) : Nonempty { x // x < a } :=
65+
nonempty_subtype.2 (exists_lt a)
66+
67+
instance [LT α] [NoMaxOrder α] (a : α) : Nonempty { x // a < x } :=
68+
nonempty_subtype.2 (exists_gt a)
69+
70+
instance [LE α] [NoTopOrder α] : NoBotOrder αᵒᵈ :=
71+
fun a => @exists_not_le α _ _ a⟩
72+
73+
instance [LE α] [NoBotOrder α] : NoTopOrder αᵒᵈ :=
74+
fun a => @exists_not_ge α _ _ a⟩
75+
76+
instance [LT α] [NoMaxOrder α] : NoMinOrder αᵒᵈ :=
77+
fun a => @exists_gt α _ _ a⟩
78+
79+
instance [LT α] [NoMinOrder α] : NoMaxOrder αᵒᵈ :=
80+
fun a => @exists_lt α _ _ a⟩
81+
82+
-- See note [lower instance priority]
83+
instance (priority := 100) [Preorder α] [NoMinOrder α] : NoBotOrder α :=
84+
fun a => (exists_lt a).imp fun _ => not_le_of_lt⟩
85+
86+
-- See note [lower instance priority]
87+
instance (priority := 100) [Preorder α] [NoMaxOrder α] : NoTopOrder α :=
88+
fun a => (exists_gt a).imp fun _ => not_le_of_lt⟩
89+
90+
-- Porting note: mathlib3 proof uses `convert`
91+
theorem NoBotOrder.to_noMinOrder (α : Type _) [LinearOrder α] [NoBotOrder α] : NoMinOrder α :=
92+
{ exists_lt := fun a => by simpa [not_le] using exists_not_ge a }
93+
#align no_bot_order.to_no_min_order NoBotOrder.to_noMinOrder
94+
95+
-- Porting note: mathlib3 proof uses `convert`
96+
theorem NoTopOrder.to_noMaxOrder (α : Type _) [LinearOrder α] [NoTopOrder α] : NoMaxOrder α :=
97+
{ exists_gt := fun a => by simpa [not_le] using exists_not_le a }
98+
#align no_top_order.to_no_max_order NoTopOrder.to_noMaxOrder
99+
100+
theorem no_bot_order_iff_no_min_order (α : Type _) [LinearOrder α] : NoBotOrder α ↔ NoMinOrder α :=
101+
fun h =>
102+
haveI := h
103+
NoBotOrder.to_noMinOrder α,
104+
fun h =>
105+
haveI := h
106+
inferInstance⟩
107+
108+
theorem no_top_order_iff_no_max_order (α : Type _) [LinearOrder α] : NoTopOrder α ↔ NoMaxOrder α :=
109+
fun h =>
110+
haveI := h
111+
NoTopOrder.to_noMaxOrder α,
112+
fun h =>
113+
haveI := h
114+
inferInstance⟩
115+
116+
theorem NoMinOrder.not_acc [LT α] [NoMinOrder α] (a : α) : ¬Acc (· < ·) a := fun h =>
117+
Acc.recOn h fun x _ => (exists_lt x).recOn
118+
119+
theorem NoMaxOrder.not_acc [LT α] [NoMaxOrder α] (a : α) : ¬Acc (· > ·) a := fun h =>
120+
Acc.recOn h fun x _ => (exists_gt x).recOn
121+
122+
section LE
123+
124+
variable [LE α] {a b : α}
125+
126+
/-- `a : α` is a bottom element of `α` if it is less than or equal to any other element of `α`.
127+
This predicate is roughly an unbundled version of `OrderBot`, except that a preorder may have
128+
several bottom elements. When `α` is linear, this is useful to make a case disjunction on
129+
`NoMinOrder α` within a proof. -/
130+
def IsBot (a : α) : Prop :=
131+
∀ b, a ≤ b
132+
133+
/-- `a : α` is a top element of `α` if it is greater than or equal to any other element of `α`.
134+
This predicate is roughly an unbundled version of `OrderBot`, except that a preorder may have
135+
several top elements. When `α` is linear, this is useful to make a case disjunction on
136+
`NoMaxOrder α` within a proof. -/
137+
def IsTop (a : α) : Prop :=
138+
∀ b, b ≤ a
139+
140+
/-- `a` is a minimal element of `α` if no element is strictly less than it. We spell it without `<`
141+
to avoid having to convert between `≤` and `<`. Instead, `is_min_iff_forall_not_lt` does the
142+
conversion. -/
143+
def IsMin (a : α) : Prop :=
144+
∀ ⦃b⦄, b ≤ a → a ≤ b
145+
146+
/-- `a` is a maximal element of `α` if no element is strictly greater than it. We spell it without
147+
`<` to avoid having to convert between `≤` and `<`. Instead, `is_max_iff_forall_not_lt` does the
148+
conversion. -/
149+
def IsMax (a : α) : Prop :=
150+
∀ ⦃b⦄, a ≤ b → b ≤ a
151+
152+
@[simp]
153+
theorem not_is_bot [NoBotOrder α] (a : α) : ¬IsBot a := fun h =>
154+
let ⟨_, hb⟩ := exists_not_ge a
155+
hb <| h _
156+
157+
@[simp]
158+
theorem not_is_top [NoTopOrder α] (a : α) : ¬IsTop a := fun h =>
159+
let ⟨_, hb⟩ := exists_not_le a
160+
hb <| h _
161+
162+
protected theorem IsBot.is_min (h : IsBot a) : IsMin a := fun b _ => h b
163+
164+
protected theorem IsTop.is_max (h : IsTop a) : IsMax a := fun b _ => h b
165+
166+
@[simp]
167+
theorem is_bot_to_dual_iff : IsBot (toDual a) ↔ IsTop a :=
168+
Iff.rfl
169+
170+
@[simp]
171+
theorem is_top_to_dual_iff : IsTop (toDual a) ↔ IsBot a :=
172+
Iff.rfl
173+
174+
@[simp]
175+
theorem is_min_to_dual_iff : IsMin (toDual a) ↔ IsMax a :=
176+
Iff.rfl
177+
178+
@[simp]
179+
theorem is_max_to_dual_iff : IsMax (toDual a) ↔ IsMin a :=
180+
Iff.rfl
181+
182+
@[simp]
183+
theorem is_bot_of_dual_iff {a : αᵒᵈ} : IsBot (ofDual a) ↔ IsTop a :=
184+
Iff.rfl
185+
186+
@[simp]
187+
theorem is_top_of_dual_iff {a : αᵒᵈ} : IsTop (ofDual a) ↔ IsBot a :=
188+
Iff.rfl
189+
190+
@[simp]
191+
theorem is_min_of_dual_iff {a : αᵒᵈ} : IsMin (ofDual a) ↔ IsMax a :=
192+
Iff.rfl
193+
194+
@[simp]
195+
theorem is_max_of_dual_iff {a : αᵒᵈ} : IsMax (ofDual a) ↔ IsMin a :=
196+
Iff.rfl
197+
198+
alias is_bot_to_dual_iff ↔ _ IsTop.to_dual
199+
200+
alias is_top_to_dual_iff ↔ _ IsBot.to_dual
201+
202+
alias is_min_to_dual_iff ↔ _ IsMax.to_dual
203+
204+
alias is_max_to_dual_iff ↔ _ IsMin.to_dual
205+
206+
alias is_bot_of_dual_iff ↔ _ IsTop.of_dual
207+
208+
alias is_top_of_dual_iff ↔ _ IsBot.of_dual
209+
210+
alias is_min_of_dual_iff ↔ _ IsMax.of_dual
211+
212+
alias is_max_of_dual_iff ↔ _ IsMin.of_dual
213+
214+
end LE
215+
216+
section Preorder
217+
218+
variable [Preorder α] {a b : α}
219+
220+
theorem IsBot.mono (ha : IsBot a) (h : b ≤ a) : IsBot b := fun _ => h.trans <| ha _
221+
222+
theorem IsTop.mono (ha : IsTop a) (h : a ≤ b) : IsTop b := fun _ => (ha _).trans h
223+
224+
theorem IsMin.mono (ha : IsMin a) (h : b ≤ a) : IsMin b := fun _ hc => h.trans <| ha <| hc.trans h
225+
226+
theorem IsMax.mono (ha : IsMax a) (h : a ≤ b) : IsMax b := fun _ hc => (ha <| h.trans hc).trans h
227+
228+
theorem IsMin.not_lt (h : IsMin a) : ¬b < a := fun hb => hb.not_le <| h hb.le
229+
230+
theorem IsMax.not_lt (h : IsMax a) : ¬a < b := fun hb => hb.not_le <| h hb.le
231+
232+
@[simp]
233+
theorem not_is_min_of_lt (h : b < a) : ¬IsMin a := fun ha => ha.not_lt h
234+
235+
@[simp]
236+
theorem not_is_max_of_lt (h : a < b) : ¬IsMax a := fun ha => ha.not_lt h
237+
238+
alias not_is_min_of_lt ← LT.lt.not_is_min
239+
240+
alias not_is_max_of_lt ← LT.lt.not_is_max
241+
242+
theorem is_min_iff_forall_not_lt : IsMin a ↔ ∀ b, ¬b < a :=
243+
fun h _ => h.not_lt, fun h _ hba => of_not_not fun hab => h _ <| hba.lt_of_not_le hab⟩
244+
245+
theorem is_max_iff_forall_not_lt : IsMax a ↔ ∀ b, ¬a < b :=
246+
fun h _ => h.not_lt, fun h _ hba => of_not_not fun hab => h _ <| hba.lt_of_not_le hab⟩
247+
248+
@[simp]
249+
theorem not_is_min_iff : ¬IsMin a ↔ ∃ b, b < a := by
250+
simp [lt_iff_le_not_le, IsMin, not_forall, exists_prop]
251+
252+
@[simp]
253+
theorem not_is_max_iff : ¬IsMax a ↔ ∃ b, a < b := by
254+
simp [lt_iff_le_not_le, IsMax, not_forall, exists_prop]
255+
256+
@[simp]
257+
theorem not_is_min [NoMinOrder α] (a : α) : ¬IsMin a :=
258+
not_is_min_iff.2 <| exists_lt a
259+
260+
@[simp]
261+
theorem not_is_max [NoMaxOrder α] (a : α) : ¬IsMax a :=
262+
not_is_max_iff.2 <| exists_gt a
263+
264+
namespace Subsingleton
265+
266+
variable [Subsingleton α]
267+
268+
protected theorem is_bot (a : α) : IsBot a := fun _ => (Subsingleton.elim _ _).le
269+
270+
protected theorem is_top (a : α) : IsTop a := fun _ => (Subsingleton.elim _ _).le
271+
272+
protected theorem is_min (a : α) : IsMin a :=
273+
(Subsingleton.is_bot _).is_min
274+
275+
protected theorem is_max (a : α) : IsMax a :=
276+
(Subsingleton.is_top _).is_max
277+
278+
end Subsingleton
279+
280+
end Preorder
281+
282+
section PartialOrder
283+
284+
variable [PartialOrder α] {a b : α}
285+
286+
protected theorem IsMin.eq_of_le (ha : IsMin a) (h : b ≤ a) : b = a :=
287+
h.antisymm <| ha h
288+
289+
protected theorem IsMin.eq_of_ge (ha : IsMin a) (h : b ≤ a) : a = b :=
290+
h.antisymm' <| ha h
291+
292+
protected theorem IsMax.eq_of_le (ha : IsMax a) (h : a ≤ b) : a = b :=
293+
h.antisymm <| ha h
294+
295+
protected theorem IsMax.eq_of_ge (ha : IsMax a) (h : a ≤ b) : b = a :=
296+
h.antisymm' <| ha h
297+
298+
end PartialOrder
299+
300+
section Prod
301+
302+
variable [Preorder α] [Preorder β] {a a₁ a₂ : α} {b b₁ b₂ : β} {x y : α × β}
303+
304+
theorem IsBot.prod_mk (ha : IsBot a) (hb : IsBot b) : IsBot (a, b) := fun _ => ⟨ha _, hb _⟩
305+
306+
theorem IsTop.prod_mk (ha : IsTop a) (hb : IsTop b) : IsTop (a, b) := fun _ => ⟨ha _, hb _⟩
307+
308+
theorem IsMin.prod_mk (ha : IsMin a) (hb : IsMin b) : IsMin (a, b) := fun _ hc => ⟨ha hc.1, hb hc.2
309+
310+
theorem IsMax.prod_mk (ha : IsMax a) (hb : IsMax b) : IsMax (a, b) := fun _ hc => ⟨ha hc.1, hb hc.2
311+
312+
theorem IsBot.fst (hx : IsBot x) : IsBot x.1 := fun c => (hx (c, x.2)).1
313+
314+
theorem IsBot.snd (hx : IsBot x) : IsBot x.2 := fun c => (hx (x.1, c)).2
315+
316+
theorem IsTop.fst (hx : IsTop x) : IsTop x.1 := fun c => (hx (c, x.2)).1
317+
318+
theorem IsTop.snd (hx : IsTop x) : IsTop x.2 := fun c => (hx (x.1, c)).2
319+
320+
theorem IsMin.fst (hx : IsMin x) : IsMin x.1 :=
321+
fun c hc => (hx <| show (c, x.2) ≤ x from (and_iff_left le_rfl).2 hc).1
322+
323+
theorem IsMin.snd (hx : IsMin x) : IsMin x.2 :=
324+
fun c hc => (hx <| show (x.1, c) ≤ x from (and_iff_right le_rfl).2 hc).2
325+
326+
theorem IsMax.fst (hx : IsMax x) : IsMax x.1 :=
327+
fun c hc => (hx <| show x ≤ (c, x.2) from (and_iff_left le_rfl).2 hc).1
328+
329+
theorem IsMax.snd (hx : IsMax x) : IsMax x.2 :=
330+
fun c hc => (hx <| show x ≤ (x.1, c) from (and_iff_right le_rfl).2 hc).2
331+
332+
theorem Prod.is_bot_iff : IsBot x ↔ IsBot x.1 ∧ IsBot x.2 :=
333+
fun hx => ⟨hx.fst, hx.snd⟩, fun h => h.1.prod_mk h.2
334+
335+
theorem Prod.is_top_iff : IsTop x ↔ IsTop x.1 ∧ IsTop x.2 :=
336+
fun hx => ⟨hx.fst, hx.snd⟩, fun h => h.1.prod_mk h.2
337+
338+
theorem Prod.is_min_iff : IsMin x ↔ IsMin x.1 ∧ IsMin x.2 :=
339+
fun hx => ⟨hx.fst, hx.snd⟩, fun h => h.1.prod_mk h.2
340+
341+
theorem Prod.is_max_iff : IsMax x ↔ IsMax x.1 ∧ IsMax x.2 :=
342+
fun hx => ⟨hx.fst, hx.snd⟩, fun h => h.1.prod_mk h.2
343+
344+
end Prod

0 commit comments

Comments
 (0)