Proof using lmi smsi misi.
(* establish maxIndex guarantee in post state *)
intros.
get_invariant_post max_index_sanity_invariant.
unfold maxIndex_sanity in *; intuition.
unfold maxIndex_lastApplied in *; intuition.
match goal with
| H : forall _, lastApplied _ <= maxIndex _ |- _ =>
specialize (H (pDst p))
end. simpl in *. repeat find_higher_order_rewrite.
rewrite_update. repeat find_rewrite.
(* SMS *)
get_invariant_pre state_machine_safety_invariant.
unfold state_machine_safety in *. intuition.
match goal with
| H : state_machine_safety_nw _ |- _ =>
specialize (H (pDst p))
end.
find_copy_apply_lem_hyp handleAppendEntries_log.
intuition; repeat find_rewrite; eauto.
- match goal with
| _ : eIndex ?e <= lastApplied (nwState ?net ?h) |- _ =>
assert (commit_recorded net h e) by (unfold commit_recorded; eauto)
end.
get_invariant_pre log_matching_invariant.
unfold log_matching, log_matching_hosts in *. intuition.
copy_eapply_prop_hyp In In.
copy_eapply_prop_hyp pBody pBody; eauto.
intuition; try omega.
subst.
find_copy_apply_lem_hyp handleAppendEntries_same_lastApplied.
repeat find_rewrite. omega.
- match goal with
| _ : eIndex ?e <= lastApplied (nwState ?net ?h) |- _ =>
assert (commit_recorded net h e) by (unfold commit_recorded; eauto)
end.
get_invariant_pre log_matching_invariant.
unfold log_matching, log_matching_hosts in *. intuition.
copy_eapply_prop_hyp In In.
copy_eapply_prop_hyp pBody pBody; eauto.
intuition.
+ apply in_app_iff. right.
apply removeAfterIndex_le_In; eauto; omega.
+ apply in_app_iff. right.
apply removeAfterIndex_le_In; eauto; omega.
+ match goal with
| _ : context [maxIndex (?a ++ ?b)] |- _ =>
pose proof maxIndex_app a b
end. intuition.
repeat find_rewrite.
find_copy_apply_lem_hyp handleAppendEntries_same_lastApplied.
repeat find_rewrite. omega.
Qed.

(* Specifications: *)
Lemma handleAppendEntries_preserves_lastApplied_entries:
forall (p : packet) (net : network) (d : raft_data)
(m : msg) (t : term) (n : name) (pli : logIndex)
(plt : term) (es : list entry) (ci : logIndex) xs ys ps' st',
raft_intermediate_reachable net ->
raft_intermediate_reachable {| nwPackets := ps'; nwState := st' |} ->
(forall h : name, st' h = update name_eq_dec (nwState net) (pDst p) d h) ->
(forall p' : packet,
In p' ps' ->
In p' (xs ++ ys) \/
p' = {| pSrc := pDst p; pDst := pSrc p; pBody := m |}) ->
handleAppendEntries (pDst p) (nwState net (pDst p)) t n pli plt es ci = (d, m) ->
nwPackets net = xs ++ p :: ys ->
pBody p = AppendEntries t n pli plt es ci ->
removeAfterIndex (log d) (lastApplied d) = removeAfterIndex (log (nwState net (pDst p)))
(lastApplied (nwState net (pDst p))).