Section first_definitions.
Variable A : Type.
Hypothesis Aeq_dec : forall x y:A, {x = y} + {x <> y}.
Definition set := list A.
Definition empty_set : set := nil.
Fixpoint set_add (a:A) (x:set) : set :=
match x with
| nil => a :: nil
| a1 :: x1 =>
match Aeq_dec a a1 with
| left _ => a1 :: x1
| right _ => a1 :: set_add a x1
end
end.
Fixpoint set_mem (a:A) (x:set) : bool :=
match x with
| nil => false
| a1 :: x1 =>
match Aeq_dec a a1 with
| left _ => true
| right _ => set_mem a x1
end
end.
(** If [a] belongs to [x], removes [a] from [x]. If not, does nothing. Invariant: any element should occur at most once in [x], see for instance [set_add]. We hence remove here only the first occurrence of [a] in [x]. *)
Fixpoint set_remove (a:A) (x:set) : set :=
match x with
| nil => empty_set
| a1 :: x1 =>
match Aeq_dec a a1 with
| left _ => x1
| right _ => a1 :: set_remove a x1
end
end.
Fixpoint set_inter (x:set) : set -> set :=
match x with
| nil => fun y => nil
| a1 :: x1 =>
fun y =>
if set_mem a1 y then a1 :: set_inter x1 y else set_inter x1 y
end.
Fixpoint set_union (x y:set) : set :=
match y with
| nil => x
| a1 :: y1 => set_add a1 (set_union x y1)
end.
(** returns the set of all els of [x] that does not belong to [y] *)
Fixpoint set_diff (x y:set) : set :=
match x with
| nil => nil
| a1 :: x1 =>
if set_mem a1 y then set_diff x1 y else set_add a1 (set_diff x1 y)
end.
Definition set_In : A -> set -> Prop := In (A:=A).
Hint Resolve set_add_intro1 set_add_intro2 : core.
intros a b x H; case (set_add_elim _ _ _ H); intros; trivial.
case H1; trivial.
Qed.
Hint Resolve set_add_intro set_add_elim set_add_elim2 : core.
Hint Resolve set_union_intro2 set_union_intro1 : core.
intros a x H; case (set_union_elim _ _ _ H); auto || contradiction.
Qed.
intros a x H; case (set_union_elim _ _ _ H); auto || contradiction.
Qed.
Hint Resolve set_inter_elim1 set_inter_elim2 : core.
intros a x y; elim x; simpl.
intros; contradiction.
intros a0 l Hrec.
apply set_mem_ind2; auto.
intros H1 H2; case (set_add_elim _ _ _ H2); intros; auto.
rewrite H; trivial.
Qed.

Lemma set_diff_nodup l l' : NoDup l -> NoDup l' -> NoDup (set_diff l l').