Timings for orders.v
Require Import
HoTT.Classes.interfaces.abstract_algebra
HoTT.Classes.interfaces.orders
HoTT.Classes.theory.apartness.
Generalizable Variables A.
Lemma irrefl_neq `{R : Relation A} `{!Irreflexive R}
: forall x y, R x y -> x <> y.
intros ?? E e;rewrite e in E.
exact (irreflexivity _ _ E).
Lemma le_flip `{Le A} `{!TotalRelation (≤)} x y : ~(y ≤ x) -> x ≤ y.
destruct (total _ x y) as [?|le];auto.
Context `{PartialOrder A}.
Lemma eq_le x y : x = y -> x ≤ y.
Lemma eq_le_flip x y : x = y -> y ≤ x.
Lemma not_le_ne x y : ~(x ≤ y) -> x <> y.
Lemma eq_iff_le x y : x = y <-> x ≤ y /\ y ≤ x.
apply (antisymmetry (≤) x y);apply E.
Context `{StrictOrder A}.
Lemma lt_flip x y : x < y -> ~(y < x).
apply (irreflexivity (<) x).
transitivity y;assumption.
Lemma lt_antisym x y : ~(x < y < x).
destruct (lt_flip x y);assumption.
Lemma lt_ne x y : x < y -> x <> y.
apply (irreflexivity (<) y).
Lemma lt_ne_flip x y : x < y -> y <> x.
apply symmetric_neq, lt_ne.
Lemma eq_not_lt x y : x = y -> ~(x < y).
apply (irreflexivity (<)).
Context `{PseudoOrder A}.
Local Existing Instance pseudo_order_apart.
Lemma apart_total_lt x y : x ≶ y -> x < y |_| y < x.
apply apart_iff_total_lt.
Lemma pseudo_order_lt_apart x y : x < y -> x ≶ y.
apply apart_iff_total_lt.
Lemma pseudo_order_lt_apart_flip x y : x < y -> y ≶ x.
apply apart_iff_total_lt.
Lemma not_lt_apart_lt_flip x y : ~(x < y) -> x ≶ y -> y < x.
apply apart_iff_total_lt in neq.
Lemma pseudo_order_cotrans_twice x₁ y₁ x₂ y₂
: x₁ < y₁ -> merely (x₂ < y₂ |_| x₁ < x₂ |_| y₂ < y₁).
apply (merely_destruct (cotransitive E1 x₂));intros [?|E2];
try solve [apply tr;auto].
apply (merely_destruct (cotransitive E2 y₂));intros [?|?];apply tr;auto.
Lemma pseudo_order_lt_ext x₁ y₁ x₂ y₂ : x₁ < y₁ ->
merely (x₂ < y₂ |_| x₁ ≶ x₂ |_| y₂ ≶ y₁).
apply (merely_destruct (pseudo_order_cotrans_twice x₁ y₁ x₂ y₂ E));
intros [?|[?|?]];apply tr;
auto using pseudo_order_lt_apart.
#[export] Instance pseudoorder_strictorder : StrictOrder (_ : Lt A).
destruct (pseudo_order_antisym x x); auto.
apply (merely_destruct (cotransitive E1 z));intros [?|?]; trivial.
destruct (pseudo_order_antisym y z); auto.
#[export] Instance nlt_trans : Transitive (complement (<)).
apply (merely_destruct (cotransitive E3 y));
intros [?|?]; contradiction.
#[export] Instance nlt_antisymm : AntiSymmetric (complement (<)).
apply apart_iff_total_lt in nap.
Lemma ne_total_lt `{!TrivialApart A} x y : x <> y -> x < y |_| y < x.
intros neq;apply trivial_apart in neq.
#[export] Instance lt_trichotomy `{!TrivialApart A} `{DecidablePaths A}
: Trichotomy (<).
destruct (dec (x = y)) as [?|?]; try auto.
destruct (ne_total_lt x y); auto.
Section full_partial_order.
Context `{FullPartialOrder A}.
Local Existing Instance strict_po_apart.
(* Duplicate of strong_setoids.apart_ne. This is useful because a
StrongSetoid is not defined as a substructure of a FullPartialOrder *)
Instance strict_po_apart_ne x y : PropHolds (x ≶ y) -> PropHolds (x <> y).
#[export] Instance fullpartialorder_strictorder : StrictOrder (<).
intros E;apply lt_iff_le_apart in E.
apply (irreflexivity (≶) x).
Lemma lt_le x y : PropHolds (x < y) -> PropHolds (x ≤ y).
Lemma not_le_not_lt x y : ~(x ≤ y) -> ~(x < y).
Lemma lt_apart x y : x < y -> x ≶ y.
Lemma lt_apart_flip x y : x < y -> y ≶ x.
apply symmetry, lt_iff_le_apart.
Lemma le_not_lt_flip x y : y ≤ x -> ~(x < y).
intros E1 E2;apply lt_iff_le_apart in E2.
destruct E2 as [E2a E2b].
apply (antisymmetry (≤));assumption.
Lemma lt_not_le_flip x y : y < x -> ~(x ≤ y).
apply (le_not_lt_flip y x);assumption.
Lemma lt_le_trans x y z : x < y -> y ≤ z -> x < z.
apply lt_iff_le_apart in E1.
destruct E1 as [E1a E1b].
transitivity y;assumption.
apply (merely_destruct (cotransitive E1b z));intros [E3 | E3]; trivial.
transitivity y;apply lt_iff_le_apart; auto.
Lemma le_lt_trans x y z : x ≤ y -> y < z -> x < z.
apply lt_iff_le_apart in E1.
destruct E1 as [E1a E1b].
apply (merely_destruct (cotransitive E1b x));intros [E3 | E3]; trivial.
transitivity y; apply lt_iff_le_apart; auto.
Lemma lt_iff_le_ne `{!TrivialApart A} x y : x < y <-> x ≤ y /\ x <> y.
transitivity (x <= y /\ apart x y).
split;intros [E1 E2];split;trivial;apply trivial_apart;trivial.
Lemma le_equiv_lt `{!TrivialApart A} `{forall x y : A, Decidable (x = y)} x y
: x ≤ y -> x = y |_| x < y.
destruct (dec (x = y)); try auto.
apply lt_iff_le_ne; auto.
Instance dec_from_lt_dec `{!TrivialApart A} `{forall x y, Decidable (x ≤ y)}
: DecidablePaths A.
destruct (decide_rel (<=) x y) as [E1|E1];
[destruct (decide_rel (<=) y x) as [E2|E2]|].
apply (antisymmetry (<=));assumption.
pattern y; apply (transport _ E3).
Definition lt_dec_slow `{!TrivialApart A} `{forall x y, Decidable (x ≤ y)} :
forall x y, Decidable (x < y).
destruct (dec (x ≤ y));
[destruct (dec (x = y))|].
#[export]
Hint Extern 5 (PropHolds (_ <> _)) =>
eapply @strict_po_apart_ne : typeclass_instances.
#[export]
Hint Extern 10 (PropHolds (_ ≤ _)) =>
eapply @lt_le : typeclass_instances.
#[export]
Hint Extern 20 (Decidable (_ < _)) =>
eapply @lt_dec_slow : typeclass_instances.
Section full_pseudo_order.
Context `{FullPseudoOrder A}.
Local Existing Instance pseudo_order_apart.
Lemma not_lt_le_flip x y : ~(y < x) -> x ≤ y.
apply le_iff_not_lt_flip.
Instance fullpseudo_partial : PartialOrder (≤) | 10.
apply not_lt_le_flip, (irreflexivity (<)).
apply le_iff_not_lt_flip;
apply le_iff_not_lt_flip in E1;
apply le_iff_not_lt_flip in E2.
change (complement (<) z x).
transitivity y;assumption.
apply le_iff_not_lt_flip in E1;
apply le_iff_not_lt_flip in E2.
apply (antisymmetry (complement (<)));assumption.
Lemma fullpseudo_fullpartial' : FullPartialOrder Ale Alt.
apply lt_flip;assumption.
apply pseudo_order_lt_apart.
apply not_lt_apart_lt_flip;[|symmetry;trivial].
apply le_iff_not_lt_flip.
#[export] Instance fullpseudo_fullpartial@{i} : FullPartialOrder Ale Alt
:= ltac:(first [exact fullpseudo_fullpartial'@{i i Set Set Set}|
exact fullpseudo_fullpartial'@{i i}]).
#[export] Instance le_stable : forall x y, Stable (x ≤ y).
apply le_iff_not_lt_flip.
intros E';apply le_iff_not_lt_flip in E';auto.
Lemma le_or_lt `{!TrivialApart A} `{DecidablePaths A} x y : x ≤ y |_| y < x.
destruct (trichotomy (<) x y) as [|[|]]; try auto.
#[export] Instance le_total `{!TrivialApart A} `{DecidablePaths A}
: TotalOrder (≤).
destruct (le_or_lt x y); auto.
Lemma not_le_lt_flip `{!TrivialApart A} `{DecidablePaths A} x y
: ~(y ≤ x) -> x < y.
destruct (le_or_lt y x); auto.
Existing Instance dec_from_lt_dec.
Definition lt_dec `{!TrivialApart A} `{forall x y, Decidable (x ≤ y)}
: forall x y, Decidable (x < y).
destruct (decide_rel (<=) y x).
right;apply le_not_lt_flip;assumption.
left; apply not_le_lt_flip;assumption.
#[export]
Hint Extern 8 (Decidable (_ < _)) => eapply @lt_dec : typeclass_instances.
(*
The following instances would be tempting, but turn out to be a bad idea.
#[export]
Hint Extern 10 (PropHolds (_ <> _)) => eapply @le_ne : typeclass_instances.
#[export]
Hint Extern 10 (PropHolds (_ <> _)) => eapply @le_ne_flip : typeclass_instances.
It will then loop like:
semirings.lt_0_1 -> lt_ne_flip -> ...
*)
Section dec_strict_setoid_order.
Context `{StrictOrder A} `{Apart A} `{!TrivialApart A} `{DecidablePaths A}.
Instance: IsApart A := dec_strong_setoid.
Context `{!Trichotomy (<)}.
Instance dec_strict_pseudo_order: PseudoOrder (<).
destruct (lt_antisym x y); auto.
destruct (trichotomy (<) x z) as [? | [Exz | Exz]];apply tr; try auto.
transitivity (x <> y);[split;apply trivial_apart|].
destruct (trichotomy (<) x y) as [?|[?|?]]; auto.
intros E;contradiction E.
intros [?|?];[apply lt_ne|apply lt_ne_flip];trivial.
End dec_strict_setoid_order.
Section dec_partial_order.
Context `{PartialOrder A} `{DecidablePaths A}.
Definition dec_lt: Lt A := fun x y => x ≤ y /\ x <> y.
Context `{Alt : Lt A} `{is_mere_relation A lt}
(lt_correct : forall x y, x < y <-> x ≤ y /\ x <> y).
Instance dec_order: StrictOrder (<).
destruct E as [_ []];trivial.
apply lt_correct;
apply lt_correct in E1;
apply lt_correct in E2.
destruct E1 as [E1a E1b],E2 as [E2a E2b].
apply (antisymmetry (≤)); trivial.
Context `{Apart A} `{!TrivialApart A}.
Instance: IsApart A := dec_strong_setoid.
Instance dec_full_partial_order: FullPartialOrder (≤) (<).
transitivity (x <= y /\ x <> y);[|
split;intros [? ?];split;trivial;apply trivial_apart;trivial].
Context `{!TotalRelation (≤)}.
Instance: Trichotomy (<).
destruct (dec (x = y)); try auto.
destruct (total (≤) x y);[left|right;right];
apply lt_correct;auto.
intro E;apply symmetry in E;auto.
Instance dec_pseudo_order: PseudoOrder (<) := dec_strict_pseudo_order.
Instance dec_full_pseudo_order: FullPseudoOrder (≤) (<).
apply lt_correct in E;destruct E as [? []].
apply (antisymmetry (≤));assumption.
destruct (total (≤) x y); trivial.
destruct (dec (x = y)) as [E2|E2].
apply lt_correct;split;auto.
apply symmetric_neq;assumption.
Lemma lt_eq_trans `{Lt A} : forall x y z, x < y -> y = z -> x < z.
Context `{PseudoOrder A}.
Lemma nlt_lt_trans {x y z : A} : ~ (y < x) -> y < z -> x < z.
assert (disj := cotransitive ltyz x).
destruct disj as [ltyx|ltxz].
Lemma lt_nlt_trans {x y z : A} : x < y -> ~ (z < y) -> x < z.
assert (disj := cotransitive ltxy z).
destruct disj as [ltxz|ltzy].
Lemma lt_transitive : Transitive (_ : Lt A).
assert (ltxyz := cotransitive ltxy z).
destruct ltxyz as [ltxz|ltzy].
destruct (pseudo_order_antisym y z (ltyz , ltzy)).
#[export] Existing Instance lt_transitive.