diff options
author | letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2009-07-22 16:24:37 +0000 |
---|---|---|
committer | letouzey <letouzey@85f007b7-540e-0410-9357-904b9bb8a0f7> | 2009-07-22 16:24:37 +0000 |
commit | 810d1013f4e554bacd096800d4282c239ed59455 (patch) | |
tree | a1cb1c85941cc8d393fac8b499b56b60511e2ccb /theories/Arith/Compare_dec.v | |
parent | d516c922b388411c46f9046ffe6df99b4061f33b (diff) |
Better comparison functions in OrderedTypeEx
The compare functions are still functions-by-tactics, but now their
computational parts are completely pure (no use of lt_eq_lt_dec in
nat_compare anymore), while their proofs parts are simply calls
to (opaque) lemmas. This seem to improve the efficiency of sets/maps,
as mentionned by T. Braibant, D. Pous and S. Lescuyer.
The earlier version of nat_compare is now called nat_compare_alt,
there is a proof of equivalence named nat_compare_equiv.
By the way, various improvements of proofs, in particular in Pnat.
git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/coq/trunk@12247 85f007b7-540e-0410-9357-904b9bb8a0f7
Diffstat (limited to 'theories/Arith/Compare_dec.v')
-rw-r--r-- | theories/Arith/Compare_dec.v | 157 |
1 files changed, 86 insertions, 71 deletions
diff --git a/theories/Arith/Compare_dec.v b/theories/Arith/Compare_dec.v index ac44586c1..573f54e9f 100644 --- a/theories/Arith/Compare_dec.v +++ b/theories/Arith/Compare_dec.v @@ -113,80 +113,95 @@ Qed. (** A ternary comparison function in the spirit of [Zcompare]. *) -Definition nat_compare (n m:nat) := - match lt_eq_lt_dec n m with - | inleft (left _) => Lt - | inleft (right _) => Eq - | inright _ => Gt +Fixpoint nat_compare n m := + match n, m with + | O, O => Eq + | O, S _ => Lt + | S _, O => Gt + | S n', S m' => nat_compare n' m' end. Lemma nat_compare_S : forall n m, nat_compare (S n) (S m) = nat_compare n m. Proof. - unfold nat_compare; intros. - simpl; destruct (lt_eq_lt_dec n m) as [[H|H]|H]; simpl; auto. + reflexivity. +Qed. + +Lemma nat_compare_eq_iff : forall n m, nat_compare n m = Eq <-> n = m. +Proof. + induction n; destruct m; simpl; split; auto; try discriminate; + destruct (IHn m); auto. Qed. Lemma nat_compare_eq : forall n m, nat_compare n m = Eq -> n = m. Proof. - induction n; destruct m; simpl; auto. - unfold nat_compare; destruct (lt_eq_lt_dec 0 (S m)) as [[H|H]|H]; - auto; intros; try discriminate. - unfold nat_compare; destruct (lt_eq_lt_dec (S n) 0) as [[H|H]|H]; - auto; intros; try discriminate. - rewrite nat_compare_S; auto. + intros; apply -> nat_compare_eq_iff; auto. Qed. Lemma nat_compare_lt : forall n m, n<m <-> nat_compare n m = Lt. Proof. - induction n; destruct m; simpl. - unfold nat_compare; simpl; intuition; [inversion H | discriminate H]. - split; auto with arith. - split; [inversion 1 |]. - unfold nat_compare; destruct (lt_eq_lt_dec (S n) 0) as [[H|H]|H]; - auto; intros; try discriminate. - rewrite nat_compare_S. - generalize (IHn m); clear IHn; intuition. + induction n; destruct m; simpl; split; auto with arith; + try solve [inversion 1]. + destruct (IHn m); auto with arith. + destruct (IHn m); auto with arith. Qed. Lemma nat_compare_gt : forall n m, n>m <-> nat_compare n m = Gt. Proof. - induction n; destruct m; simpl. - unfold nat_compare; simpl; intuition; [inversion H | discriminate H]. - split; [inversion 1 |]. - unfold nat_compare; destruct (lt_eq_lt_dec 0 (S m)) as [[H|H]|H]; - auto; intros; try discriminate. - split; auto with arith. - rewrite nat_compare_S. - generalize (IHn m); clear IHn; intuition. + induction n; destruct m; simpl; split; auto with arith; + try solve [inversion 1]. + destruct (IHn m); auto with arith. + destruct (IHn m); auto with arith. Qed. Lemma nat_compare_le : forall n m, n<=m <-> nat_compare n m <> Gt. Proof. split. - intros. - intro. - destruct (nat_compare_gt n m). - generalize (le_lt_trans _ _ _ H (H2 H0)). - exact (lt_irrefl n). - intros. - apply not_gt. - contradict H. - destruct (nat_compare_gt n m); auto. -Qed. + intros LE; contradict LE. + apply lt_not_le. apply <- nat_compare_gt; auto. + intros NGT. apply not_lt. contradict NGT. + apply -> nat_compare_gt; auto. +Qed. Lemma nat_compare_ge : forall n m, n>=m <-> nat_compare n m <> Lt. Proof. split. - intros. - intro. - destruct (nat_compare_lt n m). - generalize (le_lt_trans _ _ _ H (H2 H0)). - exact (lt_irrefl m). - intros. - apply not_lt. - contradict H. - destruct (nat_compare_lt n m); auto. -Qed. + intros GE; contradict GE. + apply lt_not_le. apply <- nat_compare_lt; auto. + intros NLT. apply not_lt. contradict NLT. + apply -> nat_compare_lt; auto. +Qed. + +(** Some projections of the above equivalences, used in OrderedTypeEx. *) + +Lemma nat_compare_Lt_lt : forall n m, nat_compare n m = Lt -> n<m. +Proof. + intros; apply <- nat_compare_lt; auto. +Qed. + +Lemma nat_compare_Gt_gt : forall n m, nat_compare n m = Gt -> n>m. +Proof. + intros; apply <- nat_compare_gt; auto. +Qed. + +(** A previous definition of [nat_compare] in terms of [lt_eq_lt_dec]. + The new version avoids the creation of proof parts. *) + +Definition nat_compare_alt (n m:nat) := + match lt_eq_lt_dec n m with + | inleft (left _) => Lt + | inleft (right _) => Eq + | inright _ => Gt + end. + +Lemma nat_compare_equiv: forall n m, + nat_compare n m = nat_compare_alt n m. +Proof. + intros; unfold nat_compare_alt; destruct lt_eq_lt_dec as [[LT|EQ]|GT]. + apply -> nat_compare_lt; auto. + apply <- nat_compare_eq_iff; auto. + apply -> nat_compare_gt; auto. +Qed. + (** A boolean version of [le] over [nat]. *) @@ -200,48 +215,48 @@ Fixpoint leb (m:nat) : nat -> bool := end end. -Lemma leb_correct : forall m n:nat, m <= n -> leb m n = true. +Lemma leb_correct : forall m n, m <= n -> leb m n = true. Proof. induction m as [| m IHm]. trivial. destruct n. intro H. elim (le_Sn_O _ H). intros. simpl in |- *. apply IHm. apply le_S_n. assumption. Qed. -Lemma leb_complete : forall m n:nat, leb m n = true -> m <= n. +Lemma leb_complete : forall m n, leb m n = true -> m <= n. Proof. induction m. trivial with arith. destruct n. intro H. discriminate H. auto with arith. Qed. -Lemma leb_correct_conv : forall m n:nat, m < n -> leb n m = false. +Lemma leb_iff : forall m n, leb m n = true <-> m <= n. Proof. - intros. + split; auto using leb_correct, leb_complete. +Qed. + +Lemma leb_correct_conv : forall m n, m < n -> leb n m = false. +Proof. + intros. generalize (leb_complete n m). destruct (leb n m); auto. - intros. - elim (lt_irrefl _ (lt_le_trans _ _ _ H (H0 (refl_equal true)))). + intros; elim (lt_not_le m n); auto. Qed. -Lemma leb_complete_conv : forall m n:nat, leb n m = false -> m < n. +Lemma leb_complete_conv : forall m n, leb n m = false -> m < n. Proof. - intros. elim (le_or_lt n m). intro. conditional trivial rewrite leb_correct in H. discriminate H. - trivial. + intros m n EQ. apply not_le. + intro LE. apply leb_correct in LE. rewrite LE in EQ; discriminate. +Qed. + +Lemma leb_iff_conv : forall m n, leb n m = false <-> m < n. +Proof. + split; auto using leb_complete_conv, leb_correct_conv. Qed. Lemma leb_compare : forall n m, leb n m = true <-> nat_compare n m <> Gt. Proof. - induction n; destruct m; simpl. - unfold nat_compare; simpl. - intuition; discriminate. - split; auto with arith. - unfold nat_compare; destruct (lt_eq_lt_dec 0 (S m)) as [[H|H]|H]; - intuition; try discriminate. - inversion H. - split; try (intros; discriminate). - unfold nat_compare; destruct (lt_eq_lt_dec (S n) 0) as [[H|H]|H]; - intuition; try discriminate. - inversion H. - rewrite nat_compare_S; auto. -Qed. + split; intros. + apply -> nat_compare_le. auto using leb_complete. + apply leb_correct. apply <- nat_compare_le; auto. +Qed. |