Section ordered.
Variable A : Type.
Variable order : A -> A -> Prop.
Variable order_trans : forall a b c : A, order a b -> order b c -> order a c.
(* Ordered list with respect to an order *)
Inductive ordered : list A -> Prop :=
| ordered_nil : ordered nil
| ordered_one : forall a : A, ordered (a :: nil)
| ordered_cons :
forall (a b : A) (l : list A),
order a b -> ordered (b :: l) -> ordered (a :: b :: l).
Hint Constructors ordered : core.
Proof using.
intros a b l H; inversion H; auto.
Qed.
Proof using.
intros a l H; inversion H; auto.
Qed.
Proof using A order order_trans.
intros a b l; case l; clear l; auto.
intros c l H; apply ordered_cons.
apply order_trans with (b := b); auto.
apply ordered_inv_order with (1 := H).
apply ordered_inv_order with (1 := ordered_inv _ _ H).
apply ordered_inv with (1 := ordered_inv _ _ H).
Qed.
Proof using A order order_trans.
intros a b l; generalize a b; elim l; clear l a b.
intros a b H H2; inversion H2.
simpl in |- *; intros c l H a b H0 [H1| H1].
rewrite <- H1; apply ordered_inv_order with (1 := H0).
apply order_trans with (b := c); auto.
apply ordered_inv_order with (1 := H0).
apply H; auto.
apply ordered_inv with (1 := H0).
Qed.
Proof using A order order_trans.
intros a b l1 l2; generalize a b; elim l1; simpl in |- *; clear l1 a b.
intros a b H H1; case H1.
intros c l H a b H0 [H1| H1] H2.
rewrite <- H1; apply ordered_trans with (1 := H0); auto with datatypes.
apply H; auto.
apply ordered_inv with (1 := H0); auto.
Qed.

(* If the order is antisymmetric, there is only one ordered list *)
Theorem ordered_perm_antisym_eq :
(forall a b : A, order a b -> order b a -> a = b) ->
forall l1 l2 : list A,
permutation l1 l2 -> ordered l1 -> ordered l2 -> l1 = l2.