Section seteq.
Variable X : Type.
(* When viewed as sets, the lists are equivalent, ie closed under perm + contraction + RST *)
Inductive seteq : list X -> list X -> Prop :=
| seteq_nil   : nil ≡ nil
| seteq_skip  : forall x l m, l ≡ m -> x::l ≡ x::m
| seteq_swap  : forall x y l, x::y::l ≡ y::x::l
| seteq_dup   : forall x l, x::x::l ≡ x::l
| seteq_sym   : forall l m, l ≡ m -> m ≡ l
| seteq_trans : forall l m k, l ≡ m -> m ≡ k -> l ≡ k
where "l ≡ m" := (seteq l m).
Hint Constructors seteq : core.
Fact perm_seteq l m : l ~p m -> l ≡ m.

Lemma list_has_dup_seteq l : list_has_dup l -> exists m, m ≡ l /\ length m < length l.