Successor and predecessor #
This file defines successor and predecessor orders. succ a
, the successor of an element a : α
is
the least element greater than a
. pred a
is the greatest element less than a
. Typical examples
include ℕ
, ℤ
, ℕ+
, fin n
, but also enat
, the lexicographic order of a successor/predecessor
order...
Typeclasses #
succ_order
: Order equipped with a sensible successor function.pred_order
: Order equipped with a sensible predecessor function.is_succ_archimedean
:succ_order
wheresucc
iterated to an element gives all the greater ones.is_pred_archimedean
:pred_order
wherepred
iterated to an element gives all the smaller ones.
Implementation notes #
Maximal elements don't have a sensible successor. Thus the naïve typeclass
class naive_succ_order (α : Type*) [preorder α] :=
(succ : α → α)
(succ_le_iff : ∀ {a b}, succ a ≤ b ↔ a < b)
(lt_succ_iff : ∀ {a b}, a < succ b ↔ a ≤ b)
can't apply to an order_top
because plugging in a = b = ⊤
into either of succ_le_iff
and
lt_succ_iff
yields ⊤ < ⊤
(or more generally m < m
for a maximal element m
).
The solution taken here is to remove the implications ≤ → <
and instead require that a < succ a
for all non maximal elements (enforced by the combination of le_succ
and the contrapositive of
max_of_succ_le
).
The stricter condition of every element having a sensible successor can be obtained through the
combination of succ_order α
and no_max_order α
.
TODO #
Is galois_connection pred succ
always true? If not, we should introduce
class succ_pred_order (α : Type*) [preorder α] extends succ_order α, pred_order α :=
(pred_succ_gc : galois_connection (pred : α → α) succ)
covby
should help here.
- succ : α → α
- le_succ : ∀ (a : α), a ≤ succ_order.succ a
- max_of_succ_le : ∀ {a : α}, succ_order.succ a ≤ a → is_max a
- succ_le_of_lt : ∀ {a b : α}, a < b → succ_order.succ a ≤ b
- le_of_lt_succ : ∀ {a b : α}, a < succ_order.succ b → a ≤ b
Order equipped with a sensible successor function.
- pred : α → α
- pred_le : ∀ (a : α), pred_order.pred a ≤ a
- min_of_le_pred : ∀ {a : α}, a ≤ pred_order.pred a → is_min a
- le_pred_of_lt : ∀ {a b : α}, a < b → a ≤ pred_order.pred b
- le_of_pred_lt : ∀ {a b : α}, pred_order.pred a < b → a ≤ b
Order equipped with a sensible predecessor function.
Equations
- order_dual.pred_order = {pred := ⇑order_dual.to_dual ∘ succ_order.succ ∘ ⇑order_dual.of_dual, pred_le := _, min_of_le_pred := _, le_pred_of_lt := _, le_of_pred_lt := _}
Equations
- order_dual.succ_order = {succ := ⇑order_dual.to_dual ∘ pred_order.pred ∘ ⇑order_dual.of_dual, le_succ := _, max_of_succ_le := _, succ_le_of_lt := _, le_of_lt_succ := _}
A constructor for succ_order α
usable when α
has no maximal element.
Equations
- succ_order.of_succ_le_iff_of_le_lt_succ succ hsucc_le_iff hle_of_lt_succ = {succ := succ, le_succ := _, max_of_succ_le := _, succ_le_of_lt := _, le_of_lt_succ := _}
A constructor for pred_order α
usable when α
has no minimal element.
Equations
- pred_order.of_le_pred_iff_of_pred_le_pred pred hle_pred_iff hle_of_pred_lt = {pred := pred, pred_le := _, min_of_le_pred := _, le_pred_of_lt := _, le_of_pred_lt := _}
A constructor for succ_order α
usable when α
is a linear order with no maximal element.
Equations
- succ_order.of_succ_le_iff succ hsucc_le_iff = {succ := succ, le_succ := _, max_of_succ_le := _, succ_le_of_lt := _, le_of_lt_succ := _}
A constructor for pred_order α
usable when α
is a linear order with no minimal element.
Equations
- pred_order.of_le_pred_iff pred hle_pred_iff = {pred := pred, pred_le := _, min_of_le_pred := _, le_pred_of_lt := _, le_of_pred_lt := _}
Successor order #
The successor of an element. If a
is not maximal, then succ a
is the least element greater
than a
. If a
is maximal, then succ a = a
.
Equations
Alias of lt_succ_iff_not_is_max
.
Alias of succ_le_succ_iff
.
Alias of succ_lt_succ_iff
.
Alias of succ_lt_succ_iff
.
Alias of succ_eq_iff_is_max
.
Alias of succ_ne_succ_iff
.
There is at most one way to define the successors in a partial_order
.
Predecessor order #
The predecessor of an element. If a
is not minimal, then pred a
is the greatest element less
than a
. If a
is minimal, then pred a = a
.
Equations
Alias of pred_lt_iff_not_is_min
.
Alias of pred_le_pred_iff
.
Alias of pred_lt_pred_iff
.
Alias of pred_lt_pred_iff
.
Alias of pred_eq_iff_is_min
.
Alias of pred_ne_pred_iff
.
There is at most one way to define the predecessors in a partial_order
.
Successor-predecessor orders #
with_bot
, with_top
#
Adding a greatest/least element to a succ_order
or to a pred_order
.
As far as successors and predecessors are concerned, there are four ways to add a bottom or top element to an order:
- Adding a
⊤
to anorder_top
: Preservessucc
andpred
. - Adding a
⊤
to ano_max_order
: Preservessucc
. Never preservespred
. - Adding a
⊥
to anorder_bot
: Preservessucc
andpred
. - Adding a
⊥
to ano_min_order
: Preservespred
. Never preservessucc
. where "preserves(succ/pred)
" means(succ/pred)_order α → (succ/pred)_order ((with_top/with_bot) α)
.
Equations
- order.with_top.succ_order = {succ := λ (a : with_top α), order.with_top.succ_order._match_1 a, le_succ := _, max_of_succ_le := _, succ_le_of_lt := _, le_of_lt_succ := _}
- order.with_top.succ_order._match_1 (some a) = ite (a = ⊤) ⊤ (some (order.succ a))
- order.with_top.succ_order._match_1 ⊤ = ⊤
Equations
- order.with_top.pred_order = {pred := λ (a : with_top α), order.with_top.pred_order._match_1 a, pred_le := _, min_of_le_pred := _, le_pred_of_lt := _, le_of_pred_lt := _}
- order.with_top.pred_order._match_1 (some a) = some (order.pred a)
- order.with_top.pred_order._match_1 ⊤ = some ⊤
Adding a ⊤
to a no_max_order
#
Equations
- order.with_top.succ_order_of_no_max_order = {succ := λ (a : with_top α), order.with_top.succ_order_of_no_max_order._match_1 a, le_succ := _, max_of_succ_le := _, succ_le_of_lt := _, le_of_lt_succ := _}
- order.with_top.succ_order_of_no_max_order._match_1 (some a) = some (order.succ a)
- order.with_top.succ_order_of_no_max_order._match_1 ⊤ = ⊤
Equations
- order.with_bot.succ_order = {succ := λ (a : with_bot α), order.with_bot.succ_order._match_1 a, le_succ := _, max_of_succ_le := _, succ_le_of_lt := _, le_of_lt_succ := _}
- order.with_bot.succ_order._match_1 (some a) = some (order.succ a)
- order.with_bot.succ_order._match_1 ⊥ = some ⊥
Equations
- order.with_bot.pred_order = {pred := λ (a : with_bot α), order.with_bot.pred_order._match_1 a, pred_le := _, min_of_le_pred := _, le_pred_of_lt := _, le_of_pred_lt := _}
- order.with_bot.pred_order._match_1 (some a) = ite (a = ⊥) ⊥ (some (order.pred a))
- order.with_bot.pred_order._match_1 ⊥ = ⊥
Adding a ⊥
to a no_min_order
#
Equations
- order.with_bot.pred_order_of_no_min_order = {pred := λ (a : with_bot α), order.with_bot.pred_order_of_no_min_order._match_1 a, pred_le := _, min_of_le_pred := _, le_pred_of_lt := _, le_of_pred_lt := _}
- order.with_bot.pred_order_of_no_min_order._match_1 (some a) = some (order.pred a)
- order.with_bot.pred_order_of_no_min_order._match_1 ⊥ = ⊥
Archimedeanness #
A succ_order
is succ-archimedean if one can go from any two comparable elements by iterating
succ
A pred_order
is pred-archimedean if one can go from any two comparable elements by iterating
pred
Induction principle on a type with a succ_order
for all elements above a given element m
.
Induction principle on a type with a pred_order
for all elements below a given element m
.