Hint Resolve nth_error_nil: coqlib.
(** Compute the length of a list, with result in [Z]. *)
Fixpoint list_length_z_aux (A: Type) (l: list A) (acc: Z) {struct l}: Z :=
match l with
| nil => acc
| hd :: tl => list_length_z_aux tl (Z.succ acc)
end.
Remark list_length_z_aux_shift:
forall (A: Type) (l: list A) n m,
list_length_z_aux l n = list_length_z_aux l m + (n - m).
Definition list_length_z (A: Type) (l: list A) : Z :=
list_length_z_aux l 0.

(* Specifications: *)
Lemma list_length_z_cons:
forall (A: Type) (hd: A) (tl: list A),
list_length_z (hd :: tl) = list_length_z tl + 1.
Lemma list_length_z_pos:
forall (A: Type) (l: list A),
list_length_z l >= 0.
Lemma list_length_z_map:
forall (A B: Type) (f: A -> B) (l: list A),
list_length_z (map f l) = list_length_z l.
Lemma list_length_z_cons:
forall (A: Type) (hd: A) (tl: list A),
list_length_z (hd :: tl) = list_length_z tl + 1.
Lemma list_length_z_pos:
forall (A: Type) (l: list A),
list_length_z l >= 0.
Lemma list_length_z_map:
forall (A B: Type) (f: A -> B) (l: list A),
list_length_z (map f l) = list_length_z l.