intros a b; case (D.lt_eq_lt_dec a b).
intro d; case d; auto.
left; apply D.lt_le_weak; trivial.
simple induction 1; left; apply le_refl.
right; trivial.
Defined.
Definition le_lt_eq_dec : forall a b : A, le a b -> {lt a b} + {a = b}.
intros a b H.
case (D.lt_eq_lt_dec a b).
trivial.
intro H0; case (le_not_lt a b H H0).
Defined.
End More_Dec_Orders.
(* the forgetful functor ! *)
Module Forget_Order (D: DEC_ORDER) : KEY with Definition A := D.A.
Module M := More_Dec_Orders D.
Definition A := D.A.
Definition eqdec : forall a b : A, {a = b} + {a <> b}.
intros a b; case (D.lt_eq_lt_dec a b).
intro H; case H.
right; apply D.lt_diff; auto.
left; trivial.
intro d; right.
intro e; rewrite e in d.
apply (M.lt_irreflexive b); auto.
Defined.
End Forget_Order.
(* Lexicographic ordering *)
Module Lexico (D1: DEC_ORDER) (D2: DEC_ORDER) <: DEC_ORDER with Definition
A := (D1.A * D2.A)%type.
Module M1 := More_Dec_Orders D1.
Module M2 := More_Dec_Orders D2.
Definition A := (D1.A * D2.A)%type.
Definition le (a b : A) : Prop :=
let (a1, a2) := a in
let (b1, b2) := b in D1.lt a1 b1 \/ a1 = b1 /\ D2.le a2 b2.
Definition lt (a b : A) : Prop :=
let (a1, a2) := a in
let (b1, b2) := b in D1.lt a1 b1 \/ a1 = b1 /\ D2.lt a2 b2.

(* Specifications: *)
Theorem ordered : order A le.
Theorem lt_le_weak : forall a b : A, lt a b -> le a b.
Theorem lt_diff : forall a b : A, lt a b -> a <> b.
Theorem le_lt_or_eq : forall a b : A, le a b -> lt a b \/ a = b.
Definition lt_eq_lt_dec : forall a b : A, {lt a b} + {a = b} + {lt b a}.
Theorem lt_le_weak : forall a b : A, lt a b -> le a b.
Theorem lt_diff : forall a b : A, lt a b -> a <> b.
Theorem le_lt_or_eq : forall a b : A, le a b -> lt a b \/ a = b.
Definition lt_eq_lt_dec : forall a b : A, {lt a b} + {a = b} + {lt b a}.