(* Some notation for array lookups *)
Notation "f '#' i " := (arrayLookup _ f i) (at level 70) : array_scope.(* A special case for array lookup when the range is lists -- returns nil instead of None when not found.  This is useful for multidimensional arrays. *)
Definition arrayLookupList(A B : Set)(eqd : EqDec A)(ls : list (A * (list B)))(a : A) :=
    match (arrayLookup _ ls a) with
      | None => nil
      | Some ls => ls
    end.Fixpoint arrayLookupOpt(A B : Set)(eqd : EqDec A)(ls : list (option (A * B)))(a : A) :=
  match ls with
    | nil => None
      | o :: ls' =>
        match o with
          | None => arrayLookupOpt _ ls' a
          | Some (a', b') =>
            if (eqb a a') then (Some b') else (arrayLookupOpt _ ls' a)
        end
  end.

Theorem list_pred_arrayLookupOpt : forall (A B C : Set)(P : B -> C -> Prop)(eqda : EqDec A)(ls1 : list (option (A * B)))(ls2 : list (option (A * C))), list_pred (fun o1 o2 => match o1 with | None => o2 = None | Some x => match o2 with | None => False | Some y => fst x = fst y /\ P (snd x) (snd y) end end) ls1 ls2 -> forall a, match (arrayLookupOpt _ ls1 a) with | None => (arrayLookupOpt _ ls2 a) = None | Some x => exists y, (arrayLookupOpt _ ls2 a) = Some y /\ P x y end.