Definition Zlength' := @Zlength.Ltac pose_Zlength_nonneg1 T A :=
     lazymatch goal with
      | H:  0 <= @Zlength T A |- _ => idtac
      | H:  0 <= @Zlength T A /\ _ |- _ => idtac
      | |- _ => pose proof (@Zlength_nonneg T A)
     end;
     (* the next three lines are to avoid blowups in the change command *)
     let x := fresh "x" in set (x:= @Zlength T A) in *;
     let y := fresh "y" in set (y := @Zlength) in x;
     fold @Zlength' in y; subst y; subst x.Ltac pose_Zlength_nonneg :=
 repeat
  match goal with
  | |- context [@Zlength ?T ?A] => pose_Zlength_nonneg1 T A
  | H: context [@Zlength ?T ?A] |- _ => pose_Zlength_nonneg1 T A
 end;
  unfold Zlength' in *.Ltac list_solve := autorewrite with sublist; pose_Zlength_nonneg; omega.Definition Znth {X}{d: Inhabitant X} n (xs: list X) :=
  if (zlt n 0) then default else nth (Z.to_nat n) xs d.

Lemma split3_full_length_list: forall {A}{a: Inhabitant A} lo mid hi (ct: list A), lo <= mid < hi -> Zlength ct = hi - lo -> ct = firstn (Z.to_nat (mid - lo)) ct ++ (Znth (mid - lo) ct :: nil) ++ skipn (Z.to_nat (mid - lo + 1)) ct.