diff options
Diffstat (limited to 'theories/Arith/Compare_dec.v')
-rw-r--r-- | theories/Arith/Compare_dec.v | 230 |
1 files changed, 142 insertions, 88 deletions
diff --git a/theories/Arith/Compare_dec.v b/theories/Arith/Compare_dec.v index e6cb5be4..8fc92579 100644 --- a/theories/Arith/Compare_dec.v +++ b/theories/Arith/Compare_dec.v @@ -6,7 +6,7 @@ (* * GNU Lesser General Public License Version 2.1 *) (************************************************************************) -(*i $Id: Compare_dec.v 10295 2007-11-06 22:46:21Z letouzey $ i*) +(*i $Id$ i*) Require Import Le. Require Import Lt. @@ -18,20 +18,24 @@ Open Local Scope nat_scope. Implicit Types m n x y : nat. Definition zerop n : {n = 0} + {0 < n}. +Proof. destruct n; auto with arith. Defined. -Definition lt_eq_lt_dec n m : {n < m} + {n = m} + {m < n}. - induction n; simple destruct m; auto with arith. - intros m0; elim (IHn m0); auto with arith. - induction 1; auto with arith. +Definition lt_eq_lt_dec : forall n m, {n < m} + {n = m} + {m < n}. +Proof. + induction n; destruct m; auto with arith. + destruct (IHn m) as [H|H]; auto with arith. + destruct H; auto with arith. Defined. -Definition gt_eq_gt_dec n m : {m > n} + {n = m} + {n > m}. - exact lt_eq_lt_dec. +Definition gt_eq_gt_dec : forall n m, {m > n} + {n = m} + {n > m}. +Proof. + intros; apply lt_eq_lt_dec; assumption. Defined. -Definition le_lt_dec n m : {n <= m} + {m < n}. +Definition le_lt_dec : forall n m, {n <= m} + {m < n}. +Proof. induction n. auto with arith. destruct m. @@ -40,43 +44,68 @@ Definition le_lt_dec n m : {n <= m} + {m < n}. Defined. Definition le_le_S_dec n m : {n <= m} + {S m <= n}. - exact le_lt_dec. +Proof. + intros; exact (le_lt_dec n m). Defined. Definition le_ge_dec n m : {n <= m} + {n >= m}. +Proof. intros; elim (le_lt_dec n m); auto with arith. Defined. Definition le_gt_dec n m : {n <= m} + {n > m}. - exact le_lt_dec. +Proof. + intros; exact (le_lt_dec n m). Defined. Definition le_lt_eq_dec n m : n <= m -> {n < m} + {n = m}. - intros; elim (lt_eq_lt_dec n m); auto with arith. +Proof. + intros; destruct (lt_eq_lt_dec n m); auto with arith. intros; absurd (m < n); auto with arith. Defined. +Theorem le_dec : forall n m, {n <= m} + {~ n <= m}. +Proof. + intros n m. destruct (le_gt_dec n m). + auto with arith. + right. apply gt_not_le. assumption. +Defined. + +Theorem lt_dec : forall n m, {n < m} + {~ n < m}. +Proof. + intros; apply le_dec. +Defined. + +Theorem gt_dec : forall n m, {n > m} + {~ n > m}. +Proof. + intros; apply lt_dec. +Defined. + +Theorem ge_dec : forall n m, {n >= m} + {~ n >= m}. +Proof. + intros; apply le_dec. +Defined. + (** Proofs of decidability *) Theorem dec_le : forall n m, decidable (n <= m). Proof. - intros x y; unfold decidable in |- *; elim (le_gt_dec x y); - [ auto with arith | intro; right; apply gt_not_le; assumption ]. + intros n m; destruct (le_dec n m); unfold decidable; auto. Qed. Theorem dec_lt : forall n m, decidable (n < m). Proof. - intros x y; unfold lt in |- *; apply dec_le. + intros; apply dec_le. Qed. Theorem dec_gt : forall n m, decidable (n > m). Proof. - intros x y; unfold gt in |- *; apply dec_lt. + intros; apply dec_lt. Qed. Theorem dec_ge : forall n m, decidable (n >= m). Proof. - intros x y; unfold ge in |- *; apply dec_le. + intros; apply dec_le. Qed. Theorem not_eq : forall n m, n <> m -> n < m \/ m < n. @@ -107,86 +136,111 @@ Qed. Theorem not_lt : forall n m, ~ n < m -> n >= m. Proof. - intros x y H; exact (not_gt y x H). + intros x y H; exact (not_gt y x H). 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. + +Lemma nat_compare_spec : forall x y, CompSpec eq lt x y (nat_compare x y). +Proof. + intros. + destruct (nat_compare x y) as [ ]_eqn; constructor. + apply nat_compare_eq; auto. + apply <- nat_compare_lt; auto. + apply <- nat_compare_gt; auto. +Qed. + + +(** Some projections of the above equivalences. *) + +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 +254,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. |