Proof using nisi ollpti rlmli llli rri.
red. unfold prefix_within_term_inductive. intros.
match goal with
| H : nwState ?net ?h = (?gd, ?d) |- _ =>
replace gd with (fst (nwState net h)) in * by (rewrite H; reflexivity);
replace d with (snd (nwState net h)) in * by (rewrite H; reflexivity);
clear H
end.
intuition.
- unfold allEntries_leaderLogs_prefix_within_term in *.
simpl in *. intros.
repeat find_higher_order_rewrite.
repeat destruct_update; simpl in *; eauto.
- unfold log_leaderLogs_prefix_within_term in *.
simpl in *. intros.
repeat find_higher_order_rewrite.
repeat destruct_update; simpl in *; eauto;
erewrite doLeader_log; eauto; eauto.
- unfold allEntries_log_prefix_within_term in *.
simpl in *. intros.
repeat find_higher_order_rewrite.
repeat destruct_update; simpl in *; eauto;
erewrite doLeader_log; eauto; eauto.
- find_copy_apply_lem_hyp entries_sorted_invariant.
unfold entries_sorted in *.
unfold allEntries_append_entries_prefix_within_term_nw in *.
simpl in *. intros.
repeat find_higher_order_rewrite.
repeat destruct_update; simpl in *; eauto.
+ find_apply_hyp_hyp.
intuition;
[repeat find_reverse_rewrite; eauto|].
do_in_map. subst. simpl in *.
find_eapply_lem_hyp doLeader_spec; eauto. intuition; subst.
* left. find_apply_lem_hyp findGtIndex_necessary. intuition.
apply findGtIndex_sufficient; eauto using allEntries_gt_0_invariant.
unfold allEntries_log_prefix_within_term, prefix_within_term in *. eauto.
* { break_exists. break_and. find_apply_lem_hyp findAtIndex_elim. break_and.
subst. find_apply_lem_hyp findGtIndex_necessary. break_and.
eapply_prop_hyp allEntries_log_prefix_within_term allEntries; eauto;
conclude_using eauto.
match goal with
| _ : eIndex ?e <= eIndex ?e', _ : eIndex ?e' > eIndex ?x |- _ =>
destruct (lt_eq_lt_dec (eIndex e) (eIndex x))
end; intuition.
- right. right. intuition.
repeat find_reverse_rewrite.
eapply sorted_term_index_lt; eauto.
repeat find_rewrite. auto.
- right. left. intuition.
repeat find_reverse_rewrite.
match goal with
| |- eTerm ?e = eTerm ?x =>
cut (e = x); intros; subst; intuition
end. repeat find_rewrite.
eapply uniqueIndices_elim_eq; eauto using sorted_uniqueIndices.
- left. apply findGtIndex_sufficient; eauto.
}
* break_exists. intuition.
find_eapply_lem_hyp nextIndex_sanity; eauto. break_exists.
unfold ghost_data in *. simpl in *. congruence.
+ find_apply_hyp_hyp.
intuition;
[repeat find_reverse_rewrite; eauto|].
do_in_map. subst. simpl in *.
find_eapply_lem_hyp doLeader_spec; eauto. intuition; subst.
* left. find_apply_lem_hyp findGtIndex_necessary. intuition.
apply findGtIndex_sufficient; eauto using allEntries_gt_0_invariant.
unfold allEntries_log_prefix_within_term, prefix_within_term in *. eauto.
* { break_exists. break_and. find_apply_lem_hyp findAtIndex_elim. break_and.
subst. find_apply_lem_hyp findGtIndex_necessary. break_and.
eapply_prop_hyp allEntries_log_prefix_within_term allEntries; eauto;
conclude_using eauto.
match goal with
| _ : eIndex ?e <= eIndex ?e', _ : eIndex ?e' > eIndex ?x |- _ =>
destruct (lt_eq_lt_dec (eIndex e) (eIndex x))
end; intuition.
- right. right. intuition.
repeat find_reverse_rewrite.
eapply sorted_term_index_lt; eauto.
repeat find_rewrite. auto.
- right. left. intuition.
repeat find_reverse_rewrite.
match goal with
| |- eTerm ?e = eTerm ?x =>
cut (e = x); intros; subst; intuition
end. repeat find_rewrite.
eapply uniqueIndices_elim_eq; eauto using sorted_uniqueIndices.
- left. apply findGtIndex_sufficient; eauto.
}
* break_exists. intuition.
find_eapply_lem_hyp nextIndex_sanity; eauto. break_exists.
unfold ghost_data in *. simpl in *. congruence.
- unfold append_entries_leaderLogs_prefix_within_term in *.
intros. simpl in *.
match goal with
| H : In ?x (leaderLogs (fst (st' ?h))) |- _ =>
assert (In x (leaderLogs (fst (nwState net h)))) by
(find_higher_order_rewrite;
destruct_update; simpl in *; auto);
clear H
end.
find_apply_hyp_hyp. intuition; eauto.
do_in_map. subst. simpl in *.
eapply prefix_within_term_subset; [eapply_prop log_leaderLogs_prefix_within_term|];
eauto using doLeader_in_entries_in_log.
- unfold append_entries_log_prefix_within_term in *.
intros. simpl in *.
match goal with
| |- context [log (snd (st' ?h)) ] =>
assert (log (snd (st' h)) = log (snd (nwState net h)))
by (find_higher_order_rewrite; destruct_update; simpl in *; auto;
eapply doLeader_log; eauto)
end.
repeat find_rewrite.
find_apply_hyp_hyp. intuition; eauto.
do_in_map. subst. simpl in *.
eapply prefix_within_term_subset; [eapply log_log_prefix_within_term_invariant|];
eauto using doLeader_in_entries_in_log.
Qed.

(* Specifications: *)
Lemma update_elections_data_requestVoteReply_leaderLogs' :
forall h h' t  st t' ll' r,
In (t', ll') (leaderLogs (update_elections_data_requestVoteReply h h' t r st)) ->
In (t', ll') (leaderLogs (fst st)) \/ ll' = log (snd st).