Proof using lmi smsi misi si.
intros.
find_copy_apply_lem_hyp handleAppendEntries_same_lastApplied.
repeat find_rewrite.
get_invariant_pre logs_sorted_invariant.
get_invariant_post logs_sorted_invariant.
unfold logs_sorted in *. intuition.
apply removeAfterIndex_same_sufficient; auto.
- unfold logs_sorted_host in *. simpl in *.
match goal with
| H : forall h, sorted (log (st' h)) |- _ =>
specialize (H (pDst p))
end.
repeat find_higher_order_rewrite.
rewrite_update. auto.
- intros. eauto using handleAppendEntries_preserves_lastApplied_entries'.
- intros.
get_invariant_pre max_index_sanity_invariant.
unfold maxIndex_sanity, maxIndex_lastApplied in *. intuition.
enough (exists e', eIndex e' = eIndex e /\ In e' (log (nwState net (pDst p)))).
+ break_exists. intuition.
find_copy_eapply_lem_hyp handleAppendEntries_preserves_lastApplied_entries';
repeat find_rewrite; eauto.
enough (x = e) by now subst.
eapply uniqueIndices_elim_eq; eauto.
apply sorted_uniqueIndices.
unfold logs_sorted_host in *. simpl in *.
match goal with
| H : forall h, sorted (log (st' h)) |- _ =>
specialize (H (pDst p))
end.
repeat find_higher_order_rewrite.
rewrite_update. auto.
+ apply log_matching_invariant; auto.
intuition; eauto using le_trans.
enough (eIndex e > 0) by auto.
get_invariant_post log_matching_invariant.
unfold log_matching, log_matching_hosts in *. intuition.
match goal with
| H : context [eIndex _ > _] |- _ =>
eapply H with (h := (pDst p))
end.
simpl. repeat find_higher_order_rewrite.
rewrite_update. auto.
Qed.

(* Specifications: *)
Lemma removeAfterIndex_cons :
forall l x i,
i < eIndex x ->
removeAfterIndex (x :: l) i = removeAfterIndex l i.