tla-checker 0.5.2 → 0.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -295
- package/package.json +1 -1
- package/tla_checker.d.ts +12 -0
- package/tla_checker.js +128 -0
- package/tla_checker_bg.wasm +0 -0
- package/tla_checker_bg.wasm.d.ts +4 -0
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
A TLA+ model checker and interactive exploration tool written in Rust.
|
|
4
4
|
|
|
5
|
-
tla-rs verifies TLA+ specifications by exploring all reachable states, checking invariants, and reporting counterexamples. Beyond pass/fail checking
|
|
5
|
+
tla-rs verifies TLA+ specifications by exploring all reachable states, checking invariants, and reporting counterexamples. Beyond pass/fail checking it offers an interactive TUI for stepping through state spaces, scenario-driven exploration, property-satisfaction analytics, parameter sweeps, tested demo walkthroughs (with an optional in-browser explorer), and an MCP server for agentic clients. The core library compiles to WebAssembly for browser embedding. It's a lightweight alternative to the official TLC model checker for specs that fit its supported subset.
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ tla-rs verifies TLA+ specifications by exploring all reachable states, checking
|
|
|
10
10
|
cargo build --release
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
The binary will be at `target/release/tla`.
|
|
13
|
+
The binary will be at `target/release/tla`. Prebuilt binaries and the `tla-mcp` server are available via Homebrew, an install script, or GitHub releases — see the [MCP Server guide](MCP.md#install).
|
|
14
14
|
|
|
15
15
|
## Quick Start
|
|
16
16
|
|
|
@@ -44,302 +44,24 @@ Constants accept integers (`42`), booleans (`TRUE`), strings (`"hello"`), and se
|
|
|
44
44
|
| `--sweep NAME=V1;V2;...` | Sweep a constant across values, compare results |
|
|
45
45
|
| `--scenario TEXT` | Explore a specific scenario (or `@file`) |
|
|
46
46
|
| `-i` | Interactive TUI exploration mode |
|
|
47
|
+
| `--present FILE` | Run a demo manifest (`.json`/`.toml`); TUI walkthrough, or `--validate` for a pass/fail report |
|
|
48
|
+
| `--export-md FILE` | With `--present`: write a Markdown walkthrough |
|
|
49
|
+
| `--export-html FILE` | With `--present`: write a self-contained HTML walkthrough |
|
|
50
|
+
| `--explorable` | With `--export-html`: embed the wasm engine for in-browser state exploration |
|
|
47
51
|
| `--json` | JSON output |
|
|
48
52
|
| `-v` | Verbose output (depth breakdowns, etc.) |
|
|
49
53
|
|
|
50
|
-
##
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
Supported directives: `INIT`/`NEXT`, `SPECIFICATION` (temporal formula in `Init /\ [][Next]_vars` form), `CONSTANT`/`CONSTANTS`, `INVARIANT`/`INVARIANTS`, `PROPERTY`/`PROPERTIES`, `SYMMETRY`, and `CHECK_DEADLOCK`. CLI flags override cfg values.
|
|
63
|
-
|
|
64
|
-
## Scenarios
|
|
65
|
-
|
|
66
|
-
Drive the checker along specific execution paths using TLA+ expressions:
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
tla spec.tla --scenario "step: count' = count + 1
|
|
70
|
-
step: count' = count + 1
|
|
71
|
-
step: count' = count + 1"
|
|
72
|
-
```
|
|
73
|
-
|
|
74
|
-
Or load from a file with `--scenario @scenario.txt`. Each `step:` line is a TLA+ predicate over current (unprimed) and next (primed) state variables.
|
|
75
|
-
|
|
76
|
-
```
|
|
77
|
-
step: x' > x # x increases
|
|
78
|
-
step: "s1" \in active' # s1 becomes active
|
|
79
|
-
step: pc'["p1"] = "critical" # p1 enters critical section
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Analytics
|
|
83
|
-
|
|
84
|
-
These flags are for understanding *how* a protocol fails, not just *whether* it fails.
|
|
85
|
-
|
|
86
|
-
Without `--continue`, the checker stops at the first violation. With it, all violations are collected and counted per-invariant across the full state space:
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
|
-
tla spec.tla --allow-deadlock --continue
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
`--count-satisfying` measures what fraction of reachable states satisfy a predicate. Add `--verbose` to get per-depth breakdowns showing at which exploration depth violations start appearing:
|
|
93
|
-
|
|
94
|
-
```bash
|
|
95
|
-
tla spec.tla --allow-deadlock --continue \
|
|
96
|
-
--count-satisfying InvSafety --verbose
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
`--sweep` varies a constant across multiple values and produces a comparison table, useful for sensitivity analysis:
|
|
100
|
-
|
|
101
|
-
```bash
|
|
102
|
-
tla spec.tla --sweep 'N=2;3;4;5' --count-satisfying Inv --allow-deadlock
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
`--json` returns structured data including `properties` array with `depth_breakdown` per property.
|
|
106
|
-
|
|
107
|
-
### The C-3PO Example
|
|
108
|
-
|
|
109
|
-
C-3PO famously calculates "the possibility of successfully navigating an asteroid field is approximately 3,720 to 1." The spec `examples/c3po_asteroid_field.tla` models the Empire Strikes Back asteroid chase: variable-damage asteroid impacts, TIE fighter attacks, TIEs getting destroyed by asteroids, hiding in the space slug's cave, mynock damage, escaping the exogorth's mouth, and the only real escape — attaching to a Star Destroyer's hull and floating away with the garbage. No hyperspace: the hyperdrive is dead.
|
|
110
|
-
|
|
111
|
-
The `Density` constant controls asteroid damage range (1..Density). Higher values create more damage variants per action, biasing the state space toward destruction.
|
|
112
|
-
|
|
113
|
-
```bash
|
|
114
|
-
tla examples/c3po_asteroid_field.tla -c 'Density=3' \
|
|
115
|
-
--allow-deadlock --continue \
|
|
116
|
-
--count-satisfying InvNeverTellMeTheOdds \
|
|
117
|
-
--count-satisfying Escaped --verbose
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
The depth breakdown shows destruction starting early and escape requiring a long sequence of correct decisions — surviving asteroids, hiding in the cave, taking mynock damage, escaping the slug, then waiting for all TIE fighters to be destroyed before drifting onto a Star Destroyer's hull.
|
|
121
|
-
|
|
122
|
-
## Interactive Mode
|
|
123
|
-
|
|
124
|
-
Launch the TUI with `-i` to step through state spaces manually. You can select and take transitions, backtrack, evaluate expressions in a REPL, trace variable changes across history, test hypotheses against all visited states, and toggle guard condition display. Actions with many variable changes expand inline so you can see exactly what each transition does.
|
|
125
|
-
|
|
126
|
-

|
|
127
|
-
|
|
128
|
-
Key bindings: `↑`/`↓` select actions, `Enter` takes the selected action, `→`/`Space` expands grouped changes, `←` collapses, `b` backtracks, `e` opens the REPL, `t` shows variable trace, `h` tests a hypothesis, `g` toggles guards, `w` random walks N steps, `u` steps until a condition holds, `s`/`l` save/load traces, `r` resets to initial state, `q` quits.
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
tla examples/c3po_asteroid_field.tla -c 'Density=3' --allow-deadlock -i
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
## Supported TLA+ Subset
|
|
135
|
-
|
|
136
|
-
tla-rs implements the Naturals, Integers, Sequences, FiniteSets, TLC, Bags, and Bits standard modules. See `SYNTAX_STATUS.md` for the full operator-by-operator coverage table.
|
|
137
|
-
|
|
138
|
-
The supported operator categories: logic (`/\`, `\/`, `~`, `=>`), comparison, arithmetic, sets (`\in`, `\union`, `\intersect`, `SUBSET`, `UNION`), functions (`[x \in S |-> e]`, `DOMAIN`, `EXCEPT`, `@@`), quantifiers (`\E`, `\A`, `CHOOSE`), records, tuples/sequences, `IF-THEN-ELSE`, `CASE`, `LET-IN`, primed variables, `UNCHANGED`, transitive closure, module instances (`INSTANCE` with qualified calls), and Unicode equivalents for all operators.
|
|
139
|
-
|
|
140
|
-
### Module Instances
|
|
141
|
-
|
|
142
|
-
Specs can use `INSTANCE` to import and compose modules:
|
|
143
|
-
|
|
144
|
-
```tla
|
|
145
|
-
---- MODULE pingpong ----
|
|
146
|
-
LOCAL INSTANCE Naturals
|
|
147
|
-
|
|
148
|
-
VARIABLES server_to_client, client_to_server
|
|
149
|
-
|
|
150
|
-
Data == [message: {"ping"}] \cup [message: {"pong"}]
|
|
151
|
-
|
|
152
|
-
ServerToClientChannel(Id) == INSTANCE MChannel WITH channels <- server_to_client
|
|
153
|
-
ClientToServerChannel(Id) == INSTANCE MChannel WITH channels <- client_to_server
|
|
154
|
-
|
|
155
|
-
Next ==
|
|
156
|
-
\/ \E id \in ClientIds: ServerToClientChannel(id)!Send([message |-> "ping"])
|
|
157
|
-
\/ \E id \in ClientIds: ClientToServerChannel(id)!Recv([message |-> "pong"])
|
|
158
|
-
====
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
Both static (`Alias == INSTANCE M WITH ...`) and parameterized (`Alias(p) == INSTANCE M WITH ...`) instances are supported. Library modules without Init/Next work as expected. The module file must be in the same directory as the spec.
|
|
162
|
-
|
|
163
|
-
### Spec Structure
|
|
164
|
-
|
|
165
|
-
```tla
|
|
166
|
-
---- MODULE Example ----
|
|
167
|
-
EXTENDS Naturals
|
|
168
|
-
|
|
169
|
-
CONSTANT N
|
|
170
|
-
VARIABLES x, y
|
|
171
|
-
|
|
172
|
-
Init == x = 0 /\ y = 0
|
|
173
|
-
|
|
174
|
-
Next ==
|
|
175
|
-
\/ (x < N /\ x' = x + 1 /\ y' = y)
|
|
176
|
-
\/ (y < N /\ x' = x /\ y' = y + 1)
|
|
177
|
-
|
|
178
|
-
TypeOK == x \in 0..N /\ y \in 0..N
|
|
179
|
-
Inv == x + y <= 2 * N
|
|
180
|
-
====
|
|
181
|
-
```
|
|
182
|
-
|
|
183
|
-
Invariants are detected by naming convention: definitions starting with `Inv`, `TypeOK`, or `NotSolved` are automatically checked.
|
|
184
|
-
|
|
185
|
-
## Output
|
|
186
|
-
|
|
187
|
-
On success:
|
|
188
|
-
```
|
|
189
|
-
Model checking complete. No errors found.
|
|
190
|
-
|
|
191
|
-
States explored: 1331
|
|
192
|
-
Transitions: 3630
|
|
193
|
-
Max depth: 31
|
|
194
|
-
Time: 0.019s
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
On invariant violation, you get a counterexample trace with state diffs marking changed variables. On deadlock, a trace to the deadlock state with a suggestion to use `--allow-deadlock`. Parse errors show source locations, and undefined variables suggest similar names.
|
|
198
|
-
|
|
199
|
-
## State Graph Visualization
|
|
200
|
-
|
|
201
|
-
```bash
|
|
202
|
-
tla spec.tla --export-dot graph.dot
|
|
203
|
-
tla spec.tla --export-dot graph.dot --dot-mode full
|
|
204
|
-
dot -Tpng graph.dot -o graph.png
|
|
205
|
-
```
|
|
206
|
-
|
|
207
|
-
Four export modes are available via `--dot-mode`:
|
|
208
|
-
|
|
209
|
-
| Mode | Description |
|
|
210
|
-
|------|-------------|
|
|
211
|
-
| `clean` (default) | All nodes, no self-loops, parallel edges merged into single labeled edges |
|
|
212
|
-
| `full` | All nodes and all edges including self-loops, each edge separate |
|
|
213
|
-
| `trace` | Only counterexample trace nodes and edges (falls back to full if no trace) |
|
|
214
|
-
| `choices` | Trace path plus alternative transitions at each trace state; non-trace nodes shown dashed, alternative edges gray/dashed (falls back to full if no trace) |
|
|
215
|
-
|
|
216
|
-
Error states are highlighted in red. Trace edges are red and thick in all modes.
|
|
217
|
-
|
|
218
|
-
## WebAssembly
|
|
219
|
-
|
|
220
|
-
The core library compiles to WASM for browser embedding:
|
|
221
|
-
|
|
222
|
-
```bash
|
|
223
|
-
cargo make wasm
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
This produces a `pkg/` directory with the WASM module and JS bindings. The WASM API provides `check_spec`, `check_spec_with_config`, `check_spec_with_cfg`, and `check_spec_with_options` — all returning JSON results with success status, state count, error traces, and optional DOT graph output.
|
|
227
|
-
|
|
228
|
-
The `check_spec_with_options` API accepts a JSON options object:
|
|
229
|
-
|
|
230
|
-
```js
|
|
231
|
-
const result = JSON.parse(check_spec_with_options(specSource, JSON.stringify({
|
|
232
|
-
constants: { N: 3 },
|
|
233
|
-
max_states: 10000,
|
|
234
|
-
max_depth: 50,
|
|
235
|
-
allow_deadlock: true,
|
|
236
|
-
export_dot: true,
|
|
237
|
-
dot_mode: "choices", // "full", "trace", "clean" (default), "choices"
|
|
238
|
-
cfg_source: "INIT Init\nNEXT Next\n"
|
|
239
|
-
})));
|
|
240
|
-
|
|
241
|
-
if (result.dot) {
|
|
242
|
-
// DOT graph string: "digraph StateGraph { ... }"
|
|
243
|
-
}
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
| Option | Type | Description |
|
|
247
|
-
|--------|------|-------------|
|
|
248
|
-
| `constants` | object | Constant values (`{"N": 3, "Procs": ["a","b"]}`) |
|
|
249
|
-
| `cfg_source` | string | TLC-style cfg file contents |
|
|
250
|
-
| `max_states` | number | Maximum states to explore |
|
|
251
|
-
| `max_depth` | number | Maximum trace depth |
|
|
252
|
-
| `allow_deadlock` | bool | Allow states with no successors |
|
|
253
|
-
| `export_dot` | bool | Include DOT graph in result |
|
|
254
|
-
| `dot_mode` | string | DOT export mode: `full`, `trace`, `clean` (default), `choices` |
|
|
255
|
-
|
|
256
|
-
## MCP Server
|
|
257
|
-
|
|
258
|
-
`tla-mcp` exposes the model checker as a Model Context Protocol server over stdio, so agentic clients (Claude Code, Cursor, etc.) can call it as a first-class tool.
|
|
259
|
-
|
|
260
|
-
### Install
|
|
261
|
-
|
|
262
|
-
Several paths are supported — pick whichever fits your toolchain.
|
|
263
|
-
|
|
264
|
-
**Homebrew (macOS, Linuxbrew)** — installs both `tla` and `tla-mcp`:
|
|
265
|
-
|
|
266
|
-
```bash
|
|
267
|
-
brew install fabracht/tla/tla-mcp
|
|
268
|
-
```
|
|
269
|
-
|
|
270
|
-
Requires the `homebrew-tla` tap to exist. The formula source lives at [`packaging/homebrew/tla-mcp.rb`](packaging/homebrew/tla-mcp.rb); [`packaging/homebrew/README.md`](packaging/homebrew/README.md) explains the one-time tap setup.
|
|
271
|
-
|
|
272
|
-
**Install script (Linux, macOS)** — downloads a prebuilt binary and verifies its SHA256, no Rust toolchain required:
|
|
273
|
-
|
|
274
|
-
```bash
|
|
275
|
-
curl -fsSL https://raw.githubusercontent.com/fabracht/tla-rs/main/scripts/install.sh | bash
|
|
276
|
-
```
|
|
277
|
-
|
|
278
|
-
Pass flags to scope the install: `--bin tla-mcp` for just the MCP server, `--version v0.4.3` to pin a release (releases prior to v0.4.3 do not ship a `SHA256SUMS` asset and are rejected), `--dir /usr/local/bin` for a system-wide install (requires `sudo`).
|
|
279
|
-
|
|
280
|
-
**Cargo (any platform with a Rust toolchain)**:
|
|
281
|
-
|
|
282
|
-
```bash
|
|
283
|
-
cargo install tla-checker --bin tla-mcp
|
|
284
|
-
```
|
|
285
|
-
|
|
286
|
-
**GitHub release downloads** — prebuilt binaries for Linux x86_64, macOS x86_64, macOS arm64, and Windows x86_64 are attached to every [release](https://github.com/fabracht/tla-rs/releases/latest) as `tla-<platform>` and `tla-mcp-<platform>`.
|
|
287
|
-
|
|
288
|
-
**From a working copy**:
|
|
289
|
-
|
|
290
|
-
```bash
|
|
291
|
-
cargo install --path . --bin tla-mcp
|
|
292
|
-
```
|
|
293
|
-
|
|
294
|
-
### Register with your client
|
|
295
|
-
|
|
296
|
-
**Claude Code (community plugin marketplace)** — once `tla-mcp` is on PATH:
|
|
297
|
-
|
|
298
|
-
```
|
|
299
|
-
/plugin marketplace add anthropics/claude-plugins-community
|
|
300
|
-
/plugin install tla-rs@claude-community
|
|
301
|
-
```
|
|
302
|
-
|
|
303
|
-
**Manual registration (any MCP client)** — add to `~/.claude/mcp.json`, `claude_desktop_config.json`, or your client's equivalent:
|
|
304
|
-
|
|
305
|
-
```json
|
|
306
|
-
{
|
|
307
|
-
"mcpServers": {
|
|
308
|
-
"tla": {
|
|
309
|
-
"command": "tla-mcp"
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
}
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
### Tools
|
|
316
|
-
|
|
317
|
-
All tools return a `schema_version: "1"` field — the contract is frozen at version 1 and will be bumped explicitly on breaking changes.
|
|
318
|
-
|
|
319
|
-
| Tool | Purpose |
|
|
320
|
-
|------|---------|
|
|
321
|
-
| `validate_spec` | Parse a `.tla` file and return a summary (vars, **constants with resolved values**, invariants, init/next presence). Returns a structured parse/config error with source span on failure. Inspect the `constants` array before every `check_spec` call — outlier values are the most common cause of timeouts. |
|
|
322
|
-
| `list_invariants` | Return the detected invariants (definitions matching `Inv*`, `TypeOK*`, `NotSolved*`, plus anything declared in a cfg `INVARIANT` directive). |
|
|
323
|
-
| `check_spec` | Run full model checking. **Requires** `max_states`, `max_depth`, AND `max_seconds` (no defaults — agents must budget all three upfront). The `max_seconds` budget is enforced during both BFS exploration and the liveness phase. Returns one of: `ok`, `invariant_violation` (with trace + invariant name + actions), `deadlock`, `liveness_violation` (with prefix + cycle), `limit_reached` (budget exhausted — not an error; `limit` is one of `max_states`/`max_depth`/`max_seconds`), or `error` (with structured phase + message + optional source span). |
|
|
324
|
-
| `replay_scenario` | Walk a spec step-by-step through a guided scenario (text of `step: <TLA+ expression>` lines). Returns the same `StateSnapshot` shape as `check_spec`, plus per-step `changes` descriptions. On a step that no transition satisfies, returns `status: "failed"` with `available_actions` to help diagnose the mismatch. |
|
|
325
|
-
|
|
326
|
-
The boolean toggles `allow_deadlock` and `check_liveness` are `Option<bool>` — omit them to defer to the cfg file (e.g., `CHECK_DEADLOCK FALSE` or `PROPERTY` directives), pass `true` / `false` to override the cfg. The `symmetry` field appends to any constants declared via cfg `SYMMETRY` rather than replacing them.
|
|
327
|
-
|
|
328
|
-
`validate_spec` and `list_invariants` include a `warnings` array surfacing parser-tolerance warnings — when the parser fails to parse an operator body it silently skips that operator and emits a warning. The same array also surfaces unsupported temporal constructs (`<<A>>_v` diamond actions, `<>[]P` stable-eventually) that the fairness extractor drops. Without the warnings array, a typo in an invariant's body would let `check_spec` "pass" without ever checking that invariant.
|
|
329
|
-
|
|
330
|
-
`check_spec` honors the cfg's `CONSTRAINT` directive (state-space pruning predicate) and accepts an inline `state_constraint: "<TLA+ expression>"` parameter. Constraints are evaluated on every state — states where the expression is false are dropped from the reachable set and not explored further. Use this to bound otherwise-explosive state spaces (e.g., `state_constraint: "Len(queue) <= 3"`) without modifying the spec.
|
|
331
|
-
|
|
332
|
-
### Counterexample format
|
|
333
|
-
|
|
334
|
-
Each state in a trace is `{ vars: { var_name: { display, json } } }`. The `display` field is the TLA+-formatted value (`"{1, 2, 3}"`, `"<<a, b>>"`); the `json` field is a typed JSON form preserving set/tuple/record/function structure via a `kind` tag.
|
|
335
|
-
|
|
336
|
-
### Mid-session reload
|
|
337
|
-
|
|
338
|
-
MCP clients spawn server processes at session startup. Rebuilding or reinstalling `tla-mcp` while a Claude Code session is already running will not hot-reload the new binary — restart the client (or open a new session) to pick up changes. Verifying outside an MCP client: `tla-mcp` invoked directly will exit with `ConnectionClosed` after stdin EOF, which is the correct behavior for a stdio server with no peer.
|
|
339
|
-
|
|
340
|
-
## Limitations
|
|
341
|
-
|
|
342
|
-
`Nat` and `Int` are bounded (-100 to 100 by default). Temporal operators `[]`, `<>`, `~>` are parsed but cannot be evaluated directly — use `--check-liveness` for fairness/liveness properties via SCC analysis. Unbounded quantifiers (`\E x : P` without `\in S`) and `Seq(S)` enumeration are not supported. Recursive operators must be declared with `RECURSIVE`.
|
|
54
|
+
## Documentation
|
|
55
|
+
|
|
56
|
+
| Guide | Contents |
|
|
57
|
+
|-------|----------|
|
|
58
|
+
| [CLI Guide](CLI_GUIDE.md) | Configuration files, scenarios, demo walkthroughs (incl. the `--explorable` browser explorer), interactive mode, analytics, output, and state-graph visualization |
|
|
59
|
+
| [TLA+ Support](TLA_SUPPORT.md) | Supported operator subset, module instances, spec structure, and limitations |
|
|
60
|
+
| [WebAssembly](WASM.md) | Browser-embeddable WASM API, including the live stepping bindings |
|
|
61
|
+
| [MCP Server](MCP.md) | `tla-mcp` install, client registration, and tool reference |
|
|
62
|
+
| [Syntax Status](SYNTAX_STATUS.md) | Operator-by-operator coverage table |
|
|
63
|
+
| [Architecture](ARCHITECTURE.md) | Internal design |
|
|
64
|
+
| [Practical TLA+ Guide](USER_GUIDE_TO_PRACTICAL_TLA.md) | Worked guidance for writing checkable specs |
|
|
343
65
|
|
|
344
66
|
## License
|
|
345
67
|
|
package/package.json
CHANGED
package/tla_checker.d.ts
CHANGED
|
@@ -9,6 +9,14 @@ export function check_spec_with_config(spec_source: string, constants_json: stri
|
|
|
9
9
|
|
|
10
10
|
export function check_spec_with_options(spec_source: string, options_json: string): string;
|
|
11
11
|
|
|
12
|
+
export function explore_eval(spec_source: string, cfg_source: string, constants_json: string, state_json: string, expr_source: string): string;
|
|
13
|
+
|
|
14
|
+
export function explore_init(spec_source: string, cfg_source: string, constants_json: string): string;
|
|
15
|
+
|
|
16
|
+
export function explore_invariants(spec_source: string, cfg_source: string, constants_json: string, state_json: string): string;
|
|
17
|
+
|
|
18
|
+
export function explore_next(spec_source: string, cfg_source: string, constants_json: string, state_json: string): string;
|
|
19
|
+
|
|
12
20
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
|
13
21
|
|
|
14
22
|
export interface InitOutput {
|
|
@@ -17,6 +25,10 @@ export interface InitOutput {
|
|
|
17
25
|
readonly check_spec_with_cfg: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
|
|
18
26
|
readonly check_spec_with_config: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
|
|
19
27
|
readonly check_spec_with_options: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
28
|
+
readonly explore_eval: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
|
|
29
|
+
readonly explore_init: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
|
|
30
|
+
readonly explore_invariants: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
|
|
31
|
+
readonly explore_next: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
|
|
20
32
|
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
|
21
33
|
readonly __wbindgen_export: (a: number, b: number) => number;
|
|
22
34
|
readonly __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|
package/tla_checker.js
CHANGED
|
@@ -115,6 +115,134 @@ export function check_spec_with_options(spec_source, options_json) {
|
|
|
115
115
|
}
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
/**
|
|
119
|
+
* @param {string} spec_source
|
|
120
|
+
* @param {string} cfg_source
|
|
121
|
+
* @param {string} constants_json
|
|
122
|
+
* @param {string} state_json
|
|
123
|
+
* @param {string} expr_source
|
|
124
|
+
* @returns {string}
|
|
125
|
+
*/
|
|
126
|
+
export function explore_eval(spec_source, cfg_source, constants_json, state_json, expr_source) {
|
|
127
|
+
let deferred6_0;
|
|
128
|
+
let deferred6_1;
|
|
129
|
+
try {
|
|
130
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
131
|
+
const ptr0 = passStringToWasm0(spec_source, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
132
|
+
const len0 = WASM_VECTOR_LEN;
|
|
133
|
+
const ptr1 = passStringToWasm0(cfg_source, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
134
|
+
const len1 = WASM_VECTOR_LEN;
|
|
135
|
+
const ptr2 = passStringToWasm0(constants_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
136
|
+
const len2 = WASM_VECTOR_LEN;
|
|
137
|
+
const ptr3 = passStringToWasm0(state_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
138
|
+
const len3 = WASM_VECTOR_LEN;
|
|
139
|
+
const ptr4 = passStringToWasm0(expr_source, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
140
|
+
const len4 = WASM_VECTOR_LEN;
|
|
141
|
+
wasm.explore_eval(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3, ptr4, len4);
|
|
142
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
143
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
144
|
+
deferred6_0 = r0;
|
|
145
|
+
deferred6_1 = r1;
|
|
146
|
+
return getStringFromWasm0(r0, r1);
|
|
147
|
+
} finally {
|
|
148
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
149
|
+
wasm.__wbindgen_export3(deferred6_0, deferred6_1, 1);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* @param {string} spec_source
|
|
155
|
+
* @param {string} cfg_source
|
|
156
|
+
* @param {string} constants_json
|
|
157
|
+
* @returns {string}
|
|
158
|
+
*/
|
|
159
|
+
export function explore_init(spec_source, cfg_source, constants_json) {
|
|
160
|
+
let deferred4_0;
|
|
161
|
+
let deferred4_1;
|
|
162
|
+
try {
|
|
163
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
164
|
+
const ptr0 = passStringToWasm0(spec_source, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
165
|
+
const len0 = WASM_VECTOR_LEN;
|
|
166
|
+
const ptr1 = passStringToWasm0(cfg_source, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
167
|
+
const len1 = WASM_VECTOR_LEN;
|
|
168
|
+
const ptr2 = passStringToWasm0(constants_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
169
|
+
const len2 = WASM_VECTOR_LEN;
|
|
170
|
+
wasm.explore_init(retptr, ptr0, len0, ptr1, len1, ptr2, len2);
|
|
171
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
172
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
173
|
+
deferred4_0 = r0;
|
|
174
|
+
deferred4_1 = r1;
|
|
175
|
+
return getStringFromWasm0(r0, r1);
|
|
176
|
+
} finally {
|
|
177
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
178
|
+
wasm.__wbindgen_export3(deferred4_0, deferred4_1, 1);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* @param {string} spec_source
|
|
184
|
+
* @param {string} cfg_source
|
|
185
|
+
* @param {string} constants_json
|
|
186
|
+
* @param {string} state_json
|
|
187
|
+
* @returns {string}
|
|
188
|
+
*/
|
|
189
|
+
export function explore_invariants(spec_source, cfg_source, constants_json, state_json) {
|
|
190
|
+
let deferred5_0;
|
|
191
|
+
let deferred5_1;
|
|
192
|
+
try {
|
|
193
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
194
|
+
const ptr0 = passStringToWasm0(spec_source, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
195
|
+
const len0 = WASM_VECTOR_LEN;
|
|
196
|
+
const ptr1 = passStringToWasm0(cfg_source, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
197
|
+
const len1 = WASM_VECTOR_LEN;
|
|
198
|
+
const ptr2 = passStringToWasm0(constants_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
199
|
+
const len2 = WASM_VECTOR_LEN;
|
|
200
|
+
const ptr3 = passStringToWasm0(state_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
201
|
+
const len3 = WASM_VECTOR_LEN;
|
|
202
|
+
wasm.explore_invariants(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
|
|
203
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
204
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
205
|
+
deferred5_0 = r0;
|
|
206
|
+
deferred5_1 = r1;
|
|
207
|
+
return getStringFromWasm0(r0, r1);
|
|
208
|
+
} finally {
|
|
209
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
210
|
+
wasm.__wbindgen_export3(deferred5_0, deferred5_1, 1);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @param {string} spec_source
|
|
216
|
+
* @param {string} cfg_source
|
|
217
|
+
* @param {string} constants_json
|
|
218
|
+
* @param {string} state_json
|
|
219
|
+
* @returns {string}
|
|
220
|
+
*/
|
|
221
|
+
export function explore_next(spec_source, cfg_source, constants_json, state_json) {
|
|
222
|
+
let deferred5_0;
|
|
223
|
+
let deferred5_1;
|
|
224
|
+
try {
|
|
225
|
+
const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);
|
|
226
|
+
const ptr0 = passStringToWasm0(spec_source, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
227
|
+
const len0 = WASM_VECTOR_LEN;
|
|
228
|
+
const ptr1 = passStringToWasm0(cfg_source, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
229
|
+
const len1 = WASM_VECTOR_LEN;
|
|
230
|
+
const ptr2 = passStringToWasm0(constants_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
231
|
+
const len2 = WASM_VECTOR_LEN;
|
|
232
|
+
const ptr3 = passStringToWasm0(state_json, wasm.__wbindgen_export, wasm.__wbindgen_export2);
|
|
233
|
+
const len3 = WASM_VECTOR_LEN;
|
|
234
|
+
wasm.explore_next(retptr, ptr0, len0, ptr1, len1, ptr2, len2, ptr3, len3);
|
|
235
|
+
var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);
|
|
236
|
+
var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);
|
|
237
|
+
deferred5_0 = r0;
|
|
238
|
+
deferred5_1 = r1;
|
|
239
|
+
return getStringFromWasm0(r0, r1);
|
|
240
|
+
} finally {
|
|
241
|
+
wasm.__wbindgen_add_to_stack_pointer(16);
|
|
242
|
+
wasm.__wbindgen_export3(deferred5_0, deferred5_1, 1);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
118
246
|
function __wbg_get_imports() {
|
|
119
247
|
const import0 = {
|
|
120
248
|
__proto__: null,
|
package/tla_checker_bg.wasm
CHANGED
|
Binary file
|
package/tla_checker_bg.wasm.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ export const check_spec: (a: number, b: number, c: number, d: number, e: number)
|
|
|
5
5
|
export const check_spec_with_cfg: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
|
|
6
6
|
export const check_spec_with_config: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
|
|
7
7
|
export const check_spec_with_options: (a: number, b: number, c: number, d: number, e: number) => void;
|
|
8
|
+
export const explore_eval: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => void;
|
|
9
|
+
export const explore_init: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
|
|
10
|
+
export const explore_invariants: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
|
|
11
|
+
export const explore_next: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => void;
|
|
8
12
|
export const __wbindgen_add_to_stack_pointer: (a: number) => number;
|
|
9
13
|
export const __wbindgen_export: (a: number, b: number) => number;
|
|
10
14
|
export const __wbindgen_export2: (a: number, b: number, c: number, d: number) => number;
|