Set Bullet Behavior "Strict Subproofs".
(* Maps are represented as partial association lists, with entries with key 0 considered to be empty. *)
Fixpoint index_of (m : list (Z * Z)) (k : Z) :=
match m with
| [] => None
| (k1, v1) :: rest => if eq_dec k1 k then Some 0
else option_map Z.succ (index_of rest k)
end.

(* Specifications: *)
Lemma index_of_spec : forall k m, match index_of m k with
| Some i => 0 <= i < Zlength m /\ fst (Znth i m) = k /\ Forall (fun x => fst x <> k) (sublist 0 i m)
| None => ~In k (map fst m) end.