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.

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