Section OutputGreatestId.
Context {orig_base_params : BaseParams}.
Context {one_node_params : OneNodeParams orig_base_params}.
Context {raft_params : RaftParams orig_base_params}.
Context {lmi : log_matching_interface}.
Context {si : sorted_interface}.
Context {aemi : applied_entries_monotonic_interface}.
Context {smsi : state_machine_safety_interface}.
Context {misi : max_index_sanity_interface}.
Context {smci : state_machine_correct_interface}.
Context {lacimi : lastApplied_commitIndex_match_interface}.
Proof using.
intros. unfold key_in_output_trace in *.
break_exists_exists.
intuition. do_in_app; intuition.
exfalso. eauto.
Qed.
Proof using.
intros.
unfold key_in_output_list in *.
break_exists; do_in_app; intuition eauto.
Qed.
Proof using.
intuition.
unfold key_in_output_list in *.
break_exists; intuition.
Qed.
Proof using.
intros. unfold doLeader, advanceCommitIndex in *.
repeat break_match; find_inversion; intuition;
find_apply_lem_hyp key_in_output_list_empty; auto.
Qed.
Proof using.
intros. unfold handleInput, handleTimeout, handleClientRequest, tryToBecomeLeader in *.
repeat break_match; find_inversion; intuition eauto using key_in_output_list_empty;
unfold key_in_output_list in *; break_exists; simpl in *; intuition; congruence.
Qed.
Proof using.
intros. unfold has_key. break_match; subst; simpl in *.
break_if; repeat (do_bool; intuition).
Qed.
Proof using.
intros. unfold has_key in *. break_match.
simpl in *. subst.
break_if; repeat (do_bool; intuition); try congruence.
Qed.
Proof using.
induction l; intros; simpl in *; intuition.
- find_inversion. simpl in *. intuition.
- unfold cacheApplyEntry, applyEntry in *.
repeat break_match; repeat find_inversion; simpl in *; intuition; eauto;
try solve
[find_inversion; find_rewrite; find_inversion; do_bool; lia];
try solve [find_inversion; repeat find_rewrite; congruence].
+ do_bool. destruct (clientId_eq_dec (eClient a) client).
* subst. find_rewrite. find_inversion.
eapply IHl; [eapply lt_le_trans; eauto|idtac|idtac|]; eauto.
unfold getLastId.
simpl. eauto using get_set_same.
* eapply IHl; eauto.
unfold getLastId in *.
simpl. rewrite get_set_diff; eauto.
+ do_bool. destruct (clientId_eq_dec (eClient a) client).
* repeat find_rewrite. congruence.
* eapply IHl; eauto.
unfold getLastId in *.
simpl. rewrite get_set_diff; eauto.
+ do_bool. destruct (clientId_eq_dec (eClient a) client).
* repeat find_rewrite. find_inversion.
eapply IHl; [eapply lt_le_trans; eauto|idtac|idtac|]; eauto.
unfold getLastId.
simpl. eauto using get_set_same.
* eapply IHl; eauto.
unfold getLastId in *.
simpl. rewrite get_set_diff; eauto.
+ do_bool. destruct (clientId_eq_dec (eClient a) client).
* repeat find_rewrite. congruence.
* eapply IHl; eauto.
unfold getLastId in *.
simpl. rewrite get_set_diff; eauto.
Qed.
Proof using.
induction l; intros; simpl in *; intuition.
- find_inversion. simpl in *. intuition.
- repeat break_match.
+ subst.
find_inversion. do_in_app. intuition.
* do_in_map. find_inversion. eauto using has_key_own_key.
* { destruct (has_key client id' a) eqn:?; eauto.
exfalso.
unfold cacheApplyEntry, applyEntry in *.
find_apply_lem_hyp has_key_true_necessary. intuition.
repeat break_match; repeat find_rewrite; find_inversion; do_bool; subst_max.
- find_eapply_lem_hyp applyEntries_cache; eauto; lia.
- find_eapply_lem_hyp applyEntries_cache; eauto; lia.
- find_eapply_lem_hyp applyEntries_cache; eauto;
unfold getLastId in *; simpl in *; eauto using get_set_same.
- find_eapply_lem_hyp applyEntries_cache; eauto;
unfold getLastId in *; simpl in *; eauto using get_set_same.
}
+ simpl in *. find_inversion.
{ destruct (has_key client id' a) eqn:?; eauto.
exfalso.
unfold cacheApplyEntry, applyEntry in *.
find_apply_lem_hyp has_key_true_necessary. intuition.
repeat break_match; repeat find_rewrite; find_inversion; do_bool; subst.
- find_eapply_lem_hyp applyEntries_cache; eauto; lia.
- find_eapply_lem_hyp applyEntries_cache; eauto; lia.
- eapply applyEntries_cache in Heqp0; eauto;
unfold getLastId in *; simpl in *; eauto using get_set_same.
- eapply applyEntries_cache in Heqp0; eauto;
unfold getLastId in *; simpl in *; eauto using get_set_same.
}
Qed.
Proof using lmi.
intros. find_apply_lem_hyp log_matching_invariant.
unfold log_matching, log_matching_hosts in *.
intuition.
unfold contiguous_range_exact_lo. intuition; eauto.
find_apply_hyp_hyp. lia.
Qed.
Proof using lacimi smci si lmi.
intros.
find_copy_apply_lem_hyp logs_sorted_invariant.
pose proof entries_contiguous.
match goal with
| H : context [contiguous_range_exact_lo] |- _ =>
specialize (H net)
end.
concludes. simpl in *.
find_copy_apply_lem_hyp state_machine_correct_invariant.
unfold state_machine_correct in *. intuition.
unfold logs_sorted in *. intuition.
unfold key_in_output_list in *.
match goal with | H : exists _, _ |- _ => destruct H as [o] end.
unfold doGenericServer in *. break_let. simpl in *.
find_inversion. simpl in *.
pose proof Heqp as Heqp'.
eapply applyEntries_before in Heqp; eauto.
match goal with
| H : before_func _ _ ?l |- _=>
eapply before_func_prepend with
(l' := (rev (removeAfterIndex (log (nwState net h))
(lastApplied (nwState net h)))))
in H
end; eauto;
[|intros;
find_apply_lem_hyp In_rev;
apply Bool.not_true_iff_false;
intuition; unfold has_key in *;
break_match; break_if; repeat (do_bool; intuition); simpl in *;
eapply_prop_hyp client_cache_complete In; eauto;
break_exists; intuition; simpl in *;
subst;
match goal with
| Ha : context [applyEntries], Hg : getLastId _ _ = Some (?x, _) |- _ =>
eapply applyEntries_cache with (id' := x) in Ha
end; eauto; lia;
intuition; find_rewrite; repeat find_rewrite].
rewrite <- rev_app_distr in *.
eapply before_func_prefix; eauto.
use_applyEntries_spec. subst. simpl in *.
break_if.
- do_bool.
erewrite findGtIndex_removeAfterIndex_i_lt_i' in *; eauto.
match goal with
| |- context [applied_entries (update _ ?sigma ?h ?st)] =>
pose proof applied_entries_update sigma h st
end. conclude_using intuition.
intuition; simpl in *;
unfold raft_data in *; simpl in *; find_rewrite; auto using Prefix_refl.
unfold applied_entries in *.
break_exists. intuition. repeat find_rewrite.
eapply contiguous_sorted_subset_prefix; eauto using removeAfterIndex_contiguous, removeAfterIndex_sorted.
intros.
find_copy_apply_lem_hyp removeAfterIndex_In_le; eauto.
find_apply_lem_hyp removeAfterIndex_in.
apply removeAfterIndex_le_In; eauto; try lia.
find_copy_apply_lem_hyp commitIndex_lastApplied_match_invariant.
unfold commitIndex_lastApplied_match in *. simpl in *.
match goal with
| _ : ?x >= ?y |- _ =>
assert (y <= x) by lia
end.
eapply_prop_hyp le le; eauto. intuition.
- do_bool.
erewrite findGtIndex_removeAfterIndex_i'_le_i in *; eauto.
match goal with
| |- context [applied_entries (update _ ?sigma ?h ?st)] =>
pose proof applied_entries_update sigma h st
end. conclude_using intuition.
intuition; simpl in *;
unfold raft_data in *; simpl in *; find_rewrite; auto using Prefix_refl.
unfold applied_entries in *.
break_exists. intuition. repeat find_rewrite.
eapply contiguous_sorted_subset_prefix; eauto using removeAfterIndex_contiguous, removeAfterIndex_sorted.
intros.
find_copy_apply_lem_hyp removeAfterIndex_In_le; eauto.
find_apply_lem_hyp removeAfterIndex_in.
apply removeAfterIndex_le_In; eauto; try lia.
find_copy_apply_lem_hyp lastApplied_lastApplied_match_invariant.
unfold lastApplied_lastApplied_match in *. simpl in *.
match goal with
| _ : ?x >= ?y |- _ =>
assert (y <= x) by lia
end.
eapply_prop_hyp le le; eauto. intuition.
Qed.

Lemma output_implies_greatest :
forall failed net failed' net' o client id id',
raft_intermediate_reachable net ->
@step_failure _ _ failure_params (failed, net) (failed', net') o ->
key_in_output_trace client id o ->
id < id' ->
before_func (has_key client id) (has_key client id') (applied_entries (nwState net')).