(***********************************************************************) (* v * The Coq Proof Assistant / The Coq Development Team *) (* t -> Prop. Definition eq_refl := @refl_equal t. Definition eq_sym := @sym_eq t. Definition eq_trans := @trans_eq t. Axiom lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z. Axiom lt_not_eq : forall x y : t, lt x y -> ~ eq x y. Parameter compare : forall x y : t, Compare lt eq x y. End UsualOrderedType. (** a [UsualOrderedType] is in particular an [OrderedType]. *) Module UOT_to_OT (U:UsualOrderedType) <: OrderedType := U. (** [nat] is an ordered type with respect to the usual order on natural numbers. *) Module Nat_as_OT <: UsualOrderedType. Definition t := nat. Definition eq := @eq nat. Definition eq_refl := @refl_equal t. Definition eq_sym := @sym_eq t. Definition eq_trans := @trans_eq t. Definition lt := lt. Lemma lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z. Proof. unfold lt in |- *; intros; apply lt_trans with y; auto. Qed. Lemma lt_not_eq : forall x y : t, lt x y -> ~ eq x y. Proof. unfold lt, eq in |- *; intros; omega. Qed. Definition compare : forall x y : t, Compare lt eq x y. Proof. intros; case (lt_eq_lt_dec x y). simple destruct 1; intro. constructor 1; auto. constructor 2; auto. intro; constructor 3; auto. Defined. End Nat_as_OT. (** [Z] is an ordered type with respect to the usual order on integers. *) Open Local Scope Z_scope. Module Z_as_OT <: UsualOrderedType. Definition t := Z. Definition eq := @eq Z. Definition eq_refl := @refl_equal t. Definition eq_sym := @sym_eq t. Definition eq_trans := @trans_eq t. Definition lt (x y:Z) := (x y x ~ x=y. Proof. intros; omega. Qed. Definition compare : forall x y, Compare lt eq x y. Proof. intros x y; case_eq (x ?= y); intros. apply EQ; unfold eq; apply Zcompare_Eq_eq; auto. apply LT; unfold lt, Zlt; auto. apply GT; unfold lt, Zlt; rewrite <- Zcompare_Gt_Lt_antisym; auto. Defined. End Z_as_OT. (** [positive] is an ordered type with respect to the usual order on natural numbers. *) Open Local Scope positive_scope. Module Positive_as_OT <: UsualOrderedType. Definition t:=positive. Definition eq:=@eq positive. Definition eq_refl := @refl_equal t. Definition eq_sym := @sym_eq t. Definition eq_trans := @trans_eq t. Definition lt p q:= (p ?= q) Eq = Lt. Lemma lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z. Proof. unfold lt; intros x y z. change ((Zpos x < Zpos y)%Z -> (Zpos y < Zpos z)%Z -> (Zpos x < Zpos z)%Z). omega. Qed. Lemma lt_not_eq : forall x y : t, lt x y -> ~ eq x y. Proof. intros; intro. rewrite H0 in H. unfold lt in H. rewrite Pcompare_refl in H; discriminate. Qed. Definition compare : forall x y : t, Compare lt eq x y. Proof. intros x y. case_eq ((x ?= y) Eq); intros. apply EQ; apply Pcompare_Eq_eq; auto. apply LT; unfold lt; auto. apply GT; unfold lt. replace Eq with (CompOpp Eq); auto. rewrite <- Pcompare_antisym; rewrite H; auto. Defined. End Positive_as_OT. (** [N] is an ordered type with respect to the usual order on natural numbers. *) Open Local Scope positive_scope. Module N_as_OT <: UsualOrderedType. Definition t:=N. Definition eq:=@eq N. Definition eq_refl := @refl_equal t. Definition eq_sym := @sym_eq t. Definition eq_trans := @trans_eq t. Definition lt p q:= Nle q p = false. Definition lt_trans := Nlt_trans. Lemma lt_not_eq : forall x y : t, lt x y -> ~ eq x y. Proof. intros; intro. rewrite H0 in H. unfold lt in H. rewrite Nle_refl in H; discriminate. Qed. Definition compare : forall x y : t, Compare lt eq x y. Proof. intros x y. case_eq ((x ?= y)%N); intros. apply EQ; apply Ncompare_Eq_eq; auto. apply LT; unfold lt; auto. generalize (Nle_Ncompare y x). destruct (Nle y x); auto. rewrite <- Ncompare_antisym. destruct (x ?= y)%N; simpl; try discriminate. intros (H0,_); elim H0; auto. apply GT; unfold lt. generalize (Nle_Ncompare x y). destruct (Nle x y); auto. destruct (x ?= y)%N; simpl; try discriminate. intros (H0,_); elim H0; auto. Defined. End N_as_OT. (** From two ordered types, we can build a new OrderedType over their cartesian product, using the lexicographic order. *) Module PairOrderedType(O1 O2:OrderedType) <: OrderedType. Module MO1:=OrderedTypeFacts(O1). Module MO2:=OrderedTypeFacts(O2). Definition t := prod O1.t O2.t. Definition eq x y := O1.eq (fst x) (fst y) /\ O2.eq (snd x) (snd y). Definition lt x y := O1.lt (fst x) (fst y) \/ (O1.eq (fst x) (fst y) /\ O2.lt (snd x) (snd y)). Lemma eq_refl : forall x : t, eq x x. Proof. intros (x1,x2); red; simpl; auto. Qed. Lemma eq_sym : forall x y : t, eq x y -> eq y x. Proof. intros (x1,x2) (y1,y2); unfold eq; simpl; intuition. Qed. Lemma eq_trans : forall x y z : t, eq x y -> eq y z -> eq x z. Proof. intros (x1,x2) (y1,y2) (z1,z2); unfold eq; simpl; intuition eauto. Qed. Lemma lt_trans : forall x y z : t, lt x y -> lt y z -> lt x z. Proof. intros (x1,x2) (y1,y2) (z1,z2); unfold eq, lt; simpl; intuition. left; eauto. left; eapply MO1.lt_eq; eauto. left; eapply MO1.eq_lt; eauto. right; split; eauto. Qed. Lemma lt_not_eq : forall x y : t, lt x y -> ~ eq x y. Proof. intros (x1,x2) (y1,y2); unfold eq, lt; simpl; intuition. apply (O1.lt_not_eq H0 H1). apply (O2.lt_not_eq H3 H2). Qed. Definition compare : forall x y : t, Compare lt eq x y. intros (x1,x2) (y1,y2). destruct (O1.compare x1 y1). apply LT; unfold lt; auto. destruct (O2.compare x2 y2). apply LT; unfold lt; auto. apply EQ; unfold eq; auto. apply GT; unfold lt; auto. apply GT; unfold lt; auto. Defined. End PairOrderedType.