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 Znth_rev: forall {A}{d: Inhabitant A} i (al:list A), 0 <= i < Zlength al -> Znth i (rev al) = Znth (Zlength al - i - 1) al.