(** [list_prod] has the same signature as [combine], but unlike [combine], it adds every possible pairs, not only those at the same position. *)
Fixpoint list_prod (l:list A) (l':list B) :
list (A * B) :=
match l with
| [] => []
| x :: t => (map (fun y:B => (x, y)) l')++(list_prod t l')
end.

(* Specifications: *)
Lemma in_prod_aux :
forall (x:A) (y:B) (l:list B),
In y l -> In (x, y) (map (fun y0:B => (x, y0)) l).
Lemma in_prod :
forall (l:list A) (l':list B) (x:A) (y:B),
In x l -> In y l' -> In (x, y) (list_prod l l').
Lemma in_prod_iff :
forall (l:list A)(l':list B)(x:A)(y:B),
In (x,y) (list_prod l l') <-> In x l /\ In y l'.
Lemma length_prod : forall (l:list A)(l':list B),
length (list_prod l l') = (length l) * (length l').
Lemma list_prod_as_flat_map : forall l l',
list_prod l l' = flat_map (fun a => map (pair a) l') l.
Lemma lel_trans : lel l m -> lel m n -> lel l n.
Lemma lel_cons_cons : lel l m -> lel (a :: l) (b :: m).
Lemma lel_cons : lel l m -> lel l (b :: m).
Lemma lel_tail : lel (a :: l) (b :: m) -> lel l m.
Lemma lel_nil : forall l':list A, lel l' [] -> [] = l'.
End length_order.