Library Nijn.Prelude.Orders.CompatibleRelation

Require Import Nijn.Prelude.Checks.
Require Import Nijn.Prelude.Basics.Decidable.
Require Import Nijn.Prelude.Relations.WellfoundedRelation.

Declare Scope qr.
Open Scope qr.
Delimit Scope qr with qr.

Quasi-orders

Record QuasiRel :=
  {
    carrier_qr :> Type ;
    ge_qr : carrier_qr → carrier_qr → Prop
  }.

Arguments ge_qr {_} _ _.

Notation "x >= y" := (ge_qr x y) : qr.

Class isQuasiRel ( X : QuasiRel ) :=
  {
    ge_qr_refl : ∀ (x : X),
      x ≥ x;
    ge_qr_trans : ∀ { x y z : X },
      x ≥ y → y ≥ z → x ≥ z
  }.

Close Scope qr.

Compatible relations


Declare Scope compat.
Open Scope compat.
Delimit Scope compat with compat.

A compatible relation is a type equipped with two relations
Record CompatRel :=
  {
    carrier :> Type ;
    gt : carrier → carrier → Prop ;
    ge : carrier → carrier → Prop
  }.

Arguments gt {_} _ _.
Arguments ge {_} _ _.

Notation "x > y" := (gt x y) : compat.
Notation "x >= y" := (ge x y) : compat.

These are the axioms that should hold for compatible relations. Note that we do not require the relations to be well-founded, but that condition is formulated separately.
Class isCompatRel (X : CompatRel) :=
  {
    gt_trans : ∀ {x y z : carrier X},
      x > y → y > z → x > z ;
    ge_trans : ∀ {x y z : X},
      x ≥ y → y ≥ z → x ≥ z ;
    ge_refl : ∀ (x : X),
      x ≥ x ;
    compat : ∀ {x y : X},
      x > y → x ≥ y ;
    ge_gt : ∀ {x y z : X},
      x ≥ y → y > z → x > z ;
    gt_ge : ∀ {x y z : X},
      x > y → y ≥ z → x > z
  }.

Lemmata for compatible relations

Proposition eq_gt
            {X : CompatRel}
            {x y z : X}
            (p : x = y)
            (q : y > z)
  : x > z.
Proof.
  induction p.
  exact q.
Qed.

Proposition gt_eq
            {X : CompatRel}
            {x y z : X}
            (p : x > y)
            (q : y = z)
  : x > z.
Proof.
  induction q.
  exact p.
Qed.

Proposition eq_ge
            {X : CompatRel}
            {x y z : X}
            (p : x = y)
            (q : y ≥ z)
  : x ≥ z.
Proof.
  induction p.
  exact q.
Qed.

Proposition ge_eq
            {X : CompatRel}
            {x y z : X}
            (p : x ≥ y)
            (q : y = z)
  : x ≥ z.
Proof.
  induction q.
  exact p.
Qed.

Proposition eq_to_ge
            {X : CompatRel}
            `{isCompatRel X}
            {x y : X}
            (p : x = y)
  : x ≥ y.
Proof.
  induction p.
  apply ge_refl.
Qed.

Minimal elements in a compatible relation

Definition is_minimal_element
           {X : CompatRel}
           (x : X)
  : Prop
  := ∀ (y : X), y ≥ x.

Record minimal_element (X : CompatRel) :=
  make_min_el
    {
      min_el :> X ;
      is_minimal : is_minimal_element min_el
    }.

Definition is_strict_minimal_element
           {X : CompatRel}
           (x : X)
  : Prop
  := ∀ (y : X), y ≠ x → y > x.

Record strict_minimal_element (X : CompatRel) :=
  make_strict_min_el
    {
      strict_min_el :> X ;
      is_strict_minimal : is_strict_minimal_element strict_min_el
    }.

Definition is_minimal_to_strict_minimal
           {X : CompatRel}
           `{decEq X}
           `{isCompatRel X}
           (x : strict_minimal_element X)
  : minimal_element X.
Proof.
  simple refine (make_min_el _ _ _).
  - exact x.
  - intros y.
    destruct (dec_eq y x) as [ p | p ].
    + apply eq_to_ge.
      exact p.
    + exact (compat (is_strict_minimal _ x y p)).
Defined.