Section CommonTheorems.
Context {orig_base_params : BaseParams}.
Context {one_node_params : OneNodeParams orig_base_params}.
Context {raft_params : RaftParams orig_base_params}.
Proof using.
unfold uniqueIndices.
eauto using NoDup_map_elim.
Qed.
Proof using.
intros.
simpl in *. intuition;
find_apply_hyp_hyp; intuition.
Qed.
Proof using.
induction ys; intros; simpl in *.
- break_match; intuition.
- break_match; intuition.
subst. apply sorted_cons; eauto.
intros. eauto using subseq_In.
Qed.
Proof using.
induction l; intros.
- simpl in *. intuition.
- simpl in *. intuition.
+ subst. auto with *.
+ find_apply_hyp_hyp. lia.
Qed.
Proof using.
induction l; intros.
- simpl in *. intuition.
- simpl in *. intuition.
+ subst. auto with *.
+ find_apply_hyp_hyp. lia.
Qed.
Proof using.
intros. intro.
find_apply_lem_hyp maxIndex_is_max; auto.
subst. lia.
Qed.
Proof using.
destruct l; intros; simpl in *; eauto; congruence.
Qed.
Proof using.
induction l; intros; simpl; auto.
repeat break_match; intuition.
- find_inversion. eauto using subseq_refl.
- right. find_reverse_rewrite. auto.
Qed.
Proof using.
intros. eauto using removeAfterIndex_subseq, sorted_subseq.
Qed.
Proof using.
eauto using removeAfterIndex_subseq, subseq_In.
Qed.
Proof using.
induction l; intros; intro.
- intuition.
- simpl in *. break_match; try discriminate. intuition.
+ subst. rewrite <- beq_nat_refl in *. discriminate.
+ find_copy_apply_hyp_hyp. intuition. break_if; do_bool; eauto. lia.
Qed.
Proof using.
induction l; intros.
- discriminate.
- simpl in *. break_match.
+ find_inversion. auto.
+ break_if; eauto; discriminate.
Qed.
Proof using.
induction l; intros.
- discriminate.
- simpl in *. break_match.
+ find_inversion. apply beq_nat_true in Heqb. auto.
+ break_if; eauto; discriminate.
Qed.
Proof using.
eauto using subseq_NoDup, removeAfterIndex_subseq.
Qed.
Notation disjoint xs ys := (forall x, In x xs -> In x ys -> False).
Proof using.
induction xs; intros.
- intuition.
- simpl in *. break_if; simpl in *; intuition.
subst. do_bool. lia.
Qed.
Proof using.
induction xs; intros.
- simpl in *. intuition.
- simpl in *.
break_if; simpl in *; do_bool; intuition; subst; auto.
find_apply_hyp_hyp. lia.
Qed.
Proof using.
induction xs; intros.
- simpl in *. intuition.
- simpl in *.
break_match; simpl in *; intuition;
subst; do_bool;
match goal with
| e : entry, H : forall _, _ = _ \/ _ -> _ |- _ =>
specialize (H e)
end;
intuition.
+ eauto using removeAfterIndex_le_In.
+ find_apply_hyp_hyp. intuition.
match goal with
| _ : eIndex ?e <= ?li, _ : eIndex ?e > eIndex ?e' |- _ =>
assert (eIndex e' <= li) by lia
end.
eauto using removeAfterIndex_le_In.
Qed.
Proof using.
induction xs; intros.
- reflexivity.
- simpl.
find_copy_apply_hyp_hyp.
repeat (break_if; simpl in *; intuition); try discriminate.
do_bool. lia.
Qed.
Proof using.
induction xs; intros; simpl.
- auto.
- repeat (break_match; simpl); intuition; try discriminate.
+ eauto using subseq_refl.
+ do_bool. assert (j < i) by lia.
rewrite removeAfterIndex_le with (j := i) (i := j) at 1; auto; lia.
+ do_bool. assert (i < j) by lia.
rewrite removeAfterIndex_le with (i := i) (j := j) at 2; auto; lia.
Qed.
Proof using.
auto using subseq_subseq_eq, removeAfterIndex_2_subseq.
Qed.
Proof using.
intros.
pose proof Min.min_spec i j. intuition.
- find_rewrite. rewrite removeAfterIndex_le with (i := i) (j := j) at 2;
eauto using removeAfterIndex_comm; lia.
- find_rewrite.
rewrite <- removeAfterIndex_le with (i := j) (j := i);
auto; lia.
Qed.
Proof using.
induction xs; intros; simpl in *; intuition; break_match; try discriminate.
- subst. do_bool. congruence.
- do_bool. break_if; eauto.
do_bool. find_apply_hyp_hyp. intuition.
Qed.
Proof using.
intros.
eapply NoDup_map_elim with (f := eIndex); eauto using findAtIndex_in, removeAfterIndex_in.
apply findAtIndex_index in H0.
apply findAtIndex_index in H1.
congruence.
Qed.
Proof using.
unfold uniqueIndices.
induction ys; intros.
- simpl in *. break_match; intuition.
- simpl in *. break_match; intuition.
+ simpl. constructor.
+ subst. simpl in *. invc H0. constructor; auto.
intro. apply H3.
eapply subseq_In; eauto.
apply subseq_map. auto.
+ subst. invc H0. eauto.
Qed.
Proof using.
induction xs; intros.
- simpl. auto.
- simpl. repeat break_match; auto.
+ find_inversion. eauto.
+ congruence.
Qed.
Proof using.
eauto using subseq_In, subseq_findGtIndex.
Qed.
Proof using.
induction entries; intros.
- simpl in *. intuition.
- simpl in *. break_if; intuition.
+ subst. in_crush.
+ subst. do_bool. lia.
+ do_bool. find_apply_hyp_hyp. lia.
Qed.
Definition contiguous_range_exact_lo xs lo :=
(forall i,
lo < i <= maxIndex xs ->
exists e,
eIndex e = i /\
In e xs) /\
(forall e,
In e xs ->
lo < eIndex e).
Proof with eauto using subseq_uniqueIndices, removeAfterIndex_subseq.
intros...
Qed.
Proof using.
destruct xs; intros.
- simpl. lia.
- destruct ys; simpl in *.
+ match goal with
| [ H : forall _, _ = _ \/ _ -> _, a : entry |- _ ] =>
solve [ specialize (H a); intuition ]
end.
+ match goal with
| [ H : forall _, _ = _ \/ _ -> _ |- eIndex ?a <= _ ] =>
specialize (H a); intuition
end; subst; auto.
find_apply_hyp_hyp. lia.
Qed.
Proof using.
destruct xs; intros.
- simpl in *. lia.
- simpl in *. eauto.
Qed.
Proof using.
induction l; intuition.
Qed.
Proof using.
intros.
apply maxIndex_subset; eauto using removeAfterIndex_sorted.
intros. eauto using removeAfterIndex_in.
Qed.
Proof using.
induction l; intros; simpl in *; intuition.
- subst. break_if; do_bool; try lia.
reflexivity.
- break_if; simpl in *.
+ do_bool.
match goal with
| H : forall _, In _ _ -> _ |- _ =>
specialize (H2 e)
end. intuition. lia.
+ eauto.
Qed.
Proof using.
intros.
destruct es; simpl in *.
- lia.
- congruence.
Qed.
Proof using one_node_params.
intros new current prev e Hsorted Huniq Hinv. intros. red. intros.
intuition.
- destruct (le_lt_dec i prev).
+ unfold contiguous_range_exact_lo in *. intuition.
match goal with
| H: forall _, _ < _ <= _ current -> _, H' : In _ current |- _ =>
specialize (H i); apply maxIndex_is_max in H'; auto; forward H; intuition
end.
break_exists. exists x. intuition.
apply in_or_app. right. subst.
eapply removeAfterIndex_le_In; eauto.
+ pose proof maxIndex_app new (removeAfterIndex current prev). intuition.
* find_rewrite.
unfold contiguous_range_exact_lo in *. intuition.
match goal with
| H: forall _, _ < _ <= _ new -> _ |- _ =>
specialize (H i); auto; forward H; intuition
end. break_exists. exists x. intuition.
* subst. simpl in *. clean.
exfalso.
pose proof maxIndex_removeAfterIndex current (eIndex e) e.
intuition.
- unfold contiguous_range_exact_lo in *.
do_in_app. intuition.
+ firstorder auto with zarith.
+ firstorder using removeAfterIndex_in.
Qed.
Proof using.
intros.
exists x. intuition.
Qed.
Proof using.
induction entries; intros; simpl in *; intuition.
- break_if; simpl in *; intuition; right; eapply IHentries; eauto.
- break_if;
simpl in *; intuition.
+ do_bool. subst. lia.
+ simpl in *; intuition; eapply IHentries; eauto.
Qed.
Proof using.
intros entries x Hsorted; intros. specialize (H i).
conclude H ltac:(lia).
break_exists. exists x0. intuition.
apply findGtIndex_sufficient; auto; lia.
Qed.
Proof using.
intros. destruct entries; simpl; auto.
break_if; simpl; intuition.
Qed.
Proof using.
intros.
pose proof findAtIndex_in _ _ _ H.
pose proof findAtIndex_index _ _ _ H.
eapply uniqueIndices_elim_eq; eauto.
Qed.
Definition entries_match' entries entries' :=
forall e e' e'',
eIndex e = eIndex e' ->
eTerm e = eTerm e' ->
In e entries ->
In e' entries' ->
eIndex e'' <= eIndex e ->
(In e'' entries -> In e'' entries').
Proof using.
unfold entries_match, entries_match'.
intros. intuition.
- eapply H; eauto.
- eapply (H e' e); eauto with *.
Qed.
Definition contiguous
(prevLogIndex : logIndex)
(prevLogTerm : term)
(leaderLog entries : list entry) : Prop :=
(prevLogIndex = 0 \/
exists e, findAtIndex leaderLog prevLogIndex = Some e /\
eTerm e = prevLogTerm) /\
(forall e,
In e leaderLog ->
eIndex e > prevLogIndex ->
eIndex e <= maxIndex entries ->
In e entries) /\
forall e e',
eIndex e = eIndex e' ->
eTerm e = eTerm e' ->
In e entries ->
In e' leaderLog ->
e = e'.
Proof using.
unfold entries_match. intuition.
Qed.
Proof using.
intros.
unfold entries_match in *.
intros. intuition.
- apply H with (e:=e')(e':=e); auto.
repeat find_rewrite. auto.
- apply H with (e:=e')(e':=e); auto.
repeat find_rewrite. auto.
Qed.
Proof using.
unfold advanceCurrentTerm. intros.
break_if; auto.
Qed.
Proof using.
unfold tryToBecomeLeader.
intros. find_inversion. auto.
Qed.
Proof using.
unfold handleRequestVote.
intros.
repeat (break_match; try discriminate; repeat (find_inversion; simpl in *));
auto using advanceCurrentTerm_same_log.
Qed.
Proof using.
unfold handleRequestVoteReply.
intros. repeat break_match; simpl; auto using advanceCurrentTerm_same_log.
Qed.
Proof using.
unfold advanceCurrentTerm. intros.
break_if; auto.
Qed.
Proof using.
intros. unfold handleTimeout, tryToBecomeLeader in *.
break_match; find_inversion; subst; auto.
Qed.
Proof using.
intros. unfold handleClientRequest in *.
break_match; find_inversion; subst; auto.
Qed.
Proof using.
unfold tryToBecomeLeader.
intros. find_inversion. auto.
Qed.
Proof using.
unfold handleRequestVote.
intros.
repeat (break_match; try discriminate; repeat (find_inversion; simpl in *));
auto using advanceCurrentTerm_same_lastApplied.
Qed.
Proof using.
unfold handleRequestVoteReply.
intros. repeat break_match; simpl; auto using advanceCurrentTerm_same_lastApplied.
Qed.
Proof using.
eauto using findAtIndex_in, findAtIndex_index.
Qed.
Proof using.
intros. split.
- lia.
- etransitivity; eauto. apply maxIndex_is_max; auto.
Qed.
Proof using.
intros.
assert (x = x').
- eapply uniqueIndices_elim_eq; eauto.
- subst. auto.
Qed.
Proof using.
induction l; intros.
- simpl in *. intuition.
- simpl in *. intuition; break_if; subst; do_bool.
+ auto.
+ congruence.
+ f_equal. eauto using uniqueIndices_elim_eq with *.
+ break_if; eauto.
* do_bool. find_apply_hyp_hyp. lia.
* eapply IHl; auto. unfold uniqueIndices in *.
simpl in *. solve_by_inversion.
Qed.
Proof using.
intros; induction l; simpl; auto.
- unfold uniqueIndices. simpl. constructor.
- unfold uniqueIndices in *. simpl in *. intuition. constructor; eauto.
intuition. do_in_map. find_apply_hyp_hyp. lia.
Qed.
Proof using.
intros.
apply findAtIndex_intro; auto using sorted_uniqueIndices.
Qed.
Proof using.
unfold doLeader.
intros.
repeat break_match; repeat find_inversion; auto.
Qed.
Proof using.
intros.
unfold handleAppendEntriesReply in *.
repeat (break_match; repeat (find_inversion; simpl in *)); auto using advanceCurrentTerm_same_log.
Qed.
Proof using.
intros.
unfold handleAppendEntriesReply in *.
repeat (break_match; repeat (find_inversion; simpl in *)); auto using advanceCurrentTerm_same_lastApplied.
Qed.
Proof using.
intros.
unfold handleAppendEntries in *.
repeat (break_match; repeat (find_inversion; simpl in *)); auto using advanceCurrentTerm_same_lastApplied.
Qed.
Definition term_of (m : msg) :=
match m with
| RequestVote t _ _ _ => Some t
| RequestVoteReply t _ => Some t
| AppendEntries t _ _ _ _ _ => Some t
| AppendEntriesReply t _ _ => Some t
end.
Proof using.
intros.
unfold wonElection in *. do_bool.
lia.
Qed.
Proof using.
intros.
find_eapply_lem_hyp subset_length;
eauto using name_eq_dec, wonElection_length.
Qed.
Proof using.
unfold wonElection.
intros.
destruct l; try discriminate.
simpl. eauto.
Qed.
Proof using.
intros. induction l; simpl in *; intuition.
find_rewrite. break_match; intuition.
repeat find_higher_order_rewrite. auto.
Qed.
Proof using.
intros. destruct l; simpl in *; intuition.
repeat break_match; congruence.
Qed.
Proof using.
induction l; intros; simpl in *; [congruence|].
repeat break_match; find_inversion.
- do_bool.
match goal with
| H : forall _, Some ?a = Some _ -> _ |- _ =>
specialize (H a)
end. intuition; subst; auto.
find_apply_hyp_hyp. lia.
- do_bool.
match goal with
| H : forall _, Some ?a = Some _ -> _ |- _ =>
specialize (H a)
end. intuition; subst; auto.
find_apply_hyp_hyp. lia.
- intuition; subst; auto.
find_apply_lem_hyp argmax_None.
subst. solve_by_inversion.
Qed.
Proof using.
intros. find_apply_lem_hyp argmax_elim. intuition.
Qed.
Proof using.
intros. induction l; simpl in *; intuition.
conclude IHl intuition.
conclude IHl intuition. intuition.
- find_rewrite. break_match; intuition.
repeat break_if; intuition.
+ do_bool. right.
find_apply_lem_hyp argmax_in; intuition.
destruct (A_eq_dec a a1); destruct (A_eq_dec a a0); repeat subst; intuition;
specialize (H0 a1); specialize (H a0); intuition; repeat find_rewrite; lia.
+ do_bool. right.
find_apply_lem_hyp argmax_in; intuition.
destruct (A_eq_dec a a1); destruct (A_eq_dec a a0); repeat subst; intuition.
* specialize (H a1); specialize (H0 a0); intuition. repeat find_rewrite. lia.
* specialize (H a1); specialize (H0 a0); intuition. repeat find_rewrite. lia.
- find_rewrite. repeat break_match; subst; intuition.
do_bool.
repeat find_apply_lem_hyp argmax_elim; intuition.
destruct (A_eq_dec a a1); destruct (A_eq_dec a a0); repeat subst; intuition.
+ specialize (H a0); specialize (H0 a1); intuition. repeat find_rewrite. lia.
+ pose proof H a0; pose proof H a1; intuition. repeat find_rewrite.
specialize (H3 a1). intuition. lia.
Qed.
Proof using.
intros. induction l; simpl in *; intuition.
find_rewrite. break_match; intuition.
repeat find_higher_order_rewrite. auto.
Qed.
Proof using.
intros. destruct l; simpl in *; intuition.
repeat break_match; congruence.
Qed.
Proof using.
induction l; intros; simpl in *; [congruence|].
repeat break_match; find_inversion.
- do_bool.
match goal with
| H : forall _, Some ?a = Some _ -> _ |- _ =>
specialize (H a)
end. intuition; subst; auto.
find_apply_hyp_hyp. lia.
- do_bool.
match goal with
| H : forall _, Some ?a = Some _ -> _ |- _ =>
specialize (H a)
end. intuition; subst; auto.
find_apply_hyp_hyp. lia.
- intuition; subst; auto.
find_apply_lem_hyp argmin_None.
subst. solve_by_inversion.
Qed.
Proof using.
intros. find_apply_lem_hyp argmin_elim. intuition.
Qed.
Proof using.
intros. induction l; simpl in *; intuition.
conclude IHl intuition.
conclude IHl intuition. intuition.
- find_rewrite. break_match; intuition.
repeat break_if; intuition.
+ do_bool. right.
find_apply_lem_hyp argmin_in; intuition.
destruct (A_eq_dec a a1); destruct (A_eq_dec a a0); repeat subst; intuition;
specialize (H0 a1); specialize (H a0); intuition; repeat find_rewrite; lia.
+ do_bool. right.
find_apply_lem_hyp argmin_in; intuition.
destruct (A_eq_dec a a1); destruct (A_eq_dec a a0); repeat subst; intuition.
* specialize (H a1); specialize (H0 a0); intuition. repeat find_rewrite. lia.
* specialize (H a1); specialize (H0 a0); intuition. repeat find_rewrite. lia.
- find_rewrite. repeat break_match; subst; intuition.
do_bool.
repeat find_apply_lem_hyp argmin_elim; intuition.
destruct (A_eq_dec a a1); destruct (A_eq_dec a a0); repeat subst; intuition.
+ specialize (H a0); specialize (H0 a1); intuition. repeat find_rewrite. lia.
+ pose proof H a0; pose proof H a1; intuition. repeat find_rewrite.
specialize (H3 a1). intuition. lia.
Qed.
Proof using.
intros.
unfold applied_entries in *.
repeat break_match; intuition;
try solve [find_apply_lem_hyp argmax_None;
exfalso;
pose proof (all_fin_all _ h); find_rewrite; intuition].
match goal with
| _ : argmax ?f ?l = _, _ : argmax ?g ?l = _ |- _ =>
pose proof argmax_one_different name name_eq_dec g f l h as Hproof
end.
forward Hproof; [intros; rewrite_update; intuition|]; concludes.
forward Hproof; [intros; update_destruct; subst; rewrite_update; intuition|]; concludes.
intuition.
- repeat find_rewrite. find_inversion.
update_destruct; subst; rewrite_update; intuition. left.
intuition. eexists; intuition eauto. repeat find_apply_lem_hyp argmax_elim; intuition eauto.
match goal with
H : _ |- _ =>
solve [specialize (H h); rewrite_update; eauto using all_fin_all]
end.
- repeat find_rewrite. find_inversion. rewrite_update. intuition.
Qed.
Proof using.
intros. unfold applied_entries in *.
repeat break_match; repeat find_rewrite; intuition;
match goal with
| _ : argmax ?f ?l = _, _ : argmax ?g ?l = _ |- _ =>
assert (argmax f l = argmax g l) by
(apply argmax_fun_ext; intros; update_destruct; subst; rewrite_update; auto)
end; repeat find_rewrite; try congruence.
match goal with | H : Some _ = Some _ |- _ => inversion H end.
subst. clean.
f_equal. update_destruct; subst; rewrite_update; repeat find_rewrite; auto.
Qed.
Proof using.
intros.
unfold applied_entries in *.
rewrite argmax_fun_ext with (g := fun h : name => lastApplied (sigma h)); intuition.
break_match; auto.
repeat find_higher_order_rewrite. auto.
Qed.
Proof using.
intros.
apply applied_entries_log_lastApplied_same;
intros; update_destruct; subst; rewrite_update; auto.
Qed.
Proof using.
intros.
unfold applied_entries in *.
break_match; simpl in *; intuition eauto.
Qed.
Proof using.
intros; induction l; simpl in *; intuition eauto using app_nil_r.
break_exists. break_if; [exists nil; eauto|].
do_bool.
match goal with
| l : list entry, e : entry |- _ =>
solve [exists (e :: l); simpl in *; f_equal; auto]
end.
Qed.
Proof using.
intros.
unfold entries_match. intuition.
- match goal with
| [ H : _ |- _ ] => solve [eapply H; eauto]
end.
- match goal with
| [ H : forall _ _, _, H' : eIndex ?e1 = eIndex ?e2 |- _ ] =>
specialize (H e1 e2); do 4 concludes
end. intuition.
match goal with
| [ H : forall _, _ < _ <= _ -> _,
_ : eIndex ?e3 <= eIndex _
|- _ ] =>
specialize (H (eIndex e3));
conclude H
ltac:(split; [eauto|
eapply le_trans; eauto; apply maxIndex_is_max; eauto])
end.
break_exists. intuition.
match goal with
| [ _ : In ?x _,
_ : eIndex ?x = eIndex ?e3,
_ : eIndex ?e3 <= eIndex _ |- _ ] =>
eapply rachet with (x' := x); eauto using sorted_uniqueIndices
end.
match goal with
| [ H : _ |- _ ] => solve [ eapply H; eauto; congruence ]
end.
Qed.
Ltac use_entries_match :=
match goal with
| [ _ : eIndex ?e1 = eIndex ?e2,
H : context [entries_match]
|- _ ] =>
first [ solve [eapply H with (e:=e2)(e':=e1); eauto; congruence] |
solve [eapply H with (e:=e1)(e':=e2); eauto; congruence]]
end.
Proof using.
intros.
unfold entries_match. intros. split; intros.
- in_crush_start.
+ match goal with
| [ H : _ |- _ ] => solve [eapply H; eauto]
end.
+ exfalso.
find_apply_lem_hyp removeAfterIndex_In_le; intuition.
find_apply_hyp_hyp. lia.
+ find_apply_lem_hyp findAtIndex_elim.
intuition subst.
match goal with
| [ H : forall _ _, _, H' : eIndex ?e1 = eIndex ?e2 |- _ ] =>
specialize (H e1 e2); do 4 concludes
end.
intuition. break_exists.
intuition.
find_copy_apply_lem_hyp removeAfterIndex_In_le; intuition.
find_apply_lem_hyp removeAfterIndex_in.
use_entries_match.
+ repeat find_apply_lem_hyp removeAfterIndex_in. use_entries_match.
- in_crush_start.
+ match goal with
| [ H : forall _ _, _, H' : eIndex ?e1 = eIndex ?e2 |- _ ] =>
specialize (H e1 e2); do 4 concludes
end.
intuition. break_exists. intuition.
destruct (le_lt_dec (eIndex e'') pli).
* apply in_or_app. right.
apply removeAfterIndex_le_In; auto.
find_apply_lem_hyp findAtIndex_elim. intuition.
subst. use_entries_match.
* apply in_or_app. left.
match goal with
| H : forall _, _ < _ <= _ -> _ |- In ?e _ =>
specialize (H (eIndex e))
end.
intuition.
conclude_using ltac:(eapply le_trans; eauto; apply maxIndex_is_max; eauto).
break_exists. intuition.
match goal with
| _: eIndex ?e1 = eIndex ?e2 |- context [ ?e2 ] =>
eapply rachet with (x' := e1); eauto using sorted_uniqueIndices with *
end.
+ apply in_or_app. right.
find_copy_apply_lem_hyp removeAfterIndex_In_le; eauto.
apply removeAfterIndex_le_In; [lia|].
find_apply_lem_hyp removeAfterIndex_in.
use_entries_match.
Qed.
Proof using.
intros.
apply applied_entries_log_lastApplied_same.
- intros. update_destruct; subst; rewrite_update; auto.
eapply doLeader_same_log; eauto.
- intros. update_destruct; subst; rewrite_update; auto.
unfold doLeader in *. repeat break_match; find_inversion; auto.
Qed.
Proof using.
induction es; intros; simpl in *; intuition.
- find_inversion. destruct st'; repeat eexists; eauto.
- unfold cacheApplyEntry, applyEntry in *.
repeat break_match; repeat find_inversion;
find_apply_hyp_hyp; break_exists; repeat eexists; eauto.
Qed.
Proof using.
intros.
find_apply_lem_hyp applyEntries_spec.
break_exists. subst. eauto.
Qed.
Proof using.
unfold handleClientRequest.
intros.
repeat break_match; find_inversion; auto.
Qed.
Proof using.
unfold handleTimeout, tryToBecomeLeader; intros; repeat break_match; repeat find_inversion; auto.
Qed.
Proof using.
unfold handleAppendEntriesReply, advanceCurrentTerm.
intros.
repeat break_match; repeat find_inversion; auto.
Qed.
Proof using.
unfold handleRequestVote, advanceCurrentTerm.
intros.
repeat break_match; repeat find_inversion; auto.
Qed.
Proof using.
unfold handleRequestVoteReply, advanceCurrentTerm.
intros. repeat break_match; simpl; auto.
Qed.
Proof using.
unfold doGenericServer.
intros.
repeat break_match; repeat find_inversion; simpl;
eapply applyEntries_spec_ind; eauto.
Qed.
Functional Scheme div2_ind := Induction for div2 Sort Prop.
Proof using.
intro n. functional induction (div2 n); lia.
Qed.
Proof using.
intros n. functional induction (div2 n); intros; try lia.
specialize (IHn0 (pred a) (pred b)). lia.
Qed.
Proof using.
intros. unfold wonElection in *. do_bool.
cut (exists h, In h (dedup name_eq_dec l) /\ In h (dedup name_eq_dec l'));
[intros; break_exists; exists x; intuition eauto using in_dedup_was_in|].
eapply pigeon with (l := nodes); eauto using all_fin_all, all_fin_NoDup, NoDup_dedup, name_eq_dec, div2_correct.
Qed.

Lemma execute_log'_app :
forall xs ys st tr,
execute_log' (xs ++ ys) st tr =
let (tr', st') := execute_log' xs st tr in
execute_log' ys st' tr'.