Proof using rmri tsi glemi lphogli glci rlmli smspi si rri.
unfold commit_invariant.
intros.
assert (In p (nwPackets net)) by (repeat find_rewrite; auto with *).
split.
- break_and.
match goal with
| [ H : commit_invariant_host _ |- _ ] =>
rename H into Hhost;
unfold commit_invariant_host in *
end.
simpl. intros.
eapply lifted_committed_ext; eauto.
match goal with
| [ H : forall _, _ = _ |- _ ] => rewrite H in *
end.
update_destruct_simplify.
+ (* e is in h's log *)
find_copy_apply_lem_hyp handleAppendEntries_log_detailed.
break_or_hyp.
* break_and. repeat find_rewrite.
eapply lifted_committed_monotonic; [
solve [eapply handleAppendEntries_preserves_commit; eauto] |
solve [eauto using handleAppendEntries_currentTerm_le] ].
* { break_or_hyp; repeat break_and.
- (* beginning of time case *)
repeat match goal with
| [ H : _ <= _, H': _ |- _ ] => rewrite H' in H
end.
find_apply_lem_hyp NPeano.Nat.max_le. break_or_hyp.
+ (* my log is just the entries in the incoming AE.
so e was in the incoming entries.
but eIndex e <= old commit index.
by maxIndex_commitIndex, exists e' in old log such that eIndex e = eIndex e'.
note that e' is committed in the pre state by IH.
now apply SMS'_nw invariant to e' to get four cases.
first three are absurd by index calculation.
it follows that e' is in es.
but our new log is just es, so e' is in the new log.
by thus e = e' by unique indices.
thus e is committed.
*)
assert (eIndex e > 0) by (eapply lifted_entries_gt_0_nw_invariant; eauto).
assert (exists e', eIndex e' = eIndex e /\ In e' (log (snd (nwState net (pDst p))))).
{
eapply contiguous_range_exact_lo_elim_exists.
- eapply lifted_entries_contiguous_invariant. auto.
- split.
+ auto.
+ eapply le_trans; [eauto|].
eapply_prop lifted_maxIndex_sanity.
}
break_exists_name e'.
break_and.
assert (lifted_committed net e' (currentTerm (snd (nwState net (pDst p))))) as He'committed
by (apply Hhost; [auto|congruence]) .
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
concludes.
assert (sorted (log d)) by (eauto using lifted_handleAppendEntries_logs_sorted).
intuition.
* omega.
* omega.
* match goal with
| [ H : _ |- _ ] => eapply maxIndex_is_max in H; eauto; [idtac]
end.
omega.
* assert (e = e') by (eapply uniqueIndices_elim_eq; eauto using sorted_uniqueIndices).
subst.
eapply lifted_committed_monotonic; [
solve [eapply handleAppendEntries_preserves_commit; eauto] |
solve [eauto using handleAppendEntries_currentTerm_le] ].
+ (* eIndex e <= incoming ci.
result follows by the network invariant. *)
match goal with
| [ H : commit_invariant_nw _ |- _ ] =>
rename H into Hnet; unfold commit_invariant_nw in *
end.
eapply_prop_hyp In In; [| eauto | | eauto using Min.min_glb_l].
* eapply handleAppendEntries_preserves_commit; eauto.
* find_eapply_lem_hyp ghost_log_correct_invariant; eauto.
conclude_using eauto.
{ intuition.
- match goal with
| [ H : In _ _, H' : _ |- _ ] => rewrite H' in H
end. auto.
- break_exists. break_and.
pose proof log_properties_hold_on_ghost_logs_invariant _ ltac:(eauto) as Hprop.
unfold log_properties_hold_on_ghost_logs in *.
unfold msg_log_property in *.
specialize (Hprop (fun l => forall e, In e l -> eIndex e > 0) p).
conclude_using ltac:(intros; eapply lifted_entries_gt_0_invariant; eauto).
conclude_using eauto. simpl in *.
find_apply_hyp_hyp.
omega.
}
- (* middle of time case *)
break_exists_name ple. break_and.
repeat match goal with
| [ H : _ <= _, H': _ |- _ ] => rewrite H' in H
end.
find_apply_lem_hyp NPeano.Nat.max_le. break_or_hyp.
+ (* eIndex e <= old commit index *)
repeat find_rewrite.
match goal with
| [ H : In e (_ ++ _) |- _ ] => apply in_app_or in H; destruct H
end.
* (* e is new *)
{ assert (eIndex e > 0) by (eapply lifted_entries_gt_0_nw_invariant; eauto).
assert (exists e', eIndex e' = eIndex e /\ In e' (log (snd (nwState net (pDst p))))).
{
eapply contiguous_range_exact_lo_elim_exists.
- eapply lifted_entries_contiguous_invariant. auto.
- split.
+ auto.
+ eapply le_trans; [eauto|].
eapply_prop lifted_maxIndex_sanity.
}
break_exists_name e'.
break_and.
assert (lifted_committed net e' (currentTerm (snd (nwState net (pDst p))))) as He'committed
by (apply Hhost; [auto|congruence]) .
find_copy_eapply_lem_hyp lifted_state_machine_safety_nw'_invariant; eauto.
concludes.
assert (sorted es) by
(eapply lifted_entries_sorted_nw'_invariant; eauto).
assert (contiguous_range_exact_lo es (eIndex ple)) by
(eapply lifted_entries_contiguous_nw_invariant; eauto).
find_eapply_lem_hyp contiguous_range_exact_lo_elim_lt; eauto.
intuition.
* omega.
* omega.
* match goal with
| [ H : _ |- _ ] => eapply maxIndex_is_max in H; eauto with *; [idtac]
end.
omega.
* assert (e = e') by (eapply uniqueIndices_elim_eq; eauto using sorted_uniqueIndices).
subst.
eapply lifted_committed_monotonic; [
solve [eapply handleAppendEntries_preserves_commit; eauto] |
solve [eauto using handleAppendEntries_currentTerm_le] ].
}
* (* e is old *)
{ eapply lifted_committed_monotonic.
- eapply handleAppendEntries_preserves_commit; eauto.
eapply Hhost with (h := pDst p); eauto using removeAfterIndex_in.
- eauto using handleAppendEntries_currentTerm_le.
}
+ (* eIndex e <= new commit index *)
match goal with
| [ H : In e _ |- _ ] =>
repeat match goal with
| [ H' : _ |- _ ] => rewrite H' in H
end;
apply in_app_or in H; destruct H
end.
* (* e is new *)
(* follows from network invariant *)
{ match goal with
| [ H : commit_invariant_nw _ |- _ ] =>
rename H into Hnet; unfold commit_invariant_nw in *
end.
match goal with
| [ H : In _ (nwPackets _), H' : _ |- _ ] => eapply H' in H
end; [| eauto | | eauto using Min.min_glb_l].
* eapply handleAppendEntries_preserves_commit; eauto.
* find_copy_eapply_lem_hyp ghost_log_correct_invariant; eauto.
conclude_using eauto.
{ intuition.
- match goal with
| [ H : In _ _, H' : _ |- _ ] => rewrite H' in H
end. auto.
- break_exists_name gple. break_and.
subst.
eauto using findGtIndex_in.
}
}
* (* e is old *)
(* eIndex e <= pli by ghost log contiguous, exists e' in ghost log such that eIndex e = eIndex e'. e' is committed by the nw invariant. by ghost log matching, e = e'. thus e is committed. *)
assert (eIndex e <= eIndex ple) by
(eapply removeAfterIndex_In_le; eauto using msg_lifted_sorted_host).
pose proof log_properties_hold_on_ghost_logs_invariant _ ltac:(eauto) as Hprop.
unfold log_properties_hold_on_ghost_logs in *.
unfold msg_log_property in *.
specialize (Hprop (fun l => contiguous_range_exact_lo l 0) p).
conclude_using ltac:(intros; eapply lifted_entries_contiguous_invariant; eauto).
concludes.
simpl in *.
find_copy_eapply_lem_hyp ghost_log_correct_invariant; eauto.
conclude_using eauto.
{ intuition.
- subst. find_apply_lem_hyp removeAfterIndex_in.
pose proof lifted_entries_gt_0_invariant _ ltac:(eauto) _ _ ltac:(eauto).
omega.
- break_exists_name gple. break_and.
assert (exists e', eIndex e' = eIndex e /\ In e' (fst (pBody p))).
{
eapply contiguous_range_exact_lo_elim_exists; eauto.
split.
+ eapply lifted_entries_gt_0_invariant; eauto using removeAfterIndex_in.
+ eapply le_trans with (m := eIndex gple); try omega.
apply maxIndex_is_max; auto.
pose proof log_properties_hold_on_ghost_logs_invariant _ ltac:(eauto) as Hsort.
unfold log_properties_hold_on_ghost_logs in *.
unfold msg_log_property in *.
specialize (Hsort sorted p msg_lifted_sorted_host).
auto.
}
break_exists_name e'. break_and.
find_apply_lem_hyp removeAfterIndex_in.
assert (e = e').
{
eapply uniqueIndices_elim_eq;
eauto using msg_lifted_sorted_host, sorted_uniqueIndices.
pose proof ghost_log_entries_match_invariant _ ltac:(eauto) (pDst p) _ ltac:(eauto)
as Hem.
specialize (Hem ple gple e').
repeat concludes.
assert (eIndex e' <= eIndex ple) by omega.
intuition.
}
subst.
match goal with
| [ H : commit_invariant_nw _ |- _ ] =>
rename H into Hnet; unfold commit_invariant_nw in *
end.
eapply handleAppendEntries_preserves_commit; eauto.
eapply Hnet; eauto using Min.min_glb_l.
}
}
+ eapply handleAppendEntries_preserves_commit; eauto.
- (* nw invariant preserved *)
break_and.
unfold commit_invariant_nw in *.
simpl. intros.
find_apply_hyp_hyp.
intuition.
+ eapply handleAppendEntries_preserves_commit; eauto.
simpl. subst. auto.
+ subst. simpl in *.
find_apply_lem_hyp handleAppendEntries_not_append_entries.
subst. exfalso. eauto 10.
Qed.

(* Specifications: *)
Lemma handleAppendEntriesReply_preserves_commit :
forall (net net' : ghost_log_network) h src t es b st' l e t',
handleAppendEntriesReply h (snd (nwState net h)) src t es b = (st', l) ->
(forall h', nwState net' h' = update name_eq_dec (nwState net) h (fst (nwState net h), st') h') ->
lifted_committed net e t' ->
lifted_committed net' e t'.