tla-ts 0.0.1 → 0.0.3-dev.a50fc89
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 +81 -42
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +215 -30
- package/dist/index.d.ts +215 -30
- package/dist/index.js +1 -1
- package/dist/parallel-worker.cjs +2 -2
- package/dist/parallel-worker.js +2 -2
- package/dist/parallel.cjs +1 -1
- package/dist/parallel.js +2 -2
- package/dist/run-cli.cjs +20 -1
- package/dist/run-cli.js +20 -1
- package/dist/transfer.cjs +388 -39
- package/dist/transfer.js +388 -39
- package/package.json +6 -2
- package/src/ast.ts +122 -5
- package/src/bags.ts +161 -71
- package/src/builtins.ts +203 -23
- package/src/bundled-modules.ts +63 -32
- package/src/check.ts +945 -238
- package/src/cli-options.ts +58 -0
- package/src/codegen.ts +52 -18
- package/src/config.ts +39 -11
- package/src/environment.ts +485 -140
- package/src/errors.ts +59 -1
- package/src/evaluate.ts +489 -137
- package/src/exit-codes.ts +75 -0
- package/src/fingerprints.ts +2 -2
- package/src/index.ts +9 -4
- package/src/instances.ts +221 -66
- package/src/java-overrides.ts +241 -0
- package/src/json.ts +153 -72
- package/src/levels.ts +850 -0
- package/src/lexer.ts +103 -28
- package/src/liveness.ts +47 -91
- package/src/obligation-action.ts +384 -0
- package/src/obligation-anon.ts +575 -0
- package/src/obligation-deref.ts +637 -0
- package/src/obligation-expression.ts +1060 -0
- package/src/obligation-format.ts +406 -0
- package/src/obligation-generate.ts +1074 -0
- package/src/obligation-levels.ts +329 -0
- package/src/obligation-module.ts +1042 -0
- package/src/obligation-printer.ts +889 -0
- package/src/obligation-proof.ts +76 -0
- package/src/obligation-source.ts +1084 -0
- package/src/obligation-tuples.ts +184 -0
- package/src/obligations.ts +316 -0
- package/src/parallel-worker.ts +57 -28
- package/src/parallel.ts +116 -62
- package/src/parser.ts +958 -205
- package/src/pretty-print.ts +259 -0
- package/src/randomization.ts +24 -113
- package/src/resolve.ts +472 -41
- package/src/run-cli.ts +427 -61
- package/src/runtime.ts +63 -28
- package/src/spec-description.ts +509 -0
- package/src/standard-levels.ts +105 -0
- package/src/standard-modules.ts +223 -92
- package/src/subexpressions.ts +21 -35
- package/src/substitution-levels.ts +184 -0
- package/src/successors.ts +261 -46
- package/src/symmetry.ts +65 -21
- package/src/tableau.ts +43 -37
- package/src/tlc-ext.ts +120 -33
- package/src/tlc-module.ts +71 -47
- package/src/tlc-modules.ts +1022 -0
- package/src/tlc-order.ts +497 -0
- package/src/tlc-random.ts +411 -0
- package/src/tlc-summary.ts +109 -0
- package/src/transfer.ts +26 -5
- package/src/values.ts +1231 -176
package/src/tlc-module.ts
CHANGED
|
@@ -1,34 +1,40 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { TlaModuleError } from "./errors";
|
|
2
|
+
import { EXIT_STATUS } from "./exit-codes";
|
|
2
3
|
import type { Builtin } from "./evaluate";
|
|
4
|
+
import { prettyPrint } from "./pretty-print";
|
|
3
5
|
import {
|
|
4
6
|
defineConstant,
|
|
5
7
|
defineHigherOrderOperator,
|
|
6
8
|
defineOperator,
|
|
7
9
|
defineStateOperator,
|
|
8
10
|
getElements,
|
|
11
|
+
getEnumerableSet,
|
|
12
|
+
getFunction,
|
|
9
13
|
getOperator,
|
|
10
14
|
getSequence,
|
|
11
15
|
getValue,
|
|
12
16
|
} from "./builtins";
|
|
13
17
|
import { getNamedRegisters, NAMED_REGISTER_PREFIX, type CheckerRuntime } from "./runtime";
|
|
18
|
+
import { createActionRecord } from "./tlc-ext";
|
|
19
|
+
import { getRandomElement } from "./tlc-random";
|
|
14
20
|
import {
|
|
21
|
+
ANY_SET,
|
|
15
22
|
createFunction,
|
|
16
23
|
createRecord,
|
|
17
24
|
createSet,
|
|
18
25
|
createTuple,
|
|
26
|
+
createWrittenFunction,
|
|
19
27
|
formatValue,
|
|
20
|
-
|
|
28
|
+
getWrittenPairs,
|
|
29
|
+
toFiniteSet,
|
|
21
30
|
type Value,
|
|
31
|
+
rankString,
|
|
22
32
|
} from "./values";
|
|
23
33
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
["endLine", 0],
|
|
29
|
-
["endColumn", 0],
|
|
30
|
-
["module", "--unknown--"],
|
|
31
|
-
]);
|
|
34
|
+
const padTime = (value: number) => String(value).padStart(2, "0");
|
|
35
|
+
|
|
36
|
+
const formatCalendarVersion = (date: Date) =>
|
|
37
|
+
`${date.getUTCFullYear()}.${padTime(date.getUTCMonth() + 1)}.${padTime(date.getUTCDate())}.${padTime(date.getUTCHours())}${padTime(date.getUTCMinutes())}${padTime(date.getUTCSeconds())}`;
|
|
32
38
|
|
|
33
39
|
const getRegisterFunction = <Key extends Value>(registers: Map<Key, Value>) =>
|
|
34
40
|
createFunction([...registers].map(([key, value]): [Value, Value] => [key, createTuple([value])]));
|
|
@@ -37,7 +43,7 @@ const getRuntimeValue = (
|
|
|
37
43
|
runtime: CheckerRuntime,
|
|
38
44
|
key: string,
|
|
39
45
|
state: (Value | undefined)[] | undefined,
|
|
40
|
-
)
|
|
46
|
+
) => {
|
|
41
47
|
const duration = Math.floor((Date.now() - runtime.startedAt) / 1000);
|
|
42
48
|
switch (key) {
|
|
43
49
|
case "level":
|
|
@@ -67,23 +73,24 @@ const getRuntimeValue = (
|
|
|
67
73
|
["mode", "bfs"],
|
|
68
74
|
["deadlock", runtime.checkDeadlock],
|
|
69
75
|
["worker", 1],
|
|
70
|
-
["seed",
|
|
76
|
+
["seed", String(runtime.seed)],
|
|
71
77
|
["fingerprint", "0"],
|
|
72
|
-
["install", ""],
|
|
78
|
+
["install", "unknown"],
|
|
73
79
|
]);
|
|
74
|
-
case "revision":
|
|
80
|
+
case "revision": {
|
|
81
|
+
const now = new Date();
|
|
75
82
|
return createRecord([
|
|
76
83
|
["count", 0],
|
|
77
|
-
["timestamp",
|
|
78
|
-
["date",
|
|
79
|
-
["tag", "
|
|
80
|
-
["calver",
|
|
84
|
+
["timestamp", Math.floor(now.getTime() / 1000)],
|
|
85
|
+
["date", rankString(`${now.toISOString().slice(0, 19)}.${now.getUTCMilliseconds()}Z`)],
|
|
86
|
+
["tag", "development"],
|
|
87
|
+
["calver", rankString(formatCalendarVersion(new Date(runtime.startedAt)))],
|
|
81
88
|
]);
|
|
89
|
+
}
|
|
90
|
+
case "spec":
|
|
91
|
+
return runtime.getSpecification();
|
|
82
92
|
case "action":
|
|
83
|
-
return
|
|
84
|
-
["name", "UnnamedAction"],
|
|
85
|
-
["location", createLocationRecord()],
|
|
86
|
-
]);
|
|
93
|
+
return createActionRecord(undefined);
|
|
87
94
|
case "all":
|
|
88
95
|
return getRegisterFunction(runtime.registers);
|
|
89
96
|
case "all:named":
|
|
@@ -91,11 +98,11 @@ const getRuntimeValue = (
|
|
|
91
98
|
}
|
|
92
99
|
if (key.startsWith(NAMED_REGISTER_PREFIX)) {
|
|
93
100
|
const value = getNamedRegisters(runtime).get(key);
|
|
94
|
-
if (value === undefined) throw new
|
|
101
|
+
if (value === undefined) throw new TlaModuleError(`TLCGet(${key}) was undefined.`);
|
|
95
102
|
return value;
|
|
96
103
|
}
|
|
97
|
-
if (key.startsWith("-D")) return runtime.properties.get(key.slice(2)) ?? key;
|
|
98
|
-
throw new
|
|
104
|
+
if (key.startsWith("-D")) return rankString(runtime.properties.get(key.slice(2)) ?? key);
|
|
105
|
+
throw new TlaModuleError(`TLCGet(${key}) was undefined.`);
|
|
99
106
|
};
|
|
100
107
|
|
|
101
108
|
const getPermutations = (elements: Value[]): Value[][] =>
|
|
@@ -108,24 +115,34 @@ const getPermutations = (elements: Value[]): Value[][] =>
|
|
|
108
115
|
]),
|
|
109
116
|
);
|
|
110
117
|
|
|
118
|
+
// TLC sorts the value of a TLCEval argument that it caches, with every value inside it.
|
|
119
|
+
const normalizeDeeply = (value: Value): void => {
|
|
120
|
+
if (typeof value !== "object") return;
|
|
121
|
+
if (value.kind === "Set" || value.kind === "MixedSet") {
|
|
122
|
+
toFiniteSet(value).elements.forEach(normalizeDeeply);
|
|
123
|
+
}
|
|
124
|
+
if (value.kind === "Function") value.range.forEach(normalizeDeeply);
|
|
125
|
+
};
|
|
126
|
+
|
|
111
127
|
export const createTlcOperators = (
|
|
112
128
|
print: (text: string) => void,
|
|
113
129
|
runtime: CheckerRuntime,
|
|
114
130
|
): Builtin[] => [
|
|
115
131
|
defineOperator("Print", 2, (args) => {
|
|
116
132
|
print(
|
|
117
|
-
`${formatValue(getValue(args, 0, "Print"), true)} ${formatValue(getValue(args, 1, "Print"), true)}`,
|
|
133
|
+
`${prettyPrint(formatValue(getValue(args, 0, "Print"), true, true))} ${prettyPrint(formatValue(getValue(args, 1, "Print"), true, true))}`,
|
|
118
134
|
);
|
|
119
135
|
return getValue(args, 1, "Print");
|
|
120
136
|
}),
|
|
121
137
|
defineOperator("PrintT", 1, (args) => {
|
|
122
|
-
print(formatValue(getValue(args, 0, "PrintT"), true));
|
|
138
|
+
print(prettyPrint(formatValue(getValue(args, 0, "PrintT"), true, true)));
|
|
123
139
|
return true;
|
|
124
140
|
}),
|
|
125
141
|
defineOperator("Assert", 2, (args) => {
|
|
126
142
|
if (getValue(args, 0, "Assert") !== true) {
|
|
127
|
-
throw new
|
|
128
|
-
`The first argument of Assert evaluated to FALSE; the second argument was:\n${formatValue(getValue(args, 1, "Assert"))}`,
|
|
143
|
+
throw new TlaModuleError(
|
|
144
|
+
`The first argument of Assert evaluated to FALSE; the second argument was:\n${prettyPrint(formatValue(getValue(args, 1, "Assert")))}`,
|
|
145
|
+
EXIT_STATUS.assertViolation,
|
|
129
146
|
);
|
|
130
147
|
}
|
|
131
148
|
return true;
|
|
@@ -135,15 +152,18 @@ export const createTlcOperators = (
|
|
|
135
152
|
createFunction([[getValue(args, 0, ":>"), getValue(args, 1, ":>")]]),
|
|
136
153
|
),
|
|
137
154
|
defineOperator("@@", 2, (args) => {
|
|
138
|
-
const left =
|
|
139
|
-
const right =
|
|
140
|
-
return
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
155
|
+
const left = getFunction(args, 0, "@@");
|
|
156
|
+
const right = getFunction(args, 1, "@@");
|
|
157
|
+
return createWrittenFunction([...getWrittenPairs(left), ...getWrittenPairs(right)]);
|
|
158
|
+
}),
|
|
159
|
+
defineOperator("ToString", 1, (args) =>
|
|
160
|
+
rankString(formatValue(getValue(args, 0, "ToString"), true)),
|
|
161
|
+
),
|
|
162
|
+
defineOperator("TLCEval", 1, (args) => {
|
|
163
|
+
const value = getValue(args, 0, "TLCEval");
|
|
164
|
+
normalizeDeeply(value);
|
|
165
|
+
return value;
|
|
144
166
|
}),
|
|
145
|
-
defineOperator("ToString", 1, (args) => formatValue(getValue(args, 0, "ToString"))),
|
|
146
|
-
defineOperator("TLCEval", 1, (args) => getValue(args, 0, "TLCEval")),
|
|
147
167
|
defineOperator("Permutations", 1, (args) => {
|
|
148
168
|
const elements = getElements(args, 0, "Permutations");
|
|
149
169
|
return createSet(
|
|
@@ -171,11 +191,11 @@ export const createTlcOperators = (
|
|
|
171
191
|
const key = getValue(args, 0, "TLCGet");
|
|
172
192
|
if (typeof key === "number" && key >= 0) {
|
|
173
193
|
const value = runtime.registers.get(key);
|
|
174
|
-
if (value === undefined) throw new
|
|
194
|
+
if (value === undefined) throw new TlaModuleError(`TLCGet(${key}) was undefined.`);
|
|
175
195
|
return value;
|
|
176
196
|
}
|
|
177
197
|
if (typeof key !== "string") {
|
|
178
|
-
throw new
|
|
198
|
+
throw new TlaModuleError(
|
|
179
199
|
`The argument of TLCGet should be a nonnegative integer, but instead it is:\n${formatValue(key)}`,
|
|
180
200
|
);
|
|
181
201
|
}
|
|
@@ -192,7 +212,13 @@ export const createTlcOperators = (
|
|
|
192
212
|
if (value === true) runtime.isStopped = true;
|
|
193
213
|
return true;
|
|
194
214
|
}
|
|
195
|
-
if (key === "pause")
|
|
215
|
+
if (key === "pause") {
|
|
216
|
+
if (value === true) {
|
|
217
|
+
print("Press enter to resume model checking.");
|
|
218
|
+
runtime.pause();
|
|
219
|
+
}
|
|
220
|
+
return true;
|
|
221
|
+
}
|
|
196
222
|
if (typeof key === "string" && key.startsWith(NAMED_REGISTER_PREFIX)) {
|
|
197
223
|
runtime.namedRegisters.set(key, value);
|
|
198
224
|
return true;
|
|
@@ -201,14 +227,12 @@ export const createTlcOperators = (
|
|
|
201
227
|
runtime.properties.set(key.slice(2), formatValue(value));
|
|
202
228
|
return true;
|
|
203
229
|
}
|
|
204
|
-
throw new
|
|
230
|
+
throw new TlaModuleError(
|
|
205
231
|
`The first argument of TLCSet should be a nonnegative integer, but instead it is:\n${formatValue(key)}`,
|
|
206
232
|
);
|
|
207
233
|
}),
|
|
208
|
-
defineConstant("Any",
|
|
209
|
-
defineOperator("RandomElement", 1, (args) =>
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
return elements[Math.floor(runtime.random() * elements.length)];
|
|
213
|
-
}),
|
|
234
|
+
defineConstant("Any", ANY_SET),
|
|
235
|
+
defineOperator("RandomElement", 1, (args) =>
|
|
236
|
+
getRandomElement(getEnumerableSet(args, 0, "RandomElement"), runtime.getRandom()),
|
|
237
|
+
),
|
|
214
238
|
];
|