Section ListArray.
Variable D R : Set.
Hypothesis D_EqDec : EqDec D.
Definition Array := list (D * R).
Fixpoint arrayLookup(ls : list (D * R)) d :=
match ls with
| nil => None
| (d', r') :: ls' =>
if (eqb d d')
then Some r'
else (arrayLookup ls' d)
end.
Definition arrayEquiv(arr1 arr2 : Array) :=
forall d,
(arrayLookup arr1 d) = (arrayLookup arr2 d).
Definition arrayLookupDef(ls : list (D * R)) d def :=
match arrayLookup ls d with
| None => def
| Some r => r
end.
Definition arrayUpdate (arr_opt : option Array) d r_opt :=
let arr := match arr_opt with
| None => nil
| Some arr => arr
end in
match r_opt with
| None => arr
| Some r =>
(d, r) :: arr
end.
induction ls; intuition; simpl in *.
rewrite eqb_refl.
trivial.
case_eq (eqb d a0); intuition;
rewrite H0 in H.
discriminate.
eauto.
Qed.
induction ls; intuition; simpl in *.
case_eq (eqb d a0); intuition;
rewrite H0 in H.
discriminate.
case_eq (eqb d' d); intuition.
rewrite eqb_leibniz in H1.
subst.
case_eq (eqb d a0); intuition.
rewrite eqb_leibniz in H1.
subst.
rewrite eqb_refl in H0.
discriminate.
eapply arrayLookup_app_some_eq.
trivial.
specialize (IHls d d').
case_eq (eqb d' a0); intuition.
rewrite H1 in IHls.
eapply IHls.
trivial.
Qed.
induction ls; intuition; simpl in *.
case_eq (eqb d' d); intuition.
rewrite eqb_leibniz in H0.
subst.
intuition.
case_eq (eqb d' a0); intuition.
Qed.
induction ls; intuition; simpl in *.
discriminate.
case_eq (eqb d a0); intuition.
rewrite H0 in H.
inversion H; clear H; subst.
rewrite eqb_leibniz in H0. subst.
case_eq (eqb d' a0); intuition.
eapply arrayLookup_app_ne.
intuition.
subst.
rewrite eqb_refl in H.
discriminate.
rewrite H0 in H.
case_eq (eqb d' a0); intuition.
eapply IHls; eauto.
Qed.
intuition.
unfold arrayUpdate.
destruct arr.
simpl.
rewrite eqb_refl.
trivial.
simpl.
rewrite eqb_refl.
trivial.
Qed.

Theorem arrayLookup_arrayUpdate_ne :
forall arr p1 p2 v,
p1 <> p2 ->
arrayLookup (arrayUpdate (Some arr) p1 (Some v)) p2 = arrayLookup arr p2.