(*									*)
(*  PRODUIT CARTESIEN 							*)
(*    On definit ici le produit cartesien de 2 ensembles. Pour cela     *)
(*    on commence par definir (singleprod x E) qui est l'ensemble	*)
(*    des couples (x,y) pour y dans E, puis (prodcart E F) qui est	*)
(*    l'union des (singleprod x F) pour x dans E.			*)
(*									*)

(*
Fixpoint singleprod [x:Elt; A:Ensf] : Ensf :=
  (<Ensf>Case A of
        (* empty *) empty
        (* add   *) [y:Elt][e:Ensf] (add (couple x y) (singleprod x e)) 
  end ).
*)
Fixpoint singleprod (x : Elt) (A : Ensf) {struct A} : Ensf :=
  match A with
  | empty => empty
  | add y e => add (couple x y) (singleprod x e)
  end.(*
Fixpoint prodcart [A:Ensf] : Ensf -> Ensf :=
  [B:Ensf]
  (<Ensf>Case A of
	(* empty *) empty
        (* add   *) [x:Elt][e:Ensf] (union (singleprod x B) (prodcart e B))
  end ).
*)
Fixpoint prodcart (A : Ensf) : Ensf -> Ensf :=
  fun B : Ensf =>
  match A with
  | empty => empty
  | add x e => union (singleprod x B) (prodcart e B)
  end.

Lemma dans_singleprod2 : forall (x x0 : Elt) (b : Ensf), dans x (singleprod x0 b) -> exists y : Elt, x = couple x0 y /\ dans y b.