Timings for CommonTheorems.v
- /home/gitlab-runner/builds/gGKko-aj/0/coq/coq/_bench/opam.OLD/ocaml-OLD/.opam-switch/build/coq-verdi-raft.dev//./theories/Raft/CommonTheorems.v.timing
- /home/gitlab-runner/builds/gGKko-aj/0/coq/coq/_bench/opam.NEW/ocaml-NEW/.opam-switch/build/coq-verdi-raft.dev//./theories/Raft/CommonTheorems.v.timing
From Coq Require Import PeanoNat FunInd.
From VerdiRaft Require Import RaftState Raft.
From VerdiRaft Require Export CommonDefinitions.
#[local] Arguments update {_} {_} _ _ _ _ _ : simpl never.
Context {orig_base_params : BaseParams}.
Context {one_node_params : OneNodeParams orig_base_params}.
Context {raft_params : RaftParams orig_base_params}.
Lemma uniqueIndices_elim_eq :
forall xs x y,
uniqueIndices xs ->
In x xs ->
In y xs ->
eIndex x = eIndex y ->
x = y.
eauto using NoDup_map_elim.
Lemma sorted_cons :
forall xs a,
sorted xs ->
(forall a', In a' xs -> eIndex a > eIndex a' /\ eTerm a >= eTerm a') ->
sorted (a :: xs).
intuition;
find_apply_hyp_hyp; intuition.
Lemma sorted_subseq :
forall ys xs,
subseq xs ys ->
sorted ys ->
sorted xs.
induction ys; intros; simpl in *.
apply sorted_cons; eauto.
Theorem maxTerm_is_max :
forall l e,
sorted l ->
In e l ->
maxTerm l >= eTerm e.
Theorem maxIndex_is_max :
forall l e,
sorted l ->
In e l ->
maxIndex l >= eIndex e.
Theorem S_maxIndex_not_in :
forall l e,
sorted l ->
eIndex e = S (maxIndex l) ->
~ In e l.
find_apply_lem_hyp maxIndex_is_max; auto.
Lemma maxIndex_non_empty :
forall l,
l <> nil ->
exists e,
In e l /\ maxIndex l = eIndex e /\ maxTerm l = eTerm e.
destruct l; intros; simpl in *; eauto; congruence.
Lemma removeAfterIndex_subseq :
forall l i,
subseq (removeAfterIndex l i) l.
induction l; intros; simpl; auto.
repeat break_match; intuition.
Lemma removeAfterIndex_sorted :
forall l i,
sorted l ->
sorted (removeAfterIndex l i).
eauto using removeAfterIndex_subseq, sorted_subseq.
Lemma removeAfterIndex_in :
forall l i a,
In a (removeAfterIndex l i) ->
In a l.
eauto using removeAfterIndex_subseq, subseq_In.
Lemma findAtIndex_not_in :
forall l e,
sorted l ->
findAtIndex l (eIndex e) = None ->
~ In e l.
induction l; intros; intro.
break_match; try discriminate.
rewrite Nat.eqb_refl in *.
break_if; do_bool; eauto.
Lemma findAtIndex_in :
forall l i e',
findAtIndex l i = Some e' ->
In e' l.
break_if; eauto; discriminate.
Lemma findAtIndex_index :
forall l i e',
findAtIndex l i = Some e' ->
i = eIndex e'.
apply Nat.eqb_eq in Heqb.
break_if; eauto; discriminate.
Lemma NoDup_removeAfterIndex :
forall l i,
NoDup l ->
NoDup (removeAfterIndex l i).
eauto using subseq_NoDup, removeAfterIndex_subseq.
Notation disjoint xs ys := (forall x, In x xs -> In x ys -> False).
Lemma removeAfterIndex_le_In :
forall xs i x,
eIndex x <= i ->
In x xs ->
In x (removeAfterIndex xs i).
break_if; simpl in *; intuition.
Lemma removeAfterIndex_In_le :
forall xs i x,
sorted xs ->
In x (removeAfterIndex xs i) ->
eIndex x <= i.
break_if; simpl in *; do_bool; intuition; subst; auto.
Lemma removeAfterIndex_covariant :
forall xs ys i x,
sorted xs ->
sorted ys ->
In x (removeAfterIndex xs i) ->
(forall x, In x xs -> In x ys) ->
In x (removeAfterIndex ys i).
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.
match goal with
| _ : eIndex ?e <= ?li, _ : eIndex ?e > eIndex ?e' |- _ =>
assert (eIndex e' <= li) by lia
end.
eauto using removeAfterIndex_le_In.
Lemma removeAfterIndex_le :
forall xs i j,
i <= j ->
removeAfterIndex xs i = removeAfterIndex (removeAfterIndex xs j) i.
repeat (break_if; simpl in *; intuition); try discriminate.
Lemma removeAfterIndex_2_subseq :
forall xs i j,
subseq (removeAfterIndex (removeAfterIndex xs i) j) (removeAfterIndex (removeAfterIndex xs j) i).
induction xs; intros; simpl.
repeat (break_match; simpl); intuition; try discriminate.
rewrite removeAfterIndex_le with (j := i) (i := j) at 1; auto; lia.
rewrite removeAfterIndex_le with (i := i) (j := j) at 2; auto; lia.
Lemma removeAfterIndex_comm :
forall xs i j,
removeAfterIndex (removeAfterIndex xs i) j =
removeAfterIndex (removeAfterIndex xs j) i.
auto using subseq_subseq_eq, removeAfterIndex_2_subseq.
Lemma removeAfterIndex_2_eq_min :
forall xs i j,
removeAfterIndex (removeAfterIndex xs i) j =
removeAfterIndex xs (min i j).
pose proof Nat.min_spec i j.
rewrite removeAfterIndex_le with (i := i) (j := j) at 2;
eauto using removeAfterIndex_comm; lia.
rewrite <- removeAfterIndex_le with (i := j) (j := i);
auto; lia.
Lemma findAtIndex_None :
forall xs i x,
sorted xs ->
findAtIndex xs i = None ->
In x xs ->
eIndex x <> i.
induction xs; intros; simpl in *; intuition; break_match; try discriminate.
Lemma findAtIndex_removeAfterIndex_agree :
forall xs i j e e',
NoDup (map eIndex xs) ->
findAtIndex xs i = Some e ->
findAtIndex (removeAfterIndex xs j) i = Some e' ->
e = e'.
eapply NoDup_map_elim with (f := eIndex); eauto using findAtIndex_in, removeAfterIndex_in.
apply findAtIndex_index in H0.
apply findAtIndex_index in H1.
Lemma subseq_uniqueIndices :
forall ys xs,
subseq xs ys ->
uniqueIndices ys ->
uniqueIndices xs.
break_match; intuition idtac.
Lemma subseq_findGtIndex :
forall xs i,
subseq (findGtIndex xs i) xs.
repeat break_match; auto.
Lemma findGtIndex_in :
forall xs i x,
In x (findGtIndex xs i) ->
In x xs.
eauto using subseq_In, subseq_findGtIndex.
Lemma findGtIndex_sufficient :
forall e entries x,
sorted entries ->
In e entries ->
eIndex e > x ->
In e (findGtIndex entries x).
induction entries; intros.
break_if; intuition auto with datatypes.
in_crush_tac (intuition auto).
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).
Lemma removeAfterIndex_uniqueIndices :
forall l i,
uniqueIndices l ->
uniqueIndices (removeAfterIndex l i).
Proof with eauto using subseq_uniqueIndices, removeAfterIndex_subseq.
Lemma maxIndex_subset :
forall xs ys,
sorted xs -> sorted ys ->
(forall x, In x xs -> In x ys) ->
maxIndex xs <= maxIndex (orig_base_params:=orig_base_params) ys.
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.
Lemma maxIndex_exists_in :
forall xs,
maxIndex xs >= 1 ->
exists x,
eIndex x = maxIndex xs /\
In x xs.
Lemma maxIndex_app :
forall l l',
maxIndex (l ++ l') = maxIndex l \/
maxIndex (l ++ l') = maxIndex l' /\ l = [].
Lemma maxIndex_removeAfterIndex_le :
forall l i,
sorted l ->
maxIndex (removeAfterIndex l i) <= maxIndex l.
apply maxIndex_subset; eauto using removeAfterIndex_sorted.
eauto using removeAfterIndex_in.
Lemma maxIndex_removeAfterIndex :
forall l i e,
sorted l ->
In e l ->
eIndex e = i ->
maxIndex (removeAfterIndex l i) = i.
induction l; intros; simpl in *; intuition.
break_if; do_bool; try lia.
match goal with
| H : forall _, In _ _ -> _ |- _ =>
specialize (H2 e)
end.
Lemma maxIndex_gt_0_nonempty :
forall es,
0 < maxIndex es ->
es <> nil.
Lemma removeIncorrect_new_contiguous :
forall new current prev e,
sorted current ->
uniqueIndices current ->
(forall e e',
eIndex e = eIndex e' ->
eTerm e = eTerm e' ->
In e new ->
In e' current ->
e = e') ->
contiguous_range_exact_lo current 0 ->
contiguous_range_exact_lo new prev ->
In e current ->
eIndex e = prev ->
contiguous_range_exact_lo (new ++ removeAfterIndex current prev)
0.
Proof using one_node_params.
intros new current prev e Hsorted Huniq Hinv.
destruct (le_lt_dec i prev).
unfold contiguous_range_exact_lo in *.
match goal with
| H: forall _, _ < _ <= _ current -> _, H' : In _ current |- _ =>
specialize (H i); apply maxIndex_is_max in H'; auto; forward H; intuition auto with zarith
end.
eapply removeAfterIndex_le_In; eauto.
pose proof maxIndex_app new (removeAfterIndex current prev).
unfold contiguous_range_exact_lo in *.
match goal with
| H: forall _, _ < _ <= _ new -> _ |- _ =>
specialize (H i); auto; forward H; intuition auto with zarith
end.
intuition auto with datatypes.
pose proof maxIndex_removeAfterIndex current (eIndex e) e.
unfold contiguous_range_exact_lo in *.
firstorder using removeAfterIndex_in.
Lemma incoming_entries_in_log :
forall es log x i,
In x es ->
uniqueIndices log ->
exists y,
eIndex x = eIndex y /\
eTerm x = eTerm y /\
In y (es ++ (removeAfterIndex log i)).
intuition auto with datatypes.
Lemma findGtIndex_necessary :
forall entries e x,
In e (findGtIndex entries x) ->
In e entries /\
eIndex e > x.
induction entries; intros; simpl in *; intuition.
break_if; simpl in *; intuition; right; eapply IHentries; eauto.
break_if;
simpl in *; intuition.
simpl in *; intuition; eapply IHentries; eauto.
Lemma findGtIndex_contiguous :
forall entries x,
sorted entries ->
(forall i, 0 < i <= maxIndex entries -> (exists e, In e entries /\ eIndex e = i)) ->
forall i, x < i <= maxIndex entries ->
exists e, In e (findGtIndex entries x) /\ eIndex e = i.
intros entries x Hsorted; intros.
apply findGtIndex_sufficient; auto; lia.
Lemma findGtIndex_max :
forall entries x,
maxIndex (findGtIndex entries x) <= maxIndex entries.
destruct entries; simpl; auto.
break_if; simpl; intuition auto with arith.
Lemma findAtIndex_uniq_equal :
forall e e' es,
findAtIndex es (eIndex e) = Some e' ->
In e es ->
uniqueIndices es ->
e = e'.
pose proof findAtIndex_in _ _ _ H.
pose proof findAtIndex_index _ _ _ H.
eapply uniqueIndices_elim_eq; eauto.
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').
Lemma entries_match_entries_match' :
forall xs ys,
entries_match xs ys ->
entries_match' xs ys /\
entries_match' ys xs.
unfold entries_match, entries_match'.
eapply (H e' e); eauto with *.
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'.
Lemma entries_match_refl :
forall l,
entries_match l l.
Lemma entries_match_sym :
forall xs ys,
entries_match xs ys ->
entries_match ys xs.
unfold entries_match in *.
apply H with (e:=e')(e':=e); auto.
apply H with (e:=e')(e':=e); auto.
Lemma advanceCurrentTerm_same_log :
forall st t,
log (advanceCurrentTerm st t) = log st.
unfold advanceCurrentTerm.
Lemma tryToBecomeLeader_same_log :
forall n st out st' ms,
tryToBecomeLeader n st = (out, st', ms) ->
log st' = log st.
unfold tryToBecomeLeader.
Lemma handleRequestVote_same_log :
forall n st t c li lt st' ms,
handleRequestVote n st t c li lt = (st', ms) ->
log st' = log st.
unfold handleRequestVote.
repeat (break_match; try discriminate; repeat (find_inversion; simpl in *));
auto using advanceCurrentTerm_same_log.
Lemma handleRequestVoteReply_same_log :
forall n st src t v,
log (handleRequestVoteReply n st src t v) = log st.
unfold handleRequestVoteReply.
repeat break_match; simpl; auto using advanceCurrentTerm_same_log.
Lemma advanceCurrentTerm_same_lastApplied :
forall st t,
lastApplied (advanceCurrentTerm st t) = lastApplied st.
unfold advanceCurrentTerm.
Theorem handleTimeout_lastApplied :
forall h st out st' ps,
handleTimeout h st = (out, st', ps) ->
lastApplied st' = lastApplied st.
unfold handleTimeout, tryToBecomeLeader in *.
break_match; find_inversion; subst; auto.
Theorem handleClientRequest_lastApplied:
forall h st client id c out st' ps,
handleClientRequest h st client id c = (out, st', ps) ->
lastApplied st' = lastApplied st.
unfold handleClientRequest in *.
break_match; find_inversion; subst; auto.
Lemma tryToBecomeLeader_same_lastApplied :
forall n st out st' ms,
tryToBecomeLeader n st = (out, st', ms) ->
lastApplied st' = lastApplied st.
unfold tryToBecomeLeader.
Lemma handleRequestVote_same_lastApplied :
forall n st t c li lt st' ms,
handleRequestVote n st t c li lt = (st', ms) ->
lastApplied st' = lastApplied st.
unfold handleRequestVote.
repeat (break_match; try discriminate; repeat (find_inversion; simpl in *));
auto using advanceCurrentTerm_same_lastApplied.
Lemma handleRequestVoteReply_same_lastApplied :
forall n st src t v,
lastApplied (handleRequestVoteReply n st src t v) = lastApplied st.
unfold handleRequestVoteReply.
repeat break_match; simpl; auto using advanceCurrentTerm_same_lastApplied.
Lemma findAtIndex_elim :
forall l i e,
findAtIndex l i = Some e ->
i = eIndex e /\ In e l.
eauto using findAtIndex_in, findAtIndex_index.
Lemma index_in_bounds :
forall e es i,
sorted es ->
In e es ->
i <> 0 ->
i <= eIndex e ->
1 <= i <= maxIndex es.
apply maxIndex_is_max; auto.
Lemma rachet :
forall x x' xs ys,
eIndex x = eIndex x' ->
In x xs ->
In x' ys ->
In x' xs ->
uniqueIndices xs ->
In x ys.
eapply uniqueIndices_elim_eq; eauto.
Lemma findAtIndex_intro :
forall l i e,
sorted l ->
In e l ->
eIndex e = i ->
uniqueIndices l ->
findAtIndex l i = Some e.
intuition; break_if; subst; do_bool.
eauto using uniqueIndices_elim_eq with *.
unfold uniqueIndices in *.
Theorem sorted_uniqueIndices :
forall l,
sorted l -> uniqueIndices l.
intros; induction l; simpl; auto.
unfold uniqueIndices in *.
Lemma findAtIndex_intro' :
forall l i e,
sorted l ->
In e l ->
eIndex e = i ->
findAtIndex l i = Some e.
apply findAtIndex_intro; auto using sorted_uniqueIndices.
Lemma doLeader_same_log :
forall st n os st' ms,
doLeader st n = (os, st', ms) ->
log st' = log st.
repeat break_match; repeat find_inversion; auto.
Lemma handleAppendEntriesReply_same_log :
forall n st src t es b st' l,
handleAppendEntriesReply n st src t es b = (st', l) ->
log st' = log st.
unfold handleAppendEntriesReply in *.
repeat (break_match; repeat (find_inversion; simpl in *)); auto using advanceCurrentTerm_same_log.
Lemma handleAppendEntriesReply_same_lastApplied :
forall n st src t es b st' l,
handleAppendEntriesReply n st src t es b = (st', l) ->
lastApplied st' = lastApplied st.
unfold handleAppendEntriesReply in *.
repeat (break_match; repeat (find_inversion; simpl in *)); auto using advanceCurrentTerm_same_lastApplied.
Lemma handleAppendEntries_same_lastApplied :
forall h st t n pli plt es ci st' ps,
handleAppendEntries h st t n pli plt es ci = (st', ps) ->
lastApplied st' = lastApplied st.
unfold handleAppendEntries in *.
repeat (break_match; repeat (find_inversion; simpl in *)); auto using advanceCurrentTerm_same_lastApplied.
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.
Lemma wonElection_length :
forall l1 l2,
wonElection l1 = true ->
length l1 <= length l2 ->
wonElection l2 = true.
Lemma wonElection_no_dup_in :
forall l1 l2,
wonElection l1 = true ->
NoDup l1 ->
(forall x, In x l1 -> In x l2) ->
wonElection l2 = true.
find_eapply_lem_hyp subset_length;
eauto using name_eq_dec, wonElection_length.
Lemma wonElection_exists_voter :
forall l,
wonElection l = true ->
exists x,
In x l.
destruct l; try discriminate.
Lemma argmax_fun_ext :
forall A (f : A -> nat) g l,
(forall a, f a = g a) ->
argmax f l = argmax g l.
induction l; simpl in *; intuition.
repeat find_higher_order_rewrite.
Lemma argmax_None :
forall A (f : A -> nat) l,
argmax f l = None ->
l = [].
destruct l; simpl in *; intuition.
repeat break_match; congruence.
Lemma argmax_elim :
forall A (f : A -> nat) l a,
argmax f l = Some a ->
(In a l /\
forall x, In x l -> f a >= f x).
induction l; intros; simpl in *; [congruence|].
repeat break_match; find_inversion.
match goal with
| H : forall _, Some ?a = Some _ -> _ |- _ =>
specialize (H a)
end.
match goal with
| H : forall _, Some ?a = Some _ -> _ |- _ =>
specialize (H a)
end.
find_apply_lem_hyp argmax_None.
Lemma argmax_in :
forall A (f : A -> nat) l a,
argmax f l = Some a ->
In a l.
find_apply_lem_hyp argmax_elim.
Lemma argmax_one_different :
forall A (A_eq_dec : forall x y : A, {x = y} + {x <> y}) f g (l : list A) a,
(forall x, In x l -> a <> x -> f x = g x) ->
(forall x, In x l -> f x <= g x) ->
(argmax g l = argmax f l \/
argmax g l = Some a).
induction l; simpl in *; intuition.
repeat break_if; intuition.
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.
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.
specialize (H a1); specialize (H0 a0); intuition.
repeat break_match; subst; intuition.
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.
pose proof H a0; pose proof H a1; intuition.
Lemma argmin_fun_ext :
forall A (f : A -> nat) g l,
(forall a, f a = g a) ->
argmin f l = argmin g l.
induction l; simpl in *; intuition.
repeat find_higher_order_rewrite.
Lemma argmin_None :
forall A (f : A -> nat) l,
argmin f l = None ->
l = [].
destruct l; simpl in *; intuition.
repeat break_match; congruence.
Lemma argmin_elim :
forall A (f : A -> nat) l a,
argmin f l = Some a ->
(In a l /\
forall x, In x l -> f a <= f x).
induction l; intros; simpl in *; [congruence|].
repeat break_match; find_inversion.
match goal with
| H : forall _, Some ?a = Some _ -> _ |- _ =>
specialize (H a)
end.
match goal with
| H : forall _, Some ?a = Some _ -> _ |- _ =>
specialize (H a)
end.
find_apply_lem_hyp argmin_None.
Lemma argmin_in :
forall A (f : A -> nat) l a,
argmin f l = Some a ->
In a l.
find_apply_lem_hyp argmin_elim.
Lemma argmin_one_different :
forall A (A_eq_dec : forall x y : A, {x = y} + {x <> y}) f g (l : list A) a,
(forall x, In x l -> a <> x -> f x = g x) ->
(forall x, In x l -> g x <= f x) ->
(argmin g l = argmin f l \/
argmin g l = Some a).
induction l; simpl in *; intuition.
repeat break_if; intuition.
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.
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.
specialize (H a1); specialize (H0 a0); intuition.
repeat break_match; subst; intuition.
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.
pose proof H a0; pose proof H a1; intuition.
Lemma applied_entries_update :
forall sigma h st,
lastApplied st >= lastApplied (sigma h) ->
(applied_entries (update name_eq_dec sigma h st) = applied_entries sigma /\
(exists h',
argmax (fun h => lastApplied (sigma h)) (all_fin N) = Some h' /\
lastApplied (sigma h') >= lastApplied st))
\/
(argmax (fun h' => lastApplied (update name_eq_dec sigma h st h')) (all_fin N) = Some h /\
applied_entries (update name_eq_dec sigma h st) = (rev (removeAfterIndex (log st) (lastApplied st)))).
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.
update_destruct; subst; rewrite_update; 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.
Lemma applied_entries_safe_update :
forall sigma h st,
lastApplied st = lastApplied (sigma h) ->
removeAfterIndex (log st) (lastApplied (sigma h))
= removeAfterIndex (log (sigma h)) (lastApplied (sigma h)) ->
applied_entries (update name_eq_dec sigma h st) = applied_entries sigma.
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.
update_destruct; subst; rewrite_update; repeat find_rewrite; auto.
Lemma applied_entries_log_lastApplied_same :
forall sigma sigma',
(forall h, log (sigma' h) = log (sigma h)) ->
(forall h, lastApplied (sigma' h) = lastApplied (sigma h)) ->
applied_entries sigma' = applied_entries sigma.
unfold applied_entries in *.
rewrite argmax_fun_ext with (g := fun h : name => lastApplied (sigma h)); intuition.
repeat find_higher_order_rewrite.
Lemma applied_entries_log_lastApplied_update_same :
forall sigma h st,
log st = log (sigma h) ->
lastApplied st = lastApplied (sigma h) ->
applied_entries (update name_eq_dec sigma h st) = applied_entries sigma.
apply applied_entries_log_lastApplied_same;
intros; update_destruct; subst; rewrite_update; auto.
Lemma applied_entries_cases :
forall sigma,
applied_entries sigma = [] \/
exists h,
applied_entries sigma = rev (removeAfterIndex (log (sigma h)) (lastApplied (sigma h))).
unfold applied_entries in *.
break_match; simpl in *; intuition eauto.
Lemma removeAfterIndex_partition :
forall l x,
exists l',
l = l' ++ removeAfterIndex l x.
intros; induction l; simpl in *; intuition eauto using app_nil_r.
break_if; [exists nil; eauto|].
match goal with
| l : list entry, e : entry |- _ =>
solve [exists (e :: l); simpl in *; f_equal; auto]
end.
Lemma entries_match_scratch :
forall es ys plt,
sorted es ->
uniqueIndices ys ->
(forall e1 e2,
eIndex e1 = eIndex e2 ->
eTerm e1 = eTerm e2 ->
In e1 es ->
In e2 ys ->
(forall e3,
eIndex e3 <= eIndex e1 ->
In e3 es ->
In e3 ys) /\
(0 <> 0 ->
exists e4,
eIndex e4 = 0 /\
eTerm e4 = plt /\
In e4 ys)) ->
(forall i, 0 < i <= maxIndex es -> exists e, eIndex e = i /\ In e es) ->
(forall e,
In e es ->
0 < eIndex e) ->
(forall y, In y ys -> 0 < eIndex y) ->
entries_match es ys.
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.
match goal with
| [ H : forall _, _ < _ <= _ -> _,
_ : eIndex ?e3 <= eIndex _
|- _ ] =>
specialize (H (eIndex e3));
conclude H
(split; [eauto| eapply Nat.le_trans; eauto; apply maxIndex_is_max; eauto])
end.
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.
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.
Lemma entries_match_append :
forall xs ys es ple pli plt,
sorted xs ->
sorted ys ->
sorted es ->
entries_match xs ys ->
(forall e1 e2,
eIndex e1 = eIndex e2 ->
eTerm e1 = eTerm e2 ->
In e1 es ->
In e2 ys ->
(forall e3,
eIndex e3 <= eIndex e1 ->
In e3 es ->
In e3 ys) /\
(pli <> 0 ->
exists e4,
eIndex e4 = pli /\
eTerm e4 = plt /\
In e4 ys)) ->
(forall i, pli < i <= maxIndex es -> exists e, eIndex e = i /\ In e es) ->
(forall e,
In e es ->
pli < eIndex e) ->
findAtIndex xs pli = Some ple ->
eTerm ple = plt ->
pli <> 0 ->
entries_match (es ++ removeAfterIndex xs pli) ys.
match goal with
| [ H : _ |- _ ] => solve [eapply H; eauto]
end.
find_apply_lem_hyp removeAfterIndex_In_le; intuition.
find_apply_lem_hyp findAtIndex_elim.
match goal with
| [ H : forall _ _, _, H' : eIndex ?e1 = eIndex ?e2 |- _ ] =>
specialize (H e1 e2); do 4 concludes
end.
find_copy_apply_lem_hyp removeAfterIndex_In_le; intuition.
find_apply_lem_hyp removeAfterIndex_in.
repeat find_apply_lem_hyp removeAfterIndex_in.
match goal with
| [ H : forall _ _, _, H' : eIndex ?e1 = eIndex ?e2 |- _ ] =>
specialize (H e1 e2); do 4 concludes
end.
destruct (le_lt_dec (eIndex e'') pli).
apply removeAfterIndex_le_In; auto.
find_apply_lem_hyp findAtIndex_elim.
match goal with
| H : forall _, _ < _ <= _ -> _ |- In ?e _ =>
specialize (H (eIndex e))
end.
conclude_using (eapply Nat.le_trans; eauto; apply maxIndex_is_max; eauto).
match goal with
| _: eIndex ?e1 = eIndex ?e2 |- context [ ?e2 ] =>
eapply rachet with (x' := e1); eauto using sorted_uniqueIndices with *
end.
find_copy_apply_lem_hyp removeAfterIndex_In_le; eauto.
apply removeAfterIndex_le_In; [lia|].
find_apply_lem_hyp removeAfterIndex_in.
Lemma doLeader_appliedEntries :
forall sigma h os st' ms,
doLeader (sigma h) h = (os, st', ms) ->
applied_entries (update name_eq_dec sigma h st') = applied_entries sigma.
apply applied_entries_log_lastApplied_same.
update_destruct; subst; rewrite_update; auto.
eapply doLeader_same_log; eauto.
update_destruct; subst; rewrite_update; auto.
repeat break_match; find_inversion; auto.
Lemma applyEntries_spec :
forall es h st os st',
applyEntries h st es = (os, st') ->
exists d cc,
st' = {[ {[ st with stateMachine := d ]} with clientCache := cc ]}.
induction es; intros; simpl in *; intuition.
destruct st'; repeat eexists; eauto.
unfold cacheApplyEntry, applyEntry in *.
repeat break_match; repeat find_inversion;
find_apply_hyp_hyp; break_exists; repeat eexists; eauto.
Lemma applyEntries_spec_ind :
forall {es h st os st'},
applyEntries h st es = (os, st') ->
forall P : raft_data -> Prop,
(forall d cc,
P {[ {[ st with stateMachine := d ]} with clientCache := cc ]}) ->
P st'.
find_apply_lem_hyp applyEntries_spec.
Lemma handleClientRequest_commitIndex :
forall h st client id c out st' l,
handleClientRequest h st client id c = (out, st', l) ->
commitIndex st' = commitIndex st.
unfold handleClientRequest.
repeat break_match; find_inversion; auto.
Lemma handleTimeout_commitIndex :
forall h st out st' l,
handleTimeout h st = (out, st', l) ->
commitIndex st' = commitIndex st.
unfold handleTimeout, tryToBecomeLeader; intros; repeat break_match; repeat find_inversion; auto.
Lemma handleAppendEntriesReply_same_commitIndex :
forall n st src t es b st' l,
handleAppendEntriesReply n st src t es b = (st', l) ->
commitIndex st' = commitIndex st.
unfold handleAppendEntriesReply, advanceCurrentTerm.
repeat break_match; repeat find_inversion; auto.
Lemma handleRequestVote_same_commitIndex :
forall n st t c li lt st' ms,
handleRequestVote n st t c li lt = (st', ms) ->
commitIndex st' = commitIndex st.
unfold handleRequestVote, advanceCurrentTerm.
repeat break_match; repeat find_inversion; auto.
Lemma handleRequestVoteReply_same_commitIndex :
forall n st src t v,
commitIndex (handleRequestVoteReply n st src t v) = commitIndex st.
unfold handleRequestVoteReply, advanceCurrentTerm.
repeat break_match; simpl; auto.
Lemma doGenericServer_commitIndex :
forall h st out st' ms,
doGenericServer h st = (out, st', ms) ->
commitIndex st' = commitIndex st.
repeat break_match; repeat find_inversion; simpl;
eapply applyEntries_spec_ind; eauto.
(* FIXME: move to StructTact *)
Functional Scheme div2_ind := Induction for div2 Sort Prop.
(* FIXME: move to StructTact *)
Theorem div2_correct' :
forall n,
n <= div2 n + S (div2 n).
functional induction (div2 n); lia.
(* FIXME: move to StructTact *)
Theorem div2_correct :
forall c a b,
a > div2 c ->
b > div2 c ->
a + b > c.
functional induction (div2 n); intros; try lia.
specialize (IHn0 (pred a) (pred b)).
Lemma wonElection_one_in_common :
forall l l',
wonElection (dedup name_eq_dec l) = true ->
wonElection (dedup name_eq_dec l') = true ->
exists h, In h l /\ In h l'.
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.
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'.
Lemma fst_execute_log' :
forall log st tr,
fst (execute_log' log st tr) = tr ++ fst (execute_log' log st []).
rewrite IHlog with (tr := [(eInput a, o)]).
Lemma snd_execute_log' :
forall log st tr,
snd (execute_log' log st tr) = snd (execute_log' log st []).
rewrite IHlog with (tr := [(eInput a, o)]).
Lemma execute_log_correct' :
forall log st,
step_1_star st (snd (execute_log' log st []))
(fst (execute_log' log st [])).
rewrite fst_execute_log'.
rewrite snd_execute_log'.
Lemma execute_log_correct :
forall log,
step_1_star init (snd (execute_log log))
(fst (execute_log log)).
apply execute_log_correct'.
Lemma contiguous_nil :
forall i,
contiguous_range_exact_lo [] i.
unfold contiguous_range_exact_lo.
Lemma contiguous_index_singleton :
forall i a,
contiguous_range_exact_lo [a] i ->
eIndex a = S i.
unfold contiguous_range_exact_lo in *.
assert (H_a: In a [a]) by auto with datatypes.
assert (H_s: i < S i) by auto.
inversion H0; subst; auto.
Lemma contiguous_index_adjacent :
forall l i a b,
sorted (a :: b :: l) ->
contiguous_range_exact_lo (a :: b :: l) i ->
eIndex a = S (eIndex b) /\ eIndex a > i.
unfold contiguous_range_exact_lo in *.
intuition auto with datatypes.
assert (i < S (eIndex b) <= eIndex a).
intuition auto with arith.
intuition auto with arith.
specialize (H1 (S (eIndex b))).
Lemma cons_contiguous_sorted :
forall l i a,
sorted (a :: l) ->
contiguous_range_exact_lo (a :: l) i ->
contiguous_range_exact_lo l i.
eapply contiguous_index_adjacent in H; eauto.
unfold contiguous_range_exact_lo in *.
intuition auto with datatypes.
assert (i < i0 <= eIndex a0) by lia.
Lemma contiguous_app :
forall l1 l2 i,
sorted (l1 ++ l2) ->
contiguous_range_exact_lo (l1 ++ l2) i ->
contiguous_range_exact_lo l2 i.
simpl ((a :: l1) ++ l2) in *.
find_apply_lem_hyp cons_contiguous_sorted; auto.
Lemma prefix_sorted :
forall l l',
sorted l ->
Prefix l' l ->
sorted l'.
find_apply_lem_hyp Prefix_nil.
find_eapply_lem_hyp Prefix_in; eauto.
apply IHl; simpl in *; intuition.
Lemma prefix_contiguous :
forall l l' e i,
l' <> [] ->
Prefix l' l ->
sorted l ->
In e l ->
eIndex e > i ->
contiguous_range_exact_lo l' i ->
In e l'.
destruct l'; try congruence.
find_copy_apply_lem_hyp prefix_sorted; auto.
find_apply_lem_hyp contiguous_index_singleton.
eapply IHl; try discriminate; eauto.
eapply cons_contiguous_sorted; eauto.
Lemma removeAfterIndex_contiguous :
forall l i i',
sorted l ->
contiguous_range_exact_lo l i ->
contiguous_range_exact_lo (removeAfterIndex l i') i.
induction l; intros; simpl in *; intuition.
eapply cons_contiguous_sorted; eauto.
Lemma sorted_NoDup :
forall l,
sorted l -> NoDup l.
induction l; intros; simpl in *; auto.
match goal with
| H : forall _, _ |- _ => specialize (H a)
end.
Lemma sorted_Permutation_eq :
forall l l',
sorted l ->
sorted l' ->
Permutation l l' ->
l = l'.
find_copy_eapply_lem_hyp Permutation_in; intuition auto with datatypes.
find_copy_apply_lem_hyp Permutation_sym.
find_copy_eapply_lem_hyp Permutation_in; intuition auto with datatypes.
intuition;
try (subst a; f_equal; eauto using Permutation_cons_inv).
repeat find_apply_hyp_hyp.
Lemma removeAfterIndex_same_sufficient :
forall x l l',
sorted l ->
sorted l' ->
(forall e, eIndex e <= x ->
In e l ->
In e l') ->
(forall e, eIndex e <= x ->
In e l' ->
In e l) ->
removeAfterIndex l' x = removeAfterIndex l x.
apply sorted_Permutation_eq;
try (apply removeAfterIndex_sorted; assumption).
apply NoDup_Permutation;
try (apply NoDup_removeAfterIndex; apply sorted_NoDup; assumption).
split; intros; apply removeAfterIndex_le_In;
eauto using removeAfterIndex_In_le, removeAfterIndex_in.
Lemma removeAfterIndex_same_sufficient' :
forall x l l',
sorted l ->
sorted l' ->
contiguous_range_exact_lo l 0 ->
(forall e, In e l' -> 0 < eIndex e) ->
x <= maxIndex l ->
(forall e, eIndex e <= x ->
In e l ->
In e l') ->
removeAfterIndex l' x = removeAfterIndex l x.
eapply removeAfterIndex_same_sufficient; eauto.
unfold contiguous_range_exact_lo in *.
specialize (H7 (eIndex e)).
repeat conclude_using lia.
copy_apply H4 H10; try lia.
eapply rachet with (xs := l'); eauto using sorted_uniqueIndices.
Lemma thing2 :
forall l l' i,
l <> [] ->
Prefix l l' ->
sorted l' ->
contiguous_range_exact_lo l i ->
contiguous_range_exact_lo l' 0 ->
l ++ (removeAfterIndex l' i) = l'.
Proof using one_node_params.
induction l; try congruence; intros.
unfold contiguous_range_exact_lo in *.
assert (H_in': In e (e :: l')).
assert (H_in: In e (e :: l)).
find_apply_lem_hyp contiguous_index_singleton.
assert (H_in: In e0 (e0 :: l')).
apply IHl; try discriminate; auto.
find_apply_lem_hyp cons_contiguous_sorted.
eauto using Prefix_cons, prefix_sorted.
find_apply_lem_hyp cons_contiguous_sorted.
unfold contiguous_range_exact_lo in *.
destruct l'; simpl in *; intuition.
assert (i < i0 <= eIndex e) by lia.
eauto using Prefix_cons, prefix_sorted.
apply cons_contiguous_sorted in H3; auto.
Lemma thing :
forall es l l' e e',
sorted l ->
sorted l' ->
contiguous_range_exact_lo l' 0 ->
entries_match l l' ->
es <> [] ->
Prefix es l' ->
contiguous_range_exact_lo es (eIndex e) ->
In e l ->
In e' l' ->
eIndex e = eIndex e' ->
eTerm e = eTerm e' ->
es ++ (removeAfterIndex l (eIndex e)) = l'.
Proof using one_node_params.
rewrite removeAfterIndex_same_sufficient with (l := l'); auto.
unfold entries_match in *.
unfold entries_match in *.
Lemma sorted_findGtIndex_0 :
forall l,
(forall e, In e l -> eIndex e > 0) ->
sorted l ->
findGtIndex l 0 = l.
induction l; intros; simpl in *; intuition.
specialize (H a); intuition; lia.
Lemma findGtIndex_app_in_1 :
forall l1 l2 e,
sorted (l1 ++ l2) ->
In e l1 ->
exists l',
findGtIndex (l1 ++ l2) (eIndex e) = l' /\
forall x,
In x l' -> In x l1.
induction l1; intros; simpl in *; intuition.
break_if; do_bool; try lia.
eexists; repeat (simpl in *; intuition).
specialize (H1 e); intuition.
conclude H1 (apply in_app_iff; intuition).
break_if; do_bool; try lia.
eexists; intuition; eauto.
eapply_prop_hyp sorted sorted; eauto.
Lemma sorted_app_in_1 :
forall l1 l2 e,
sorted (l1 ++ l2) ->
eIndex e > 0 ->
In e l1 ->
eIndex e > maxIndex l2.
induction l1; intros; simpl in *; intuition.
destruct l2; simpl in *; auto.
specialize (H2 e0); conclude_using eauto; intuition.
Lemma findGtIndex_Prefix :
forall l i,
Prefix (findGtIndex l i) l.
induction l; intros; simpl in *; intuition.
break_if; simpl in *; intuition.
Lemma findGtIndex_app_in_2 :
forall l1 l2 e,
sorted (l1 ++ l2) ->
In e l2 ->
exists l',
findGtIndex (l1 ++ l2) (eIndex e) = l1 ++ l' /\
Prefix l' l2.
induction l1; intros; simpl in *; intuition.
eexists; intuition eauto using findGtIndex_Prefix.
break_if; simpl in *; intuition.
eapply_prop_hyp sorted sorted; eauto.
break_exists; intuition; find_rewrite; eauto.
specialize (H1 e); conclude H1 (apply in_app_iff; intuition).
Lemma findGtIndex_nil :
forall l i,
(forall e', In e' l -> eIndex e' <= i) ->
findGtIndex l i = [].
intros; induction l; simpl in *; intuition.
break_if; do_bool; intuition.
specialize (H a); intuition.
Lemma findGtIndex_removeAfterIndex_commute :
forall l i i',
sorted l ->
removeAfterIndex (findGtIndex l i) i' =
findGtIndex (removeAfterIndex l i') i.
induction l; simpl in *; auto.
repeat (break_if; simpl; intuition); do_bool;
try congruence.
find_apply_lem_hyp removeAfterIndex_in.
Lemma findGtIndex_app_1 :
forall l l' i,
maxIndex l' <= i ->
findGtIndex (l ++ l') i = findGtIndex l i.
induction l; intros; simpl in *; intuition.
destruct l'; simpl in *; intuition.
break_if; do_bool; auto; lia.
Lemma findGtIndex_app_2 :
forall l l' i,
sorted (l ++ l') ->
i < maxIndex l' ->
findGtIndex (l ++ l') i = l ++ findGtIndex l' i.
induction l; intros; simpl in *; intuition.
destruct l'; simpl in *; [lia|];
specialize (H1 e).
conclude_using (intuition auto with datatypes);
lia.
Lemma thing3 :
forall l l' e,
sorted (l ++ l') ->
(forall e', In e' (l ++ l') -> eIndex e' > 0) ->
In e (l ++ l') ->
eIndex e <= maxIndex l' ->
In e l'.
induction l; intros; simpl in *; intuition.
destruct l'; simpl in *; intuition.
conclude_using (intuition auto with datatypes);
lia.
Lemma findGtIndex_non_empty :
forall l i,
i < maxIndex l ->
findGtIndex l i <> [].
induction l; simpl in *; [lia|].
break_if; do_bool; simpl in *; [|lia].
Lemma sorted_Prefix_in_eq :
forall l' l,
sorted l ->
Prefix l' l ->
(forall e, In e l -> In e l') ->
l' = l.
induction l'; intros; simpl in *; intuition.
destruct l; simpl in *; auto.
specialize (H1 e); intuition.
specialize (H1 e0); intuition.
specialize (H0 e0); intuition.
Lemma removeAfterIndex_eq :
forall l i,
(forall e, In e l -> eIndex e <= i) ->
removeAfterIndex l i = l.
induction l; intros; simpl in *; intuition.
Lemma removeAfterIndex_in_app :
forall l l' e,
In e l ->
removeAfterIndex (l ++ l') (eIndex e) =
(removeAfterIndex l (eIndex e)) ++ l'.
induction l; intros; simpl in *; intuition;
subst; break_if; do_bool; eauto using app_assoc.
Lemma removeAfterIndex_in_app_l' :
forall l l' e,
(forall e', In e' l -> eIndex e' > eIndex e) ->
In e l' ->
removeAfterIndex (l ++ l') (eIndex e) =
removeAfterIndex l' (eIndex e).
induction l; intros; simpl in *; intuition;
subst; break_if; do_bool; eauto using app_assoc.
Lemma removeAfterIndex_maxIndex_sorted :
forall l,
sorted l ->
l = removeAfterIndex l (maxIndex l).
intros; induction l; simpl in *; intuition.
Lemma contiguous_singleton_sufficient :
forall x n,
S n = eIndex x ->
contiguous_range_exact_lo [x] n.
intuition auto with datatypes.
inv H2; [reflexivity | lia].
Lemma contiguous_adjacent_sufficient :
forall x y l i,
eIndex x = S (eIndex y) ->
contiguous_range_exact_lo (y :: l) i ->
contiguous_range_exact_lo (x :: y :: l) i.
unfold contiguous_range_exact_lo in *.
eexists; intuition auto with datatypes.
find_apply_lem_hyp Nat.succ_inj.
assert (i < i0 <= maxIndex (y :: l)).
intuition; subst; eexists; intuition auto.
Lemma contiguous_partition :
forall l1 x l2 i,
sorted (l1 ++ x :: l2) ->
contiguous_range_exact_lo (l1 ++ x :: l2) i ->
contiguous_range_exact_lo l1 (eIndex x).
destruct l1; simpl in *; find_copy_apply_lem_hyp contiguous_index_adjacent; auto.
apply contiguous_singleton_sufficient.
eapply contiguous_adjacent_sufficient; auto.
eauto using contiguous_singleton_sufficient.
eauto using sorted_subseq, subseq_skip, subseq_refl.
eauto using cons_contiguous_sorted.
Lemma rev_exists :
forall A (l : list A) l',
(exists l'',
l = l'' ++ l') ->
exists l'',
rev l = rev l' ++ l''.
eauto using rev_app_distr.
Lemma app_in_2 :
forall A l l1 l2 (x : A),
l = l1 ++ l2 ->
In x l2 ->
In x l.
intuition auto with datatypes.
Lemma app_contiguous_maxIndex_le_eq :
forall l l1 l2 l2' i,
l = l1 ++ l2 ->
Prefix l2 l2' ->
contiguous_range_exact_lo l i ->
maxIndex l2' <= i ->
l = l1.
destruct l2; eauto using app_nil_r.
unfold contiguous_range_exact_lo in *.
conclude_using (intuition auto with datatypes).
Lemma sorted_app_1 :
forall l1 l2,
sorted (l1 ++ l2) ->
sorted l1.
induction l1; simpl in *; intuition auto with datatypes;
eapply H0; intuition auto with datatypes.
Lemma Prefix_maxIndex :
forall l l' e,
sorted l' ->
Prefix l l' ->
In e l ->
eIndex e <= maxIndex l'.
induction l; intros; simpl in *; intuition;
break_match; intuition; repeat subst; simpl in *; auto.
eapply_prop_hyp sorted sorted; eauto.
match goal with
| _ : eIndex _ <= maxIndex ?l |- _ =>
destruct l
end.
find_apply_lem_hyp Prefix_nil.
match goal with
| [ H : forall _, _ = _ \/ In _ _ -> _, _ : eIndex _ <= eIndex ?e |- _ ] =>
specialize (H e)
end; intuition lia.
Lemma app_maxIndex_In_l :
forall l l' e,
sorted (l ++ l') ->
In e (l ++ l') ->
maxIndex l' < eIndex e ->
In e l.
induction l; intros; simpl in *; intuition.
destruct l'; simpl in *; intuition auto; subst; try lia.
intuition auto with datatypes.
Lemma contiguous_app_prefix_contiguous :
forall l1 l2 l2' i,
Prefix l2 l2' ->
sorted (l1 ++ l2) ->
contiguous_range_exact_lo (l1 ++ l2) i ->
(l2 <> [] \/ i = maxIndex l2') ->
contiguous_range_exact_lo l1 (maxIndex l2').
match goal with H : _ \/ _ |- _ => clear H end.
eauto using contiguous_partition.
Lemma sorted_term_index_lt :
forall l e e',
sorted l ->
In e l ->
In e' l ->
eIndex e < eIndex e' ->
eTerm e <= eTerm e'.
induction l; simpl in *; intuition auto; repeat subst; auto;
find_apply_hyp_hyp; lia.
Lemma contiguous_app_prefix_2 :
forall l l' l'' i,
sorted (l ++ l') ->
contiguous_range_exact_lo (l ++ l') 0 ->
Prefix l' l'' ->
maxIndex l'' < i <= maxIndex l ->
exists e, eIndex e = i /\ In e l.
eapply_prop (contiguous_range_exact_lo l).
find_eapply_lem_hyp contiguous_app_prefix_contiguous; eauto.
Lemma contiguous_0_app :
forall l1 l2 e,
sorted (l1 ++ l2) ->
contiguous_range_exact_lo (l1 ++ l2) 0 ->
In e l1 ->
eIndex e > maxIndex l2.
rewrite <- app_comm_cons in *.
match goal with
| H : In _ _ |- _ => simpl in H
end.
unfold contiguous_range_exact_lo in *.
intuition auto with datatypes.
match goal with
| H : _ |- eIndex _ > eIndex ?e =>
specialize (H e)
end.
conclude_using (intuition auto with datatypes).
find_apply_lem_hyp cons_contiguous_sorted; eauto.
Lemma deduplicate_log'_In_if :
forall e l ks,
In e (deduplicate_log' l ks) ->
In e l.
induction l; intros; simpl in *; intuition.
repeat break_match; simpl in *; intuition; find_apply_hyp_hyp; auto.
Lemma findGtIndex_removeAfterIndex_i_lt_i' :
forall l i i',
sorted l ->
i < i' ->
(filter
(fun x : entry =>
(i <? eIndex x) && (eIndex x <=? i'))
(findGtIndex l i))
++ removeAfterIndex l i =
removeAfterIndex l i'.
induction l; intros; intuition.
repeat break_if; simpl in *; repeat break_if;
repeat (do_bool; intuition auto); try lia.
apply removeAfterIndex_eq.
Lemma findGtIndex_removeAfterIndex_i'_le_i :
forall l i i',
sorted l ->
i' <= i ->
(filter
(fun x : entry =>
(i <? eIndex x) && (eIndex x <=? i'))
(findGtIndex l i))
++ removeAfterIndex l i =
removeAfterIndex l i.
induction l; intros; intuition.
repeat break_if; simpl in *; repeat break_if;
repeat (do_bool; intuition); lia.
Lemma sorted_cons_elim :
forall e l,
sorted (e :: l) ->
sorted l.
eauto using sorted_subseq, subseq_skip, subseq_refl.
Lemma contiguous_sorted_last :
forall l x i,
sorted (l ++ [x]) ->
contiguous_range_exact_lo (l ++ [x]) i ->
eIndex x = S i /\ contiguous_range_exact_lo l (S i).
find_apply_lem_hyp contiguous_index_singleton.
find_copy_apply_lem_hyp contiguous_index_adjacent; auto.
find_apply_lem_hyp cons_contiguous_sorted; auto.
find_copy_apply_lem_hyp contiguous_index_singleton.
eapply contiguous_singleton_sufficient.
find_copy_apply_lem_hyp contiguous_index_adjacent; auto.
find_apply_lem_hyp cons_contiguous_sorted; auto.
find_apply_lem_hyp sorted_cons_elim.
eapply contiguous_adjacent_sufficient; intuition.
Lemma sorted_app_gt :
forall l1 l2 e1 e2,
sorted (l1 ++ l2) ->
In e1 l1 ->
In e2 l2 ->
eIndex e1 > eIndex e2.
assert (In e2 (l1 ++ l2)).
Lemma sorted_app_In_reduce:
forall l1 l2 e1 e2,
sorted (l1 ++ [e1]) ->
sorted (l2 ++ [e2]) ->
eIndex e1 = eIndex e2 ->
(forall e, In e (l1 ++ [e1]) -> In e (l2 ++ [e2])) ->
(forall e, In e l1 -> In e l2).
find_copy_eapply_lem_hyp (sorted_app_gt l1 [e1]); simpl; eauto.
assert (In e (l1 ++ [e1])).
find_apply_lem_hyp in_app_or.
Lemma contiguous_sorted_subset_prefix :
forall l1 l2 i,
contiguous_range_exact_lo l1 i ->
contiguous_range_exact_lo l2 i ->
sorted l1 ->
sorted l2 ->
(forall e, In e l1 -> In e l2) ->
Prefix (rev l1) (rev l2).
induction l1 using rev_ind; intuition.
induction l2 using rev_ind.
find_apply_lem_hyp contiguous_sorted_last; auto.
find_apply_lem_hyp contiguous_sorted_last; auto.
repeat find_reverse_rewrite.
eapply uniqueIndices_elim_eq; eauto using sorted_uniqueIndices.
eapply IHl1; eauto using sorted_app_1, sorted_app_In_reduce.
Lemma not_empty_false :
forall A (l : list A),
not_empty l = false ->
l = [].
destruct l; [auto|discriminate].
Lemma moreUpToDate_refl :
forall x y,
moreUpToDate x y x y = true.
unfold moreUpToDate in *.
apply Bool.orb_true_intro.
intuition; do_bool; intuition.
Lemma wonElection_dedup_spec :
forall l,
wonElection (dedup name_eq_dec l) = true ->
exists quorum,
NoDup quorum /\
length quorum > div2 (length nodes) /\
(forall h, In h quorum -> In h l).
exists (dedup name_eq_dec l).
intuition; eauto using NoDup_dedup, in_dedup_was_in.
Lemma contiguous_findAtIndex :
forall l s i,
sorted l ->
contiguous_range_exact_lo l s ->
s < i <= maxIndex l ->
exists e, findAtIndex l i = Some e.
unfold contiguous_range_exact_lo.
match goal with
| [ H : forall _, _ |- _ ] => specialize (H i)
end.
eapply findAtIndex_intro; auto using sorted_uniqueIndices.
Notation is_append_entries m :=
(exists t n prevT prevI entries c,
m = AppendEntries t n prevT prevI entries c).
Notation is_request_vote_reply m :=
(exists t r,
m = RequestVoteReply t r).
Ltac use_applyEntries_spec :=
match goal with
| H : context [applyEntries] |- _ => eapply applyEntries_spec in H; eauto; break_exists
end.
Ltac unfold_invariant hyp :=
(red in hyp; (* try unfolding the invariant and look for conjunction *)
match type of hyp with
| _ /\ _ => break_and
| _ => fail 1 (* better to not unfold *)
end) ||
break_and.
(* introduces an invariant then tries to break apart any nested
conjunctions to return the usable invariants as hypotheses *)
Ltac intro_invariant lem :=
match goal with
| [ h: raft_intermediate_reachable _ |- _ ] =>
let x := fresh in
pose proof h as x;
apply lem in x;
unfold_invariant x
end.