Proof using.
unfold applyEntry.
intros.
repeat break_match; repeat find_inversion.
simpl in *. intuition.
subst.
unfold output_correct.
rewrite deduplicate_log_snoc_split by auto.
destruct (execute_log (deduplicate_log es)) eqn:?.
eexists. eexists. exists []. eexists. eexists. intuition eauto.
- rewrite execute_log_app. repeat find_rewrite. simpl in *. find_rewrite. eauto.
- rewrite rev_app_distr. simpl. auto.
Qed.

(* Specifications: *)
Lemma cacheApplyEntry_output_correct :
forall e es st l st' o,
cacheApplyEntry st e = (l, st') ->
In o l ->
(forall c i o,
getLastId st c = Some (i, o) ->
output_correct c i o es) ->
stateMachine st = snd (execute_log (deduplicate_log es)) ->
(forall c i o e',
getLastId st c = Some (i, o) ->
In e' es ->
eClient e' = c ->
eId e' <= i) ->
(forall e',
In e' es ->
exists i o,
getLastId st (eClient e') = Some (i, o) /\
eId e' <= i) ->
output_correct (eClient e) (eId e) o (es ++ [e]).