End Dupfree.
Section Undup.
Variable X : Type.
Context {eq_X_dec : eq_dec X}.
Implicit Types A B : list X.
Fixpoint undup (A : list X) : list X :=
match A with
| nil => nil
| x::A' => if decision (x el A') then undup A' else  x :: undup A'
end.

(* Specifications: *)
Lemma undup_fp_equi A :
undup A === A.
Lemma dupfree_undup A :
dupfree (undup A).
Lemma undup_incl A B :
A <<= B <-> undup A <<= undup B.
Lemma undup_equi A B :
A === B <-> undup A === undup B.
Lemma undup_eq A :
dupfree A -> undup A = A.
Lemma undup_idempotent A :
undup (undup A) = undup A.
Lemma dupfree_le A B :
dupfree A -> dupfree B -> A <<= B -> |A| <= |B|.
Lemma dupfree_eq A B :
dupfree A -> dupfree B -> A === B -> |A|=|B|.
Lemma dupfree_lt A B x :
dupfree A -> dupfree B -> A <<= B ->
x el B -> ~ x el A  -> |A| < |B|.
Lemma dupfree_ex A B :
eq_dec X -> dupfree A -> dupfree B -> |A| < |B| -> exists x, x el B /\ ~ x el A.
Lemma dupfree_equi A B :
eq_dec X -> dupfree A -> dupfree B -> A <<= B -> |A|=|B| -> A === B.