Proof using.
induction l; intros; simpl in *; intuition.
- find_inversion.
apply a_equiv_refl.
- repeat break_let. find_inversion.
break_if.
+ do_bool.
unfold cacheApplyEntry in *.
repeat break_match; repeat find_inversion; do_bool.
* find_apply_lem_hyp getLastId_clientCache_to_ks_assoc.
find_erewrite_lem assoc_assoc_default. omega.
* find_apply_hyp_hyp.
subst.
rewrite assoc_set_same; eauto using a_equiv_refl.
eauto using getLastId_clientCache_to_ks_assoc.
* subst.
unfold applyEntry in *.
break_let. find_inversion.
find_apply_hyp_hyp.
eapply a_equiv_trans; eauto.
simpl.
erewrite clientCache_to_ks_assoc_set; eauto using a_equiv_refl.
* subst.
unfold applyEntry in *.
break_let. find_inversion.
find_apply_hyp_hyp.
eapply a_equiv_trans; eauto.
simpl.
erewrite clientCache_to_ks_assoc_set; eauto using a_equiv_refl.
+ do_bool. find_apply_lem_hyp i_lt_assoc_default_0.
break_exists. intuition.
find_apply_lem_hyp clientCache_to_ks_assoc_getLastId.
break_exists.
unfold cacheApplyEntry in *.
repeat find_rewrite. break_if; do_bool; try omega.
find_inversion. eauto.
Qed.

(* Specifications: *)
Lemma applyEntries_execute_log'_cache :
forall l h st os st' client id out,
applyEntries h st l = (os, st') ->
getLastId st' client = Some (id, out) ->
(getLastId st client = Some (id, out) \/
exists e xs ys,
deduplicate_log' l (clientCache_to_ks (clientCache st)) = xs ++ e :: ys /\
eClient e = client /\
eId e = id /\
Some (eInput e, out) = hd_error (rev (fst (execute_log'
(xs ++ [e])
(stateMachine st) [])))).