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.

(* Specifications: *)
Lemma Znth_map:
forall {A:Type} {da: Inhabitant A}{B:Type}{db: Inhabitant B} i (f: A -> B) (al: list A),
0 <= i < Zlength al ->
Znth i (map f al)  = f (Znth i al).