Module OrderedPair (X:OrderedType) (Y:OrderedType) <: OrderedType with
Definition t := (X.t * Y.t)%type.
Definition t := (X.t * Y.t)%type.
Definition eq (xy1:t) (xy2:t) :=
let (x1,y1) := xy1 in
let (x2,y2) := xy2 in
(X.eq x1 x2) /\ (Y.eq y1 y2).
Definition lt (xy1:t) (xy2:t) :=
let (x1,y1) := xy1 in
let (x2,y2) := xy2 in
(X.lt x1 x2) \/ ((X.eq x1 x2) /\ (Y.lt y1 y2)).
destruct x.
unfold eq.
split;[apply X.eq_refl | apply Y.eq_refl].
Qed.
destruct x;destruct y;unfold eq;intro.
elim H;clear H;intros.
split;[apply X.eq_sym | apply Y.eq_sym];trivial.
Qed.
unfold eq;destruct x;destruct y;destruct z;intros.
elim H;clear H;intros.
elim H0;clear H0;intros.
split;[eapply X.eq_trans | eapply Y.eq_trans];eauto.
Qed.
unfold lt;destruct x;destruct y;destruct z;intros.
case H;clear H;intro.
case H0;clear H0;intro.
left.
eapply X.lt_trans;eauto.
elim H0;clear H0;intros.
left.
case (X.compare t0 t4);trivial;intros.
generalize (X.eq_sym H0);intro.
generalize (X.eq_trans e H2);intro.
elim (X.lt_not_eq H H3).
generalize (X.lt_trans l H);intro.
generalize (X.eq_sym H0);intro.
elim (X.lt_not_eq H2 H3).
elim H;clear H;intros.
case H0;clear H0;intro.
left.
case (X.compare t0 t4);trivial;intros.
generalize (X.eq_sym H);intro.
generalize (X.eq_trans H2 e);intro.
elim (X.lt_not_eq H0 H3).
generalize (X.lt_trans H0 l);intro.
generalize (X.eq_sym H);intro.
elim (X.lt_not_eq H2 H3).
elim H0;clear H0;intros.
right.
split.
eauto.
eauto.
Qed.
unfold lt, eq;destruct x;destruct y;intro;intro.
elim H0;clear H0;intros.
case H.
intro.
apply (X.lt_not_eq H2 H0).
intro.
elim H2;clear H2;intros.
apply (Y.lt_not_eq H3 H1).
Qed.
Definition compare : forall (x y:t),(Compare lt eq x y).
destruct x;destruct y.
case (X.compare t0 t2);intro.
apply LT.
left;trivial.
case (Y.compare t1 t3);intro.
apply LT.
right.
tauto.
apply EQ.
split;trivial.
apply GT.
right;auto.
apply GT.
left;trivial.
Defined.
Definition eq_dec : forall (x y: t), { eq x y } + { ~ eq x y}.
unfold eq;auto.
Qed.

Lemma eq_trans : forall (x y z:t),(eq x y)->(eq y z)->(eq x z).