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.

(* Specifications: *)
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.
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.
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.
Lemma handleTimeout_commitIndex : forall h st out st' l, handleTimeout h st = (out, st', l) -> commitIndex st' = commitIndex st.
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.
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.
Lemma handleRequestVoteReply_same_commitIndex : forall n st src t v, commitIndex (handleRequestVoteReply n st src t v) = commitIndex st.
Lemma doGenericServer_commitIndex : forall h st out st' ms, doGenericServer h st = (out, st', ms) -> commitIndex st' = commitIndex st.
Theorem div2_correct' : forall n, n <= div2 n + S (div2 n).
Theorem div2_correct : forall c a b, a > div2 c -> b > div2 c -> a + b > c.
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'.
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 execute_log_correct : forall log, step_1_star init (snd (execute_log log)) (fst (execute_log log)).
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.
Lemma cons_contiguous_sorted : forall l i a, sorted (a :: l) -> contiguous_range_exact_lo (a :: l) i -> contiguous_range_exact_lo l i.
Lemma contiguous_app : forall l1 l2 i, sorted (l1 ++ l2) -> contiguous_range_exact_lo (l1 ++ l2) i -> contiguous_range_exact_lo l2 i.
Lemma prefix_sorted : forall l l', sorted l -> Prefix l' l -> sorted l'.
Lemma removeAfterIndex_contiguous : forall l i i', sorted l -> contiguous_range_exact_lo l i -> contiguous_range_exact_lo (removeAfterIndex l i') i.
Lemma sorted_NoDup : forall l, sorted l -> NoDup l.
Lemma sorted_Permutation_eq : forall l l', sorted l -> sorted l' -> Permutation l l' -> l = l'.
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.
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.
Lemma sorted_findGtIndex_0 : forall l, (forall e, In e l -> eIndex e > 0) -> sorted l -> findGtIndex l 0 = l.
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.
Lemma sorted_app_in_1 : forall l1 l2 e, sorted (l1 ++ l2) -> eIndex e > 0 -> In e l1 -> eIndex e > maxIndex l2.
Lemma findGtIndex_Prefix : forall l i, Prefix (findGtIndex l i) l.
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.
Lemma findGtIndex_removeAfterIndex_commute : forall l i i', sorted l -> removeAfterIndex (findGtIndex l i) i' = findGtIndex (removeAfterIndex l i') i.
Lemma findGtIndex_app_1 : forall l l' i, maxIndex l' <= i -> findGtIndex (l ++ l') i = findGtIndex l i.
Lemma findGtIndex_app_2 : forall l l' i, sorted (l ++ l') -> i < maxIndex l' -> findGtIndex (l ++ l') i = l ++ findGtIndex l' i.
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'.
Lemma sorted_Prefix_in_eq : forall l' l, sorted l -> Prefix l' l -> (forall e, In e l -> In e l') -> l' = l.
Lemma removeAfterIndex_eq : forall l i, (forall e, In e l -> eIndex e <= i) -> removeAfterIndex l i = l.
Lemma removeAfterIndex_in_app : forall l l' e, In e l -> removeAfterIndex (l ++ l') (eIndex e) = (removeAfterIndex l (eIndex e)) ++ l'.
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).
Lemma removeAfterIndex_maxIndex_sorted : forall l, sorted l -> l = removeAfterIndex l (maxIndex l).
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.
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).
Lemma rev_exists : forall A (l : list A) l', (exists l'', l = l'' ++ l') -> exists l'', rev l = rev l' ++ l''.
Lemma app_in_2 : forall A l l1 l2 (x : A), l = l1 ++ l2 -> In x l2 -> In x l.
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.
Lemma sorted_app_1 : forall l1 l2, sorted (l1 ++ l2) -> sorted l1.
Lemma Prefix_maxIndex : forall l l' e, sorted l' -> Prefix l l' -> In e l -> eIndex e <= maxIndex l'.
Lemma app_maxIndex_In_l : forall l l' e, sorted (l ++ l') -> In e (l ++ l') -> maxIndex l' < eIndex e -> In e l.
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'.
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.
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.
Lemma deduplicate_log'_In_if : forall e l ks, In e (deduplicate_log' l ks) -> In e l.
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'.
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.
Lemma sorted_cons_elim : forall e l, sorted (e :: l) -> sorted l.
Lemma sorted_app_gt : forall l1 l2 e1 e2, sorted (l1 ++ l2) -> In e1 l1 -> In e2 l2 -> eIndex e1 > eIndex e2.
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).
Lemma moreUpToDate_refl : forall x y, moreUpToDate x y x y = true.
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).
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.