(* matchIndex *)
  Definition matchIndex_preserved st st' :=
    type st' = Leader ->
    (type st = Leader /\ matchIndex st' = matchIndex st /\ log st' = log st).Definition matchIndex_preserved_except_at_host h st st' :=
    type st' = Leader ->
    (type st = Leader /\
     forall h',
       h <> h' ->
       (assoc_default name_eq_dec (matchIndex st') h' 0) = (assoc_default name_eq_dec (matchIndex st) h') 0).

(* Specifications: *)
Lemma handleAppendEntries_matchIndex_preserved: forall h st (d : raft_data) (m : msg) (t : term) (n : name) (pli : logIndex) (plt : term) (es : list entry) (ci : logIndex), handleAppendEntries h st t n pli plt es ci = (d, m) -> matchIndex_preserved st d.
Lemma handleAppendEntriesReply_matchIndex_leader_preserved: forall h st (d : raft_data) (m : list (name * msg)) (t : nat) (es : list entry) (res : bool) h', handleAppendEntriesReply h st h' t es res = (d, m) -> matchIndex_preserved_except_at_host h' st d.
Lemma advanceCurrentTerm_matchIndex_preserved : forall st t, matchIndex_preserved st (advanceCurrentTerm st t).
Theorem handleTimeout_matchIndex_preserved : forall h st out st' ps, handleTimeout h st = (out, st', ps) -> matchIndex_preserved st st'.
Theorem handleClientRequest_matchIndex_maxIndex: forall h st client id c out st' ps, handleClientRequest h st client id c = (out, st', ps) -> (maxIndex (log st') = maxIndex (log st) /\ matchIndex st' = matchIndex st) \/ (assoc_default name_eq_dec (matchIndex st') h 0) = maxIndex (log st').
Theorem handleClientRequest_matchIndex : forall h st client id c out st' ps, handleClientRequest h st client id c = (out, st', ps) -> (maxIndex (log st') = maxIndex (log st) /\ matchIndex st' = matchIndex st) \/ matchIndex st' = assoc_set name_eq_dec (matchIndex st) h (maxIndex (log st')) /\ maxIndex (log st') = S (maxIndex (log st)).
Lemma tryToBecomeLeader_matchIndex_preserved : forall n st out st' ms, tryToBecomeLeader n st = (out, st', ms) -> matchIndex_preserved st st'.
Lemma handleRequestVote_matchIndex_preserved : forall n st t c li lt st' ms, handleRequestVote n st t c li lt = (st', ms) -> matchIndex_preserved st st'.
Lemma doGenericServer_matchIndex_preserved : forall h st os st' ps, doGenericServer h st = (os, st', ps) -> matchIndex_preserved st st'.
Lemma handleRequestVoteReply_matchIndex : forall n st src t v, type (handleRequestVoteReply n st src t v) = Leader -> (type st = Leader /\ matchIndex (handleRequestVoteReply n st src t v) = matchIndex st) \/ (assoc_default name_eq_dec (matchIndex (handleRequestVoteReply n st src t v)) n 0 = maxIndex (log (handleRequestVoteReply n st src t v))).
Lemma doLeader_matchIndex_preserved : forall st h os st' ms, doLeader st h = (os, st', ms) -> matchIndex_preserved st st'.
Lemma doLeader_lastApplied : forall st h os st' ms, doLeader st h = (os, st', ms) -> lastApplied st' = lastApplied st.
Lemma handleRequestVote_no_append_entries : forall st h h' t lli llt st' m, handleRequestVote h st t h' lli llt = (st', m) -> ~ is_append_entries m.
Theorem handleClientRequest_no_append_entries : forall h st client id c out st' ps m, handleClientRequest h st client id c = (out, st', ps) -> In m ps -> ~ is_append_entries (snd m).
Lemma handleTimeout_packets : forall h d out d' ps m, handleTimeout h d = (out, d', ps) -> In m ps -> ~ is_append_entries (snd m).
Lemma doLeader_messages : forall st h os st' ms m t n pli plt es ci, doLeader st h = (os, st', ms) -> In m ms -> snd m = AppendEntries t n pli plt es ci -> t = currentTerm st /\ log st' = log st /\ type st = Leader /\ ((plt = 0) \/ ((exists e, findAtIndex (log st) pli = Some e /\ eTerm e = plt))).
Lemma doLeader_message_entries : forall st h os st' ms m t n pli plt es ci e, doLeader st h = (os, st', ms) -> In m ms -> snd m = AppendEntries t n pli plt es ci -> In e es -> In e (log st).
Theorem handleAppendEntries_log_term_type : forall h st t n pli plt es ci st' ps, handleAppendEntries h st t n pli plt es ci = (st', ps) -> (log st' = log st /\ currentTerm st' = currentTerm st /\ type st' = type st) \/ type st' = Follower.
Theorem handleAppendEntries_votesReceived : forall h st t n pli plt es ci st' ps, handleAppendEntries h st t n pli plt es ci = (st', ps) -> votesReceived st' = votesReceived st.
Theorem handleAppendEntriesReply_log_term_type : forall h st n t es r st' ps, handleAppendEntriesReply h st n t es r = (st', ps) -> (log st' = log st /\ currentTerm st' = currentTerm st /\ type st' = type st) \/ type st' = Follower.
Theorem handleAppendEntriesReply_votesReceived : forall h st n t es r st' ps, handleAppendEntriesReply h st n t es r = (st', ps) -> votesReceived st' = votesReceived st.
Theorem handleRequestVote_log_term_type : forall h st t c li lt st' m, handleRequestVote h st t c li lt = (st', m) -> (log st' = log st /\ currentTerm st' = currentTerm st /\ type st' = type st) \/ type st' = Follower.
Theorem handleRequestVote_votesReceived : forall h st t c li lt st' m, handleRequestVote h st t c li lt = (st', m) -> votesReceived st' = votesReceived st.
Theorem handleRequestVoteReply_log_term_type : forall h st t h' r st', type st' = Candidate -> handleRequestVoteReply h st h' t r = st' -> (log st' = log st /\ currentTerm st' = currentTerm st /\ type st' = type st).
Theorem handleRequestVoteReply_votesReceived : forall h st t h' r v, In v (votesReceived (handleRequestVoteReply h st h' t r)) -> In v (votesReceived st) \/ (r = true /\ v = h' /\ currentTerm (handleRequestVoteReply h st h' t r) = t).
Theorem handleTimeout_log_term_type : forall h st out st' ps, handleTimeout h st = (out, st', ps) -> (log st' = log st /\ currentTerm st' = currentTerm st /\ type st' = type st) \/ currentTerm st' = S (currentTerm st).
Lemma handleClientRequest_candidate : forall h st client id c os st' m, handleClientRequest h st client id c = (os, st', m) -> type st' = Candidate -> st' = st.
Lemma doLeader_candidate : forall st h os st' ms, doLeader st h = (os, st', ms) -> type st' = Candidate -> st' = st.
Lemma doLeader_term_votedFor : forall st h os st' ms, doLeader st h = (os, st', ms) -> currentTerm st' = currentTerm st /\ votedFor st' = votedFor st.
Lemma doGenericServer_log_type_term_votesReceived : forall h st os st' ps, doGenericServer h st = (os, st', ps) -> log st' = log st /\ type st' = type st /\ currentTerm st' = currentTerm st /\ votesReceived st' = votesReceived st /\ votedFor st' = votedFor st.
Lemma handleClientRequest_term_votedFor : forall h st client id c os st' m, handleClientRequest h st client id c = (os, st', m) -> type st' = type st /\ currentTerm st' = currentTerm st /\ votedFor st' = votedFor st.
Theorem handleAppendEntries_term_votedFor : forall h st t n pli plt es ci st' ps h', handleAppendEntries h st t n pli plt es ci = (st', ps) -> votedFor st' = Some h' -> currentTerm st' = currentTerm st /\ votedFor st' = votedFor st.
Theorem handleAppendEntriesReply_term_votedFor : forall h st n t es r st' ps h', handleAppendEntriesReply h st n t es r = (st', ps) -> votedFor st' = Some h' -> currentTerm st' = currentTerm st /\ votedFor st' = votedFor st.
Theorem handleRequestVoteReply_term_votedFor : forall h st t h' h'' r st', handleRequestVoteReply h st h' t r = st' -> votedFor st' = Some h'' -> currentTerm st' = currentTerm st /\ votedFor st' = votedFor st.
Lemma handleRequestVote_reply_true: forall h h' st t lli llt st' t', handleRequestVote h st t h' lli llt = (st', RequestVoteReply t' true) -> votedFor st' = Some h' /\ currentTerm st' = t'.
Lemma handleTimeout_messages: forall (out : list raft_output) (st : raft_data) (l : list (name * msg)) h (mi : logIndex) (mt : term) m st' t n, handleTimeout h st = (out, st', l) -> In m l -> snd m = RequestVote t n mi mt -> maxIndex (log st') = mi /\ maxTerm (log st') = mt /\ t = currentTerm st'.
Lemma handleRequestVoteReply_currentTerm : forall h st h' t r x, x <= currentTerm st -> x <= currentTerm (handleRequestVoteReply h st h' t r).
Lemma handleRequestVote_reply_true': forall (h : name) (h' : fin N) (st : RaftState.raft_data term name entry logIndex serverType data clientId output) (t lli llt : nat) (st' : raft_data) (t' : term), handleRequestVote h st t h' lli llt = (st', RequestVoteReply t' true) -> t' = t /\ currentTerm st' = t.