Skip to content

Commit d5307c0

Browse files
committed
feat(Order): Galois connection between pred and succ (#13505)
This was a longstanding TODO. Kudos to Kevin for putting the pieces together!
1 parent 4d90b64 commit d5307c0

File tree

2 files changed

+52
-25
lines changed

2 files changed

+52
-25
lines changed

Mathlib/Order/Cover.lean

+2
Original file line numberDiff line numberDiff line change
@@ -322,6 +322,8 @@ theorem wcovBy_iff_covBy_or_le_and_le : a ⩿ b ↔ a ⋖ b ∨ a ≤ b ∧ b
322322
fun h' => h'.elim (fun h => h.wcovBy) fun h => h.1.wcovBy_of_le h.2
323323
#align wcovby_iff_covby_or_le_and_le wcovBy_iff_covBy_or_le_and_le
324324

325+
alias ⟨WCovBy.covBy_or_le_and_le, _⟩ := wcovBy_iff_covBy_or_le_and_le
326+
325327
theorem AntisymmRel.trans_covBy (hab : AntisymmRel (· ≤ ·) a b) (hbc : b ⋖ c) : a ⋖ c :=
326328
⟨hab.1.trans_lt hbc.lt, fun _ had hdc => hbc.2 (hab.2.trans_lt had) hdc⟩
327329
#align antisymm_rel.trans_covby AntisymmRel.trans_covBy

Mathlib/Order/SuccPred/Basic.lean

+50-25
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ Authors: Yaël Dillies
55
-/
66
import Mathlib.Order.CompleteLattice
77
import Mathlib.Order.Cover
8+
import Mathlib.Order.GaloisConnection
89
import Mathlib.Order.Iterate
910
import Mathlib.Order.WellFounded
1011

@@ -43,15 +44,6 @@ for all non maximal elements (enforced by the combination of `le_succ` and the c
4344
`max_of_succ_le`).
4445
The stricter condition of every element having a sensible successor can be obtained through the
4546
combination of `SuccOrder α` and `NoMaxOrder α`.
46-
47-
## TODO
48-
49-
Is `GaloisConnection pred succ` always true? If not, we should introduce
50-
```lean
51-
class SuccPredOrder (α : Type*) [Preorder α] extends SuccOrder α, PredOrder α :=
52-
(pred_succ_gc : GaloisConnection (pred : α → α) succ)
53-
```
54-
`CovBy` should help here.
5547
-/
5648

5749

@@ -240,6 +232,8 @@ theorem succ_le_of_lt {a b : α} : a < b → succ a ≤ b :=
240232
SuccOrder.succ_le_of_lt
241233
#align order.succ_le_of_lt Order.succ_le_of_lt
242234

235+
alias _root_.LT.lt.succ_le := succ_le_of_lt
236+
243237
theorem le_of_lt_succ {a b : α} : a < succ b → a ≤ b :=
244238
SuccOrder.le_of_lt_succ
245239
#align order.le_of_lt_succ Order.le_of_lt_succ
@@ -249,6 +243,8 @@ theorem succ_le_iff_isMax : succ a ≤ a ↔ IsMax a :=
249243
⟨max_of_succ_le, fun h => h <| le_succ _⟩
250244
#align order.succ_le_iff_is_max Order.succ_le_iff_isMax
251245

246+
alias ⟨_root_.IsMax.of_succ_le, _root_.IsMax.succ_le⟩ := succ_le_iff_isMax
247+
252248
@[simp]
253249
theorem lt_succ_iff_not_isMax : a < succ a ↔ ¬IsMax a :=
254250
⟨not_isMax_of_lt, fun ha => (le_succ a).lt_of_not_le fun h => ha <| max_of_succ_le h⟩
@@ -298,6 +294,16 @@ theorem succ_le_succ (h : a ≤ b) : succ a ≤ succ b := by
298294
theorem succ_mono : Monotone (succ : α → α) := fun _ _ => succ_le_succ
299295
#align order.succ_mono Order.succ_mono
300296

297+
/-- See also `Order.succ_eq_of_covBy`. -/
298+
lemma le_succ_of_wcovBy (h : a ⩿ b) : b ≤ succ a := by
299+
obtain hab | ⟨-, hba⟩ := h.covBy_or_le_and_le
300+
· by_contra hba
301+
exact h.2 (lt_succ_of_not_isMax hab.lt.not_isMax) $ hab.lt.succ_le.lt_of_not_le hba
302+
· exact hba.trans (le_succ _)
303+
304+
alias _root_.WCovBy.le_succ := le_succ_of_wcovBy
305+
#align wcovby.le_succ WCovBy.le_succ
306+
301307
theorem le_succ_iterate (k : ℕ) (x : α) : x ≤ succ^[k] x := by
302308
conv_lhs => rw [(by simp only [Function.iterate_id, id] : x = id^[k] x)]
303309
exact Monotone.le_iterate_of_le succ_mono le_succ k x
@@ -445,15 +451,11 @@ theorem le_le_succ_iff : a ≤ b ∧ b ≤ succ a ↔ b = a ∨ b = succ a := by
445451
· exact ⟨le_succ a, le_rfl⟩
446452
#align order.le_le_succ_iff Order.le_le_succ_iff
447453

448-
theorem _root_.CovBy.succ_eq (h : a ⋖ b) : succ a = b :=
449-
(succ_le_of_lt h.lt).eq_of_not_lt fun h' => h.2 (lt_succ_of_not_isMax h.lt.not_isMax) h'
450-
#align covby.succ_eq CovBy.succ_eq
454+
/-- See also `Order.le_succ_of_wcovBy`. -/
455+
lemma succ_eq_of_covBy (h : a ⋖ b) : succ a = b := (succ_le_of_lt h.lt).antisymm h.wcovBy.le_succ
451456

452-
theorem _root_.WCovBy.le_succ (h : a ⩿ b) : b ≤ succ a := by
453-
obtain h | rfl := h.covBy_or_eq
454-
· exact (CovBy.succ_eq h).ge
455-
· exact le_succ _
456-
#align wcovby.le_succ WCovBy.le_succ
457+
alias _root_.CovBy.succ_eq := succ_eq_of_covBy
458+
#align covby.succ_eq CovBy.succ_eq
457459

458460
theorem le_succ_iff_eq_or_le : a ≤ succ b ↔ a = succ b ∨ a ≤ b := by
459461
by_cases hb : IsMax b
@@ -628,6 +630,8 @@ theorem le_pred_of_lt {a b : α} : a < b → a ≤ pred b :=
628630
PredOrder.le_pred_of_lt
629631
#align order.le_pred_of_lt Order.le_pred_of_lt
630632

633+
alias _root_.LT.lt.le_pred := le_pred_of_lt
634+
631635
theorem le_of_pred_lt {a b : α} : pred a < b → a ≤ b :=
632636
PredOrder.le_of_pred_lt
633637
#align order.le_of_pred_lt Order.le_of_pred_lt
@@ -637,6 +641,8 @@ theorem le_pred_iff_isMin : a ≤ pred a ↔ IsMin a :=
637641
⟨min_of_le_pred, fun h => h <| pred_le _⟩
638642
#align order.le_pred_iff_is_min Order.le_pred_iff_isMin
639643

644+
alias ⟨_root_.IsMin.of_le_pred, _root_.IsMin.le_pred⟩ := le_pred_iff_isMin
645+
640646
@[simp]
641647
theorem pred_lt_iff_not_isMin : pred a < a ↔ ¬IsMin a :=
642648
⟨not_isMin_of_lt, fun ha => (pred_le a).lt_of_not_le fun h => ha <| min_of_le_pred h⟩
@@ -680,6 +686,16 @@ theorem pred_le_pred {a b : α} (h : a ≤ b) : pred a ≤ pred b :=
680686
theorem pred_mono : Monotone (pred : α → α) := fun _ _ => pred_le_pred
681687
#align order.pred_mono Order.pred_mono
682688

689+
/-- See also `Order.pred_eq_of_covBy`. -/
690+
lemma pred_le_of_wcovBy (h : a ⩿ b) : pred b ≤ a := by
691+
obtain hab | ⟨-, hba⟩ := h.covBy_or_le_and_le
692+
· by_contra hba
693+
exact h.2 (hab.lt.le_pred.lt_of_not_le hba) (pred_lt_of_not_isMin hab.lt.not_isMin)
694+
· exact (pred_le _).trans hba
695+
696+
alias _root_.WCovBy.pred_le := pred_le_of_wcovBy
697+
#align wcovby.pred_le WCovBy.pred_le
698+
683699
theorem pred_iterate_le (k : ℕ) (x : α) : pred^[k] x ≤ x := by
684700
conv_rhs => rw [(by simp only [Function.iterate_id, id] : x = id^[k] x)]
685701
exact Monotone.iterate_le_of_le pred_mono pred_le k x
@@ -817,15 +833,11 @@ theorem pred_le_le_iff {a b : α} : pred a ≤ b ∧ b ≤ a ↔ b = a ∨ b = p
817833
· exact ⟨le_rfl, pred_le a⟩
818834
#align order.pred_le_le_iff Order.pred_le_le_iff
819835

820-
theorem _root_.CovBy.pred_eq {a b : α} (h : a ⋖ b) : pred b = a :=
821-
(le_pred_of_lt h.lt).eq_of_not_gt fun h' => h.2 h' <| pred_lt_of_not_isMin h.lt.not_isMin
822-
#align covby.pred_eq CovBy.pred_eq
836+
/-- See also `Order.pred_le_of_wcovBy`. -/
837+
lemma pred_eq_of_covBy (h : a ⋖ b) : pred b = a := h.wcovBy.pred_le.antisymm (le_pred_of_lt h.lt)
823838

824-
theorem _root_.WCovBy.pred_le (h : a ⩿ b) : pred b ≤ a := by
825-
obtain h | rfl := h.covBy_or_eq
826-
· exact (CovBy.pred_eq h).le
827-
· exact pred_le _
828-
#align wcovby.pred_le WCovBy.pred_le
839+
alias _root_.CovBy.pred_eq := pred_eq_of_covBy
840+
#align covby.pred_eq CovBy.pred_eq
829841

830842
theorem pred_le_iff_eq_or_le : pred a ≤ b ↔ b = pred a ∨ a ≤ b := by
831843
by_cases ha : IsMin a
@@ -971,6 +983,19 @@ end CompleteLattice
971983
/-! ### Successor-predecessor orders -/
972984

973985
section SuccPredOrder
986+
section Preorder
987+
variable [Preorder α] [SuccOrder α] [PredOrder α] {a b : α}
988+
989+
lemma le_succ_pred (a : α) : a ≤ succ (pred a) := (pred_wcovBy _).le_succ
990+
lemma pred_succ_le (a : α) : pred (succ a) ≤ a := (wcovBy_succ _).pred_le
991+
992+
lemma pred_le_iff_le_succ : pred a ≤ b ↔ a ≤ succ b where
993+
mp hab := (le_succ_pred _).trans (succ_mono hab)
994+
mpr hab := (pred_mono hab).trans (pred_succ_le _)
995+
996+
lemma gc_pred_succ : GaloisConnection (pred : α → α) succ := fun _ _ ↦ pred_le_iff_le_succ
997+
998+
end Preorder
974999

9751000
variable [PartialOrder α] [SuccOrder α] [PredOrder α] {a b : α}
9761001

0 commit comments

Comments
 (0)