Section first_definitions.
Variable A : Set.
Hypothesis Aeq_dec : forall x y : A, {x = y} + {x <> y}.
Definition set := list A.
Definition empty_set := nil (A:=A).
Fixpoint set_add (a : A) (x : set) {struct x} : 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) {struct x} : 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 *)
Fixpoint set_remove (a : A) (x : set) {struct x} : set :=
match x with
| nil => empty_set
| a1 :: x1 =>
match Aeq_dec a a1 with
| left _ => set_remove a x1
| right _ => a1 :: set_remove a x1
end
end.
Fixpoint set_inter (x : set) : set -> set :=
match x with
| nil => fun y => nil (A:=A)
| 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) {struct y} : 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 : set) : set -> set :=
fun y =>
match x with
| nil => nil (A:=A)
| a1 :: x1 =>
if set_mem a1 y then set_diff x1 y else set_add a1 (set_diff x1 y)
end.
(** Inductive set_In : A -> set -> Prop := set_In_singl : (a:A)(x:set)(set_In a (cons a (nil A))) | set_In_add : (a,b:A)(x:set)(set_In a x)->(set_In a (set_add b x)) . **)
Definition set_In : A -> set -> Prop := In (A:=A).
intro; intro.
induction  B as [| a B HrecB].
auto.
simpl in |- *.
elim (Aeq_dec x a).
intro.
unfold not in |- *.
unfold not in HrecB.
intro.
apply HrecB; auto.
intro.
unfold not in |- *.
unfold not in HrecB.
simpl in |- *.
intro.
elim H.
intro.
cut (a = x /\ a <> x).
intro.
auto.
split.
auto.
auto.
auto.
Qed.
unfold set_In in |- *.
simple induction x.
auto.
intros.
cut ({a = a0} + {a <> a0}).
intro Eq_dec; elim Eq_dec.
intro Eq; rewrite Eq; left; auto with datatypes.
elim H.
auto with datatypes.
unfold not in |- *; intros; right; intro.
elim H0; auto.
auto.
Qed.
Hint Resolve set_add_intro1 set_add_intro2 Set_remove1.
Hint Resolve set_add_intro set_add_elim.
Hint Resolve set_union_intro2 set_union_intro1.
Hint Resolve set_inter_elim1 set_inter_elim2.

Lemma set_inter_elim :
forall (a : A) (x y : set),
set_In a (set_inter x y) -> set_In a x /\ set_In a y.