TypeOK /\ H_PrimaryTermGTELogTerm /\ H_TermsMonotonic /\ Next => H_TermsMonotonic'
H_TermsMonotonic asserts that for every server sv, the term sequence
log[sv] is monotonically non-decreasing: ∀ i ≤ j ∈ DOMAIN log[sv]: log[sv][i] ≤ log[sv][j].
The proof proceeds by case analysis over each action in Next.
log in a way that can decrease an entry, so the invariant is
preserved trivially via definitional unfolding. SMT discharges these in a single step.
currentTerm[p]
to server p's log. The proof splits into four domain-membership cases for indices ii, jj:
ii old, jj new (= Len+1): H_PrimaryTermGTELogTerm guarantees
log[p][ii] ≤ currentTerm[p] since state[p] = Primary.ii = jj and the inequality is trivial.ii new, jj old: impossible since Len+1 > any old index, contradicting ii ≤ jj.r appends one entry from
sender at position Len(log[r])+1. The proof again uses four domain cases.
The critical sub-case is ii old, jj new, requiring:
log[r][ii] ≤ log[sender][Len(log[r])+1]. This is established by chaining two
applications of H_TermsMonotonic:
log[r][ii] ≤ log[r][Len(log[r])] — monotonicity on r.log[r][Len(log[r])] = log[sender][Len(log[r])] — from GetEntries logOk condition.log[sender][Len(log[r])] ≤ log[sender][Len(log[r])+1] — monotonicity on sender.| Step | Action | Prover | Status | Timing |
|---|---|---|---|---|
| <1>1 | ClientRequestAction | smt | proved | cached |
| <1>2 | GetEntriesAction | smt | proved | ~8 min (multi-run) |
| <1>3 | RollbackEntriesAction | smt | proved | cached |
| <1>4 | BecomeLeaderAction | smt | proved | cached |
| <1>5 | CommitEntryAction | smt | proved | cached |
| <1>6 | UpdateTermsAction | smt | proved | cached |
| Total: 227 obligations | smt + trivial | ALL PROVED | ~8 min total | |
Generated 2026-04-03 • TLAPM 1.5.0 • 8 threads •
Final run: tlapm --threads 8 --toolbox 858 994 AbstractRaft_IndProofs_test.tla
• All 227 obligations proved (6 runs, 15:04–15:12)