tla-ts 0.0.1 → 0.0.2
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 +34 -41
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +166 -30
- package/dist/index.d.ts +166 -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 +2 -1
- package/dist/run-cli.js +2 -1
- package/dist/transfer.cjs +388 -39
- package/dist/transfer.js +388 -39
- package/package.json +4 -2
- package/src/ast.ts +82 -5
- package/src/bags.ts +161 -71
- package/src/builtins.ts +203 -23
- package/src/bundled-modules.ts +63 -32
- package/src/check.ts +904 -230
- package/src/codegen.ts +52 -18
- package/src/config.ts +39 -11
- package/src/environment.ts +485 -140
- package/src/errors.ts +22 -0
- package/src/evaluate.ts +486 -136
- 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 +97 -27
- package/src/liveness.ts +47 -91
- package/src/parallel-worker.ts +57 -28
- package/src/parallel.ts +116 -62
- package/src/parser.ts +703 -183
- package/src/pretty-print.ts +259 -0
- package/src/randomization.ts +24 -113
- package/src/resolve.ts +472 -41
- package/src/run-cli.ts +142 -44
- 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 +4 -4
- package/src/values.ts +1186 -164
package/dist/index.d.ts
CHANGED
|
@@ -12,10 +12,22 @@ interface LocalResolution {
|
|
|
12
12
|
interface SourceLocation {
|
|
13
13
|
line: number;
|
|
14
14
|
column: number;
|
|
15
|
+
range?: SourceRange;
|
|
16
|
+
}
|
|
17
|
+
interface SourceRange {
|
|
18
|
+
module: string;
|
|
19
|
+
start: SourceLocation;
|
|
20
|
+
end: SourceLocation;
|
|
15
21
|
}
|
|
16
22
|
interface NumberExpression {
|
|
17
23
|
kind: "Number";
|
|
18
24
|
value: number;
|
|
25
|
+
text?: string;
|
|
26
|
+
location: SourceLocation;
|
|
27
|
+
}
|
|
28
|
+
interface DecimalExpression {
|
|
29
|
+
kind: "Decimal";
|
|
30
|
+
text: string;
|
|
19
31
|
location: SourceLocation;
|
|
20
32
|
}
|
|
21
33
|
interface StringExpression {
|
|
@@ -249,7 +261,7 @@ interface SubexpressionExpression {
|
|
|
249
261
|
selectors: Selector[];
|
|
250
262
|
location: SourceLocation;
|
|
251
263
|
}
|
|
252
|
-
type Expression = NumberExpression | StringExpression | IdentifierExpression | ApplyExpression | OperatorReferenceExpression | LambdaExpression | JunctionExpression | PrimeExpression | UnchangedExpression | EnabledExpression | IfExpression | CaseExpression | LetExpression | QuantifierExpression | UnboundedQuantifierExpression | ChooseExpression | SetEnumerationExpression | SetFilterExpression | SetMapExpression | TupleExpression | FunctionConstructionExpression | FunctionSetExpression | RecordExpression | ExceptExpression | ExceptAtExpression | FunctionApplicationExpression | FieldAccessExpression | ProductExpression | TemporalExpression | ActionExpression | FairnessExpression | LabelExpression | SubexpressionExpression;
|
|
264
|
+
type Expression = NumberExpression | DecimalExpression | StringExpression | IdentifierExpression | ApplyExpression | OperatorReferenceExpression | LambdaExpression | JunctionExpression | PrimeExpression | UnchangedExpression | EnabledExpression | IfExpression | CaseExpression | LetExpression | QuantifierExpression | UnboundedQuantifierExpression | ChooseExpression | SetEnumerationExpression | SetFilterExpression | SetMapExpression | TupleExpression | FunctionConstructionExpression | FunctionSetExpression | RecordExpression | ExceptExpression | ExceptAtExpression | FunctionApplicationExpression | FieldAccessExpression | ProductExpression | TemporalExpression | ActionExpression | FairnessExpression | LabelExpression | SubexpressionExpression;
|
|
253
265
|
interface OperatorParam {
|
|
254
266
|
name: string;
|
|
255
267
|
arity: number;
|
|
@@ -259,6 +271,7 @@ interface OperatorDefinition {
|
|
|
259
271
|
name: string;
|
|
260
272
|
params: OperatorParam[];
|
|
261
273
|
body: Expression;
|
|
274
|
+
bodyRange?: SourceRange;
|
|
262
275
|
isLocal: boolean;
|
|
263
276
|
isRecursive: boolean;
|
|
264
277
|
location: SourceLocation;
|
|
@@ -276,6 +289,7 @@ type Definition = OperatorDefinition | FunctionDefinition;
|
|
|
276
289
|
interface Declaration {
|
|
277
290
|
name: string;
|
|
278
291
|
arity: number;
|
|
292
|
+
location: SourceLocation;
|
|
279
293
|
}
|
|
280
294
|
interface Assumption {
|
|
281
295
|
name: string | undefined;
|
|
@@ -296,20 +310,101 @@ interface Instance {
|
|
|
296
310
|
isLocal: boolean;
|
|
297
311
|
location: SourceLocation;
|
|
298
312
|
}
|
|
299
|
-
interface
|
|
300
|
-
|
|
301
|
-
|
|
313
|
+
interface NewSymbol {
|
|
314
|
+
kind: "NewSymbol";
|
|
315
|
+
name: string;
|
|
316
|
+
arity: number;
|
|
317
|
+
level: "Constant" | "Variable" | "State" | "Action" | "Temporal";
|
|
318
|
+
set: Expression | undefined;
|
|
319
|
+
location: SourceLocation;
|
|
320
|
+
}
|
|
321
|
+
interface AssumeProve {
|
|
322
|
+
kind: "AssumeProve";
|
|
323
|
+
assumptions: (Expression | NewSymbol | AssumeProve)[];
|
|
324
|
+
conclusion: Expression;
|
|
325
|
+
location: SourceLocation;
|
|
326
|
+
}
|
|
327
|
+
type Fact = Expression | {
|
|
328
|
+
kind: "ModuleFact";
|
|
329
|
+
name: string;
|
|
330
|
+
location: SourceLocation;
|
|
331
|
+
};
|
|
332
|
+
interface UseOrHide {
|
|
333
|
+
kind: "Use" | "Hide";
|
|
334
|
+
isOnly: boolean;
|
|
335
|
+
facts: Fact[];
|
|
336
|
+
defs: Fact[];
|
|
337
|
+
location: SourceLocation;
|
|
338
|
+
}
|
|
339
|
+
type Proof = {
|
|
340
|
+
kind: "Obvious" | "Omitted";
|
|
341
|
+
location: SourceLocation;
|
|
342
|
+
} | {
|
|
343
|
+
kind: "By";
|
|
344
|
+
isOnly: boolean;
|
|
345
|
+
facts: Fact[];
|
|
346
|
+
defs: Fact[];
|
|
347
|
+
location: SourceLocation;
|
|
348
|
+
} | {
|
|
349
|
+
kind: "Steps";
|
|
350
|
+
level: number;
|
|
351
|
+
steps: ProofStep[];
|
|
352
|
+
location: SourceLocation;
|
|
353
|
+
};
|
|
354
|
+
interface DefineStep {
|
|
355
|
+
kind: "Define";
|
|
356
|
+
definitions: (Definition | Instance)[];
|
|
357
|
+
location: SourceLocation;
|
|
358
|
+
}
|
|
359
|
+
type StepBody = UseOrHide | Instance | DefineStep | {
|
|
360
|
+
kind: "Have";
|
|
361
|
+
expression: Expression;
|
|
362
|
+
} | {
|
|
363
|
+
kind: "Take";
|
|
364
|
+
names: string[];
|
|
365
|
+
bounds: Bound[];
|
|
366
|
+
} | {
|
|
367
|
+
kind: "Witness";
|
|
368
|
+
expressions: Expression[];
|
|
369
|
+
} | {
|
|
370
|
+
kind: "Pick";
|
|
371
|
+
names: string[];
|
|
372
|
+
bounds: Bound[];
|
|
373
|
+
body: Expression;
|
|
374
|
+
} | {
|
|
375
|
+
kind: "Case";
|
|
376
|
+
expression: Expression;
|
|
377
|
+
} | {
|
|
378
|
+
kind: "Assert";
|
|
379
|
+
isSuffices: boolean;
|
|
380
|
+
statement: Expression | AssumeProve;
|
|
381
|
+
} | {
|
|
382
|
+
kind: "Qed";
|
|
383
|
+
};
|
|
384
|
+
interface ProofStep {
|
|
385
|
+
name: string | undefined;
|
|
386
|
+
body: StepBody;
|
|
387
|
+
proof: Proof | undefined;
|
|
388
|
+
location: SourceLocation;
|
|
389
|
+
}
|
|
390
|
+
interface Theorem {
|
|
391
|
+
name: string | undefined;
|
|
392
|
+
statement: Expression | AssumeProve;
|
|
393
|
+
proof: Proof | undefined;
|
|
394
|
+
location: SourceLocation;
|
|
302
395
|
}
|
|
303
396
|
interface Module {
|
|
304
397
|
name: string;
|
|
305
|
-
outer: OuterScope | undefined;
|
|
306
398
|
modules: Module[];
|
|
307
399
|
extends: string[];
|
|
308
400
|
constants: Declaration[];
|
|
309
|
-
variables:
|
|
401
|
+
variables: Declaration[];
|
|
310
402
|
definitions: Definition[];
|
|
311
403
|
instances: Instance[];
|
|
312
404
|
assumptions: Assumption[];
|
|
405
|
+
location: SourceLocation;
|
|
406
|
+
theorems: Theorem[];
|
|
407
|
+
uses: UseOrHide[];
|
|
313
408
|
}
|
|
314
409
|
type ConfigValue = {
|
|
315
410
|
kind: "Number";
|
|
@@ -351,10 +446,28 @@ interface ModelConfig {
|
|
|
351
446
|
checkDeadlock: boolean;
|
|
352
447
|
symmetry: string | undefined;
|
|
353
448
|
view: string | undefined;
|
|
449
|
+
alias: string | undefined;
|
|
354
450
|
postconditions: string[];
|
|
355
451
|
possible: string[];
|
|
452
|
+
periodic: string | undefined;
|
|
453
|
+
rlReward: string | undefined;
|
|
356
454
|
}
|
|
357
455
|
export declare const parseConfig: (source: string) => ModelConfig;
|
|
456
|
+
export declare class TlaError extends Error {
|
|
457
|
+
constructor(message: string, cause?: unknown);
|
|
458
|
+
}
|
|
459
|
+
export declare class TlaSyntaxError extends TlaError {
|
|
460
|
+
constructor(message: string, cause?: unknown);
|
|
461
|
+
}
|
|
462
|
+
export declare class TlaConfigError extends TlaError {
|
|
463
|
+
constructor(message: string, cause?: unknown);
|
|
464
|
+
}
|
|
465
|
+
export declare class TlaEvaluationError extends TlaError {
|
|
466
|
+
constructor(message: string, cause?: unknown);
|
|
467
|
+
}
|
|
468
|
+
export declare class TlaUnsupportedError extends TlaError {
|
|
469
|
+
constructor(message: string, cause?: unknown);
|
|
470
|
+
}
|
|
358
471
|
interface ModelValue {
|
|
359
472
|
kind: "ModelValue";
|
|
360
473
|
name: string;
|
|
@@ -365,12 +478,17 @@ interface SetValue {
|
|
|
365
478
|
hash: number;
|
|
366
479
|
fingerprint: number;
|
|
367
480
|
}
|
|
481
|
+
interface MixedSetValue {
|
|
482
|
+
kind: "MixedSet";
|
|
483
|
+
elements: Value[];
|
|
484
|
+
}
|
|
368
485
|
interface FunctionValue {
|
|
369
486
|
kind: "Function";
|
|
370
487
|
domain: Value[];
|
|
371
488
|
range: Value[];
|
|
372
489
|
hash: number;
|
|
373
490
|
fingerprint: number;
|
|
491
|
+
writtenKeys: Value[] | undefined;
|
|
374
492
|
}
|
|
375
493
|
interface IntervalValue {
|
|
376
494
|
kind: "Interval";
|
|
@@ -414,58 +532,76 @@ interface FilteredSetValue {
|
|
|
414
532
|
base: Value;
|
|
415
533
|
test: (element: Value) => boolean;
|
|
416
534
|
}
|
|
535
|
+
interface UnionValue {
|
|
536
|
+
kind: "Union";
|
|
537
|
+
base: Value;
|
|
538
|
+
}
|
|
539
|
+
interface LazyFunctionParameter {
|
|
540
|
+
name: string;
|
|
541
|
+
domain: Value;
|
|
542
|
+
}
|
|
543
|
+
interface LazyFunctionSource {
|
|
544
|
+
parameters: LazyFunctionParameter[];
|
|
545
|
+
body: string;
|
|
546
|
+
}
|
|
417
547
|
interface LazyFunctionValue {
|
|
418
548
|
kind: "LazyFunction";
|
|
419
549
|
domain: Value;
|
|
420
550
|
apply: (argument: Value) => Value;
|
|
551
|
+
source?: LazyFunctionSource;
|
|
421
552
|
}
|
|
422
|
-
type Value = boolean | number | string | ModelValue | SetValue | FunctionValue | IntervalValue | InfiniteSetValue | SubsetValue | FunctionSetValue | RecordSetValue | ProductSetValue | SequenceSetValue | SetOperationValue | FilteredSetValue | LazyFunctionValue;
|
|
423
|
-
export declare const formatValue: (value: Value,
|
|
553
|
+
type Value = boolean | number | string | ModelValue | SetValue | MixedSetValue | FunctionValue | IntervalValue | InfiniteSetValue | SubsetValue | FunctionSetValue | RecordSetValue | ProductSetValue | SequenceSetValue | SetOperationValue | FilteredSetValue | UnionValue | LazyFunctionValue;
|
|
554
|
+
export declare const formatValue: (value: Value, isStrict?: boolean, isNormalized?: boolean) => string;
|
|
424
555
|
interface CheckOptions {
|
|
425
556
|
source: string;
|
|
426
557
|
config: string | ModelConfig;
|
|
427
558
|
loadModule?: (name: string) => string | undefined;
|
|
559
|
+
loadClass?: (name: string) => Uint8Array | undefined;
|
|
428
560
|
onPrint?: (text: string) => void;
|
|
561
|
+
onPause?: () => void;
|
|
429
562
|
readFile?: (path: string) => string | undefined;
|
|
430
563
|
writeFile?: (path: string, content: string) => void;
|
|
564
|
+
seed?: bigint;
|
|
565
|
+
workers?: number;
|
|
566
|
+
livenessCheck?: "default" | "final";
|
|
431
567
|
}
|
|
432
|
-
type CheckStatus = "success" | "assumption-violation" | "invariant-violation" | "property-violation" | "liveness-violation" | "postcondition-violation" | "deadlock";
|
|
568
|
+
type CheckStatus = "success" | "assumption-violation" | "invariant-violation" | "property-violation" | "liveness-violation" | "postcondition-violation" | "deadlock" | "error";
|
|
433
569
|
interface TraceStep {
|
|
434
570
|
action: string | undefined;
|
|
571
|
+
label: string | undefined;
|
|
435
572
|
state: Record<string, Value>;
|
|
436
573
|
}
|
|
437
574
|
interface Violation {
|
|
438
575
|
name: string;
|
|
439
576
|
trace: TraceStep[];
|
|
440
577
|
loopStart: number | undefined;
|
|
578
|
+
loopLabel?: string;
|
|
441
579
|
message?: string;
|
|
580
|
+
counts?: string;
|
|
581
|
+
unwitnessed?: Postcondition;
|
|
582
|
+
}
|
|
583
|
+
interface Postcondition {
|
|
584
|
+
name: string;
|
|
585
|
+
message: string;
|
|
586
|
+
counts?: string;
|
|
587
|
+
}
|
|
588
|
+
interface EvaluationFailure {
|
|
589
|
+
message: string;
|
|
590
|
+
trace: TraceStep[];
|
|
591
|
+
initialState: Record<string, Value> | undefined;
|
|
592
|
+
exitCode: number;
|
|
442
593
|
}
|
|
443
594
|
interface CheckResult {
|
|
444
595
|
status: CheckStatus;
|
|
445
596
|
violation: Violation | undefined;
|
|
597
|
+
failure: EvaluationFailure | undefined;
|
|
446
598
|
generatedStates: number;
|
|
447
599
|
distinctStates: number;
|
|
600
|
+
queuedStates: number;
|
|
448
601
|
depth: number;
|
|
602
|
+
outDegrees: number[] | undefined;
|
|
603
|
+
fingerprintDistance: bigint | undefined;
|
|
449
604
|
}
|
|
450
|
-
export declare const check: (options: CheckOptions) => CheckResult
|
|
451
|
-
export declare class TlaError extends Error {
|
|
452
|
-
constructor(message: string, cause?: unknown);
|
|
453
|
-
}
|
|
454
|
-
export declare class TlaSyntaxError extends TlaError {
|
|
455
|
-
constructor(message: string, cause?: unknown);
|
|
456
|
-
}
|
|
457
|
-
export declare class TlaConfigError extends TlaError {
|
|
458
|
-
constructor(message: string, cause?: unknown);
|
|
459
|
-
}
|
|
460
|
-
export declare class TlaEvaluationError extends TlaError {
|
|
461
|
-
constructor(message: string, cause?: unknown);
|
|
462
|
-
}
|
|
463
|
-
export declare class TlaUnsupportedError extends TlaError {
|
|
464
|
-
constructor(message: string, cause?: unknown);
|
|
465
|
-
}
|
|
466
|
-
interface ParallelCheckOptions extends CheckOptions {
|
|
467
|
-
workers: number;
|
|
468
|
-
}
|
|
469
|
-
export declare const checkInParallel: (options: ParallelCheckOptions) => Promise<CheckResult>;
|
|
605
|
+
export declare const check: (options: CheckOptions) => Promise<CheckResult>;
|
|
470
606
|
export declare const parseModule: (source: string) => Module;
|
|
471
|
-
export type { CheckOptions, CheckResult, CheckStatus, ConfigValue, ConstantAssignment, ModelConfig, Module,
|
|
607
|
+
export type { CheckOptions, CheckResult, CheckStatus, ConfigValue, ConstantAssignment, EvaluationFailure, ModelConfig, Module, Substitution, TraceStep, Value, Violation };
|
package/dist/index.js
CHANGED
|
@@ -6,4 +6,4 @@
|
|
|
6
6
|
* This source code is licensed under the MIT license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
|
-
import{
|
|
9
|
+
import{A as e,D as t,E as n,O as r,S as i,_ as a,j as o,k as s}from"./transfer.js";import{t as c}from"./parallel.js";export{t as TlaConfigError,r as TlaError,s as TlaEvaluationError,e as TlaSyntaxError,o as TlaUnsupportedError,c as check,i as formatValue,n as parseConfig,a as parseModule};
|
package/dist/parallel-worker.cjs
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* This source code is licensed under the MIT license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
|
-
const e=require("./transfer.cjs"),t=e=>{let t=e.reduce((e,t)=>e+t,0),n=t/e.length;if(Math.max(...e)-Math.min(...e)<=Math.max(64,n/4))return[];let r=e.map((
|
|
9
|
+
const e=require("./transfer.cjs"),t=e=>{let t=e.reduce((e,t)=>e+t,0),n=t/e.length;if(Math.max(...e)-Math.min(...e)<=Math.max(64,n/4))return[];let r=e.map((r,i)=>Math.floor(n)+ +(i<t%e.length)),i=e.flatMap((e,t)=>e>r[t]?[{index:t,amount:e-r[t]}]:[]),a=e.flatMap((e,t)=>e<r[t]?[{index:t,amount:r[t]-e}]:[]),o=[];for(let e of i)for(let t of a){let n=Math.min(e.amount,t.amount);n!==0&&(o.push({from:e.index,to:t.index,count:n}),e.amount-=n,t.amount-=n)}return o},n=async()=>typeof globalThis.postMessage==`function`?globalThis:(await import(
|
|
10
10
|
/* @vite-ignore */
|
|
11
11
|
/* webpackIgnore: true */
|
|
12
|
-
`node:worker_threads`)).parentPort,r=()=>{let e=/* @__PURE__ */ new Map,t=/* @__PURE__ */ new Map,n=(e,t)=>`${e}:${t}`,r=n=>{let r=t.get(n),i=e.get(n)??[];!r||i.length<r.count||(t.delete(n),e.delete(n),r.resolve(i))};return{deliver:t=>{let i=n(t.phase,t.level);e.set(i,[...e.get(i)??[],t]),r(i)},receive:(e,i,a)=>new Promise(o=>{let s=n(e,i);t.set(s,{count:a,resolve:o}),r(s)})}},i=(n,i)=>{let a=new Map(n.modules),o=e.
|
|
12
|
+
`node:worker_threads`)).parentPort,r=()=>{let e=/* @__PURE__ */ new Map,t=/* @__PURE__ */ new Map,n=(e,t)=>`${e}:${t}`,r=n=>{let r=t.get(n),i=e.get(n)??[];!r||i.length<r.count||(t.delete(n),e.delete(n),r.resolve(i))};return{deliver:t=>{let i=n(t.phase,t.level);e.set(i,[...e.get(i)??[],t]),r(i)},receive:(e,i,a)=>new Promise(o=>{let s=n(e,i);t.set(s,{count:a,resolve:o}),r(s)})}},i=(n,i)=>{let a=new Map(n.modules),o=e=>a.get(e),s=new Map(n.classes);e.w(e.m(n.source,n.config,o));let c=e.C(),l=e.g(n.config,{source:n.source,loadModule:o,loadClass:e=>s.get(e),print:()=>{},files:{readFile:void 0,writeFile:void 0}}).environment,u=e.s(n.config,l,()=>e.h(n.source,o)),d=u?.spec.next;if(!u||d===void 0)return i.postMessage({type:`abort`});let f=n.count,p=n.index,m=e.x(),h=e.t(l.variables.length),g=e.r(),_=e.r(),v=/* @__PURE__ */ new Int32Array(2),y=r(),b=n.ports.flatMap((e,t)=>e?[{port:e,index:t}]:[]);b.forEach(e=>{e.port.addEventListener(`message`,e=>y.deliver(e.data)),e.port.start?.()});for(let e=0;e<n.seedFingerprints.length;e+=2)g.insert(n.seedFingerprints[e],n.seedFingerprints[e+1]);let x={states:h(n.seed).map(m)},S=(e,t,r)=>n.ports[e]?.postMessage(t,r),C=(t,r)=>{let i=Array.from({length:f},()=>({states:[],origins:[],fingerprints:[]})),a={generated:0},o=new Int32Array(t.length);for(let s=0;s<t.length;s++){let c=t[s],h=e.b(d,c,l,u.spec.scope);if(a.generated+=h.length,h.length===0&&n.config.checkDeadlock)return;for(let t of h){if(u.findViolatedActionProperty(c,t.state))return;if(!u.satisfiesActionConstraints(c,t.state))continue;m(t.state),e.a(u.getFingerprintState(t.state),v);let n=e.i(v[1],f);if(n===p){if(!g.insert(v[0],v[1]))continue;if(u.findViolatedInvariant(t.state,c))return;if(!u.satisfiesConstraints(t.state,c)){g.remove(v[0],v[1]);continue}r.push(t.state),o[s]++}else _.insert(v[0],v[1])&&(i[n].states.push(t.state),i[n].origins.push(s),i[n].fingerprints.push(v[0],v[1]))}}return{pending:i,generated:a.generated,newStates:o}},w=e=>{let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=+!!g.insert(e[n*2],e[n*2+1]);return t},T=(e,t,n,r)=>{let i=[];for(let a=0;a<t.length;a++){if(t[a]===0)continue;let o=e.states[a],s=x.states[e.origins[a]];if(u.findViolatedInvariant(o,s))return;u.satisfiesConstraints(o,s)?(n.push(o),r[e.origins[a]]++):(_.remove(e.fingerprints[a*2],e.fingerprints[a*2+1]),i.push(e.fingerprints[a*2],e.fingerprints[a*2+1]))}return Int32Array.from(i)},E=e=>{for(let t=0;t<e.length;t+=2)g.remove(e[t],e[t+1])},D=async(n,r,i)=>{let a=t(i);if(a.length===0)return!0;let o=new Map(b.map(t=>[t.index,e.n()]));for(let e of a.filter(e=>e.from===p)){let t=o.get(e.to),n=r.splice(r.length-e.count,e.count);if(!t||!n.every(t.encode))return!1}return o.forEach((e,t)=>{let r=e.finish();S(t,{phase:`balance`,level:n,from:p,states:r},[r.words.buffer])}),(await y.receive(`balance`,n,b.length)).forEach(e=>{e.states&&r.push(...h(e.states).map(m))}),!0},O=async t=>{let n=[],r=C(x.states,n);if(!r||e.C()!==c)return;b.forEach(e=>{let n=Int32Array.from(r.pending[e.index].fingerprints);S(e.index,{phase:`query`,level:t,from:p,fingerprints:n},[n.buffer])}),(await y.receive(`query`,t,b.length)).forEach(e=>{let n=w(e.fingerprints??[]);S(e.from,{phase:`answer`,level:t,from:p,bits:n},[n.buffer])});let i=await y.receive(`answer`,t,b.length);for(let e of i){let i=T(r.pending[e.from],e.bits??/* @__PURE__ */ new Uint8Array,n,r.newStates);if(!i)return;S(e.from,{phase:`sizes`,level:t,from:p,unmarks:i},[i.buffer])}let a=n.length,o=Array.from({length:32},()=>0);r.newStates.forEach(e=>o[Math.min(e,31)]++);let s=BigInt64Array.from(n,e=>l.runtime.getFingerprint(e)),u=Array.from({length:f},()=>0);if(u[p]=a,b.forEach(e=>S(e.index,{phase:`sizes`,level:t,from:p,size:a},[])),(await y.receive(`sizes`,t,b.length*2)).forEach(e=>{e.unmarks?E(e.unmarks):u[e.from]=e.size??0}),e.C()===c&&await D(t,n,u))return x.states=n,{type:`level`,level:t,generated:r.generated,added:a,outDegrees:o,fingerprints:s}},k=e=>i.postMessage(e,e.type===`level`?[e.fingerprints.buffer]:[]),A=e=>{O(e).then(e=>k(e??{type:`abort`}),()=>k({type:`abort`}))};i.addEventListener(`message`,e=>{let t=e.data;t.type===`level`&&A(t.level)}),k({type:`ready`})};n().then(e=>{let t=n=>{let r=n.data;if(r.type===`start`){e.removeEventListener?.(`message`,t);try{i(r,e)}catch{e.postMessage({type:`abort`})}}};e.addEventListener(`message`,t),e.start?.()});
|
package/dist/parallel-worker.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* This source code is licensed under the MIT license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
|
-
import{
|
|
9
|
+
import{C as e,a as t,b as n,g as r,h as i,i as a,m as o,n as s,r as c,s as l,t as u,w as d,x as f}from"./transfer.js";const p=e=>{let t=e.reduce((e,t)=>e+t,0),n=t/e.length;if(Math.max(...e)-Math.min(...e)<=Math.max(64,n/4))return[];let r=e.map((r,i)=>Math.floor(n)+ +(i<t%e.length)),i=e.flatMap((e,t)=>e>r[t]?[{index:t,amount:e-r[t]}]:[]),a=e.flatMap((e,t)=>e<r[t]?[{index:t,amount:r[t]-e}]:[]),o=[];for(let e of i)for(let t of a){let n=Math.min(e.amount,t.amount);n!==0&&(o.push({from:e.index,to:t.index,count:n}),e.amount-=n,t.amount-=n)}return o},m=async()=>typeof globalThis.postMessage==`function`?globalThis:(await import(
|
|
10
10
|
/* @vite-ignore */
|
|
11
11
|
/* webpackIgnore: true */
|
|
12
|
-
`node:worker_threads`)).parentPort,
|
|
12
|
+
`node:worker_threads`)).parentPort,h=()=>{let e=/* @__PURE__ */ new Map,t=/* @__PURE__ */ new Map,n=(e,t)=>`${e}:${t}`,r=n=>{let r=t.get(n),i=e.get(n)??[];!r||i.length<r.count||(t.delete(n),e.delete(n),r.resolve(i))};return{deliver:t=>{let i=n(t.phase,t.level);e.set(i,[...e.get(i)??[],t]),r(i)},receive:(e,i,a)=>new Promise(o=>{let s=n(e,i);t.set(s,{count:a,resolve:o}),r(s)})}},g=(m,g)=>{let _=new Map(m.modules),v=e=>_.get(e),y=new Map(m.classes);d(o(m.source,m.config,v));let b=e(),x=r(m.config,{source:m.source,loadModule:v,loadClass:e=>y.get(e),print:()=>{},files:{readFile:void 0,writeFile:void 0}}).environment,S=l(m.config,x,()=>i(m.source,v)),C=S?.spec.next;if(!S||C===void 0)return g.postMessage({type:`abort`});let w=m.count,T=m.index,E=f(),D=u(x.variables.length),O=c(),k=c(),A=/* @__PURE__ */ new Int32Array(2),j=h(),M=m.ports.flatMap((e,t)=>e?[{port:e,index:t}]:[]);M.forEach(e=>{e.port.addEventListener(`message`,e=>j.deliver(e.data)),e.port.start?.()});for(let e=0;e<m.seedFingerprints.length;e+=2)O.insert(m.seedFingerprints[e],m.seedFingerprints[e+1]);let N={states:D(m.seed).map(E)},P=(e,t,n)=>m.ports[e]?.postMessage(t,n),F=(e,r)=>{let i=Array.from({length:w},()=>({states:[],origins:[],fingerprints:[]})),o={generated:0},s=new Int32Array(e.length);for(let c=0;c<e.length;c++){let l=e[c],u=n(C,l,x,S.spec.scope);if(o.generated+=u.length,u.length===0&&m.config.checkDeadlock)return;for(let e of u){if(S.findViolatedActionProperty(l,e.state))return;if(!S.satisfiesActionConstraints(l,e.state))continue;E(e.state),t(S.getFingerprintState(e.state),A);let n=a(A[1],w);if(n===T){if(!O.insert(A[0],A[1]))continue;if(S.findViolatedInvariant(e.state,l))return;if(!S.satisfiesConstraints(e.state,l)){O.remove(A[0],A[1]);continue}r.push(e.state),s[c]++}else k.insert(A[0],A[1])&&(i[n].states.push(e.state),i[n].origins.push(c),i[n].fingerprints.push(A[0],A[1]))}}return{pending:i,generated:o.generated,newStates:s}},I=e=>{let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=+!!O.insert(e[n*2],e[n*2+1]);return t},L=(e,t,n,r)=>{let i=[];for(let a=0;a<t.length;a++){if(t[a]===0)continue;let o=e.states[a],s=N.states[e.origins[a]];if(S.findViolatedInvariant(o,s))return;S.satisfiesConstraints(o,s)?(n.push(o),r[e.origins[a]]++):(k.remove(e.fingerprints[a*2],e.fingerprints[a*2+1]),i.push(e.fingerprints[a*2],e.fingerprints[a*2+1]))}return Int32Array.from(i)},R=e=>{for(let t=0;t<e.length;t+=2)O.remove(e[t],e[t+1])},z=async(e,t,n)=>{let r=p(n);if(r.length===0)return!0;let i=new Map(M.map(e=>[e.index,s()]));for(let e of r.filter(e=>e.from===T)){let n=i.get(e.to),r=t.splice(t.length-e.count,e.count);if(!n||!r.every(n.encode))return!1}return i.forEach((t,n)=>{let r=t.finish();P(n,{phase:`balance`,level:e,from:T,states:r},[r.words.buffer])}),(await j.receive(`balance`,e,M.length)).forEach(e=>{e.states&&t.push(...D(e.states).map(E))}),!0},B=async t=>{let n=[],r=F(N.states,n);if(!r||e()!==b)return;M.forEach(e=>{let n=Int32Array.from(r.pending[e.index].fingerprints);P(e.index,{phase:`query`,level:t,from:T,fingerprints:n},[n.buffer])}),(await j.receive(`query`,t,M.length)).forEach(e=>{let n=I(e.fingerprints??[]);P(e.from,{phase:`answer`,level:t,from:T,bits:n},[n.buffer])});let i=await j.receive(`answer`,t,M.length);for(let e of i){let i=L(r.pending[e.from],e.bits??/* @__PURE__ */ new Uint8Array,n,r.newStates);if(!i)return;P(e.from,{phase:`sizes`,level:t,from:T,unmarks:i},[i.buffer])}let a=n.length,o=Array.from({length:32},()=>0);r.newStates.forEach(e=>o[Math.min(e,31)]++);let s=BigInt64Array.from(n,e=>x.runtime.getFingerprint(e)),c=Array.from({length:w},()=>0);if(c[T]=a,M.forEach(e=>P(e.index,{phase:`sizes`,level:t,from:T,size:a},[])),(await j.receive(`sizes`,t,M.length*2)).forEach(e=>{e.unmarks?R(e.unmarks):c[e.from]=e.size??0}),e()===b&&await z(t,n,c))return N.states=n,{type:`level`,level:t,generated:r.generated,added:a,outDegrees:o,fingerprints:s}},V=e=>g.postMessage(e,e.type===`level`?[e.fingerprints.buffer]:[]),H=e=>{B(e).then(e=>V(e??{type:`abort`}),()=>V({type:`abort`}))};g.addEventListener(`message`,e=>{let t=e.data;t.type===`level`&&H(t.level)}),V({type:`ready`})};m().then(e=>{let t=n=>{let r=n.data;if(r.type===`start`){e.removeEventListener?.(`message`,t);try{g(r,e)}catch{e.postMessage({type:`abort`})}}};e.addEventListener(`message`,t),e.start?.()});
|
package/dist/parallel.cjs
CHANGED
|
@@ -9,4 +9,4 @@
|
|
|
9
9
|
const e=require("./transfer.cjs"),t=async e=>{if(typeof Worker==`function`){let t=new Worker(new URL(`./parallel-worker.js`,require("url").pathToFileURL(__filename).href),{type:`module`});return t.addEventListener(`message`,t=>e(t.data)),t.addEventListener(`error`,()=>e({type:`abort`})),t}let t=new(await(import(
|
|
10
10
|
/* @vite-ignore */
|
|
11
11
|
/* webpackIgnore: true */
|
|
12
|
-
`node:worker_threads`))).Worker(new URL(`./parallel-worker.js`,require("url").pathToFileURL(__filename).href));return t.on(`message`,
|
|
12
|
+
`node:worker_threads`))).Worker(new URL(`./parallel-worker.js`,require("url").pathToFileURL(__filename).href));return t.on(`message`,e),t.on(`error`,()=>e({type:`abort`})),{postMessage:(e,n)=>t.postMessage(e,n),terminate:()=>void t.terminate()}},n=async n=>{let r=typeof n.config==`string`?e.E(n.config):n.config,i=()=>e.o({...n,config:r}),a=n.workers??1;if(a<2||r.view!==void 0||r.postconditions.length>0||r.possible.length>0)return i();let o=/* @__PURE__ */ new Map,s=e=>{let t=n.loadModule?.(e);return o.set(e,t),t},c=/* @__PURE__ */ new Map,l=e=>{let t=n.loadClass?.(e);return c.set(e,t),t};e.w(e.m(n.source,r,s));let u=e.C(),d=e.g(r,{source:n.source,loadModule:s,loadClass:l,print:n.onPrint??console.log,files:{readFile:n.readFile,writeFile:n.writeFile}}),f=d.environment,p=e.s(r,f,()=>e.h(n.source,s));if(e.c(d.assumptions,f)||!p||p.spec.init===void 0||p.spec.next===void 0||p.properties.liveness.length>0||e.v(f))return i();let m=e.x(),h=e.r(),g=/* @__PURE__ */ new Int32Array(2),_=Array.from({length:a},()=>({encoder:e.n(),fingerprints:[]})),v={generatedStates:0,distinctStates:0,queuedStates:0,depth:0,outDegrees:Array.from({length:32},()=>0)},y=[],b=()=>({status:`success`,violation:void 0,failure:void 0,...v,fingerprintDistance:e.d(v.distinctStates,v.generatedStates,()=>{let e=new BigInt64Array(v.distinctStates);return y.reduce((t,n)=>(e.set(n,t),t+n.length),0),e})}),x=t=>{let n=[];for(let r of e.y(t,f,p.spec.scope)){if(m(r),v.generatedStates++,e.a(p.getFingerprintState(r),g),!h.insert(g[0],g[1]))continue;if(p.findViolatedInvariant(r)||p.findFailedInitialPredicate(r))return!1;if(!p.satisfiesConstraints(r)){h.remove(g[0],g[1]);continue}let t=_[e.i(g[1],a)];if(!t.encoder.encode(r))return!1;t.fingerprints.push(g[0],g[1]),n.push(r),v.distinctStates++}return y.push(BigInt64Array.from(n,e=>f.runtime.getFingerprint(e))),!0};try{if(!x(p.spec.init))return i()}catch(t){if(!(t instanceof e.k))throw t;return i()}if(e.C()!==u)return i();if(v.depth=v.generatedStates===0?0:1,v.distinctStates===0)return b();let S=[],C={resolve:e=>{}},w=e=>{S.push(e),(e.type===`abort`||S.length===a)&&C.resolve(S.splice(0))},T=()=>new Promise(e=>{C.resolve=e}),E=T(),D=await Promise.all(Array.from({length:a},()=>t(w))),O=()=>D.forEach(e=>e.terminate()),k=/* @__PURE__ */ new Map,A=(e,t)=>{let n=e<t?`${e}:${t}`:`${t}:${e}`,r=k.get(n)??new MessageChannel;return k.set(n,r),e<t?r.port1:r.port2};D.forEach((e,t)=>{let i=Array.from({length:a},(e,n)=>n===t?void 0:A(t,n)),s=_[t].encoder.finish(),l=Int32Array.from(_[t].fingerprints),u={type:`start`,source:n.source,config:r,modules:[...o],classes:[...c],index:t,count:a,ports:i,seed:s,seedFingerprints:l};e.postMessage(u,[...i.filter(e=>e!==void 0),s.words.buffer,l.buffer])});let j=e=>e.some(e=>e.type===`abort`);if(j(await E))return O(),i();for(let e=1;;e++){let t=T();D.forEach(t=>t.postMessage({type:`level`,level:e}));let n=await t;if(j(n))return O(),i();let r=n.flatMap(e=>e.type===`level`?[e]:[]),a=r.reduce((e,t)=>e+t.added,0);if(v.generatedStates+=r.reduce((e,t)=>e+t.generated,0),v.distinctStates+=a,r.forEach(e=>{e.outDegrees.forEach((e,t)=>v.outDegrees[t]+=e),y.push(e.fingerprints)}),a===0)return O(),b();v.depth++}};Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return n}});
|
package/dist/parallel.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* This source code is licensed under the MIT license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
|
-
import{
|
|
9
|
+
import{C as e,E as t,a as n,c as r,d as i,g as a,h as o,i as s,k as c,m as l,n as u,o as d,r as f,s as p,v as m,w as h,x as g,y as _}from"./transfer.js";const v=async e=>{if(typeof Worker==`function`){let t=new Worker(new URL(`./parallel-worker.js`,import.meta.url),{type:`module`});return t.addEventListener(`message`,t=>e(t.data)),t.addEventListener(`error`,()=>e({type:`abort`})),t}let t=new(await(import(
|
|
10
10
|
/* @vite-ignore */
|
|
11
11
|
/* webpackIgnore: true */
|
|
12
|
-
`node:worker_threads`))).Worker(new URL(`./parallel-worker.js`,import.meta.url));return t.on(`message`,
|
|
12
|
+
`node:worker_threads`))).Worker(new URL(`./parallel-worker.js`,import.meta.url));return t.on(`message`,e),t.on(`error`,()=>e({type:`abort`})),{postMessage:(e,n)=>t.postMessage(e,n),terminate:()=>void t.terminate()}},y=async y=>{let b=typeof y.config==`string`?t(y.config):y.config,x=()=>d({...y,config:b}),S=y.workers??1;if(S<2||b.view!==void 0||b.postconditions.length>0||b.possible.length>0)return x();let C=/* @__PURE__ */ new Map,w=e=>{let t=y.loadModule?.(e);return C.set(e,t),t},T=/* @__PURE__ */ new Map,E=e=>{let t=y.loadClass?.(e);return T.set(e,t),t};h(l(y.source,b,w));let D=e(),O=a(b,{source:y.source,loadModule:w,loadClass:E,print:y.onPrint??console.log,files:{readFile:y.readFile,writeFile:y.writeFile}}),k=O.environment,A=p(b,k,()=>o(y.source,w));if(r(O.assumptions,k)||!A||A.spec.init===void 0||A.spec.next===void 0||A.properties.liveness.length>0||m(k))return x();let j=g(),M=f(),N=/* @__PURE__ */ new Int32Array(2),P=Array.from({length:S},()=>({encoder:u(),fingerprints:[]})),F={generatedStates:0,distinctStates:0,queuedStates:0,depth:0,outDegrees:Array.from({length:32},()=>0)},I=[],L=()=>({status:`success`,violation:void 0,failure:void 0,...F,fingerprintDistance:i(F.distinctStates,F.generatedStates,()=>{let e=new BigInt64Array(F.distinctStates);return I.reduce((t,n)=>(e.set(n,t),t+n.length),0),e})}),R=e=>{let t=[];for(let r of _(e,k,A.spec.scope)){if(j(r),F.generatedStates++,n(A.getFingerprintState(r),N),!M.insert(N[0],N[1]))continue;if(A.findViolatedInvariant(r)||A.findFailedInitialPredicate(r))return!1;if(!A.satisfiesConstraints(r)){M.remove(N[0],N[1]);continue}let e=P[s(N[1],S)];if(!e.encoder.encode(r))return!1;e.fingerprints.push(N[0],N[1]),t.push(r),F.distinctStates++}return I.push(BigInt64Array.from(t,e=>k.runtime.getFingerprint(e))),!0};try{if(!R(A.spec.init))return x()}catch(e){if(!(e instanceof c))throw e;return x()}if(e()!==D)return x();if(F.depth=F.generatedStates===0?0:1,F.distinctStates===0)return L();let z=[],B={resolve:e=>{}},V=e=>{z.push(e),(e.type===`abort`||z.length===S)&&B.resolve(z.splice(0))},H=()=>new Promise(e=>{B.resolve=e}),U=H(),W=await Promise.all(Array.from({length:S},()=>v(V))),G=()=>W.forEach(e=>e.terminate()),K=/* @__PURE__ */ new Map,q=(e,t)=>{let n=e<t?`${e}:${t}`:`${t}:${e}`,r=K.get(n)??new MessageChannel;return K.set(n,r),e<t?r.port1:r.port2};W.forEach((e,t)=>{let n=Array.from({length:S},(e,n)=>n===t?void 0:q(t,n)),r=P[t].encoder.finish(),i=Int32Array.from(P[t].fingerprints),a={type:`start`,source:y.source,config:b,modules:[...C],classes:[...T],index:t,count:S,ports:n,seed:r,seedFingerprints:i};e.postMessage(a,[...n.filter(e=>e!==void 0),r.words.buffer,i.buffer])});let J=e=>e.some(e=>e.type===`abort`);if(J(await U))return G(),x();for(let e=1;;e++){let t=H();W.forEach(t=>t.postMessage({type:`level`,level:e}));let n=await t;if(J(n))return G(),x();let r=n.flatMap(e=>e.type===`level`?[e]:[]),i=r.reduce((e,t)=>e+t.added,0);if(F.generatedStates+=r.reduce((e,t)=>e+t.generated,0),F.distinctStates+=i,r.forEach(e=>{e.outDegrees.forEach((e,t)=>F.outDegrees[t]+=e),I.push(e.fingerprints)}),i===0)return G(),L();F.depth++}};export{y as t};
|
package/dist/run-cli.cjs
CHANGED
|
@@ -6,4 +6,5 @@
|
|
|
6
6
|
* This source code is licensed under the MIT license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
|
-
const e=require("./transfer.cjs"),t=require("./parallel.cjs");let n=require("node:fs"),r=require("node:path"),i=require("node:os");const a={success:
|
|
9
|
+
const e=require("./transfer.cjs"),t=require("./parallel.cjs");let n=require("node:fs"),r=require("node:path"),i=require("node:os");const a={success:e.N.success,"assumption-violation":e.N.assumptionViolation,deadlock:e.N.deadlock,"invariant-violation":e.N.safetyViolation,"property-violation":e.N.safetyViolation,"liveness-violation":e.N.livenessViolation,"postcondition-violation":e.N.assumptionViolation,error:e.N.error},o=e=>/^[+-]?\d+$/.test(e)&&BigInt.asIntN(64,BigInt(e))===BigInt(e),s=e=>{let t=e.indexOf(`-workers`);if(t===-1)return 1;let n=e[t+1];return n===`auto`?(0,i.availableParallelism)():Math.max(1,Number.parseInt(n,10)||1)},c=t=>{let n=Object.entries(t);n.forEach(([t,r])=>console.log(`${n.length===1?``:`/\\ `}${t} = ${e.T(e.S(r))}`)),console.log(``)},l=(e,t=`Error: The behavior up to this point is:`)=>{e.length>0&&console.log(t),e.forEach((e,t)=>{console.log(`State ${t+1}: <${e.label??e.action??`Initial predicate`}>`),c(e.state)})},u=t=>{if(t.failure)console.log(`Error: ${t.failure.message}`),t.failure.initialState&&(console.log(`While working on the initial state:`),c(t.failure.initialState)),l(t.failure.trace);else if(t.violation){let e=t.violation,n=e.name,r=e.loopStart,i=r===void 0&&e.trace.length===1&&(t.status===`invariant-violation`||t.status===`liveness-violation`),a={success:``,error:``,"assumption-violation":e.message?`Error: Evaluating assumption ${n} failed.\n${e.message}`:`Error: Assumption ${n} is false.`,deadlock:`Error: Deadlock reached.`,"invariant-violation":i?`Error: Invariant ${n} is violated by the initial state:`:`Error: Invariant ${n} is violated.`,"property-violation":`Error: Property ${n} is violated.`,"liveness-violation":r===void 0?i?`Error: Property ${n} is violated by the initial state:`:`Error: Action property ${n} is violated.`:`Error: Temporal property ${n} was violated.\n`,"postcondition-violation":`Error: ${e.message??`Postcondition ${n} is false.`}`}[t.status];if(e.counts&&console.log(e.counts),console.log(a),i)c(e.trace[0].state);else if(r===void 0)l(e.trace);else{l(e.trace,`Error: The following behavior constitutes a counter-example:
|
|
10
|
+
`);let t=r===e.trace.length-1;console.log(t?`State ${r+2}: Stuttering`:`Back to state ${r+1}${e.loopLabel?`: <${e.loopLabel}>\n`:``}`)}let o=e.unwitnessed;if(o?.counts&&console.log(o.counts),o&&console.log(`Error: ${o.message}`),i||t.status===`assumption-violation`)return}else{let n=e.f(t.distinctStates,t.generatedStates);if(console.log(`Model checking completed. No error has been found.`),console.log(` Estimates of the probability that TLC did not check all reachable states`),console.log(` because two distinct states had the same fingerprint:`),console.log(` calculated (optimistic): val = ${e.l(n)}`),t.fingerprintDistance!==void 0){let n=e.u(t.fingerprintDistance);console.log(` based on the actual fingerprints: val = ${e.l(n)}`)}}console.log(`${t.generatedStates} states generated, ${t.distinctStates} distinct states found, ${t.queuedStates} states left on queue.`),console.log(`The depth of the complete state graph search is ${t.depth}.`);let n=t.outDegrees&&e.p(t.outDegrees);n&&console.log(n)},d=async i=>{let c=i.find((e,t)=>e.endsWith(`.tla`)&&i[t-1]!==`-config`);if(!c)return console.error(`Usage: tla-ts <Spec.tla> [-config <Spec.cfg>] [-deadlock] [-lncheck <final|default>] [-seed <num>] [-workers <count|auto>]`),1;if(!(0,n.existsSync)(c))return console.error(`Cannot find the specification file ${c}`),e.N.configParseError;let l=i.indexOf(`-config`),d=l===-1?c.replace(/\.tla$/,`.cfg`):i[l+1];if(!d||!(0,n.existsSync)(d))return console.error(`Cannot find the configuration file ${d??``}`),e.N.configParseError;let f=e.E((0,n.readFileSync)(d,`utf8`));i.includes(`-deadlock`)&&(f.checkDeadlock=!1);let p=i.indexOf(`-seed`),m=p===-1?`0`:i[p+1];if(m===void 0)return console.error(`Error: seed required.`),1;if(!o(m))return console.error(`Error: An integer for seed required. But encountered ${m}`),1;let h=i.indexOf(`-lncheck`),g=h===-1?`default`:i[h+1]?.toLowerCase();if(g===void 0)return console.error(`Error: expect a strategy such as final for -lncheck option.`),1;let _=(0,r.dirname)(c);console.log(`Checking ${(0,r.basename)(c)} with ${(0,r.basename)(d)}`);let v=await t.t({workers:s(i),livenessCheck:[`final`,`seqfinal`,`off`].includes(g)?`final`:`default`,seed:BigInt(m),source:(0,n.readFileSync)(c,`utf8`),config:f,onPause:()=>(0,n.readSync)(0,Buffer.alloc(1)),loadModule:e=>{let t=(0,r.join)(_,`${e}.tla`);return(0,n.existsSync)(t)?(0,n.readFileSync)(t,`utf8`):void 0},loadClass:e=>{let t=(0,r.join)(_,`${e}.class`);return(0,n.existsSync)(t)?(0,n.readFileSync)(t):void 0},readFile:e=>(0,n.existsSync)(e)?(0,n.readFileSync)(e,`utf8`):void 0,writeFile:(e,t)=>{(0,n.mkdirSync)((0,r.dirname)((0,r.resolve)(e)),{recursive:!0}),(0,n.writeFileSync)(e,t)}});return u(v),v.failure?.exitCode??a[v.status]},f=t=>{if(t instanceof e.D||t instanceof e.k)return console.log(`Error: ${t.message}`);console.error(`${t.name}: ${t.message}`)},p=async()=>{try{process.exitCode=await d(process.argv.slice(2))}catch(t){if(!(t instanceof e.O))throw t;f(t),process.exitCode=e.M(t)}};exports.runCli=p;
|
package/dist/run-cli.js
CHANGED
|
@@ -6,4 +6,5 @@
|
|
|
6
6
|
* This source code is licensed under the MIT license found in the
|
|
7
7
|
* LICENSE file in the root directory of this source tree.
|
|
8
8
|
*/
|
|
9
|
-
import{
|
|
9
|
+
import{D as e,E as t,M as n,N as r,O as i,S as a,T as o,f as s,k as c,l,p as u,u as d}from"./transfer.js";import{t as f}from"./parallel.js";import{existsSync as p,mkdirSync as m,readFileSync as h,readSync as g,writeFileSync as _}from"node:fs";import{basename as v,dirname as y,join as b,resolve as x}from"node:path";import{availableParallelism as S}from"node:os";const C={success:r.success,"assumption-violation":r.assumptionViolation,deadlock:r.deadlock,"invariant-violation":r.safetyViolation,"property-violation":r.safetyViolation,"liveness-violation":r.livenessViolation,"postcondition-violation":r.assumptionViolation,error:r.error},w=e=>/^[+-]?\d+$/.test(e)&&BigInt.asIntN(64,BigInt(e))===BigInt(e),T=e=>{let t=e.indexOf(`-workers`);if(t===-1)return 1;let n=e[t+1];return n===`auto`?S():Math.max(1,Number.parseInt(n,10)||1)},E=e=>{let t=Object.entries(e);t.forEach(([e,n])=>console.log(`${t.length===1?``:`/\\ `}${e} = ${o(a(n))}`)),console.log(``)},D=(e,t=`Error: The behavior up to this point is:`)=>{e.length>0&&console.log(t),e.forEach((e,t)=>{console.log(`State ${t+1}: <${e.label??e.action??`Initial predicate`}>`),E(e.state)})},O=e=>{if(e.failure)console.log(`Error: ${e.failure.message}`),e.failure.initialState&&(console.log(`While working on the initial state:`),E(e.failure.initialState)),D(e.failure.trace);else if(e.violation){let t=e.violation,n=t.name,r=t.loopStart,i=r===void 0&&t.trace.length===1&&(e.status===`invariant-violation`||e.status===`liveness-violation`),a={success:``,error:``,"assumption-violation":t.message?`Error: Evaluating assumption ${n} failed.\n${t.message}`:`Error: Assumption ${n} is false.`,deadlock:`Error: Deadlock reached.`,"invariant-violation":i?`Error: Invariant ${n} is violated by the initial state:`:`Error: Invariant ${n} is violated.`,"property-violation":`Error: Property ${n} is violated.`,"liveness-violation":r===void 0?i?`Error: Property ${n} is violated by the initial state:`:`Error: Action property ${n} is violated.`:`Error: Temporal property ${n} was violated.\n`,"postcondition-violation":`Error: ${t.message??`Postcondition ${n} is false.`}`}[e.status];if(t.counts&&console.log(t.counts),console.log(a),i)E(t.trace[0].state);else if(r===void 0)D(t.trace);else{D(t.trace,`Error: The following behavior constitutes a counter-example:
|
|
10
|
+
`);let e=r===t.trace.length-1;console.log(e?`State ${r+2}: Stuttering`:`Back to state ${r+1}${t.loopLabel?`: <${t.loopLabel}>\n`:``}`)}let o=t.unwitnessed;if(o?.counts&&console.log(o.counts),o&&console.log(`Error: ${o.message}`),i||e.status===`assumption-violation`)return}else{let t=s(e.distinctStates,e.generatedStates);if(console.log(`Model checking completed. No error has been found.`),console.log(` Estimates of the probability that TLC did not check all reachable states`),console.log(` because two distinct states had the same fingerprint:`),console.log(` calculated (optimistic): val = ${l(t)}`),e.fingerprintDistance!==void 0){let t=d(e.fingerprintDistance);console.log(` based on the actual fingerprints: val = ${l(t)}`)}}console.log(`${e.generatedStates} states generated, ${e.distinctStates} distinct states found, ${e.queuedStates} states left on queue.`),console.log(`The depth of the complete state graph search is ${e.depth}.`);let t=e.outDegrees&&u(e.outDegrees);t&&console.log(t)},k=async e=>{let n=e.find((t,n)=>t.endsWith(`.tla`)&&e[n-1]!==`-config`);if(!n)return console.error(`Usage: tla-ts <Spec.tla> [-config <Spec.cfg>] [-deadlock] [-lncheck <final|default>] [-seed <num>] [-workers <count|auto>]`),1;if(!p(n))return console.error(`Cannot find the specification file ${n}`),r.configParseError;let i=e.indexOf(`-config`),a=i===-1?n.replace(/\.tla$/,`.cfg`):e[i+1];if(!a||!p(a))return console.error(`Cannot find the configuration file ${a??``}`),r.configParseError;let o=t(h(a,`utf8`));e.includes(`-deadlock`)&&(o.checkDeadlock=!1);let s=e.indexOf(`-seed`),c=s===-1?`0`:e[s+1];if(c===void 0)return console.error(`Error: seed required.`),1;if(!w(c))return console.error(`Error: An integer for seed required. But encountered ${c}`),1;let l=e.indexOf(`-lncheck`),u=l===-1?`default`:e[l+1]?.toLowerCase();if(u===void 0)return console.error(`Error: expect a strategy such as final for -lncheck option.`),1;let d=y(n);console.log(`Checking ${v(n)} with ${v(a)}`);let S=await f({workers:T(e),livenessCheck:[`final`,`seqfinal`,`off`].includes(u)?`final`:`default`,seed:BigInt(c),source:h(n,`utf8`),config:o,onPause:()=>g(0,Buffer.alloc(1)),loadModule:e=>{let t=b(d,`${e}.tla`);return p(t)?h(t,`utf8`):void 0},loadClass:e=>{let t=b(d,`${e}.class`);return p(t)?h(t):void 0},readFile:e=>p(e)?h(e,`utf8`):void 0,writeFile:(e,t)=>{m(y(x(e)),{recursive:!0}),_(e,t)}});return O(S),S.failure?.exitCode??C[S.status]},A=t=>{if(t instanceof e||t instanceof c)return console.log(`Error: ${t.message}`);console.error(`${t.name}: ${t.message}`)},j=async()=>{try{process.exitCode=await k(process.argv.slice(2))}catch(e){if(!(e instanceof i))throw e;A(e),process.exitCode=n(e)}};export{j as runCli};
|