Fixpoint zip (s : seq S) (t : seq T) {struct t} :=
  match s, t with
  | x :: s', y :: t' => (x, y) :: zip s' t'
  | _, _ => [::]
  end.Definition unzip1 := map (@fst S T).Definition unzip2 := map (@snd S T).

(* Specifications: *)
Lemma zip_unzip s : zip (unzip1 s) (unzip2 s) = s.
Lemma unzip1_zip s t : size s <= size t -> unzip1 (zip s t) = s.
Lemma unzip2_zip s t : size t <= size s -> unzip2 (zip s t) = t.
Lemma size1_zip s t : size s <= size t -> size (zip s t) = size s.
Lemma size2_zip s t : size t <= size s -> size (zip s t) = size t.
Lemma size_zip s t : size (zip s t) = minn (size s) (size t).
Lemma zip_cat s1 s2 t1 t2 : size s1 = size t1 -> zip (s1 ++ s2) (t1 ++ t2) = zip s1 t1 ++ zip s2 t2.
Lemma nth_zip x y s t i : size s = size t -> nth (x, y) (zip s t) i = (nth x s i, nth y t i).
Lemma zip_rcons s1 s2 z1 z2 : size s1 = size s2 -> zip (rcons s1 z1) (rcons s2 z2) = rcons (zip s1 s2) (z1, z2).
Lemma rev_zip s1 s2 : size s1 = size s2 -> rev (zip s1 s2) = zip (rev s1) (rev s2).