Load loadpath.
Definition StrictCompSpec {A} (eq lt: A -> A -> Prop)
(cmp: A -> A -> comparison) :=
StrictOrder lt /\ forall x y, CompSpec eq lt x y (cmp x y).
Definition CompSpec' {A} (cmp: A -> A -> comparison) :=
StrictCompSpec (@Logic.eq A) (fun x y => Lt = cmp x y) cmp.
Ltac do_comp cspec x y := destruct (CompSpec2Type (proj2 cspec x y)).
Definition isGe (c: comparison) := match c with Lt => False | _ => True end.
Definition isGeq cc := match cc with Lt => false | _ => true end.
Fixpoint insert {A: Type} (cmp: A -> A -> comparison) (a: A) (l: list A)
: list A:=
match l with
| h :: t => if isGeq (cmp a h)
then a :: l
else h :: (insert cmp a t)
| nil => a :: nil
end.
Fixpoint rsort {A: Type} (cmp: A -> A -> comparison) (l: list A) : list A :=
match l with nil => nil | h::t => insert cmp h (rsort cmp t)
end.
Fixpoint insert_uniq {A: Type} (cmp: A -> A -> comparison) (a: A) (l: list A)
: list A:=
match l with
| h :: t => match cmp a h with
| Eq => l
| Gt => a :: l
| Lt => h :: (insert_uniq cmp a t)
end
| nil => a::nil
end.
Fixpoint rsort_uniq {A: Type} (cmp: A -> A -> comparison) (l: list A)
: list A :=
match l with nil => nil | h::t => insert_uniq cmp h (rsort_uniq cmp t)
end.

(*put somewhere else, maybe in datatypes.v*)
Lemma perm_insert {T} cmp (a : T) l : Permutation (insert cmp a l) (a :: l).