Fixpoint nodup (l : list A) : list A :=
    match l with
      | [] => []
      | x::xs => if in_dec decA x xs then nodup xs else x::(nodup xs)
    end.

(* Specifications: *)
Lemma nodup_fixed_point (l : list A) : NoDup l -> nodup l = l.
Lemma nodup_In l x : In x (nodup l) <-> In x l.
Lemma nodup_incl l1 l2 : incl l1 (nodup l2) <-> incl l1 l2.
Lemma NoDup_nodup l: NoDup (nodup l).
Lemma nodup_inv k l a : nodup k = a :: l -> ~ In a l.
Theorem NoDup_count_occ l: NoDup l <-> (forall x:A, count_occ decA l x <= 1).
Theorem NoDup_count_occ' l: NoDup l <-> (forall x:A, In x l -> count_occ decA l x = 1).
Lemma NoDup_nth_error l : NoDup l <-> (forall i j, i<length l -> nth_error l i = nth_error l j -> i = j).
Lemma NoDup_nth l d : NoDup l <-> (forall i j, i<length l -> j<length l -> nth i l d = nth j l d -> i = j).
Lemma NoDup_incl_length l l' : NoDup l -> incl l l' -> length l <= length l'.
Lemma NoDup_length_incl l l' : NoDup l -> length l' <= length l -> incl l l' -> incl l' l.
Lemma NoDup_incl_NoDup (l l' : list A) : NoDup l -> length l' <= length l -> incl l l' -> NoDup l'.
Lemma NoDup_map_inv A B (f:A->B) l : NoDup (map f l) -> NoDup l.
Lemma cons_seq : forall len start, start :: seq (S start) len = seq start (S len).
Lemma length_seq : forall len start, length (seq start len) = len.
Lemma seq_nth : forall len start n d, n < len -> nth n (seq start len) d = start+n.
Lemma seq_shift : forall len start, map S (seq start len) = seq (S start) len.
Lemma in_seq len start n : In n (seq start len) <-> start <= n < start+len.
Lemma seq_NoDup len start : NoDup (seq start len).
Lemma seq_app : forall len1 len2 start, seq start (len1 + len2) = seq start len1 ++ seq (start + len1) len2.
Lemma seq_S : forall len start, seq start (S len) = seq start len ++ [start + len].
Lemma skipn_seq n start len : skipn n (seq start len) = seq (start+n) (len-n).
Lemma nth_error_seq start len n : nth_error (seq start len) n = if Nat.ltb n len then Some (start + n) else None.