Section AllPairs.
Variables (S T R : Type) (f : S -> T -> R).
Implicit Types (s : seq S) (t : seq T).
Definition allpairs s t := foldr (fun x => cat (map (f x) t)) [::] s.

(* Specifications: *)
Lemma size_allpairs s t : size (allpairs s t) = size s * size t.
Lemma mem_allpairs R (f : S -> T -> R) s1 t1 s2 t2 :
s1 =i s2 -> t1 =i t2 -> allpairs f s1 t1 =i allpairs f s2 t2.
Lemma allpairs_catr R (f : S -> T -> R) s t1 t2 :
allpairs f s (t1 ++ t2) =i allpairs f s t1 ++ allpairs f s t2.
Lemma allpairs_uniq R (f : S -> T -> R) s t :
uniq s -> uniq t ->
{in [seq (x, y) | x <- s, y <- t] &, injective (prod_curry f)} ->
uniq (allpairs f s t).