# Library Coq.Arith.Compare_dec

Require Import Le.
Require Import Lt.
Require Import Gt.
Require Import Decidable.

Open Local Scope nat_scope.

Implicit Types m n x y : nat.

Definition zerop n : {n = 0} + {0 < n}.
Defined.

Definition lt_eq_lt_dec n m : {n < m} + {n = m} + {m < n}.
Defined.

Definition gt_eq_gt_dec n m : {m > n} + {n = m} + {n > m}.
Defined.

Definition le_lt_dec n m : {n <= m} + {m < n}.
Defined.

Definition le_le_S_dec n m : {n <= m} + {S m <= n}.
Defined.

Definition le_ge_dec n m : {n <= m} + {n >= m}.
Defined.

Definition le_gt_dec n m : {n <= m} + {n > m}.
Defined.

Definition le_lt_eq_dec n m : n <= m -> {n < m} + {n = m}.
Defined.

Proofs of decidability

Theorem dec_le : forall n m, decidable (n <= m).

Theorem dec_lt : forall n m, decidable (n < m).

Theorem dec_gt : forall n m, decidable (n > m).

Theorem dec_ge : forall n m, decidable (n >= m).

Theorem not_eq : forall n m, n <> m -> n < m \/ m < n.

Theorem not_le : forall n m, ~ n <= m -> n > m.

Theorem not_gt : forall n m, ~ n > m -> n <= m.

Theorem not_ge : forall n m, ~ n >= m -> n < m.

Theorem not_lt : forall n m, ~ n < m -> n >= m.

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
end.

Lemma nat_compare_S : forall n m, nat_compare (S n) (S m) = nat_compare n m.

Lemma nat_compare_eq : forall n m, nat_compare n m = Eq -> n = m.

Lemma nat_compare_lt : forall n m, n<m <-> nat_compare n m = Lt.

Lemma nat_compare_gt : forall n m, n>m <-> nat_compare n m = Gt.

Lemma nat_compare_le : forall n m, n<=m <-> nat_compare n m <> Gt.

Lemma nat_compare_ge : forall n m, n>=m <-> nat_compare n m <> Lt.

A boolean version of le over nat.

Fixpoint leb (m:nat) : nat -> bool :=
match m with
| O => fun _:nat => true
| S m' =>
fun n:nat => match n with
| O => false
| S n' => leb m' n'
end
end.

Lemma leb_correct : forall m n:nat, m <= n -> leb m n = true.

Lemma leb_complete : forall m n:nat, leb m n = true -> m <= n.

Lemma leb_correct_conv : forall m n:nat, m < n -> leb n m = false.

Lemma leb_complete_conv : forall m n:nat, leb n m = false -> m < n.

Lemma leb_compare : forall n m, leb n m = true <-> nat_compare n m <> Gt.