(* Given two list returns the list of possible product of an element
   of the first list with an element of the second list *)
 
Fixpoint mProd (A B C : Set) (l1 : list A) (l2 : list B) {struct l2} :
 list (A * B) :=
  match l2 with
  | nil => nil
  | b :: l2' => map (fun a : A => (a, b)) l1 ++ mProd A B C l1 l2'
  end.

Theorem mProd_correct : forall (A B C : Set) (l1 : list A) (l2 : list B) (a : A) (b : B), In a l1 -> In b l2 -> In (a, b) (mProd A B C l1 l2).