Class Inhabitant (A: Type) := default : A.
Instance Inhabitant_Z : Inhabitant Z := 0.
Instance Inhabitant_nat : Inhabitant nat := O.
Instance Inhabitant_positive : Inhabitant positive := 1%positive.
Instance Inhabitant_list {T: Type} : Inhabitant (list T) := @nil T.
Instance Inhabitant_fun {T1 T2: Type} {H: Inhabitant T2} : Inhabitant (T1->T2) := fun _ => H.
Instance Inhabitant_Prop : Inhabitant Prop := False.
Instance Inhabitant_bool : Inhabitant bool := false.
Instance Inhabitant_pair {T1 T2 : Type} {x1: Inhabitant T1} {x2: Inhabitant T2} : Inhabitant (T1*T2)%type := (x1,x2).
Hint Rewrite @ZtoNat_Zlength : norm.
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_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).