(** Succeed iff [x] is in the list [ls], represented with left-associated nested tuples. *)
Ltac inList x ls :=
  match ls with
    | x => idtac
    | (_, x) => idtac
    | (?LS, _) => inList x LS
  end.(** Try calling tactic function [f] on every element of tupled list [ls], keeping the first call not to fail. *)
Ltac app f ls :=
  match ls with
    | (?LS, ?X) => f X || app f LS || fail 1
    | _ => f ls
  end.(** Run [f] on every element of [ls], not just the first that doesn't fail. *)
Ltac all f ls :=
  match ls with
    | (?LS, ?X) => f X; all f LS
    | (_, _) => fail 1
    | _ => f ls
  end.

(* Specifications: *)
Lemma appendEntries_haveNewEntries_false : forall net p t n pli plt es ci h e, refined_raft_intermediate_reachable net -> In p (nwPackets net) -> pBody p = AppendEntries t n pli plt es ci -> haveNewEntries (snd (nwState net h)) es = false -> In e es -> In e (log (snd (nwState net h))).
Lemma maxIndex_le : forall l1 l2, sorted l1 -> contiguous_range_exact_lo l1 0 -> findAtIndex l1 (maxIndex l2) = None -> l2 = nil \/ (exists e, In e l2 /\ eIndex e = 0) \/ maxIndex l1 <= maxIndex l2.
Lemma maxIndex_le' : forall l1 l2 i, sorted l1 -> contiguous_range_exact_lo l1 0 -> l2 <> nil -> contiguous_range_exact_lo l2 i -> findAtIndex l1 (maxIndex l2) = None -> maxIndex l1 <= maxIndex l2.
Lemma sorted_app_in_in : forall l1 l2 e e', sorted (l1 ++ l2) -> In e l1 -> In e' l2 -> eIndex e' < eIndex e.
Lemma sorted_app_sorted_app_in1_in2 : forall l1 l2 l3 e e', sorted (l1 ++ l3) -> sorted (l2 ++ l3) -> In e l1 -> In e' (l2 ++ l3) -> eIndex e' = eIndex e -> In e' l2.
Lemma sorted_app_sorted_app_in1_in2_prefix : forall l1 l2 l3 l4 e e', sorted (l1 ++ l3) -> sorted (l2 ++ l4) -> Prefix l4 l3 -> In e l1 -> In e' (l2 ++ l4) -> eIndex e' = eIndex e -> In e' l2.
Lemma sorted_app_in2_in2 : forall l1 l2 e e', sorted (l1 ++ l2) -> In e' (l1 ++ l2) -> In e l2 -> eIndex e' = eIndex e -> In e' l2.
Lemma sorted_term_index_le : forall l e e', sorted l -> In e l -> In e' l -> eTerm e' < eTerm e -> eIndex e' <= eIndex e.
Lemma term_ne_in_l2 : forall l e e' l1 l2, sorted l -> In e l -> (forall e', In e' l -> eTerm e' <= eTerm e) -> removeAfterIndex l (eIndex e) = l1 ++ l2 -> (forall e', In e' l1 -> eTerm e' = eTerm e) -> In e' l -> eTerm e' <> eTerm e -> In e' l2.
Lemma Prefix_maxIndex_eq : forall l l', Prefix l l' -> l <> nil -> maxIndex l = maxIndex l'.
Lemma sorted_gt_maxIndex : forall e l1 l2, sorted (e :: l1 ++ l2) -> l2 <> nil -> maxIndex l2 < eIndex e.
Lemma allEntries_log_append_entries : refined_raft_net_invariant_append_entries allEntries_log.
Lemma handleAppendEntriesReply_currentTerm_leaderId : forall h st h' t es res st' m, handleAppendEntriesReply h st h' t es res = (st', m) -> currentTerm st < currentTerm st' \/ (currentTerm st = currentTerm st' /\ leaderId st' = leaderId st).
Lemma allEntries_log_append_entries_reply : refined_raft_net_invariant_append_entries_reply allEntries_log.
Lemma update_elections_data_requestVote_leaderLogs : forall h h' t lli llt st, leaderLogs (update_elections_data_requestVote h h' t h' lli llt st) = leaderLogs (fst st).
Lemma update_elections_data_requestVoteReply_leaderLogs : forall h h' t st t' ll' r, In (t', ll') (leaderLogs (fst st)) -> In (t', ll') (leaderLogs (update_elections_data_requestVoteReply h h' t r st)).
Lemma allEntries_log_request_vote : refined_raft_net_invariant_request_vote allEntries_log.
Lemma handleRequestVoteReply_log' : forall h st h' t r, log (handleRequestVoteReply h st h' t r) = log st.
Lemma allEntries_log_request_vote_reply : refined_raft_net_invariant_request_vote_reply allEntries_log.
Lemma update_elections_data_client_request_allEntries' : forall h st client id c out st' ms t e, handleClientRequest h (snd st) client id c = (out, st', ms) -> In (t, e) (allEntries (update_elections_data_client_request h st client id c)) -> In (t, e) (allEntries (fst st)) \/ In e (log st').
Lemma handleClientRequest_currentTerm_leaderId : forall h st client id c out st' ms, handleClientRequest h st client id c = (out, st', ms) -> currentTerm st' = currentTerm st /\ leaderId st' = leaderId st.
Lemma allEntries_log_client_request : refined_raft_net_invariant_client_request allEntries_log.
Lemma handleTimeout_currentTerm_leaderId : forall h st out st' ms, handleTimeout h st = (out, st', ms) -> currentTerm st < currentTerm st' \/ currentTerm st' = currentTerm st /\ leaderId st' = leaderId st.
Lemma allEntries_log_timeout : refined_raft_net_invariant_timeout allEntries_log.
Lemma doLeader_currentTerm_leaderId : forall st h out st' m, doLeader st h = (out, st', m) -> currentTerm st' = currentTerm st /\ leaderId st' = leaderId st.
Lemma allEntries_log_do_leader : refined_raft_net_invariant_do_leader allEntries_log.
Lemma doGenericServer_currentTerm_leaderId : forall st h out st' m, doGenericServer h st = (out, st', m) -> currentTerm st' = currentTerm st /\ leaderId st' = leaderId st.
Lemma allEntries_log_do_generic_server : refined_raft_net_invariant_do_generic_server allEntries_log.
Lemma allEntries_log_init : refined_raft_net_invariant_init allEntries_log.
Lemma allEntries_log_state_same_packet_subset : refined_raft_net_invariant_state_same_packet_subset allEntries_log.
Lemma allEntries_log_reboot : refined_raft_net_invariant_reboot allEntries_log.
Lemma allEntries_log_invariant : forall net, refined_raft_intermediate_reachable net -> allEntries_log net.