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.
Files changed (71) hide show
  1. package/README.md +81 -42
  2. package/dist/index.cjs +1 -1
  3. package/dist/index.d.cts +215 -30
  4. package/dist/index.d.ts +215 -30
  5. package/dist/index.js +1 -1
  6. package/dist/parallel-worker.cjs +2 -2
  7. package/dist/parallel-worker.js +2 -2
  8. package/dist/parallel.cjs +1 -1
  9. package/dist/parallel.js +2 -2
  10. package/dist/run-cli.cjs +20 -1
  11. package/dist/run-cli.js +20 -1
  12. package/dist/transfer.cjs +388 -39
  13. package/dist/transfer.js +388 -39
  14. package/package.json +6 -2
  15. package/src/ast.ts +122 -5
  16. package/src/bags.ts +161 -71
  17. package/src/builtins.ts +203 -23
  18. package/src/bundled-modules.ts +63 -32
  19. package/src/check.ts +945 -238
  20. package/src/cli-options.ts +58 -0
  21. package/src/codegen.ts +52 -18
  22. package/src/config.ts +39 -11
  23. package/src/environment.ts +485 -140
  24. package/src/errors.ts +59 -1
  25. package/src/evaluate.ts +489 -137
  26. package/src/exit-codes.ts +75 -0
  27. package/src/fingerprints.ts +2 -2
  28. package/src/index.ts +9 -4
  29. package/src/instances.ts +221 -66
  30. package/src/java-overrides.ts +241 -0
  31. package/src/json.ts +153 -72
  32. package/src/levels.ts +850 -0
  33. package/src/lexer.ts +103 -28
  34. package/src/liveness.ts +47 -91
  35. package/src/obligation-action.ts +384 -0
  36. package/src/obligation-anon.ts +575 -0
  37. package/src/obligation-deref.ts +637 -0
  38. package/src/obligation-expression.ts +1060 -0
  39. package/src/obligation-format.ts +406 -0
  40. package/src/obligation-generate.ts +1074 -0
  41. package/src/obligation-levels.ts +329 -0
  42. package/src/obligation-module.ts +1042 -0
  43. package/src/obligation-printer.ts +889 -0
  44. package/src/obligation-proof.ts +76 -0
  45. package/src/obligation-source.ts +1084 -0
  46. package/src/obligation-tuples.ts +184 -0
  47. package/src/obligations.ts +316 -0
  48. package/src/parallel-worker.ts +57 -28
  49. package/src/parallel.ts +116 -62
  50. package/src/parser.ts +958 -205
  51. package/src/pretty-print.ts +259 -0
  52. package/src/randomization.ts +24 -113
  53. package/src/resolve.ts +472 -41
  54. package/src/run-cli.ts +427 -61
  55. package/src/runtime.ts +63 -28
  56. package/src/spec-description.ts +509 -0
  57. package/src/standard-levels.ts +105 -0
  58. package/src/standard-modules.ts +223 -92
  59. package/src/subexpressions.ts +21 -35
  60. package/src/substitution-levels.ts +184 -0
  61. package/src/successors.ts +261 -46
  62. package/src/symmetry.ts +65 -21
  63. package/src/tableau.ts +43 -37
  64. package/src/tlc-ext.ts +120 -33
  65. package/src/tlc-module.ts +71 -47
  66. package/src/tlc-modules.ts +1022 -0
  67. package/src/tlc-order.ts +497 -0
  68. package/src/tlc-random.ts +411 -0
  69. package/src/tlc-summary.ts +109 -0
  70. package/src/transfer.ts +26 -5
  71. package/src/values.ts +1231 -176
@@ -0,0 +1,509 @@
1
+ import type { Definition, Expression, SourceLocation, SourceRange } from "./ast";
2
+ import type { ModelConfig } from "./config";
3
+ import type { InstanceAction } from "./environment";
4
+ import { TlaError } from "./errors";
5
+ import {
6
+ bindDefinitions,
7
+ bindOperatorArguments,
8
+ evaluate,
9
+ forEachBinding,
10
+ formatRange,
11
+ getDefinition,
12
+ isConstantLevel,
13
+ isLocallyResolved,
14
+ lookupScope,
15
+ resolveGlobalOperator,
16
+ type Closure,
17
+ type Environment,
18
+ type Scope,
19
+ } from "./evaluate";
20
+ import { TEMPORAL_LEVEL } from "./levels";
21
+ import { getLevel } from "./liveness";
22
+ import { createRecord, createSet, createTuple, formatValue, type Value } from "./values";
23
+
24
+ export interface SpecAction {
25
+ name: string;
26
+ location: SourceLocation;
27
+ parameters: [string, Value][];
28
+ expression: Expression;
29
+ scope: Scope | undefined;
30
+ }
31
+
32
+ interface SpecDescription {
33
+ inits: SpecAction[];
34
+ actions: SpecAction[];
35
+ temporals: SpecAction[];
36
+ invariants: SpecAction[];
37
+ impliedInits: SpecAction[];
38
+ impliedActions: SpecAction[];
39
+ impliedTemporals: SpecAction[];
40
+ }
41
+
42
+ const UNNAMED_ACTION = "UnnamedAction";
43
+
44
+ const BUILTIN_RANGE: SourceRange = {
45
+ module: "--TLA+ BUILTINS--",
46
+ start: { line: 0, column: 0 },
47
+ end: { line: 0, column: 0 },
48
+ };
49
+
50
+ const toLocationValue = (location: SourceLocation) => {
51
+ const range = location.range ?? BUILTIN_RANGE;
52
+ return createRecord([
53
+ ["beginLine", range.start.line],
54
+ ["beginColumn", range.start.column],
55
+ ["endLine", range.end.line],
56
+ ["endColumn", range.end.column],
57
+ ["module", range.module],
58
+ ]);
59
+ };
60
+
61
+ const toActionValue = (action: SpecAction) => {
62
+ const fields: [string, Value][] = [
63
+ ["name", action.name],
64
+ ["location", toLocationValue(action.location)],
65
+ ];
66
+ if (action.parameters.length === 0) return createRecord(fields);
67
+ return createRecord([
68
+ ...fields,
69
+ ["context", createRecord(action.parameters)],
70
+ ["parameters", createTuple(action.parameters.map((parameter) => parameter[0]))],
71
+ ]);
72
+ };
73
+
74
+ const createAction = (name: string, expression: Expression): SpecAction => ({
75
+ name,
76
+ location: expression.location,
77
+ parameters: [],
78
+ expression,
79
+ scope: undefined,
80
+ });
81
+
82
+ const getConstantContext = (environment: Environment, scope: Scope | undefined) => ({
83
+ environment,
84
+ scope,
85
+ state: undefined,
86
+ next: undefined,
87
+ });
88
+
89
+ const getOperatorName = (expression: Expression) =>
90
+ expression.kind === "Identifier"
91
+ ? expression.name
92
+ : expression.kind === "Apply"
93
+ ? expression.operator
94
+ : undefined;
95
+
96
+ const getArguments = (expression: Expression) =>
97
+ expression.kind === "Apply" ? expression.args : [];
98
+
99
+ const resolveClosure = (
100
+ expression: Expression,
101
+ scope: Scope | undefined,
102
+ environment: Environment,
103
+ ) => {
104
+ const name = getOperatorName(expression);
105
+ if (name === undefined) return undefined;
106
+ if (isLocallyResolved(expression)) {
107
+ const binding = lookupScope(scope, name);
108
+ return binding?.kind === "Operator" && binding.operator.kind === "Closure"
109
+ ? binding.operator
110
+ : undefined;
111
+ }
112
+ if (environment.constants.has(name) || environment.variableIndex.has(name)) return undefined;
113
+ const operator = resolveGlobalOperator(name, environment);
114
+ return operator?.kind === "Closure" ? operator : undefined;
115
+ };
116
+
117
+ const isEvaluable = (expression: Expression, environment: Environment) => {
118
+ try {
119
+ evaluate(expression, getConstantContext(environment, undefined));
120
+ return true;
121
+ } catch (error) {
122
+ if (error instanceof TlaError) return false;
123
+ throw error;
124
+ }
125
+ };
126
+
127
+ const isConstantValue = (definition: Definition | undefined, environment: Environment) =>
128
+ definition?.kind === "Operator" &&
129
+ definition.params.length === 0 &&
130
+ definition.body.kind !== "Number" &&
131
+ definition.body.kind !== "String" &&
132
+ isConstantLevel(definition, environment) &&
133
+ isEvaluable(definition.body, environment);
134
+
135
+ const isConstantDefinition = (closure: Closure, environment: Environment) => {
136
+ const definition = getDefinition(closure.name, environment);
137
+ return definition?.body === closure.body && isConstantValue(definition, environment);
138
+ };
139
+
140
+ const getThunk = (expression: Expression, scope: Scope | undefined) => {
141
+ if (expression.kind !== "Identifier" || !isLocallyResolved(expression)) return undefined;
142
+ const binding = lookupScope(scope, expression.name);
143
+ return binding?.kind === "Thunk" ? binding : undefined;
144
+ };
145
+
146
+ const getParameters = (closure: Closure | undefined, scope: Scope | undefined) =>
147
+ (closure?.params ?? []).flatMap((param): [string, Value][] => {
148
+ const binding = lookupScope(scope, param.name);
149
+ return binding?.kind === "Value" ? [[param.name, binding.value]] : [];
150
+ });
151
+
152
+ const tryCollect = <Result>(collect: () => Result, fallback: () => Result) => {
153
+ try {
154
+ return collect();
155
+ } catch (error) {
156
+ if (error instanceof TlaError) return fallback();
157
+ throw error;
158
+ }
159
+ };
160
+
161
+ const getInstanceActions = (
162
+ instanceAction: InstanceAction,
163
+ expression: Expression,
164
+ scope: Scope | undefined,
165
+ called: Closure | undefined,
166
+ environment: Environment,
167
+ ): SpecAction[] => {
168
+ const args = getArguments(expression);
169
+ const callAction = (): SpecAction[] => [
170
+ { name: instanceAction.name, location: expression.location, parameters: [], expression, scope },
171
+ ];
172
+ if (!called || args.length === 0) {
173
+ return [{ ...instanceAction, parameters: [], expression, scope }];
174
+ }
175
+ if (args.some((arg) => getLevel(arg, scope, environment) !== 0)) return callAction();
176
+ return tryCollect(
177
+ () => [
178
+ {
179
+ ...instanceAction,
180
+ parameters: args.map((arg, index): [string, Value] => [
181
+ called.params[index].name.replace(/#\d+$/, ""),
182
+ evaluate(arg, getConstantContext(environment, scope)),
183
+ ]),
184
+ expression,
185
+ scope,
186
+ },
187
+ ],
188
+ callAction,
189
+ );
190
+ };
191
+
192
+ const getActions = (
193
+ expression: Expression,
194
+ scope: Scope | undefined,
195
+ closure: Closure | undefined,
196
+ environment: Environment,
197
+ instanceActions: Map<string, InstanceAction>,
198
+ ): SpecAction[] => {
199
+ const createSplitAction = (): SpecAction => ({
200
+ name: closure?.name ?? UNNAMED_ACTION,
201
+ location: expression.location,
202
+ parameters: getParameters(closure, scope),
203
+ expression,
204
+ scope,
205
+ });
206
+ switch (expression.kind) {
207
+ case "Let":
208
+ return getActions(
209
+ expression.body,
210
+ bindDefinitions(expression.definitions, getConstantContext(environment, scope)),
211
+ closure,
212
+ environment,
213
+ instanceActions,
214
+ );
215
+ case "Label":
216
+ return getActions(expression.body, scope, closure, environment, instanceActions);
217
+ case "Or":
218
+ return expression.operands.flatMap((operand) =>
219
+ getActions(operand, scope, closure, environment, instanceActions),
220
+ );
221
+ case "Exists":
222
+ return tryCollect(
223
+ () => {
224
+ const actions: SpecAction[] = [];
225
+ forEachBinding(
226
+ expression.bounds,
227
+ getConstantContext(environment, scope),
228
+ (boundScope) => {
229
+ actions.push(
230
+ ...getActions(expression.body, boundScope, closure, environment, instanceActions),
231
+ );
232
+ return false;
233
+ },
234
+ );
235
+ return actions.length === 0 ? [createSplitAction()] : actions;
236
+ },
237
+ () => [createSplitAction()],
238
+ );
239
+ }
240
+ const instanceAction = isLocallyResolved(expression)
241
+ ? undefined
242
+ : instanceActions.get(getOperatorName(expression) ?? "");
243
+ const called = resolveClosure(expression, scope, environment);
244
+ if (instanceAction)
245
+ return getInstanceActions(instanceAction, expression, scope, called, environment);
246
+ if (!called) return [createSplitAction()];
247
+ const args = getArguments(expression);
248
+ const callAction = (): SpecAction[] => [
249
+ { name: called.name, location: expression.location, parameters: [], expression, scope },
250
+ ];
251
+ if (isConstantDefinition(called, environment)) return callAction();
252
+ if (args.some((arg) => getLevel(arg, scope, environment) !== 0)) return callAction();
253
+ return tryCollect(() => {
254
+ const boundScope = args.reduce<Scope | undefined>(
255
+ (current, arg, index) => ({
256
+ name: called.params[index].name,
257
+ binding: {
258
+ kind: "Value",
259
+ value: evaluate(arg, getConstantContext(environment, scope)),
260
+ },
261
+ parent: current,
262
+ }),
263
+ called.scope,
264
+ );
265
+ return getActions(called.body, boundScope, called, environment, instanceActions);
266
+ }, callAction);
267
+ };
268
+
269
+ const describeSpecification = (
270
+ expression: Expression,
271
+ scope: Scope | undefined,
272
+ environment: Environment,
273
+ description: SpecDescription,
274
+ next: { expression: Expression; scope: Scope | undefined }[],
275
+ ): void => {
276
+ const recurse = (inner: Expression, innerScope: Scope | undefined) =>
277
+ describeSpecification(inner, innerScope, environment, description, next);
278
+ if (expression.kind === "Let") {
279
+ recurse(
280
+ expression.body,
281
+ bindDefinitions(expression.definitions, getConstantContext(environment, scope)),
282
+ );
283
+ return;
284
+ }
285
+ const thunk = getThunk(expression, scope);
286
+ if (thunk) {
287
+ recurse(thunk.expression, thunk.scope);
288
+ return;
289
+ }
290
+ const called = resolveClosure(expression, scope, environment);
291
+ if (called && isConstantDefinition(called, environment)) return;
292
+ if (called && called.params.length === 0) {
293
+ if (getLevel(called.body, called.scope, environment) === 1) {
294
+ description.inits.push(createAction(called.name, called.body));
295
+ return;
296
+ }
297
+ recurse(called.body, called.scope);
298
+ return;
299
+ }
300
+ if (called && expression.kind === "Apply" && called.params.length === expression.args.length) {
301
+ recurse(
302
+ called.body,
303
+ bindOperatorArguments(called, expression.args, getConstantContext(environment, scope)),
304
+ );
305
+ return;
306
+ }
307
+ if (expression.kind === "And") {
308
+ expression.operands.forEach((operand) => recurse(operand, scope));
309
+ return;
310
+ }
311
+ if (expression.kind === "Always") {
312
+ if (expression.expression.kind === "BoxAction") {
313
+ next.push({ expression: expression.expression.action, scope });
314
+ return;
315
+ }
316
+ description.temporals.push(createAction(UNNAMED_ACTION, expression));
317
+ return;
318
+ }
319
+ const level = getLevel(expression, scope, environment);
320
+ if (level <= 1) description.inits.push(createAction(UNNAMED_ACTION, expression));
321
+ else if (level === TEMPORAL_LEVEL) {
322
+ description.temporals.push(createAction(UNNAMED_ACTION, expression));
323
+ }
324
+ };
325
+
326
+ const describeProperty = (
327
+ configName: string,
328
+ expression: Expression,
329
+ scope: Scope | undefined,
330
+ environment: Environment,
331
+ description: SpecDescription,
332
+ ): void => {
333
+ const recurse = (inner: Expression, innerScope: Scope | undefined) =>
334
+ describeProperty(configName, inner, innerScope, environment, description);
335
+ if (expression.kind === "Let") {
336
+ recurse(
337
+ expression.body,
338
+ bindDefinitions(expression.definitions, getConstantContext(environment, scope)),
339
+ );
340
+ return;
341
+ }
342
+ const thunk = getThunk(expression, scope);
343
+ if (thunk) {
344
+ recurse(thunk.expression, thunk.scope);
345
+ return;
346
+ }
347
+ const called = resolveClosure(expression, scope, environment);
348
+ if (called && isConstantDefinition(called, environment)) return;
349
+ if (called && called.params.length === getArguments(expression).length) {
350
+ recurse(
351
+ called.body,
352
+ expression.kind === "Apply"
353
+ ? bindOperatorArguments(called, expression.args, getConstantContext(environment, scope))
354
+ : called.scope,
355
+ );
356
+ return;
357
+ }
358
+ if (expression.kind === "Forall") {
359
+ const isEnumerated = tryCollect(
360
+ () => {
361
+ forEachBinding(expression.bounds, getConstantContext(environment, scope), (boundScope) => {
362
+ recurse(expression.body, boundScope);
363
+ return false;
364
+ });
365
+ return true;
366
+ },
367
+ () => false,
368
+ );
369
+ if (isEnumerated) return;
370
+ }
371
+ if (expression.kind === "And") {
372
+ expression.operands.forEach((operand) => recurse(operand, scope));
373
+ return;
374
+ }
375
+ if (expression.kind === "Always") {
376
+ const inner = expression.expression;
377
+ if (inner.kind === "BoxAction") {
378
+ description.impliedActions.push(createAction(configName, inner));
379
+ } else if (getLevel(inner, scope, environment) < 2) {
380
+ description.invariants.push(createAction(configName, inner));
381
+ } else {
382
+ description.impliedTemporals.push(createAction(configName, expression));
383
+ }
384
+ return;
385
+ }
386
+ const level = getLevel(expression, scope, environment);
387
+ if (level <= 1) description.impliedInits.push(createAction(configName, expression));
388
+ else if (level === TEMPORAL_LEVEL) {
389
+ description.impliedTemporals.push(createAction(configName, expression));
390
+ }
391
+ };
392
+
393
+ const getOperatorDefinition = (name: string, environment: Environment) => {
394
+ const definition = getDefinition(name, environment);
395
+ return definition?.kind === "Operator" && !isConstantValue(definition, environment)
396
+ ? definition
397
+ : undefined;
398
+ };
399
+
400
+ const describeDefinition = (definition: Definition) =>
401
+ createRecord([
402
+ ["name", definition.name],
403
+ ["location", toLocationValue(definition.location)],
404
+ ]);
405
+
406
+ const describe = (
407
+ config: ModelConfig,
408
+ environment: Environment,
409
+ instanceActions: Map<string, InstanceAction>,
410
+ ) => {
411
+ const description: SpecDescription = {
412
+ inits: [],
413
+ actions: [],
414
+ temporals: [],
415
+ invariants: [],
416
+ impliedInits: [],
417
+ impliedActions: [],
418
+ impliedTemporals: [],
419
+ };
420
+ const next: { expression: Expression; scope: Scope | undefined }[] = [];
421
+ const specification =
422
+ config.specification === undefined
423
+ ? undefined
424
+ : getOperatorDefinition(config.specification, environment);
425
+ if (specification) {
426
+ describeSpecification(specification.body, undefined, environment, description, next);
427
+ next.forEach((item) =>
428
+ description.actions.push(
429
+ ...getActions(item.expression, item.scope, undefined, environment, instanceActions),
430
+ ),
431
+ );
432
+ }
433
+ const init =
434
+ config.init === undefined ? undefined : resolveGlobalOperator(config.init, environment);
435
+ if (init?.kind === "Closure") description.inits.push(createAction(config.init ?? "", init.body));
436
+ const nextOperator =
437
+ config.next === undefined ? undefined : resolveGlobalOperator(config.next, environment);
438
+ if (nextOperator?.kind === "Closure") {
439
+ description.actions.push(
440
+ ...getActions(
441
+ nextOperator.body,
442
+ nextOperator.scope,
443
+ nextOperator,
444
+ environment,
445
+ instanceActions,
446
+ ),
447
+ );
448
+ }
449
+ config.invariants.forEach((name) => {
450
+ const definition = getOperatorDefinition(name, environment);
451
+ if (definition) description.invariants.push(createAction(name, definition.body));
452
+ });
453
+ config.properties.forEach((name) => {
454
+ const definition = getOperatorDefinition(name, environment);
455
+ if (definition) describeProperty(name, definition.body, undefined, environment, description);
456
+ });
457
+ return description;
458
+ };
459
+
460
+ // TLC's split of the next-state relation into the actions it names in a behavior.
461
+ export const getNextActions = (
462
+ config: ModelConfig,
463
+ environment: Environment,
464
+ instanceActions: Map<string, InstanceAction>,
465
+ ) => describe(config, environment, instanceActions).actions;
466
+
467
+ export const getActionLabel = (action: SpecAction) => {
468
+ const parameters = action.parameters.map((parameter) => formatValue(parameter[1]));
469
+ return `${action.name === UNNAMED_ACTION ? "Action" : action.name}${parameters.length === 0 ? "" : `(${parameters.join(",")})`} ${formatRange(action.location.range ?? BUILTIN_RANGE)}`;
470
+ };
471
+
472
+ export const getSpecificationValue = (
473
+ config: ModelConfig,
474
+ environment: Environment,
475
+ variableLocations: SourceLocation[],
476
+ instanceActions: Map<string, InstanceAction>,
477
+ ): Value => {
478
+ const description = describe(config, environment, instanceActions);
479
+ const toSet = (actions: SpecAction[]) => createSet(actions.map(toActionValue));
480
+ const toDefinitionSet = (names: string[]) =>
481
+ createSet(
482
+ names.flatMap((name) => {
483
+ const definition = getOperatorDefinition(name, environment);
484
+ return definition ? [describeDefinition(definition)] : [];
485
+ }),
486
+ );
487
+ return createRecord([
488
+ ["inits", toSet(description.inits)],
489
+ ["actions", toSet(description.actions)],
490
+ ["temporals", toSet(description.temporals)],
491
+ ["invariants", toSet(description.invariants)],
492
+ ["impliedinits", toSet(description.impliedInits)],
493
+ ["impliedactions", toSet(description.impliedActions)],
494
+ ["impliedtemporals", toSet(description.impliedTemporals)],
495
+ [
496
+ "variables",
497
+ createSet(
498
+ environment.variables.map((name, index) =>
499
+ createRecord([
500
+ ["name", name],
501
+ ["location", toLocationValue(variableLocations[index])],
502
+ ]),
503
+ ),
504
+ ),
505
+ ],
506
+ ["actionconstraints", toDefinitionSet(config.actionConstraints)],
507
+ ["constraints", toDefinitionSet(config.constraints)],
508
+ ]);
509
+ };
@@ -0,0 +1,105 @@
1
+ import type { OperatorLevels } from "./levels";
2
+
3
+ type Signature =
4
+ | [string, number, number[], number[], number[]]
5
+ | [string, number, number[], number[], number[], number[][], string[]];
6
+
7
+ // The levels SANY computes for the dummy definitions in tla2sany/StandardModules of the operators
8
+ // that tla-ts implements natively.
9
+ const SIGNATURES: Signature[] = [
10
+ ["Nat", 0, [], [], []],
11
+ ["+", 0, [0, 0], [2, 2], [1, 1]],
12
+ ["-", 0, [0, 0], [2, 2], [1, 1]],
13
+ ["*", 0, [0, 0], [3, 3], [0, 0]],
14
+ ["^", 0, [0, 0], [2, 2], [1, 1]],
15
+ ["<", 0, [0, 0], [2, 2], [1, 1]],
16
+ [">", 0, [0, 0], [2, 2], [1, 1]],
17
+ ["<=", 0, [0, 0], [2, 2], [1, 1]],
18
+ [">=", 0, [0, 0], [2, 2], [1, 1]],
19
+ ["%", 0, [0, 0], [2, 2], [1, 1]],
20
+ ["\\div", 0, [0, 0], [2, 2], [1, 1]],
21
+ ["..", 0, [0, 0], [2, 2], [1, 1]],
22
+ ["Int", 0, [], [], []],
23
+ ["-.", 0, [0], [2], [1]],
24
+ ["Seq", 0, [0], [2], [1]],
25
+ ["Len", 0, [0], [2], [1]],
26
+ ["\\o", 0, [0, 0], [2, 2], [1, 1]],
27
+ ["Append", 0, [0, 0], [2, 2], [1, 1]],
28
+ ["Head", 0, [0], [2], [1]],
29
+ ["Tail", 0, [0], [2], [1]],
30
+ ["SubSeq", 0, [0, 0, 0], [2, 2, 2], [1, 1, 1]],
31
+ ["SelectSeq", 0, [0, 1], [2, 2], [1, 1], [], ["1,0,0"]],
32
+ ["IsFiniteSet", 0, [0], [2], [1]],
33
+ ["Cardinality", 0, [0], [2], [1]],
34
+ ["IsABag", 0, [0], [2], [1]],
35
+ ["BagToSet", 0, [0], [2], [1]],
36
+ ["SetToBag", 0, [0], [3], [1]],
37
+ ["BagIn", 0, [0, 0], [2, 2], [1, 1]],
38
+ ["EmptyBag", 0, [], [], []],
39
+ ["\\oplus", 0, [0, 0], [2, 2], [1, 1]],
40
+ ["\\ominus", 0, [0, 0], [2, 2], [1, 1]],
41
+ ["BagUnion", 0, [0], [2], [1]],
42
+ ["\\sqsubseteq", 0, [0, 0], [2, 2], [1, 1]],
43
+ ["SubBag", 0, [0], [2], [1]],
44
+ ["BagOfAll", 0, [1, 0], [2, 2], [1, 1]],
45
+ ["BagCardinality", 0, [0], [2], [1]],
46
+ ["CopiesIn", 0, [0, 0], [2, 2], [1, 1]],
47
+ ["Print", 0, [0, 0], [3, 3], [0, 1]],
48
+ ["PrintT", 0, [0], [3], [0]],
49
+ ["Assert", 0, [0, 0], [2, 3], [1, 0]],
50
+ ["JavaTime", 0, [], [], []],
51
+ ["TLCGet", 0, [0], [3], [0]],
52
+ ["TLCSet", 0, [0, 0], [3, 3], [0, 0]],
53
+ [":>", 0, [0, 0], [2, 3], [1, 1]],
54
+ ["@@", 0, [0, 0], [2, 2], [1, 1]],
55
+ ["Permutations", 0, [0], [2], [1]],
56
+ ["SortSeq", 0, [0, 2], [2, 2], [1, 1], [], ["1,0,0", "1,0,1"]],
57
+ ["RandomElement", 0, [0], [3], [1]],
58
+ ["Any", 0, [], [], []],
59
+ ["ToString", 0, [0], [2], [1]],
60
+ ["TLCEval", 0, [0], [3], [1]],
61
+ ["AssertEq", 0, [0, 0], [2, 2], [1, 1]],
62
+ ["AssertError", 0, [0, 0], [2, 3], [1, 0]],
63
+ ["TLCGetOrDefault", 0, [0, 0], [3, 3], [0, 0]],
64
+ ["TLCGetAndSet", 0, [0, 2, 0, 0], [3, 3, 3, 3], [0, 0, 0, 0], [], ["1,2,1"]],
65
+ ["Trace", 0, [], [], []],
66
+ ["CounterExample", 0, [], [], []],
67
+ ["ToTrace", 0, [0], [3], [0]],
68
+ ["TLCModelValue", 0, [0], [2], [1]],
69
+ ["TLCDefer", 0, [0], [3], [0]],
70
+ ["TLCNoOp", 0, [0], [3], [1]],
71
+ ["PickSuccessor", 0, [0], [3], [1]],
72
+ ["TLCCache", 0, [0, 0], [3, 3], [1, 0]],
73
+ ["TLCFP", 0, [0], [3], [0]],
74
+ ["TLCEvalDefinition", 0, [0], [3], [0]],
75
+ ["ToJson", 0, [0], [2], [1]],
76
+ ["ToJsonArray", 0, [0], [2], [1]],
77
+ ["ToJsonObject", 0, [0], [2], [1]],
78
+ ["JsonSerialize", 0, [0, 0], [3, 3], [0, 0]],
79
+ ["JsonDeserialize", 0, [0], [3], [0]],
80
+ ["ndJsonSerialize", 0, [0, 0], [3, 3], [0, 0]],
81
+ ["ndJsonDeserialize", 0, [0], [3], [0]],
82
+ ["RandomSubset", 0, [0, 0], [2, 2], [1, 1]],
83
+ ["RandomSetOfSubsets", 0, [0, 0, 0], [2, 3, 2], [1, 0, 1]],
84
+ ["TestRandomSetOfSubsets", 0, [0, 0, 0], [2, 3, 2], [1, 0, 1]],
85
+ ];
86
+
87
+ export const STANDARD_LEVELS = new Map(
88
+ SIGNATURES.map((signature): [string, OperatorLevels] => [
89
+ signature[0],
90
+ {
91
+ name: signature[0],
92
+ level: signature[1],
93
+ params: new Set(),
94
+ constraints: new Map(),
95
+ argConstraints: new Map(),
96
+ argParams: new Set(),
97
+ formals: signature[2].map((arity, index) => ({ name: `$${index}`, arity })),
98
+ maxLevels: signature[3],
99
+ weights: signature[4],
100
+ minMaxLevels: signature[5] ?? [],
101
+ conditions: new Set(signature[6]),
102
+ nonLeibniz: new Set(),
103
+ },
104
+ ]),
105
+ );