(* given a list of vectors produce the list of all products *)
Fixpoint all_prods (n: nat) (vs: list (vect n)) {struct vs} : list (vect n) :=
match vs with
nil => 1 :: nil
| v::vs1 => let vs1 := all_prods n vs1 in
(map (join n v) vs1 ++ vs1)%list
end.

(* Lift of all products *)
Lemma all_prods_lift n vs :
all_prods n.+1 (map (lift n) vs) = map (lift n) (all_prods n vs).