mirror of
https://github.com/idris-lang/Idris2.git
synced 2024-12-19 09:12:34 +03:00
115 lines
4.1 KiB
Idris
115 lines
4.1 KiB
Idris
||| An order is a particular kind of binary relation. The order
|
|
||| relation is intended to proceed in some direction, though not
|
|
||| necessarily with a unique path.
|
|
|||
|
|
||| Orders are often defined simply as bundles of binary relation
|
|
||| properties.
|
|
|||
|
|
||| A prominent example of an order relation is LTE over Nat.
|
|
|
|
module Control.Order
|
|
|
|
import Control.Relation
|
|
|
|
||| A preorder is reflexive and transitive.
|
|
public export
|
|
interface (Reflexive ty rel, Transitive ty rel) => Preorder ty rel where
|
|
|
|
||| A partial order is an antisymmetrics preorder.
|
|
public export
|
|
interface (Preorder ty rel, Antisymmetric ty rel) => PartialOrder ty rel where
|
|
|
|
||| A relation is connex if for any two distinct x and y, either x ~ y or y ~ x.
|
|
|||
|
|
||| This can also be stated as a trichotomy: x ~ y or x = y or y ~ x.
|
|
public export
|
|
interface Connex ty rel where
|
|
connex : {x, y : ty} -> Not (x = y) -> Either (rel x y) (rel y x)
|
|
|
|
||| A relation is strongly connex if for any two x and y, either x ~ y or y ~ x.
|
|
public export
|
|
interface StronglyConnex ty rel where
|
|
order : (x, y : ty) -> Either (rel x y) (rel y x)
|
|
|
|
||| A linear order is a connex partial order.
|
|
public export
|
|
interface (PartialOrder ty rel, Connex ty rel) => LinearOrder ty rel where
|
|
|
|
----------------------------------------
|
|
|
|
||| Every equivalence relation is a preorder.
|
|
public export
|
|
[EP] Equivalence ty rel => Preorder ty rel where
|
|
|
|
--- Derivaties of order-based stuff ---
|
|
|
|
||| Gives the leftmost of a strongly connex relation among the given two elements, generalisation of `min`.
|
|
|||
|
|
||| That is, leftmost x y ~ x and leftmost x y ~ y, and `leftmost x y` is either `x` or `y`
|
|
public export
|
|
leftmost : (0 rel : _) -> StronglyConnex ty rel => ty -> ty -> ty
|
|
leftmost rel x y = either (const x) (const y) $ order {rel} x y
|
|
|
|
||| Gives the rightmost of a strongly connex relation among the given two elements, generalisation of `max`.
|
|
|||
|
|
||| That is, x ~ rightmost x y and y ~ rightmost x y, and `rightmost x y` is either `x` or `y`
|
|
public export
|
|
rightmost : (0 rel : _) -> StronglyConnex ty rel => ty -> ty -> ty
|
|
rightmost rel x y = either (const y) (const x) $ order {rel} x y
|
|
|
|
-- properties --
|
|
|
|
export
|
|
leftmostRelL : (0 rel : _) -> Reflexive ty rel => StronglyConnex ty rel => (x, y : ty) -> leftmost rel x y `rel` x
|
|
leftmostRelL rel x y with (order {rel} x y)
|
|
_ | Left _ = reflexive {rel}
|
|
_ | Right yx = yx
|
|
|
|
export
|
|
leftmostRelR : (0 rel : _) -> Reflexive ty rel => StronglyConnex ty rel => (x, y : ty) -> leftmost rel x y `rel` y
|
|
leftmostRelR rel x y with (order {rel} x y)
|
|
_ | Left xy = xy
|
|
_ | Right _ = reflexive {rel}
|
|
|
|
export
|
|
leftmostPreserves : (0 rel : _) -> StronglyConnex ty rel => (x, y : ty) -> Either (leftmost rel x y = x) (leftmost rel x y = y)
|
|
leftmostPreserves rel x y with (order {rel} x y)
|
|
_ | Left _ = Left Refl
|
|
_ | Right _ = Right Refl
|
|
|
|
export
|
|
leftmostIsRightmostLeft : (0 rel : _) -> StronglyConnex ty rel =>
|
|
(x, y : ty) ->
|
|
(z : ty) -> (z `rel` x) -> (z `rel` y) ->
|
|
(z `rel` leftmost rel x y)
|
|
leftmostIsRightmostLeft rel x y z zx zy with (order {rel} x y)
|
|
_ | Left _ = zx
|
|
_ | Right _ = zy
|
|
|
|
export
|
|
rightmostRelL : (0 rel : _) -> Reflexive ty rel => StronglyConnex ty rel => (x, y : ty) -> x `rel` rightmost rel x y
|
|
rightmostRelL rel x y with (order {rel} x y)
|
|
_ | Left xy = xy
|
|
_ | Right _ = reflexive {rel}
|
|
|
|
export
|
|
rightmostRelR : (0 rel : _) -> Reflexive ty rel => StronglyConnex ty rel => (x, y : ty) -> y `rel` rightmost rel x y
|
|
rightmostRelR rel x y with (order {rel} x y)
|
|
_ | Left _ = reflexive {rel}
|
|
_ | Right yx = yx
|
|
|
|
export
|
|
rightmostPreserves : (0 rel : _) -> StronglyConnex ty rel => (x, y : ty) -> Either (rightmost rel x y = x) (rightmost rel x y = y)
|
|
rightmostPreserves rel x y with (order {rel} x y)
|
|
_ | Left _ = Right Refl
|
|
_ | Right _ = Left Refl
|
|
|
|
export
|
|
rightmostIsLeftmostRight : (0 rel : _) -> StronglyConnex ty rel =>
|
|
(x, y : ty) ->
|
|
(z : ty) -> (x `rel` z) -> (y `rel` z) ->
|
|
(leftmost rel x y `rel` z)
|
|
rightmostIsLeftmostRight rel x y z zx zy with (order {rel} x y)
|
|
_ | Left _ = zx
|
|
_ | Right _ = zy
|