tla-ts 0.0.1 → 0.0.3-dev.6979965
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 +85 -40
- 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 +48 -13
- 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 +121 -123
- package/src/parallel.ts +167 -83
- 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/builtins.ts
CHANGED
|
@@ -1,22 +1,60 @@
|
|
|
1
|
-
import { TlaEvaluationError } from "./errors";
|
|
1
|
+
import { TlaEvaluationError, TlaModuleError } from "./errors";
|
|
2
2
|
import type { Builtin, BuiltinArgument, Context, OperatorValue } from "./evaluate";
|
|
3
3
|
import {
|
|
4
|
-
checkInteger,
|
|
5
4
|
formatValue,
|
|
6
5
|
getSequenceElements,
|
|
7
6
|
isEnumerable,
|
|
7
|
+
isFunctionValue,
|
|
8
8
|
isSetValue,
|
|
9
|
+
toFiniteFunction,
|
|
10
|
+
MAXIMUM_INTEGER,
|
|
11
|
+
MINIMUM_INTEGER,
|
|
9
12
|
toFiniteSet,
|
|
10
13
|
type Value,
|
|
11
14
|
} from "./values";
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
// TLC evaluates these operators in its core, or its Java code for them takes integers, so a wrong
|
|
17
|
+
// argument is an evaluation failure. Every other standard-module operator checks its arguments in
|
|
18
|
+
// Java and raises an EvalException.
|
|
19
|
+
const CORE_OPERATOR_NAMES = new Set([
|
|
20
|
+
"=",
|
|
21
|
+
"#",
|
|
22
|
+
"~",
|
|
23
|
+
"<=>",
|
|
24
|
+
"/\\",
|
|
25
|
+
"\\/",
|
|
26
|
+
"=>",
|
|
27
|
+
"\\in",
|
|
28
|
+
"\\notin",
|
|
29
|
+
"\\subseteq",
|
|
30
|
+
"\\cup",
|
|
31
|
+
"\\cap",
|
|
32
|
+
"\\",
|
|
33
|
+
"SUBSET",
|
|
34
|
+
"UNION",
|
|
35
|
+
"DOMAIN",
|
|
36
|
+
"+",
|
|
37
|
+
"-",
|
|
38
|
+
"*",
|
|
39
|
+
"^",
|
|
40
|
+
"\\div",
|
|
41
|
+
"%",
|
|
42
|
+
"..",
|
|
43
|
+
"Seq",
|
|
44
|
+
"IsFiniteSet",
|
|
45
|
+
"RandomElement",
|
|
46
|
+
]);
|
|
47
|
+
|
|
48
|
+
const createArgumentError = (name: string, message: string) =>
|
|
49
|
+
CORE_OPERATOR_NAMES.has(name) ? new TlaEvaluationError(message) : new TlaModuleError(message);
|
|
50
|
+
|
|
51
|
+
const isOperatorValue = (argument: BuiltinArgument): argument is OperatorValue =>
|
|
14
52
|
typeof argument === "object" && argument.kind === "Operator";
|
|
15
53
|
|
|
16
54
|
export const getValue = (args: BuiltinArgument[], index: number, name: string): Value => {
|
|
17
55
|
const argument = args[index];
|
|
18
56
|
if (argument === undefined || isOperatorValue(argument)) {
|
|
19
|
-
throw
|
|
57
|
+
throw createArgumentError(name, `${name} expects a value as argument ${index + 1}`);
|
|
20
58
|
}
|
|
21
59
|
return argument;
|
|
22
60
|
};
|
|
@@ -24,7 +62,10 @@ export const getValue = (args: BuiltinArgument[], index: number, name: string):
|
|
|
24
62
|
export const getNumber = (args: BuiltinArgument[], index: number, name: string) => {
|
|
25
63
|
const value = getValue(args, index, name);
|
|
26
64
|
if (typeof value !== "number") {
|
|
27
|
-
throw
|
|
65
|
+
throw createArgumentError(
|
|
66
|
+
name,
|
|
67
|
+
`${name} expects an integer but received ${formatValue(value)}`,
|
|
68
|
+
);
|
|
28
69
|
}
|
|
29
70
|
return value;
|
|
30
71
|
};
|
|
@@ -32,7 +73,7 @@ export const getNumber = (args: BuiltinArgument[], index: number, name: string)
|
|
|
32
73
|
export const getBoolean = (args: BuiltinArgument[], index: number, name: string) => {
|
|
33
74
|
const value = getValue(args, index, name);
|
|
34
75
|
if (typeof value !== "boolean") {
|
|
35
|
-
throw
|
|
76
|
+
throw createArgumentError(name, `${name} expects a boolean but received ${formatValue(value)}`);
|
|
36
77
|
}
|
|
37
78
|
return value;
|
|
38
79
|
};
|
|
@@ -40,20 +81,24 @@ export const getBoolean = (args: BuiltinArgument[], index: number, name: string)
|
|
|
40
81
|
export const getSet = (args: BuiltinArgument[], index: number, name: string) => {
|
|
41
82
|
const value = getValue(args, index, name);
|
|
42
83
|
if (!isSetValue(value))
|
|
43
|
-
throw
|
|
84
|
+
throw createArgumentError(name, `${name} expects a set but received ${formatValue(value)}`);
|
|
44
85
|
return value;
|
|
45
86
|
};
|
|
46
87
|
|
|
47
|
-
export const
|
|
88
|
+
export const getEnumerableSet = (args: BuiltinArgument[], index: number, name: string) => {
|
|
48
89
|
const set = getSet(args, index, name);
|
|
49
90
|
if (!isEnumerable(set)) {
|
|
50
|
-
throw
|
|
91
|
+
throw createArgumentError(
|
|
92
|
+
name,
|
|
51
93
|
`${name} cannot enumerate the non-enumerable set ${formatValue(set)}`,
|
|
52
94
|
);
|
|
53
95
|
}
|
|
54
|
-
return
|
|
96
|
+
return set;
|
|
55
97
|
};
|
|
56
98
|
|
|
99
|
+
const getFiniteSet = (args: BuiltinArgument[], index: number, name: string) =>
|
|
100
|
+
toFiniteSet(getEnumerableSet(args, index, name));
|
|
101
|
+
|
|
57
102
|
export const getElements = (args: BuiltinArgument[], index: number, name: string) =>
|
|
58
103
|
getFiniteSet(args, index, name).elements;
|
|
59
104
|
|
|
@@ -61,14 +106,28 @@ export const getSequence = (args: BuiltinArgument[], index: number, name: string
|
|
|
61
106
|
const value = getValue(args, index, name);
|
|
62
107
|
const elements = getSequenceElements(value);
|
|
63
108
|
if (!elements)
|
|
64
|
-
throw
|
|
109
|
+
throw createArgumentError(
|
|
110
|
+
name,
|
|
111
|
+
`${name} expects a sequence but received ${formatValue(value)}`,
|
|
112
|
+
);
|
|
65
113
|
return elements;
|
|
66
114
|
};
|
|
67
115
|
|
|
116
|
+
export const getFunction = (args: BuiltinArgument[], index: number, name: string) => {
|
|
117
|
+
const value = getValue(args, index, name);
|
|
118
|
+
if (!isFunctionValue(value)) {
|
|
119
|
+
throw createArgumentError(
|
|
120
|
+
name,
|
|
121
|
+
`${name} expects a function but received ${formatValue(value)}`,
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
return toFiniteFunction(value);
|
|
125
|
+
};
|
|
126
|
+
|
|
68
127
|
export const getOperator = (args: BuiltinArgument[], index: number, name: string) => {
|
|
69
128
|
const argument = args[index];
|
|
70
129
|
if (argument === undefined || !isOperatorValue(argument)) {
|
|
71
|
-
throw
|
|
130
|
+
throw createArgumentError(name, `${name} expects an operator as argument ${index + 1}`);
|
|
72
131
|
}
|
|
73
132
|
return argument;
|
|
74
133
|
};
|
|
@@ -122,13 +181,6 @@ export const defineStateOperator = (
|
|
|
122
181
|
isStateLevel: true,
|
|
123
182
|
});
|
|
124
183
|
|
|
125
|
-
export const toNumber = (value: Value, name: string) => {
|
|
126
|
-
if (typeof value !== "number") {
|
|
127
|
-
throw new TlaEvaluationError(`${name} expects an integer but received ${formatValue(value)}`);
|
|
128
|
-
}
|
|
129
|
-
return value;
|
|
130
|
-
};
|
|
131
|
-
|
|
132
184
|
export const defineBinary = (
|
|
133
185
|
name: string,
|
|
134
186
|
compute: (left: Value, right: Value) => Value,
|
|
@@ -141,13 +193,141 @@ export const defineBinary = (
|
|
|
141
193
|
evaluateBinary: compute,
|
|
142
194
|
});
|
|
143
195
|
|
|
144
|
-
export const
|
|
145
|
-
|
|
146
|
-
|
|
196
|
+
export const isOutOfRange = (value: number) => value > MAXIMUM_INTEGER || value < MINIMUM_INTEGER;
|
|
197
|
+
|
|
198
|
+
export const createOverflowError = (computation: string) =>
|
|
199
|
+
new TlaModuleError(`Overflow when computing ${computation}`);
|
|
200
|
+
|
|
201
|
+
const JAVA_CLASSES: Record<string, string> = {
|
|
202
|
+
ModelValue: "ModelValue",
|
|
203
|
+
Set: "SetEnumValue",
|
|
204
|
+
Interval: "IntervalValue",
|
|
205
|
+
InfiniteSet: "UserValue",
|
|
206
|
+
SequenceSet: "UserValue",
|
|
207
|
+
Subset: "SubsetValue",
|
|
208
|
+
FunctionSet: "SetOfFcnsValue",
|
|
209
|
+
RecordSet: "SetOfRcdsValue",
|
|
210
|
+
ProductSet: "SetOfTuplesValue",
|
|
211
|
+
FilteredSet: "SetPredValue",
|
|
212
|
+
LazyFunction: "FcnLambdaValue",
|
|
213
|
+
Union: "UnionValue",
|
|
214
|
+
MixedSet: "SetEnumValue",
|
|
215
|
+
};
|
|
216
|
+
|
|
217
|
+
const SET_OPERATION_CLASSES = {
|
|
218
|
+
"\\cup": "SetCupValue",
|
|
219
|
+
"\\cap": "SetCapValue",
|
|
220
|
+
"\\": "SetDiffValue",
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
const KIND_STRINGS: Record<string, string> = {
|
|
224
|
+
BoolValue: "a Boolean value",
|
|
225
|
+
IntValue: "an integer",
|
|
226
|
+
StringValue: "a string",
|
|
227
|
+
RecordValue: "a record",
|
|
228
|
+
SetEnumValue: "a set of the form {e1, ... ,eN}",
|
|
229
|
+
SetPredValue: "a set of the form {x \\in S : expr}",
|
|
230
|
+
TupleValue: "a tuple",
|
|
231
|
+
FcnLambdaValue: "a function of the form [x \\in S |-> expr]",
|
|
232
|
+
FcnRcdValue: "a function of the form (d1 :> e1 @@ ... @@ dN :> eN)",
|
|
233
|
+
SetOfFcnsValue: "a set of the form [S -> T]",
|
|
234
|
+
SetOfRcdsValue: "a set of the form [d1 : S1, ... , dN : SN]",
|
|
235
|
+
SetOfTuplesValue: "a cartesian product",
|
|
236
|
+
SubsetValue: "a set of the form SUBSET S",
|
|
237
|
+
SetDiffValue: "a set of the form S \\ T",
|
|
238
|
+
SetCapValue: "a set of the form S \\cap T",
|
|
239
|
+
SetCupValue: "a set of the form S \\cup T",
|
|
240
|
+
ModelValue: "a model value",
|
|
241
|
+
UserValue: "a special set constant",
|
|
242
|
+
IntervalValue: "a set of the form i..j",
|
|
243
|
+
UnionValue: "a set of the form UNION S",
|
|
244
|
+
};
|
|
245
|
+
|
|
246
|
+
// TLC stores a function as a TupleValue or a RecordValue when it has that shape, so the
|
|
247
|
+
// shape stands in for how TLC built the value.
|
|
248
|
+
export const getJavaClassName = (value: Value) => {
|
|
249
|
+
if (typeof value === "number") return "IntValue";
|
|
250
|
+
if (typeof value === "string") return "StringValue";
|
|
251
|
+
if (typeof value === "boolean") return "BoolValue";
|
|
252
|
+
if (value.kind === "SetOperation") return SET_OPERATION_CLASSES[value.operator];
|
|
253
|
+
if (value.kind !== "Function") return JAVA_CLASSES[value.kind];
|
|
254
|
+
const domain = value.domain;
|
|
255
|
+
if (domain.every((key, index) => key === index + 1)) return "TupleValue";
|
|
256
|
+
return domain.every((key) => typeof key === "string") ? "RecordValue" : "FcnRcdValue";
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
export const getKindString = (value: Value) => KIND_STRINGS[getJavaClassName(value)];
|
|
260
|
+
|
|
261
|
+
export const createJavaOverrideError = (signature: string, message: string) =>
|
|
262
|
+
new TlaEvaluationError(
|
|
263
|
+
`Attempted to apply the operator overridden by the Java method\n${signature},\nbut it produced the following error:\n${message}`,
|
|
147
264
|
);
|
|
148
265
|
|
|
266
|
+
// TLC reports a failure inside an operator's Java method as a failure of the method, except an
|
|
267
|
+
// EvalException that the method raises itself. A method that evaluates its own arguments reports
|
|
268
|
+
// every failure that way.
|
|
269
|
+
export const overrideWithJava = (builtin: Builtin, signature: string): Builtin => {
|
|
270
|
+
const guard =
|
|
271
|
+
<Arguments extends unknown[]>(compute: (...args: Arguments) => Value) =>
|
|
272
|
+
(...args: Arguments) => {
|
|
273
|
+
try {
|
|
274
|
+
return compute(...args);
|
|
275
|
+
} catch (error) {
|
|
276
|
+
const isWrapped =
|
|
277
|
+
error instanceof TlaEvaluationError &&
|
|
278
|
+
(builtin.isLazy === true || !(error instanceof TlaModuleError));
|
|
279
|
+
throw isWrapped ? createJavaOverrideError(signature, error.message) : error;
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
return {
|
|
283
|
+
...builtin,
|
|
284
|
+
evaluate: guard(builtin.evaluate),
|
|
285
|
+
evaluateUnary: builtin.evaluateUnary && guard(builtin.evaluateUnary),
|
|
286
|
+
evaluateBinary: builtin.evaluateBinary && guard(builtin.evaluateBinary),
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
export const getJavaInteger = (value: Value, signature: string) => {
|
|
291
|
+
if (typeof value !== "number") {
|
|
292
|
+
throw createJavaOverrideError(
|
|
293
|
+
signature,
|
|
294
|
+
`Cannot cast tlc2.value.impl.${getJavaClassName(value)} to tlc2.value.impl.IntValue`,
|
|
295
|
+
);
|
|
296
|
+
}
|
|
297
|
+
return value;
|
|
298
|
+
};
|
|
299
|
+
|
|
300
|
+
export const getIntegersSignature = (method: string, result: string, arity: number) =>
|
|
301
|
+
`public static tlc2.value.impl.${result} tlc2.module.Integers.${method}(${Array.from({ length: arity }, () => "tlc2.value.impl.IntValue").join(",")})`;
|
|
302
|
+
|
|
303
|
+
export const defineArithmetic = (
|
|
304
|
+
name: string,
|
|
305
|
+
method: string,
|
|
306
|
+
compute: (left: number, right: number) => number,
|
|
307
|
+
) => {
|
|
308
|
+
const signature = getIntegersSignature(method, "IntValue", 2);
|
|
309
|
+
return defineBinary(name, (left, right) => {
|
|
310
|
+
const leftNumber = getJavaInteger(left, signature);
|
|
311
|
+
const rightNumber = getJavaInteger(right, signature);
|
|
312
|
+
const result = compute(leftNumber, rightNumber);
|
|
313
|
+
if (isOutOfRange(result)) throw createOverflowError(`${leftNumber}${name}${rightNumber}`);
|
|
314
|
+
return result;
|
|
315
|
+
});
|
|
316
|
+
};
|
|
317
|
+
|
|
318
|
+
const getIntegerArgument = (value: Value, position: string, name: string) => {
|
|
319
|
+
if (typeof value !== "number") {
|
|
320
|
+
throw new TlaModuleError(
|
|
321
|
+
`The ${position} argument of ${name} should be an integer, but instead it is:\n${formatValue(value)}`,
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
return value;
|
|
325
|
+
};
|
|
326
|
+
|
|
149
327
|
export const defineComparison = (name: string, compare: (left: number, right: number) => boolean) =>
|
|
150
|
-
defineBinary(name, (left, right) =>
|
|
328
|
+
defineBinary(name, (left, right) =>
|
|
329
|
+
compare(getIntegerArgument(left, "first", name), getIntegerArgument(right, "second", name)),
|
|
330
|
+
);
|
|
151
331
|
|
|
152
332
|
export const defineLazyOperator = (
|
|
153
333
|
name: string,
|
package/src/bundled-modules.ts
CHANGED
|
@@ -1,48 +1,79 @@
|
|
|
1
|
-
|
|
1
|
+
// TLC's Reals.tla, RealTime.tla, and Toolbox.tla, verbatim, so that errors inside them name the same
|
|
2
|
+
// lines as TLC's errors.
|
|
3
|
+
const REALS = `-------------------------------- MODULE Reals -------------------------------
|
|
4
|
+
(***************************************************************************)
|
|
5
|
+
(* This module provides dummy definitions of the operators that are *)
|
|
6
|
+
(* defined by the real Reals module. It is expected that any tool that *)
|
|
7
|
+
(* handles specifications that use real numbers will provide its own *)
|
|
8
|
+
(* implementations of these operators. TLC currently does not handle real *)
|
|
9
|
+
(* numbers and produces an error if a specification requires TLC to *)
|
|
10
|
+
(* evaluate the operators defined here or to evaluate any operator defined *)
|
|
11
|
+
(* in the Integers module that is applied to non-integer real numbers. *)
|
|
12
|
+
(* *)
|
|
13
|
+
(* See the book "Specifying Systems" for the real Reals module. *)
|
|
14
|
+
(***************************************************************************)
|
|
2
15
|
EXTENDS Integers
|
|
3
16
|
|
|
4
|
-
Real
|
|
17
|
+
Real == "Reals"
|
|
18
|
+
a / b == CHOOSE m \\in Real : m * b = a
|
|
19
|
+
Infinity == CHOOSE i : (i \\notin Real) /\\ (\\A r \\in Real : i > r)
|
|
20
|
+
=============================================================================`;
|
|
5
21
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
22
|
+
const REAL_TIME = `----------------------------- MODULE RealTime -------------------------------
|
|
23
|
+
(***************************************************************************)
|
|
24
|
+
(* This standard module is described in Chapter 9 of the book "Specifying *)
|
|
25
|
+
(* Systems". The type of specification described there cannot be handled *)
|
|
26
|
+
(* by the TLC model checker. *)
|
|
27
|
+
(***************************************************************************)
|
|
28
|
+
EXTENDS Reals
|
|
29
|
+
VARIABLE now
|
|
10
30
|
|
|
11
|
-
|
|
12
|
-
|
|
31
|
+
RTBound(A, v, D, E) ==
|
|
32
|
+
LET TNext(t) == t' = IF <<A>>_v \\/ ~(ENABLED <<A>>_v)'
|
|
33
|
+
THEN 0
|
|
34
|
+
ELSE t + (now'-now)
|
|
13
35
|
|
|
14
|
-
|
|
36
|
+
Timer(t) == (t=0) /\\ [][TNext(t)]_<<t, v, now>>
|
|
15
37
|
|
|
16
|
-
|
|
17
|
-
LET TNext(timer) == timer' = IF <<A>>_v \\/ ~(ENABLED <<A>>_v)'
|
|
18
|
-
THEN 0
|
|
19
|
-
ELSE timer + (now' - now)
|
|
20
|
-
Timer(timer) == (timer = 0) /\\ [][TNext(timer)]_<<timer, v, now>>
|
|
21
|
-
MaxTime(timer) == [](timer \\leq E)
|
|
22
|
-
MinTime(timer) == [][A => timer \\geq D]_v
|
|
23
|
-
IN \\EE timer : Timer(timer) /\\ MaxTime(timer) /\\ MinTime(timer)
|
|
38
|
+
MaxTime(t) == [](t \\leq E)
|
|
24
39
|
|
|
25
|
-
|
|
40
|
+
MinTime(t) == [][A => t \\geq D]_v
|
|
41
|
+
IN \\EE t : Timer(t) /\\ MaxTime(t) /\\ MinTime(t)
|
|
42
|
+
-----------------------------------------------------------------------------
|
|
43
|
+
RTnow(v) == LET NowNext == /\\ now' \\in {r \\in Real : r > now}
|
|
26
44
|
/\\ UNCHANGED v
|
|
27
|
-
IN
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
45
|
+
IN /\\ now \\in Real
|
|
46
|
+
/\\ [][NowNext]_now
|
|
47
|
+
/\\ \\A r \\in Real : WF_now(NowNext /\\ (now'>r))
|
|
48
|
+
=============================================================================`;
|
|
31
49
|
|
|
32
|
-
const TOOLBOX =
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
50
|
+
const TOOLBOX = `----------------------------- MODULE Toolbox --------------------------------
|
|
51
|
+
(***************************************************************************)
|
|
52
|
+
(* *)
|
|
53
|
+
(***************************************************************************)
|
|
54
|
+
LOCAL INSTANCE Naturals \\* a + b
|
|
55
|
+
LOCAL INSTANCE FiniteSets \\* Cardinality
|
|
56
|
+
LOCAL INSTANCE TLC \\* TLCGet
|
|
36
57
|
|
|
37
|
-
|
|
58
|
+
-----------------------------------------------------------------------------
|
|
59
|
+
|
|
60
|
+
(* Trace Exploration *)
|
|
61
|
+
|
|
62
|
+
_TETrace ==
|
|
63
|
+
CHOOSE f \\in [ (Nat \\ {0}) -> STRING ] : TRUE
|
|
38
64
|
|
|
39
65
|
LOCAL _TETraceLength == Cardinality(DOMAIN _TETrace)
|
|
40
66
|
|
|
41
|
-
_TEPosition
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
67
|
+
\\* When evaluated as part of a TLC ALIAS expression, \`_TEPosition\` should be
|
|
68
|
+
\\* redefined as \`TLCGet("level"), or replace with \`TLCGet(level)\` right away.
|
|
69
|
+
\\* The definition below accounts for several "peculiarities" of the
|
|
70
|
+
\\* Toolbox's trace exploration.
|
|
71
|
+
_TEPosition ==
|
|
72
|
+
IF TLCGet("level") >= _TETraceLength
|
|
73
|
+
THEN _TETraceLength
|
|
74
|
+
ELSE IF TLCGet("level") = 0 THEN 1 ELSE TLCGet("level")
|
|
75
|
+
|
|
76
|
+
=============================================================================`;
|
|
46
77
|
|
|
47
78
|
export const BUNDLED_MODULES = new Map([
|
|
48
79
|
["Reals", REALS],
|