let rec all_permutations l1 l2 = (*assert (List.length l1 <= List.length l2);*) match l1 with | [] -> [[]] | x::l -> cross l [] x l2 and cross l pr x st = match st with | [] -> [] | y::p -> let acc = all_permutations l (List.rev_append pr p) in let acc = if acc = [] then [[x,y]] else List.rev_map (fun ds -> (x, y)::ds) acc in List.rev_append acc (cross l (y::pr) x p)