(* 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 in_map_inv : forall (A B : Set) (f : A -> B) (l : list A) (x : A), (forall a b : A, f a = f b -> a = b) -> In (f x) (map f l) -> In x l.