(** * The order tactic *)

(** This tactic is designed to solve systems of (in)equations
    involving [eq], [lt], [le] and [~eq] on some type. This tactic is
    domain-agnostic; it will only use equivalence+order axioms, and
    not analyze elements of the domain. Hypothesis or goal of the form
    [~lt] or [~le] are initially turned into [le] and [lt], other
    parts of the goal are ignored. This initial preparation of the
    goal is the only moment where totality is used. In particular,
    the core of the tactic only proceeds by saturation of transitivity
    and similar properties, and does not perform case splitting.
    The tactic will fail if it doesn't solve the goal. *)


(** An abstract vision of the predicates. This allows a one-line
    statement for interesting transitivity properties: for instance
    [trans_ord OLE OLE = OLE] will imply later
    [le x y -> le y z -> le x z].
*)

Inductive ord : Set := OEQ | OLT | OLE.(** * The order tactic *)

(** This tactic is designed to solve systems of (in)equations
    involving [eq], [lt], [le] and [~eq] on some type. This tactic is
    domain-agnostic; it will only use equivalence+order axioms, and
    not analyze elements of the domain. Hypothesis or goal of the form
    [~lt] or [~le] are initially turned into [le] and [lt], other
    parts of the goal are ignored. This initial preparation of the
    goal is the only moment where totality is used. In particular,
    the core of the tactic only proceeds by saturation of transitivity
    and similar properties, and does not perform case splitting.
    The tactic will fail if it doesn't solve the goal. *)


(** An abstract vision of the predicates. This allows a one-line
    statement for interesting transitivity properties: for instance
    [trans_ord OLE OLE = OLE] will imply later
    [le x y -> le y z -> le x z].
*)

Inductive ord : Set := OEQ | OLT | OLE.(** * The order tactic *)

(** This tactic is designed to solve systems of (in)equations
    involving [eq], [lt], [le] and [~eq] on some type. This tactic is
    domain-agnostic; it will only use equivalence+order axioms, and
    not analyze elements of the domain. Hypothesis or goal of the form
    [~lt] or [~le] are initially turned into [le] and [lt], other
    parts of the goal are ignored. This initial preparation of the
    goal is the only moment where totality is used. In particular,
    the core of the tactic only proceeds by saturation of transitivity
    and similar properties, and does not perform case splitting.
    The tactic will fail if it doesn't solve the goal. *)


(** An abstract vision of the predicates. This allows a one-line
    statement for interesting transitivity properties: for instance
    [trans_ord OLE OLE = OLE] will imply later
    [le x y -> le y z -> le x z].
*)

Inductive ord : Set := OEQ | OLT | OLE.(** * The order tactic *)

(** This tactic is designed to solve systems of (in)equations
    involving [eq], [lt], [le] and [~eq] on some type. This tactic is
    domain-agnostic; it will only use equivalence+order axioms, and
    not analyze elements of the domain. Hypothesis or goal of the form
    [~lt] or [~le] are initially turned into [le] and [lt], other
    parts of the goal are ignored. This initial preparation of the
    goal is the only moment where totality is used. In particular,
    the core of the tactic only proceeds by saturation of transitivity
    and similar properties, and does not perform case splitting.
    The tactic will fail if it doesn't solve the goal. *)


(** An abstract vision of the predicates. This allows a one-line
    statement for interesting transitivity properties: for instance
    [trans_ord OLE OLE = OLE] will imply later
    [le x y -> le y z -> le x z].
*)

Inductive ord : Set := OEQ | OLT | OLE.Definition trans_ord o o' :=
 match o, o' with
 | OEQ, _ => o'
 | _, OEQ => o
 | OLE, OLE => OLE
 | _, _ => OLT
 end.Local Infix "+" := trans_ord.(** ** The tactic requirements : a total order

   We need :
   - an equivalence [eq],
   - a strict order [lt] total and compatible with [eq],
   - a larger order [le] synonym for [lt\/eq].

   This used to be provided here via a [TotalOrder], but
   for technical reasons related to extraction, we now ask
   for two separate parts: relations in a [EqLtLe] + properties in
   [IsTotalOrder]. Note that [TotalOrder = EqLtLe <+ IsTotalOrder]
*)

Module Type IsTotalOrder (O:EqLtLe) :=
 IsEq O <+ IsStrOrder O <+ LeIsLtEq O <+ LtIsTotal O.

Lemma neq_sym : forall x y, ~x==y -> ~y==x.