Fixpoint hlist_split ls ls' : hlist (ls ++ ls') -> hlist ls * hlist ls' :=
      match ls as ls return hlist (ls ++ ls') -> hlist ls * hlist ls' with
        | nil => fun h => (Hnil, h)
        | l :: ls => fun h =>
                       let (a,b) := @hlist_split ls ls' (hlist_tl h) in
                       (Hcons (hlist_hd h) a, b)
      end.

(* Specifications: *)
Lemma hlist_app_hlist_split : forall ls' ls (h : hlist (ls ++ ls')), hlist_app (fst (hlist_split ls ls' h)) (snd (hlist_split ls ls' h)) = h.
Lemma hlist_split_hlist_app : forall ls' ls (h : hlist ls) (h' : hlist ls'), hlist_split _ _ (hlist_app h h') = (h,h').
Lemma hlist_hd_fst_hlist_split : forall t (xs ys : list _) (h : hlist (t :: xs ++ ys)), hlist_hd (fst (hlist_split (t :: xs) ys h)) = hlist_hd h.
Lemma hlist_tl_fst_hlist_split : forall t (xs ys : list _) (h : hlist (t :: xs ++ ys)), hlist_tl (fst (hlist_split (t :: xs) ys h)) = fst (hlist_split xs ys (hlist_tl h)).
Lemma hlist_tl_snd_hlist_split : forall t (xs ys : list _) (h : hlist (t :: xs ++ ys)), snd (hlist_split xs ys (hlist_tl h)) = snd (hlist_split (t :: xs) ys h).