Proof using lacimi si.
intros.
unfold doGenericServer in *. break_let. find_inversion.
use_applyEntries_spec. subst. simpl in *. unfold raft_data in *.
simpl in *.
break_if; [|rewrite applied_entries_safe_update; simpl in *; eauto using app_nil_r].
do_bool.
match goal with
| |- context [update _ ?sigma ?h ?st] => pose proof applied_entries_update sigma h st
end.
simpl in *.
assert (commitIndex (sigma h) >= lastApplied (sigma h)) by omega.
concludes. intuition.
- find_rewrite. eauto using app_nil_r.
- pose proof applied_entries_cases sigma.
intuition; repeat find_rewrite; eauto.
match goal with | H : exists _, _ |- _ => destruct H as [h'] end.
repeat find_rewrite.
find_apply_lem_hyp argmax_elim. intuition.
match goal with
| H : forall _: name, _ |- _ =>
specialize (H h'); conclude H ltac:(eauto using all_fin_all)
end.
rewrite_update. simpl in *.
update_destruct_hyp; subst; rewrite_update; simpl in *.
+ apply rev_exists.
erewrite removeAfterIndex_le with (i := lastApplied (sigma h')) (j := commitIndex (sigma h')); [|omega].
eauto using removeAfterIndex_partition.
+ apply rev_exists.
match goal with
| _ : ?h <> ?h' |- exists _, removeAfterIndex ?l (commitIndex (?sigma ?h)) = _ =>
pose proof removeAfterIndex_partition (removeAfterIndex l (commitIndex (sigma h)))
(lastApplied (sigma h'))
end. break_exists_exists.
repeat match goal with | H : applied_entries _ = _ |- _ => clear H end.
find_rewrite. f_equal.
erewrite <- removeAfterIndex_le; eauto.
find_copy_apply_lem_hyp logs_sorted_invariant. unfold logs_sorted in *.
intuition. find_copy_apply_lem_hyp lastApplied_commitIndex_match_invariant.
eapply removeAfterIndex_same_sufficient; eauto;
intros;
eapply_prop_hyp lastApplied_commitIndex_match le; intuition eauto.
Qed.

(* Specifications: *)
Theorem applied_entries_monotonic' :
forall failed net failed' net' os,
raft_intermediate_reachable net ->
(@step_failure _ _ failure_params (failed, net) (failed', net') os) ->
exists es,
applied_entries (nwState net') = applied_entries (nwState net) ++ es.