Learn · All the Ways It Can Break
growing
Actions Are Predicates Over Two States
A step constrains old values and primed new values; it does not execute assignments in order.
You will define an initial-state predicate, read two parameterized actions, use primed variables and UNCHANGED, and combine choices into Next. You will also diagnose the omitted-variable bug that makes a specification more nondeterministic than intended.
Init describes a set of starting states
The lifecycle starts every job queued and both tracking sets empty:
tla code/all-the-ways-it-can-break/job-lifecycle/JobLifecycle.tla#init JobLifecycle.tla Init may denote several states when its expressions leave choices open; this version denotes one state for each concrete Jobs assignment.
The conjunction does not run top to bottom. It simultaneously constrains all three variable values. Reordering the conjuncts changes typography, not meaning.
Read one action as a relation
tla code/all-the-ways-it-can-break/job-lifecycle/JobLifecycle.tla#start-cancel JobLifecycle.tla Start(job) changes one function entry. Cancel(job) grows a set. Each explicitly preserves the other coordinates.
Start(job) admits a pair of states when the old phase is queued, the new phase function changes that job to running, and the two other variables keep their values. The EXCEPT expression calculates a whole new function value; the prime tells us it belongs to the new state.
Cancel(job) leaves phase unchanged and gives canceled' the old set plus the selected job. Because set union is idempotent, canceling an already canceled running job may be a stuttering step: the new state equals the old. Whether to admit that step is a modeling decision, not an implementation fact.
Next keeps every admitted choice
The complete relation existentially chooses a job and disjoins actions:
Next == \E job \in Jobs:
Start(job) \/ Cancel(job) \/ Complete(job) \/ Publish(job)
This says that some job and some listed action relate the current state to the next. It does not choose a priority. If two jobs can start, both outgoing edges belong to the graph. If cancellation and completion are both enabled, TLC may explore each ordering. Writing if cancellation then ... else completion would erase one race unless that priority is itself part of the system contract.
Under the hood: actions are sets of pairs
Mathematically, an action denotes a relation: a set of ordered pairs (oldState, newState). Conjunction intersects constraints on those pairs; disjunction unions permitted pairs; existential quantification hides which job witness made the relation true. This is why statement-order intuition fails.
The model is declarative but not vague. A new state is admitted only when every relevant primed coordinate satisfies the formula. The discipline is to close the frame explicitly. A useful review is mechanical: for every action, list every variable and point to either its primed constraint or its UNCHANGED membership.
Lessons
Initis a predicate describing permitted starting states.- An action is true or false of an old-state/new-state pair.
- A prime selects the next value; it is not an ordered assignment.
- Omitted primed variables are unconstrained, not implicitly preserved.
- Disjunction and existential choice preserve alternatives for exploration.
Practice
- Retrieval. Explain the difference between
phaseandphase'. - Discrimination. When two enabled actions update distinct jobs, should
Nextselect one by priority merely to reduce states? - Transfer. Write
Enter(person)for a turnstile that adds one person toinsideand leaveslockedunchanged.
Worked answers
phaseis the old function;phase'is the candidate next function.- No, unless priority is a real contract. Otherwise it removes an admitted ordering and may hide a race.
/\ person \in People /\ inside' = inside \union {person} /\ UNCHANGED locked.
References
- Leslie Lamport. Specifying Systems, Chapters 3–4. — state predicates, actions, primes, and next-state relations
- Leslie Lamport. A High-Level View of TLA+. — behaviors as sequences of states