Proof using rmri tsi rlmli smspi si rri.
intros.
unfold lifted_committed in *.
break_exists_name host. break_exists_name e'.
exists host, e'.
intuition.
- (* directly committed doesn't change *)
unfold lifted_directly_committed in *.
break_exists_exists; intuition.
find_higher_order_rewrite.
update_destruct_simplify; eauto using update_elections_data_appendEntries_preserves_allEntries'.
- (* e is still around *)
find_higher_order_rewrite.
update_destruct_simplify; simpl in *; eauto.
assert (lifted_committed net e (currentTerm (snd (nwState net host)))) by
(unfold lifted_committed;
exists host, e'; intuition;
eapply lifted_no_entries_past_current_term_host_invariant; eauto).
find_eapply_lem_hyp handleAppendEntries_log_detailed. intuition; repeat find_rewrite; eauto.
+ (* pli = 0, no entry at maxIndex es *)
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
assert (eIndex e > 0) by (eapply lifted_entries_gt_0_invariant; eauto).
intuition; try omega.
find_copy_eapply_lem_hyp msg_lifted_sorted_host.
exfalso.
enough (exists e, eIndex e = (maxIndex es) /\ In e (log (snd (nwState net host)))) by
(break_exists;
intuition; eapply findAtIndex_None; eauto).
eapply contiguous_range_exact_lo_elim_exists;
[apply lifted_entries_contiguous_invariant; auto|].
intuition.
* find_apply_lem_hyp maxIndex_non_empty.
break_exists; intuition; repeat find_rewrite.
enough (eIndex x > 0) by omega.
eapply lifted_entries_contiguous_nw_invariant; eauto.
* enough (eIndex e <= maxIndex (log (snd (nwState net host)))) by omega.
apply maxIndex_is_max; auto.
+ (* pli = 0, bad entry at maxIndex es *)
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
assert (eIndex e > 0) by (eapply lifted_entries_gt_0_invariant; eauto).
intuition; try omega.
break_exists. intuition.
find_apply_lem_hyp maxIndex_non_empty.
break_exists_name maxEntry; intuition.
repeat find_rewrite.
find_false.
f_equal.
find_apply_lem_hyp findAtIndex_elim.
intuition.
eapply uniqueIndices_elim_eq; [| |eauto|];
eauto using sorted_uniqueIndices,lifted_entries_sorted_nw.
match goal with
| |- In ?e _ =>
assert (lifted_committed net e (currentTerm (snd (nwState net host)))) by
(unfold lifted_committed;
exists host, e'; intuition;
eapply lifted_no_entries_past_current_term_host_invariant; eauto)
end.
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
assert (eIndex x > 0) by (eapply lifted_entries_gt_0_invariant; eauto).
intuition; omega.
+ find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
intuition;
try solve
[apply in_app_iff; right; apply removeAfterIndex_le_In; auto; omega];
[idtac].
find_copy_eapply_lem_hyp msg_lifted_sorted_host.
exfalso.
enough (exists e, eIndex e = (maxIndex es) /\ In e (log (snd (nwState net host)))) by
(break_exists;
intuition; eapply findAtIndex_None; eauto).
eapply contiguous_range_exact_lo_elim_exists;
[apply lifted_entries_contiguous_invariant; auto|].
intuition.
* find_apply_lem_hyp maxIndex_non_empty.
break_exists; intuition; repeat find_rewrite.
enough (eIndex x0 > 0) by omega.
enough (eIndex x0 > pli) by omega.
eapply lifted_entries_contiguous_nw_invariant; eauto.
* enough (eIndex e <= maxIndex (log (snd (nwState net host)))) by omega.
apply maxIndex_is_max; auto.
+ find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
intuition;
try solve
[apply in_app_iff; right; apply removeAfterIndex_le_In; auto; omega];
[idtac].
break_exists. intuition.
find_apply_lem_hyp maxIndex_non_empty.
break_exists_name maxEntry; intuition.
repeat find_rewrite.
find_false.
f_equal.
find_apply_lem_hyp findAtIndex_elim.
intuition.
eapply uniqueIndices_elim_eq; [| |eauto|];
eauto using sorted_uniqueIndices,lifted_entries_sorted_nw.
match goal with
| |- In ?e _ =>
assert (lifted_committed net e (currentTerm (snd (nwState net host)))) by
(unfold lifted_committed;
exists host, e'; intuition;
eapply lifted_no_entries_past_current_term_host_invariant; eauto)
end.
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
intuition; try omega;
enough (pli < eIndex maxEntry) by omega;
eapply lifted_entries_contiguous_nw_invariant; eauto.
- find_higher_order_rewrite.
update_destruct_simplify; simpl in *; eauto.
assert (lifted_committed net e' (currentTerm (snd (nwState net host)))) by
(unfold lifted_committed;
exists host, e'; intuition;
eapply lifted_no_entries_past_current_term_host_invariant; eauto).
find_eapply_lem_hyp handleAppendEntries_log_detailed. intuition; repeat find_rewrite; eauto.
+ (* pli = 0, no entry at maxIndex es *)
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
assert (eIndex e' > 0) by (eapply lifted_entries_gt_0_invariant; eauto).
intuition; try omega.
find_copy_eapply_lem_hyp msg_lifted_sorted_host.
exfalso.
enough (exists e, eIndex e = (maxIndex es) /\ In e (log (snd (nwState net host)))) by
(break_exists;
intuition; eapply findAtIndex_None; eauto).
eapply contiguous_range_exact_lo_elim_exists;
[apply lifted_entries_contiguous_invariant; auto|].
intuition.
* find_apply_lem_hyp maxIndex_non_empty.
break_exists; intuition; repeat find_rewrite.
enough (eIndex x > 0) by omega.
eapply lifted_entries_contiguous_nw_invariant; eauto.
* enough (eIndex e' <= maxIndex (log (snd (nwState net host)))) by omega.
apply maxIndex_is_max; auto.
+ (* pli = 0, bad entry at maxIndex es *)
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
assert (eIndex e' > 0) by (eapply lifted_entries_gt_0_invariant; eauto).
intuition; try omega.
break_exists. intuition.
find_apply_lem_hyp maxIndex_non_empty.
break_exists_name maxEntry; intuition.
repeat find_rewrite.
find_false.
f_equal.
find_apply_lem_hyp findAtIndex_elim.
intuition.
eapply uniqueIndices_elim_eq; [| |eauto|];
eauto using sorted_uniqueIndices,lifted_entries_sorted_nw.
match goal with
| |- In ?e _ =>
assert (lifted_committed net e (currentTerm (snd (nwState net host)))) by
(unfold lifted_committed;
exists host, e'; intuition;
eapply lifted_no_entries_past_current_term_host_invariant; eauto)
end.
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
assert (eIndex x > 0) by (eapply lifted_entries_gt_0_invariant; eauto).
intuition; omega.
+ find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
intuition;
try solve
[apply in_app_iff; right; apply removeAfterIndex_le_In; auto; omega];
[idtac].
find_copy_eapply_lem_hyp msg_lifted_sorted_host.
exfalso.
enough (exists e, eIndex e = (maxIndex es) /\ In e (log (snd (nwState net host)))) by
(break_exists;
intuition; eapply findAtIndex_None; eauto).
eapply contiguous_range_exact_lo_elim_exists;
[apply lifted_entries_contiguous_invariant; auto|].
intuition.
* find_apply_lem_hyp maxIndex_non_empty.
break_exists; intuition; repeat find_rewrite.
enough (eIndex x0 > 0) by omega.
enough (eIndex x0 > pli) by omega.
eapply lifted_entries_contiguous_nw_invariant; eauto.
* enough (eIndex e' <= maxIndex (log (snd (nwState net host)))) by omega.
apply maxIndex_is_max; auto.
+ find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
intuition;
try solve
[apply in_app_iff; right; apply removeAfterIndex_le_In; auto; omega];
[idtac].
break_exists. intuition.
find_apply_lem_hyp maxIndex_non_empty.
break_exists_name maxEntry; intuition.
repeat find_rewrite.
find_false.
f_equal.
find_apply_lem_hyp findAtIndex_elim.
intuition.
eapply uniqueIndices_elim_eq; [| |eauto|];
eauto using sorted_uniqueIndices,lifted_entries_sorted_nw.
match goal with
| |- In ?e _ =>
assert (lifted_committed net e (currentTerm (snd (nwState net host)))) by
(unfold lifted_committed;
exists host, e'; intuition;
eapply lifted_no_entries_past_current_term_host_invariant; eauto)
end.
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
intuition; try omega;
enough (pli < eIndex maxEntry) by omega;
eapply lifted_entries_contiguous_nw_invariant; eauto.
Qed.

(* Specifications: *)
Lemma handleAppendEntries_currentTerm_le :
forall h st t n pli plt es ci st' m,
handleAppendEntries h st t n pli plt es ci = (st', m) ->
currentTerm st <= currentTerm st'.