intros p q r; unfold mZlist in |- *; CaseEq (q - p)%Z.
intros H' H'0; elim H'0; auto with zarith.
intros H'1; elim H'1.
intros p0 H' H'0.
rewrite <- (Zplus_minus p q).
rewrite <- inject_nat_convert with (1 := H').
apply mZlist_aux_correct_rev2; auto.
intros p0 H' H'0; elim H'0.
Qed.
(* 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.

(* Specifications: *)
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).