Section StateMachineSafetyProof.
Context {orig_base_params : BaseParams}.
Context {one_node_params : OneNodeParams orig_base_params}.
Context {raft_params : RaftParams orig_base_params}.
Context {rri : raft_refinement_interface}.
Context {si : sorted_interface}.
Context {lmi : log_matching_interface}.
Context {smspi : state_machine_safety'interface}.
Context {rlmli : refined_log_matching_lemmas_interface}.
Context {pllsi : prevLog_leader_sublog_interface}.
Context {ctgt0 : current_term_gt_zero_interface}.
Context {lalcii : lastApplied_le_commitIndex_interface}.
Context {miaei : match_index_all_entries_interface}.
Context {lhlli : leaders_have_leaderLogs_interface}.
Context {lci : leader_completeness_interface}.
Context {lsi : leader_sublog_interface}.
Context {taifoli : terms_and_indices_from_one_log_interface}.
Context {glci : ghost_log_correct_interface}.
Context {lphogli : log_properties_hold_on_ghost_logs_interface}.
Context {glemi : ghost_log_entries_match_interface}.
Context {tci : transitive_commit_interface}.
Context {tsi : term_sanity_interface}.
Context {lhllsi : leaders_have_leaderLogs_strong_interface}.
Context {ollpti : one_leaderLog_per_term_interface}.
Context {rmri : raft_msg_refinement_interface}.
Proof using.
intros.
unfold deghost in *. simpl in *. do_in_map.
subst. eexists; eauto.
Qed.
Proof using.
intros. unfold state_machine_safety in *. intuition.
- unfold state_machine_safety_host. intros.
do 2 eapply_prop_hyp commit_recorded_committed commit_recorded.
unfold state_machine_safety' in *. intuition. eauto.
- unfold state_machine_safety_nw. intros.
eapply_prop_hyp commit_recorded_committed commit_recorded.
unfold state_machine_safety', state_machine_safety_nw' in *. intuition.
find_apply_lem_hyp exists_deghost_packet. break_exists.
intuition. subst. simpl in *. repeat break_match. simpl in *.
subst. eapply_prop_hyp In In; repeat find_rewrite; simpl; eauto.
Qed.
Definition ghost_log_network : Type := @network _ raft_msg_refined_multi_params.
Definition ghost_log_packet : Type := @packet _ raft_msg_refined_multi_params.
Definition lifted_maxIndex_sanity (net : ghost_log_network) : Prop :=
(forall h,
lastApplied (snd (nwState net h)) <= maxIndex (log (snd (nwState net h)))) /\
(forall h, commitIndex (snd (nwState net h)) <= maxIndex (log (snd (nwState net h)))).
Proof using.
unfold msg_refined_raft_net_invariant_init, lifted_maxIndex_sanity, maxIndex_lastApplied, maxIndex_commitIndex.
intuition.
Qed.
Proof using.
unfold handleClientRequest.
intros.
repeat break_match; find_inversion; auto.
Qed.
Proof using.
intros.
destruct (log st') using (handleClientRequest_log_ind ltac:(eauto)).
- auto.
- simpl in *. break_and.
destruct (log st); simpl in *.
+ lia.
+ find_insterU. conclude_using eauto. intuition.
Qed.
Proof using si rri.
intros.
pose proof (lift_prop _ logs_sorted_invariant).
find_insterU. conclude_using eauto.
unfold logs_sorted, logs_sorted_host in *. break_and.
unfold deghost in *. simpl in *. break_match. eauto.
Qed.
Proof using rmri si rri.
intros net0 ??.
rewrite <- msg_deghost_spec with (net := net0).
eapply msg_lift_prop.
- auto using lifted_sorted_host.
- auto.
Qed.
Proof using rlmli.
intros. eapply entries_sorted_nw_invariant; eauto.
Qed.
Definition lifted_no_entries_past_current_term_host net :=
forall (h : name) e,
In e (log (snd (nwState net h))) ->
eTerm e <= currentTerm (snd (nwState net h)).
Proof using rmri tsi.
intros.
enough (no_entries_past_current_term_host (deghost (mgv_deghost net))) by
(unfold no_entries_past_current_term_host, lifted_no_entries_past_current_term_host, deghost, mgv_deghost in *;
simpl in *;
repeat break_match; simpl in *; auto).
apply msg_lift_prop_all_the_way; eauto.
intros.
eapply no_entries_past_current_term_invariant; eauto.
Qed.
Proof using rmri rri.
intros net0 ?.
rewrite deghost_spec.
rewrite msg_deghost_spec with (net := net0).
auto.
Qed.
Proof using rmri rri.
auto using simulation_1, msg_simulation_1.
Qed.
Proof using rmri si rri.
unfold msg_refined_raft_net_invariant_client_request, lifted_maxIndex_sanity, maxIndex_lastApplied, maxIndex_commitIndex.
simpl. intros.
find_copy_apply_lem_hyp handleClientRequest_maxIndex.
- intuition; simpl in *; repeat find_higher_order_rewrite; update_destruct_simplify; auto.
+ erewrite handleClientRequest_lastApplied by eauto. eauto using le_trans.
+ erewrite handleClientRequest_commitIndex by eauto. eauto using le_trans.
- match goal with H : _ |- _ => rewrite all_the_way_deghost_spec with (net := net) in H end.
eapply handleClientRequest_logs_sorted; eauto.
* auto using all_the_way_simulation_1.
* apply logs_sorted_invariant. auto using all_the_way_simulation_1.
Qed.
Proof using.
unfold msg_refined_raft_net_invariant_timeout, lifted_maxIndex_sanity, maxIndex_lastApplied, maxIndex_commitIndex.
intuition; simpl in *; repeat find_higher_order_rewrite; update_destruct_simplify; auto;
erewrite handleTimeout_log_same by eauto.
- erewrite handleTimeout_lastApplied; eauto.
- erewrite handleTimeout_commitIndex; eauto.
Qed.
Proof using.
unfold handleAppendEntries, advanceCurrentTerm;
intros; repeat break_match; repeat find_inversion; simpl; auto.
Qed.
Proof using.
induction l1; intros; simpl in *; intuition.
destruct l2; intuition. simpl in *.
specialize (H0 e). conclude H0 intuition. intuition.
Qed.
Proof using.
intros.
destruct (max a (min b c)) using (Max.max_case _ _); intuition.
Qed.
Proof using.
unfold deghost.
simpl. intuition.
apply in_map_iff.
eexists; eauto.
Qed.
Proof using.
unfold mgv_deghost.
simpl. intuition.
apply in_map_iff.
eexists; eauto.
Qed.
Proof using.
unfold deghost_packet.
simpl. auto.
Qed.
Proof using.
unfold deghost_packet.
simpl. auto.
Qed.
Proof using.
unfold mgv_deghost_packet.
simpl. auto.
Qed.
Proof using.
unfold mgv_deghost_packet.
simpl. auto.
Qed.
Proof using rmri si rri.
intros.
eapply (handleAppendEntries_logs_sorted _ (deghost_packet (mgv_deghost_packet p))).
- eauto using all_the_way_simulation_1.
- apply lift_prop.
+ apply logs_sorted_invariant.
+ auto using msg_simulation_1.
- rewrite <- all_the_way_deghost_spec.
rewrite pDst_deghost_packet.
rewrite pDst_mgv_deghost_packet.
eauto.
- rewrite pBody_deghost_packet.
rewrite pBody_mgv_deghost_packet.
auto.
- apply in_ghost_packet. apply in_mgv_ghost_packet. auto.
Qed.
Proof using.
unfold contiguous_range_exact_lo.
intuition.
Qed.
Proof using.
unfold contiguous_range_exact_lo.
intuition.
Qed.
Proof using rri.
unfold state_machine_safety, state_machine_safety_nw.
intuition.
match goal with
| [ H : _ |- _ ] => eapply H with (p := deghost_packet p)
end.
- auto using in_ghost_packet.
- rewrite pBody_deghost_packet. eauto.
- rewrite deghost_spec. eauto.
- auto.
Qed.
Proof using rmri rri.
intros net0;intros.
eapply lifted_sms_nw.
- eauto.
- eauto using in_mgv_ghost_packet.
- rewrite pBody_mgv_deghost_packet. eauto.
- rewrite msg_deghost_spec with (net := net0). eauto.
- auto.
Qed.
Proof using rri.
unfold commit_recorded.
intros.
rewrite deghost_spec.
auto.
Qed.
Proof using rmri rri.
unfold commit_recorded.
intros net0;intros.
rewrite deghost_spec.
rewrite msg_deghost_spec with (net := net0).
auto.
Qed.
Definition lifted_entries_contiguous (net : ghost_log_network) : Prop :=
forall h, contiguous_range_exact_lo (log (snd (nwState net h))) 0.
Proof using rmri rlmli.
unfold lifted_entries_contiguous.
intros.
pose proof (msg_lift_prop _ entries_contiguous_invariant _ ltac:(eauto) h).
find_rewrite_lem msg_deghost_spec.
auto.
Qed.
Definition lifted_entries_contiguous_nw (net : ghost_log_network) : Prop :=
forall p t n pli plt es ci,
In p (nwPackets net) ->
snd (pBody p) = AppendEntries t n pli plt es ci ->
contiguous_range_exact_lo es pli.
Proof using rmri rlmli.
unfold lifted_entries_contiguous_nw.
intros.
pose proof msg_lift_prop _ entries_contiguous_nw_invariant _ ltac:(eauto) (mgv_deghost_packet p).
match goal with
| [ H : context [In] |- _ ] => eapply H
end.
- auto using in_mgv_ghost_packet.
- rewrite pBody_mgv_deghost_packet. eauto.
Qed.
Definition lifted_entries_gt_0 (net : ghost_log_network) : Prop :=
forall h e,
In e (log (snd (nwState net h))) -> eIndex e > 0.
Proof using rmri rlmli.
unfold lifted_entries_gt_0.
intros.
pose proof msg_lift_prop _ entries_gt_0_invariant _ ltac:(eauto).
unfold entries_gt_0 in *.
match goal with
| [ H : _ |- _ ] => eapply H; eauto
end.
rewrite msg_deghost_spec.
eauto.
Qed.
Proof using rmri rlmli si rri.
unfold lifted_maxIndex_sanity, maxIndex_lastApplied, maxIndex_commitIndex.
intros.
intuition; simpl in *; repeat find_higher_order_rewrite; update_destruct_simplify; auto.
- erewrite handleAppendEntries_lastApplied by eauto.
assert (sorted (log d)) by (eauto using lifted_handleAppendEntries_logs_sorted).
match goal with
| _ : handleAppendEntries ?h ?s ?t ?n ?pli ?plt ?es ?ci = (?s', ?m) |- _ =>
pose proof handleAppendEntries_log_detailed
h s t n pli plt es ci s' m
end.
intuition; repeat find_rewrite.
+ eauto.
+ subst.
destruct (le_lt_dec (lastApplied (snd (nwState net (pDst p))))
(maxIndex (log d))); auto.
exfalso.
assert (In p (nwPackets net)) by (find_rewrite; intuition).
assert (exists x, eIndex x = maxIndex (log d) /\ In x (log (snd (nwState net (pDst p))))).
{
eapply contiguous_range_exact_lo_elim_exists.
- eapply lifted_entries_contiguous_invariant. auto.
- split.
+ find_apply_lem_hyp maxIndex_non_empty. break_exists.  break_and.
repeat find_rewrite.
eapply contiguous_range_exact_lo_elim_lt.
* eapply lifted_entries_contiguous_nw_invariant; eauto.
* auto.
+ eapply le_trans; [|eauto]. simpl in *. lia.
}
break_exists. break_and.
eapply findAtIndex_None; [|eauto| |]; eauto.
apply msg_lifted_sorted_host; auto.
+ subst.
destruct (le_lt_dec (lastApplied (snd (nwState net (pDst p))))
(maxIndex (log d))); auto.
exfalso.
assert (In p (nwPackets net)) by (find_rewrite; intuition).
break_exists; intuition. find_apply_lem_hyp findAtIndex_elim; intuition.
find_eapply_lem_hyp msg_lifted_sms_nw; eauto;
[|eapply msg_commit_recorded_lift_intro; eauto;
left; repeat find_rewrite; auto using lt_le_weak].
intuition.
* subst.
assert (0 < eIndex x) by (eapply lifted_entries_contiguous_invariant; eauto).
lia.
* destruct (log d); intuition. simpl in *.
intuition; subst; auto.
find_apply_hyp_hyp. lia.
+ destruct (le_lt_dec (lastApplied (snd (nwState net (pDst p)))) pli); intuition;
[eapply le_trans; [| apply sorted_maxIndex_app]; auto;
break_exists; break_and;
erewrite maxIndex_removeAfterIndex by (eauto; apply msg_lifted_sorted_host; auto);
auto|]; [idtac].
destruct (le_lt_dec (lastApplied (snd (nwState net (pDst p)))) (maxIndex es)); intuition;
[match goal with
| |- context [ maxIndex (?ll1 ++ ?ll2) ] =>
pose proof maxIndex_app ll1 ll2
end; simpl in *; intuition|]; [idtac].
assert (exists x, eIndex x = maxIndex es /\ In x (log (snd (nwState net (pDst p))))).
{
eapply contiguous_range_exact_lo_elim_exists.
- eapply lifted_entries_contiguous_invariant. auto.
- split.
+ find_apply_lem_hyp maxIndex_non_empty. break_exists.  break_and.
repeat find_rewrite.
destruct es.
* simpl in *. intuition.
* simpl.  subst.
{ eapply le_lt_trans with (m := eIndex x).
- lia.
- eapply contiguous_range_exact_lo_elim_lt.
+ eapply lifted_entries_contiguous_nw_invariant; eauto.
+ intuition.
}
+ eapply le_trans; [|eauto]. simpl in *. lia.
}
break_exists. intuition.
match goal with
| H : findAtIndex _ _ = None |- _ =>
eapply @findAtIndex_None with (x := x) in H
end; eauto.
* congruence.
* apply msg_lifted_sorted_host. auto.
+   destruct (le_lt_dec (lastApplied (snd (nwState net (pDst p)))) (maxIndex es)); intuition;
[match goal with
| |- context [ maxIndex (?ll1 ++ ?ll2) ] =>
pose proof maxIndex_app ll1 ll2
end; simpl in *; intuition|]; [idtac].
exfalso.
assert (In p (nwPackets net)) by (find_rewrite; intuition).
break_exists; intuition. find_apply_lem_hyp findAtIndex_elim; intuition.
find_copy_apply_lem_hyp maxIndex_non_empty.
break_exists. intuition.
find_eapply_lem_hyp msg_lifted_sms_nw; eauto;
[|eapply msg_commit_recorded_lift_intro; eauto;
left; repeat find_rewrite; auto using lt_le_weak].
match goal with
| _ : In ?x es, _ : maxIndex es = eIndex ?x |- _ =>
assert (pli < eIndex x)
by ( eapply contiguous_range_exact_lo_elim_lt; eauto;
eapply lifted_entries_contiguous_nw_invariant; eauto)
end.
intuition.
match goal with
| H : _ = _ ++ _ |- _ => symmetry in H
end.
destruct es; intuition;
simpl in *;
intuition; subst_max; intuition;
repeat clean;
match goal with
| _ : eIndex ?x' = eIndex ?x, H : context [eIndex ?x'] |- _ =>
specialize (H x); conclude H ltac:(apply in_app_iff; auto)
end; intuition.
- assert (sorted (log d)) by (eauto using lifted_handleAppendEntries_logs_sorted).
match goal with
| _ : handleAppendEntries ?h ?s ?t ?n ?pli ?plt ?es ?ci = (?s', ?m) |- _ =>
pose proof handleAppendEntries_log_detailed
h s t n pli plt es ci s' m
end.
intuition; repeat find_rewrite; try apply max_min_thing;
match goal with
| H : context [ lastApplied _ ] |- _ => clear H
end.
+ eauto.
+ subst.
destruct (le_lt_dec (commitIndex (snd (nwState net (pDst p))))
(maxIndex (log d))); auto.
exfalso.
assert (In p (nwPackets net)) by (find_rewrite; intuition).
assert (exists x, eIndex x = maxIndex (log d) /\ In x (log (snd (nwState net (pDst p))))).
{
eapply contiguous_range_exact_lo_elim_exists.
- eapply lifted_entries_contiguous_invariant. auto.
- split.
+ find_apply_lem_hyp maxIndex_non_empty. break_exists.  break_and.
repeat find_rewrite.
eapply contiguous_range_exact_lo_elim_lt.
* eapply lifted_entries_contiguous_nw_invariant; eauto.
* auto.
+ eapply le_trans; [|eauto]. simpl in *. lia.
}
break_exists. intuition.
find_eapply_lem_hyp findAtIndex_None; eauto.
apply msg_lifted_sorted_host. auto.
+ subst.
destruct (le_lt_dec (commitIndex (snd (nwState net (pDst p))))
(maxIndex (log d))); auto.
exfalso.
assert (In p (nwPackets net)) by (find_rewrite; intuition).
break_exists; intuition. find_apply_lem_hyp findAtIndex_elim; intuition.
find_eapply_lem_hyp msg_lifted_sms_nw; eauto;
[|eapply msg_commit_recorded_lift_intro; eauto;
right; repeat find_rewrite; intuition].
intuition.
* subst.
assert (0 < eIndex x) by (eapply lifted_entries_contiguous_invariant; eauto).
lia.
* destruct (log d); intuition. simpl in *.
intuition; subst; auto.
find_apply_hyp_hyp. lia.
+ destruct (le_lt_dec (commitIndex (snd (nwState net (pDst p)))) pli); intuition;
[eapply le_trans; [| apply sorted_maxIndex_app]; auto;
break_exists; intuition;
erewrite maxIndex_removeAfterIndex; eauto; apply msg_lifted_sorted_host; auto|]; [idtac].
destruct (le_lt_dec (commitIndex (snd (nwState net (pDst p)))) (maxIndex es)); intuition;
[match goal with
| |- context [ maxIndex (?ll1 ++ ?ll2) ] =>
pose proof maxIndex_app ll1 ll2
end; simpl in *; intuition|]; [idtac].
assert (exists x, eIndex x = maxIndex es /\ In x (log (snd (nwState net (pDst p))))).
{
eapply contiguous_range_exact_lo_elim_exists.
- eapply lifted_entries_contiguous_invariant. auto.
- split.
+ find_apply_lem_hyp maxIndex_non_empty. break_exists.  break_and.
repeat find_rewrite.
destruct es.
* simpl in *. intuition.
* simpl.  subst.
{ eapply le_lt_trans with (m := eIndex x).
- lia.
- eapply contiguous_range_exact_lo_elim_lt.
+ eapply lifted_entries_contiguous_nw_invariant; eauto.
+ intuition.
}
+ eapply le_trans; [|eauto]. simpl in *. lia.
}
break_exists. intuition.
match goal with
| H : findAtIndex _ _ = None |- _ =>
eapply @findAtIndex_None with (x := x) in H
end; eauto.
* congruence.
* apply msg_lifted_sorted_host; auto.
+ destruct (le_lt_dec (commitIndex (snd (nwState net (pDst p)))) (maxIndex es)); intuition;
[match goal with
| |- context [ maxIndex (?ll1 ++ ?ll2) ] =>
pose proof maxIndex_app ll1 ll2
end; simpl in *; intuition|]; [idtac].
exfalso.
assert (In p (nwPackets net)) by (find_rewrite; intuition).
break_exists; intuition. find_apply_lem_hyp findAtIndex_elim; intuition.
find_copy_apply_lem_hyp maxIndex_non_empty.
break_exists. intuition.
find_eapply_lem_hyp msg_lifted_sms_nw; eauto;
[|eapply msg_commit_recorded_lift_intro; eauto;
right; repeat find_rewrite; intuition].
match goal with
| _ : In ?x es, _ : maxIndex es = eIndex ?x |- _ =>
assert (pli < eIndex x)
by (eapply contiguous_range_exact_lo_elim_lt; eauto;
eapply lifted_entries_contiguous_nw_invariant; eauto)
end.
intuition.
* match goal with
| H : _ = _ ++ _ |- _ => symmetry in H
end.
destruct es; intuition;
simpl in *;
intuition; subst_max; intuition;
repeat clean;
match goal with
| _ : eIndex ?x' = eIndex ?x, H : context [eIndex ?x'] |- _ =>
specialize (H x); conclude H ltac:(apply in_app_iff; auto)
end; intuition.
Qed.
Proof using.
unfold msg_refined_raft_net_invariant_append_entries_reply,
lifted_maxIndex_sanity, maxIndex_lastApplied, maxIndex_commitIndex.
intuition; repeat find_higher_order_rewrite; update_destruct_simplify; auto.
- erewrite handleAppendEntriesReply_same_lastApplied by eauto.
erewrite handleAppendEntriesReply_same_log by eauto.
auto.
- erewrite handleAppendEntriesReply_same_commitIndex by eauto.
erewrite handleAppendEntriesReply_same_log by eauto.
auto.
Qed.
Proof using.
unfold msg_refined_raft_net_invariant_request_vote,
lifted_maxIndex_sanity, maxIndex_lastApplied, maxIndex_commitIndex.
intuition; repeat find_higher_order_rewrite; update_destruct_simplify; auto.
- erewrite handleRequestVote_same_log by eauto.
erewrite handleRequestVote_same_lastApplied by eauto.
auto.
- erewrite handleRequestVote_same_log by eauto.
erewrite handleRequestVote_same_commitIndex by eauto.
auto.
Qed.
Proof using.
unfold msg_refined_raft_net_invariant_request_vote_reply,
lifted_maxIndex_sanity, maxIndex_lastApplied, maxIndex_commitIndex.
intuition; repeat find_higher_order_rewrite; update_destruct_simplify; auto.
- rewrite handleRequestVoteReply_same_log.
rewrite handleRequestVoteReply_same_lastApplied.
auto.
- rewrite handleRequestVoteReply_same_log.
rewrite handleRequestVoteReply_same_commitIndex.
auto.
Qed.
Proof using.
unfold doLeader.
intros.
repeat break_match; repeat find_inversion; auto.
Qed.
Proof using.
induction l; intros.
- auto.
- simpl. apply IHl. apply Max.max_case_strong; lia.
Qed.
Proof using.
intros. apply fold_left_maximum_le'.
auto.
Qed.
Proof using.
induction l; intros.
- auto.
- simpl in *. revert H.
repeat (apply Max.max_case_strong; intros).
+ eauto.
+ assert (a = y) by lia. subst_max. eauto.
+ subst x. pose proof (fold_left_maximum_le l a).
assert (fold_left max l a = a) by lia.
eauto.
+ subst x.
pose proof (fold_left_maximum_le l a).
assert (fold_left max l a = a) by lia.
assert (a = y) by lia.
subst. auto.
Qed.
Proof using.
induction l; simpl.
- auto.
- intros.
specialize (IHl (max x a)).
intuition.
+ revert H.
apply Max.max_case_strong; intuition.
intuition eauto using fold_left_maxmimum_increase_init.
+ break_exists. break_and. eauto.
Qed.
Proof using.
intros.
destruct (fold_left_maximum_cases l x).
- find_rewrite. auto.
- break_exists. break_and. find_rewrite. eauto.
Qed.
Proof using.
unfold doLeader.
intros.
repeat break_match; repeat find_inversion; simpl; auto;
apply fold_left_maximum_ind; auto.
- intros. do_in_map. find_apply_lem_hyp filter_In.
subst. break_and.
apply maxIndex_is_max; eauto using findGtIndex_in.
- intros. do_in_map. find_apply_lem_hyp filter_In.
break_and. subst.
apply maxIndex_is_max; eauto using findGtIndex_in.
Qed.
Proof using rmri si rri.
unfold msg_refined_raft_net_invariant_do_leader,
lifted_maxIndex_sanity, maxIndex_lastApplied, maxIndex_commitIndex.
intuition; repeat find_higher_order_rewrite; update_destruct_simplify; auto.
- erewrite doLeader_same_log by eauto.
erewrite doLeader_same_lastApplied by eauto.
repeat match goal with
| [ H : forall _ , _ |- _ ] => specialize (H h0)
end.
unfold mgv_refined_base_params, raft_refined_base_params, refined_base_params in *.
simpl in *.
repeat find_rewrite. auto.
- repeat match goal with
| [ H : forall _ , _ |- _ ] => specialize (H h0)
end.
unfold mgv_refined_base_params, raft_refined_base_params, refined_base_params in *.
simpl in *.
repeat find_rewrite. simpl in *.
erewrite doLeader_same_commitIndex; eauto.
find_eapply_lem_hyp (msg_lifted_sorted_host net h0).
unfold mgv_refined_base_params, raft_refined_base_params, refined_base_params in *.
simpl in *.
find_rewrite. auto.
Qed.

Lemma doGenericServer_lastApplied :
forall h st out st' ms,
doGenericServer h st = (out, st', ms) ->
lastApplied st' = lastApplied st \/
(lastApplied st < commitIndex st  /\
lastApplied st' = commitIndex st).