DieHardest: compare jug configurations via parallel and interleaved self-composition#199
DieHardest: compare jug configurations via parallel and interleaved self-composition#199
Conversation
1fedc7f to
4af357d
Compare
d872bd6 to
f9d4e0c
Compare
f9d4e0c to
05ea707
Compare
Add DieHardest.tla, which composes two instances of DieHarder to
check a 2-hyperproperty as an ordinary invariant: given two jug
configurations that can each solve the Die Hard problem, which one
reaches the Goal in fewer steps? The invariant NotSolved holds as
long as both configurations have not yet reached the Goal; a
counterexample is a behavior in which both solve the problem,
revealing which configuration is faster.
The module also defines HasSolution, a GCD-based predicate (via
Bézout's identity) used in ASSUME to reject unsolvable
configurations before model checking begins.
Four composition approaches are contrasted in clearly labeled
sections that progressively motivate interleaved composition:
1. Parallel — shows that BFS finds the shortest path for the slower
configuration but not the faster one.
2. Parallel + per-behavior freeze — shows that freezing after
reaching the Goal does not help.
3. Parallel + g BFS-level freeze — correct, but relies on
TLC-specific operators outsi the logic of TLA+.
4. Interleaved — the clean solution: each instanceteps
independently, so BFS minimizes both step counts.
Annotated counterexample traces in Sections 1 and 3 illustrate the
difference concretely.
MCDieHardest instantiates the spec with Goal = 4, comparing a 2-jug
<<5, 3>> setup against a 3-jug <<5, 3, 3>> setup — the duplicate jug
reduces the shortest solution from 6 to steps.
Co-authored-by: Dmitry Kulagin <craft095@users.noreply.github.com>
Signed-off-by: Markus Alexander Kuppe <github.com@lemmster.de>
05ea707 to
1c146d0
Compare
|
@hwayne Could you please review this example? It references your “Hypermodeling Hyperproperties” article. |
| (* *) | ||
| (* Both paths are individually shortest. However, TLCSet and TLCGet *) | ||
| (* are TLC-specific operators outside the logic of TLA+, making this *) | ||
| (* approach incompatible with other TLA+ tools (e.g. Apalache). *) |
There was a problem hiding this comment.
Also, unless things changed recently, TLC global registers are local to each worker
There was a problem hiding this comment.
Indeed, this would also only work with a single worker.
|
These solutions depend on two assumptions: that the states are searched with BFS, and that the BFS is strict. The first is violated with the
It's pretty rare, but I've seen it happen! A robust and universal TLA+ spec would probably have to store the diehard traces as data values and implement Dijkstra's algorithm to find the shortest path, with the property that |
Strict BFS has in fact been an implicit assumption in the current formulation. This directly contradicts the spec's own statement: "This approach stays entirely within the logic of TLA+ and is compatible with all TLA+ tools." Given that contradiction, what do you think about removing that statement and instead making the assumption explicit, for example: ASSUME TLCGet("config").mode = "bfs" /\ TLCGet("config").worker = 1In my view, the example would still offer an interesting and valuable perspective on self-composition, even with this assumption made explicit. |
Add DieHardest.tla, which composes two instances of DieHarder to compare which configuration has the shorter path to the Goal (state).
Four composition approaches are contrasted in clearly labeled sections that progressively motivate interleaved composition: