(** * Perm: Basic Techniques for Permutations and Ordering *)
(** Consider these algorithms and data structures: - sort a sequence of numbers; - finite maps from numbers to (arbitrary-type) data - finite maps from any ordered type to (arbitrary-type) data - priority queues: finding/deleting the highest number in a set  To prove the correctness of such programs, we need to reason about less-than comparisons (for example, on integers) and about "these two sets/sequences have the same contents".  In this chapter, we introduce some techniques for reasoning about: - less-than comparisons on natural numbers - permutations (rearrangements of lists) Then, in later chapters, we'll apply these proof techniques to reasoning about algorithms and data structures. *)
Require Export Coq.Bool.Bool.
Require Export Coq.Arith.Arith.
Require Export Coq.Arith.EqNat.
Require Export Coq.omega.Omega.
Require Export Coq.Lists.List.
Export ListNotations.
Require Export Permutation.
(* ################################################################# *)
(** * The Less-Than Order on the Natural Numbers *)
(** These [Check] and [Locate] commands remind us about _Propositional_ and the _Boolean_ less-than operators in the Coq standard library. *)
Check Nat.lt.        (* : nat -> nat -> Prop *)
Check lt.             (* : nat -> nat -> Prop *)
Goal Nat.lt = lt. Proof. reflexivity. Qed. (* They are the same *)
Check Nat.ltb.       (* : nat -> nat -> bool *)
Locate "_ < _".  (* "x < y" := lt x y *)
Locate "<?".     (* x <? y  := Nat.ltb x y *)
(** We write [x < y] for the Proposition that [x] _is_ less than [y], and we write [x <? y] for the computable _test_ that returns [true] or [false] depending on whether [x<y].  The theorem that [lt] is related in this way to [ltb] is this one: *)
Check Nat.ltb_lt.
(* : forall n m : nat, (n <? m) = true <-> n < m *)
(** For some reason, the Coq library has [ <? ] and [ <=? ] notations, but is missing these three: *)
Notation  "a >=? b" := (Nat.leb b a)
(at level 70, only parsing) : nat_scope.
Notation  "a >? b"  := (Nat.ltb b a)
(at level 70, only parsing) : nat_scope.
Notation " a =? b"  := (beq_nat a b)
(at level 70) : nat_scope.
(* ================================================================= *)
(** ** Relating [Prop] to [bool] *)
(** The [reflect] relation connects a [Proposition] to a [Boolean]. *)
Print reflect.
(** That is, [reflect P b] means that [P<->True] if and only if [b=true]. The way to use [reflect] is, for each of your operators, make a lemma like these next three: *)

(* Specifications: *)
Lemma beq_reflect : forall x y, reflect (x = y) (x =? y).
Lemma blt_reflect : forall x y, reflect (x < y) (x <? y).
Lemma ble_reflect : forall x y, reflect (x <= y) (x <=? y).
Example reflect_example1: forall a, (if a<?5 then a else 2) < 6.