Proof using aertsi aelmi llsi ollpti rlmli llli.
red. unfold prefix_within_term_inductive. intuition.
- unfold allEntries_leaderLogs_prefix_within_term. intros.
simpl in *. subst. repeat find_higher_order_rewrite.
repeat destruct_update; simpl in *; eauto;
try find_rewrite_lem update_elections_data_appendEntries_leaderLogs; eauto;
solve [
eapply prefix_within_term_union;
[|idtac|eapply update_elections_data_appendEntries_allEntries; eauto]; eauto].
- unfold log_leaderLogs_prefix_within_term. intros.
simpl in *. subst. repeat find_higher_order_rewrite.
repeat destruct_update; simpl in *; eauto;
try find_rewrite_lem update_elections_data_appendEntries_leaderLogs; eauto;
find_apply_lem_hyp handleAppendEntries_log; intuition;
repeat find_rewrite; eauto;
match goal with
| |- context [?es ++ removeAfterIndex ?l _] =>
eapply prefix_within_term_union with (l1' := es) (l1'' := l)
end; eauto;
intros;
do_in_app; intuition; eauto using removeAfterIndex_in.
- unfold allEntries_log_prefix_within_term. intros.
simpl in *. subst. repeat find_higher_order_rewrite.
repeat destruct_update; simpl in *; eauto;
try find_rewrite_lem update_elections_data_appendEntries_leaderLogs; eauto;
find_apply_lem_hyp handleAppendEntries_log; intuition; subst; repeat find_rewrite;
try solve [
eapply prefix_within_term_union;
[|idtac|solve[eapply update_elections_data_appendEntries_allEntries; eauto]]; eauto].
Unshelve. all:eauto.
+ unfold prefix_within_term, allEntries_append_entries_prefix_within_term_nw in *.
intros.
find_apply_lem_hyp update_elections_data_appendEntries_allEntries. intuition.
eapply_prop_hyp pBody pBody; eauto. intuition; try omega.
find_apply_lem_hyp allEntries_gt_0_invariant; eauto. omega.
+ unfold prefix_within_term, allEntries_append_entries_prefix_within_term_nw in *.
intros.
find_apply_lem_hyp update_elections_data_appendEntries_allEntries. intuition.
do_in_app. intuition.
* {
copy_eapply_prop_hyp pBody pBody; eauto. intuition.
- subst. apply in_app_iff. right.
apply removeAfterIndex_le_In; auto.
break_exists. intuition.
assert (x = e) by (eapply allEntries_log_matching_invariant; eauto).
subst. auto.
- break_exists. intuition. subst.
(* use the fact that the lists are sorted to prove eTerm e = eTerm x, then use allEntries_log_pwt *)
match goal with
| _ : eIndex ?e < eIndex ?x |- _ =>
destruct (lt_eq_lt_dec (eTerm e) (eTerm x))
end; intuition; try omega.
+ exfalso.
eapply append_entries_request_term_sanity_invariant in H1; eauto.
conclude_using eauto; omega.
+ apply in_app_iff. right.
apply removeAfterIndex_le_In; [omega|].
eapply_prop allEntries_log_prefix_within_term; eauto; omega.
}
* find_copy_apply_lem_hyp removeAfterIndex_in;
find_apply_lem_hyp removeAfterIndex_In_le; [|eapply entries_sorted_invariant; eauto].
apply in_app_iff; right. apply removeAfterIndex_le_In; eauto; try omega.
eapply_prop allEntries_log_prefix_within_term; eauto.
+ unfold prefix_within_term, allEntries_append_entries_prefix_within_term_nw in *.
intros.
eapply_prop_hyp pBody pBody; eauto. intuition; try omega.
find_apply_lem_hyp allEntries_gt_0_invariant; eauto. omega.
+ unfold prefix_within_term, allEntries_append_entries_prefix_within_term_nw in *.
intros.
do_in_app. intuition.
* {
copy_eapply_prop_hyp pBody pBody; eauto. intuition.
- subst. apply in_app_iff. right.
apply removeAfterIndex_le_In; auto.
break_exists. intuition.
assert (x = e) by (eapply allEntries_log_matching_invariant; eauto).
subst. auto.
- break_exists. intuition. subst.
(* use the fact that the lists are sorted to prove eTerm e = eTerm x, then use allEntries_log_pwt *)
match goal with
| _ : eIndex ?e < eIndex ?x |- _ =>
destruct (lt_eq_lt_dec (eTerm e) (eTerm x))
end; intuition; try omega.
+ exfalso.
eapply append_entries_request_term_sanity_invariant in H1; eauto.
conclude_using eauto. omega.
+ apply in_app_iff. right.
apply removeAfterIndex_le_In; [omega|].
eapply_prop allEntries_log_prefix_within_term; eauto; omega.
}
* find_copy_apply_lem_hyp removeAfterIndex_in;
find_apply_lem_hyp removeAfterIndex_In_le; [|eapply entries_sorted_invariant; eauto].
apply in_app_iff; right. apply removeAfterIndex_le_In; eauto; try omega.
eapply_prop allEntries_log_prefix_within_term; eauto.
- (* nw nw invariant *)
unfold allEntries_append_entries_prefix_within_term_nw. intros.
simpl in *. subst. repeat find_higher_order_rewrite.
repeat destruct_update; simpl in *; eauto;
try find_rewrite_lem update_elections_data_appendEntries_leaderLogs; eauto.
+ find_apply_lem_hyp update_elections_data_appendEntries_allEntries.
intuition.
* eapply_prop_hyp allEntries_append_entries_prefix_within_term_nw In;
try eapply H13; eauto; repeat find_rewrite; intuition.
find_apply_hyp_hyp. intuition; [in_crush|].
subst. simpl in *. subst.
unfold handleAppendEntries in *. repeat break_match; find_inversion; congruence.
*
find_eapply_lem_hyp append_entries_append_entries_prefix_within_term_invariant.
conclude_using eauto. find_rewrite.
eapply H0.
Focus 5. eauto.
all:eauto.
find_apply_hyp_hyp. intuition; [find_rewrite; in_crush|].
repeat (subst; simpl in *).
unfold handleAppendEntries in *; repeat break_match; find_inversion; congruence.
+ find_apply_hyp_hyp. intuition.
* copy_eapply_prop_hyp allEntries_append_entries_prefix_within_term_nw pBody;
[|repeat find_rewrite; in_crush].
repeat conclude_using eauto. repeat find_rewrite. intuition.
* exfalso.
subst. simpl in *. subst.
unfold handleAppendEntries in *; repeat break_match; find_inversion; congruence.
- (* trivial *)
unfold append_entries_leaderLogs_prefix_within_term. intros.
simpl in *. find_apply_hyp_hyp. intuition;
[|subst; simpl in *; subst;
unfold handleAppendEntries in *; repeat break_match; find_inversion; congruence].
repeat find_higher_order_rewrite.
repeat destruct_update; simpl in *; eauto;
try find_rewrite_lem update_elections_data_appendEntries_leaderLogs; eauto.
- unfold append_entries_log_prefix_within_term. intros. simpl in *. subst.
find_apply_hyp_hyp.
intuition; [| subst; simpl in *; subst;
unfold handleAppendEntries in *; repeat break_match;
find_inversion; congruence].
find_higher_order_rewrite.
destruct_update; simpl in *; eauto.
find_apply_lem_hyp handleAppendEntries_log. intuition; subst; repeat find_rewrite; eauto.
+ unfold prefix_within_term. intros.
find_copy_apply_lem_hyp append_entries_append_entries_prefix_within_term_invariant.
match goal with
| H : append_entries_append_entries_prefix_within_term_nw _,
_ : pBody ?p = AppendEntries ?t ?n ?pli ?plt ?es ?ci,
_ : pBody ?p' = AppendEntries ?t' ?n' ?pli' ?plt' ?es' ?ci',
_ : In ?e' ?es', _ : In ?e ?es |-
In ?e ?es' =>
specialize (H p t n pli plt es ci p' t' n' pli' plt' es' ci' e e')
end.
conclude_using ltac:(repeat find_rewrite; in_crush).
concludes.
conclude_using ltac:(repeat find_rewrite; in_crush).
repeat concludes. intuition.
* exfalso.
match goal with
| _ : eIndex ?e = 0 |- _ =>
cut (eIndex e > 0); [intuition|]
end.
eapply entries_gt_0_nw_invariant; [|idtac|idtac|eauto]; [|idtac|eauto]; eauto.
* omega.
+ { unfold prefix_within_term. intros.
do_in_app. intuition.
- find_copy_apply_lem_hyp append_entries_append_entries_prefix_within_term_invariant.
match goal with
| H : append_entries_append_entries_prefix_within_term_nw _,
_ : pBody ?p = AppendEntries ?t ?n ?pli ?plt ?es ?ci,
_ : pBody ?p' = AppendEntries ?t' ?n' ?pli' ?plt' ?es' ?ci',
_ : In ?e' ?es', _ : In ?e ?es |-
In ?e (?es' ++ _) =>
specialize (H p t n pli plt es ci p' t' n' pli' plt' es' ci' e e')
end.
conclude_using ltac:(repeat find_rewrite; in_crush).
concludes.
conclude_using ltac:(repeat find_rewrite; in_crush).
repeat concludes. intuition.
+ (* use  log matching *)
break_exists. intuition.
subst.
apply in_app_iff. right.
apply removeAfterIndex_le_In; auto.
eapply entries_match_nw_host_invariant. Focus 8. eauto.
Focus 3. eauto. all:eauto.
+ (* contra terms_ge_prevTerm *)
find_eapply_lem_hyp append_entries_request_term_sanity_invariant; eauto.
repeat find_rewrite.
match goal with
| _ : ?x >= ?y, _ : ?x <= ?y |- _ =>
assert (x = y) by eauto using le_antisym
end. subst.
break_exists. intuition.
subst.
apply in_app_iff. right.
apply removeAfterIndex_le_In; auto; [omega|].
eapply_prop append_entries_log_prefix_within_term. Focus 6. eauto.
Focus 5. eauto. Focus 2. eauto. all:eauto; repeat find_rewrite; intuition.
- apply in_app_iff. right.
find_copy_apply_lem_hyp removeAfterIndex_in.
find_apply_lem_hyp removeAfterIndex_In_le; [|eapply entries_sorted_invariant; eauto].
eapply removeAfterIndex_le_In; [omega|].
eapply_prop append_entries_log_prefix_within_term. Focus 6. eauto.
Focus 5. eauto. Focus 2. eauto. all:eauto.
}
Qed.

Lemma handleClientRequest_log' :
forall h st client id c out st' ms e,
handleClientRequest h st client id c = (out, st', ms) ->
In e (log st') ->
In e (log st) \/
eIndex e = S (maxIndex (log st))
/\ eTerm e = currentTerm st
/\ type st = Leader.