Fixpoint splitVector(A : Set)(n m : nat) : Vector.t A (n + m) -> (Vector.t A n * Vector.t A m) :=
  match n with
          | 0 => 
            fun (v : Vector.t A (O + m)) => (@Vector.nil A, v)
          | S n' => 
            fun (v : Vector.t A (S n' + m)) => 
              let (v1, v2) := splitVector _ _ (Vector.tl v) in
                (Vector.cons _ (Vector.hd v) _ v1, v2)
    end.

(* Specifications: *)
Theorem splitVector_append : forall (A : Set) n1 (v1 : Vector.t A n1) n2 (v2 : Vector.t A n2), splitVector n1 n2 (Vector.append v1 v2) = (v1, v2).
Theorem append_splitVector_h : forall (A : Set) n1 n2 (x : Vector.t A (n1 + n2)), (Vector.append (fst (splitVector n1 n2 x)) (snd (splitVector n1 n2 x))) = x.
Theorem append_splitVector: forall (A : Set) n1 n2 (x : Vector.t A (n1 + n2)) x1 x2, (x1, x2) = (splitVector n1 n2 x) -> (Vector.append x1 x2) = x.
Theorem shiftOut_plus : forall (n1 n2 : nat) s b s', shiftOut s (n1 + n2) = Some (b, s') -> exists b1 b2 s'', shiftOut s n1 = Some (b1, s'') /\ shiftOut s'' n2 = Some (b2, s') /\ splitVector n1 n2 b = (b1, b2).
Theorem shiftOut_plus_None : forall n1 n2 s, shiftOut s (n1 + n2) = None -> shiftOut s n1 = None \/ (exists x s', shiftOut s n1 = Some (x, s') /\ shiftOut s' n2 = None).
Theorem Vector_cons_app_assoc : forall (A : Type)(a : A)(n1 n2 : nat)(v1 : Vector.t A n1)(v2 : Vector.t A n2), Vector.cons _ a _ (Vector.append v1 v2) = Vector.append (Vector.cons _ a _ v1) v2.
Theorem shiftOut_plus_if : forall n1 n2 s s' s'' b1 b2, shiftOut s n1 = Some (b1, s') -> shiftOut s' n2 = Some (b2, s'') -> shiftOut s (n1 + n2) = Some (Vector.append b1 b2, s'').
Theorem shiftOut_plus_None_if : forall n1 n2 s, (shiftOut s n1 = None \/ (exists b s', shiftOut s n1 = Some (b, s') /\ shiftOut s' n2 = None)) -> shiftOut s (n1 + n2) = None.