tla-ts 0.0.2 → 0.0.3-dev.763cc71

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 CHANGED
@@ -3,9 +3,9 @@
3
3
  [![version](https://img.shields.io/npm/v/tla-ts?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/tla-ts)
4
4
  [![downloads](https://img.shields.io/npm/dt/tla-ts.svg?style=flat&colorA=000000&colorB=000000)](https://npmjs.com/package/tla-ts)
5
5
 
6
- A TLA+ model checker in TypeScript, **2× faster than TLC**.
6
+ tla-ts is a drop-in replacement for [TLC](https://github.com/tlaplus/tlaplus) that's **2× faster**.
7
7
 
8
- tla-ts checks TLA+ specs with the same verdicts, error traces, and state counts as TLC. It runs in Node and in the browser without a JVM. Try it in the [playground](https://tla-ts.aidenybai.com).
8
+ TLA+ lets you write formal models of a system, and TLC model checks them. But TLC is written in Java and needs the JVM. tla-ts runs anywhere JavaScript runs, such as the browser, Node, and Bun. Try it in the [playground](https://tla-ts.aidenybai.com).
9
9
 
10
10
  ```ts
11
11
  import { check } from "tla-ts";
@@ -30,19 +30,65 @@ result.status; // "invariant-violation"
30
30
  npm install tla-ts
31
31
  ```
32
32
 
33
- ## Usage
33
+ ## Command line
34
+
35
+ The `tla-ts` command takes TLC's options and prints TLC's output. `tla-ts prove` takes tlapm's options and prints tlapm's output.
36
+
37
+ ### Check a spec
38
+
39
+ To check a spec, pass its path:
34
40
 
35
41
  ```shell
36
- npx tla-ts Spec.tla [-config Spec.cfg] [-deadlock] [-lncheck final] [-seed 0] [-workers auto]
42
+ npx tla-ts Spec.tla
37
43
  ```
38
44
 
39
- - `-config`: the TLC configuration. Defaults to `Spec.cfg` next to the spec.
40
- - `-deadlock`: turns off deadlock checking.
41
- - `-lncheck final`: checks liveness once, after the search.
42
- - `-seed`: seeds `RandomElement` and the Randomization module. Defaults to 0.
43
- - `-workers`: the number of worker threads, or `auto` for one per core. Defaults to 1.
45
+ tla-ts reads the configuration from `Spec.cfg` next to the spec. It exits with the exit code TLC uses for the same result.
46
+
47
+ You can pass several paths, or a glob such as `"specs/*.tla"`. tla-ts checks each spec in turn and exits with the exit code of the first spec that fails. A glob skips each module that has no `.cfg` next to it, so it doesn't check helper modules that other specs import. tla-ts never skips a path that you pass by name. If you pass a `.cfg` path, tla-ts checks the `.tla` file with the same name.
48
+
49
+ The options are:
50
+
51
+ - `-config <Spec.cfg>`: read the configuration from this file. You can use it only when you check one spec.
52
+ - `-deadlock`: don't report deadlocks.
53
+ - `-lncheck final`: check liveness once, after the search ends.
54
+ - `-seed <num>`: seed `RandomElement` and the `Randomization` module. The default is 0.
55
+ - `-workers <count|auto>`: search with this number of worker threads. `auto` uses one thread per core. The default is 1.
56
+
57
+ TLC can replace a module's operators with Java methods, and tla-ts reads the same files. If the spec's directory has `Module.class`, tla-ts replaces each operator in `Module` with the public static method that has the same name and arity.
58
+
59
+ ### Generate proof obligations
60
+
61
+ A proof obligation is one claim that a backend prover must prove. `tla-ts prove -N` prints the obligations of a module, as `tlapm -N` does. It doesn't run a prover. For example, this command prints every obligation in `Module.tla` with its text:
62
+
63
+ ```shell
64
+ npx tla-ts prove -N --toolbox 0 0 --printallobs Module.tla
65
+ ```
66
+
67
+ With `--toolbox` or `--line`, tla-ts writes the messages of the TLA+ Toolbox protocol to stderr, as tlapm does. If you pass a tlapm option that isn't in this list, tla-ts prints an error:
68
+
69
+ - `--toolbox <start> <end>`: print Toolbox messages for the proofs from line `start` to line `end`. `0 0` selects the whole module.
70
+ - `--line <num>`: print Toolbox messages for the proof at this line.
71
+ - `--printallobs`: print the text of each obligation.
72
+ - `--summary`: print the number of obligations in each module, and list its missing and omitted proofs. You don't need `-N` with `--summary`.
73
+ - `--strict`: report missing proofs, omitted proofs and a selected range with no obligations as errors.
74
+ - `-I <directory>`: search this directory for modules.
75
+
76
+ tla-ts searches for modules in the same order as tlapm:
77
+
78
+ 1. The directory of each module you pass, the last one first.
79
+ 2. The current directory.
80
+ 3. The standard library of tlapm, which has the `TLAPS` module. tla-ts searches it only if `tlapm` is on your `PATH`.
81
+ 4. The `-I` directories, the last one first.
82
+
83
+ ### Prove with tlapm
84
+
85
+ tla-ts doesn't include a prover. Without `-N` or `--summary`, `tla-ts prove` runs [tlapm](https://github.com/tlaplus/tlapm) from your `PATH`:
86
+
87
+ ```shell
88
+ npx tla-ts prove Module.tla
89
+ ```
44
90
 
45
- Output and exit codes match TLC's. The CLI loads a compiled Java class such as `Module.class` from the spec's directory as an override for that module.
91
+ tla-ts expands the globs and passes every argument to tlapm, so all of tlapm's options work. tlapm sends the obligations to its provers, and tla-ts exits with the exit code of tlapm. If `tlapm` isn't on your `PATH`, tla-ts prints an error and exits with code 1.
46
92
 
47
93
  ## API reference
48
94
 
package/dist/index.cjs 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
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./transfer.cjs"),t=require("./parallel.cjs");exports.TlaConfigError=e.D,exports.TlaError=e.O,exports.TlaEvaluationError=e.k,exports.TlaSyntaxError=e.A,exports.TlaUnsupportedError=e.j,exports.check=t.t,exports.formatValue=e.S,exports.parseConfig=e.E,exports.parseModule=e._;
9
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./transfer.cjs"),t=require("./parallel.cjs");exports.TlaConfigError=e.k,exports.TlaError=e.A,exports.TlaEvaluationError=e.j,exports.TlaSyntaxError=e.N,exports.TlaUnsupportedError=e.P,exports.check=t.t,exports.formatValue=e.C,exports.parseConfig=e.D,exports.parseModule=e._;
package/dist/index.d.cts CHANGED
@@ -45,6 +45,7 @@ interface ApplyExpression {
45
45
  kind: "Apply";
46
46
  operator: string;
47
47
  args: Expression[];
48
+ argumentCounts?: number[];
48
49
  location: SourceLocation;
49
50
  resolution?: LocalResolution;
50
51
  }
@@ -62,6 +63,7 @@ interface LambdaExpression {
62
63
  interface JunctionExpression {
63
64
  kind: "And" | "Or";
64
65
  operands: Expression[];
66
+ isBulleted?: boolean;
65
67
  location: SourceLocation;
66
68
  }
67
69
  interface PrimeExpression {
@@ -122,6 +124,7 @@ interface QuantifierExpression {
122
124
  }
123
125
  interface UnboundedQuantifierExpression {
124
126
  kind: "UnboundedQuantifier";
127
+ quantifier: "Forall" | "Exists";
125
128
  names: string[];
126
129
  isTemporal?: boolean;
127
130
  body: Expression;
@@ -265,6 +268,7 @@ type Expression = NumberExpression | DecimalExpression | StringExpression | Iden
265
268
  interface OperatorParam {
266
269
  name: string;
267
270
  arity: number;
271
+ location?: SourceLocation;
268
272
  }
269
273
  interface OperatorDefinition {
270
274
  kind: "Operator";
@@ -309,6 +313,8 @@ interface Instance {
309
313
  substitutions: InstanceSubstitution[];
310
314
  isLocal: boolean;
311
315
  location: SourceLocation;
316
+ instanceRange: SourceRange;
317
+ definitionRange?: SourceRange;
312
318
  }
313
319
  interface NewSymbol {
314
320
  kind: "NewSymbol";
@@ -334,16 +340,19 @@ interface UseOrHide {
334
340
  isOnly: boolean;
335
341
  facts: Fact[];
336
342
  defs: Fact[];
343
+ keyword: SourceRange;
337
344
  location: SourceLocation;
338
345
  }
339
346
  type Proof = {
340
347
  kind: "Obvious" | "Omitted";
348
+ keyword: SourceRange;
341
349
  location: SourceLocation;
342
350
  } | {
343
351
  kind: "By";
344
352
  isOnly: boolean;
345
353
  facts: Fact[];
346
354
  defs: Fact[];
355
+ keyword: SourceRange;
347
356
  location: SourceLocation;
348
357
  } | {
349
358
  kind: "Steps";
@@ -383,7 +392,9 @@ type StepBody = UseOrHide | Instance | DefineStep | {
383
392
  };
384
393
  interface ProofStep {
385
394
  name: string | undefined;
395
+ token: string;
386
396
  body: StepBody;
397
+ head: SourceRange;
387
398
  proof: Proof | undefined;
388
399
  location: SourceLocation;
389
400
  }
@@ -393,10 +404,39 @@ interface Theorem {
393
404
  proof: Proof | undefined;
394
405
  location: SourceLocation;
395
406
  }
407
+ type ModuleUnit = {
408
+ kind: "Constants";
409
+ declarations: Declaration[];
410
+ } | {
411
+ kind: "Variables";
412
+ declarations: Declaration[];
413
+ } | {
414
+ kind: "Recursive";
415
+ declarations: Declaration[];
416
+ } | {
417
+ kind: "Definition";
418
+ definition: Definition;
419
+ } | {
420
+ kind: "Instance";
421
+ instance: Instance;
422
+ } | {
423
+ kind: "Assumption";
424
+ assumption: Assumption;
425
+ } | {
426
+ kind: "Theorem";
427
+ theorem: Theorem;
428
+ } | {
429
+ kind: "Use";
430
+ use: UseOrHide;
431
+ } | {
432
+ kind: "Module";
433
+ module: Module;
434
+ };
396
435
  interface Module {
397
436
  name: string;
398
437
  modules: Module[];
399
438
  extends: string[];
439
+ extendsRanges: SourceRange[];
400
440
  constants: Declaration[];
401
441
  variables: Declaration[];
402
442
  definitions: Definition[];
@@ -405,6 +445,7 @@ interface Module {
405
445
  location: SourceLocation;
406
446
  theorems: Theorem[];
407
447
  uses: UseOrHide[];
448
+ units: ModuleUnit[];
408
449
  }
409
450
  type ConfigValue = {
410
451
  kind: "Number";
@@ -456,8 +497,15 @@ export declare const parseConfig: (source: string) => ModelConfig;
456
497
  export declare class TlaError extends Error {
457
498
  constructor(message: string, cause?: unknown);
458
499
  }
500
+ interface SyntaxFailure {
501
+ reason: string;
502
+ line: number;
503
+ column: number;
504
+ isEnd: boolean;
505
+ }
459
506
  export declare class TlaSyntaxError extends TlaError {
460
- constructor(message: string, cause?: unknown);
507
+ failure: SyntaxFailure | undefined;
508
+ constructor(message: string, cause?: unknown, failure?: SyntaxFailure);
461
509
  }
462
510
  export declare class TlaConfigError extends TlaError {
463
511
  constructor(message: string, cause?: unknown);
@@ -471,6 +519,7 @@ export declare class TlaUnsupportedError extends TlaError {
471
519
  interface ModelValue {
472
520
  kind: "ModelValue";
473
521
  name: string;
522
+ type: string | undefined;
474
523
  }
475
524
  interface SetValue {
476
525
  kind: "Set";
package/dist/index.d.ts CHANGED
@@ -45,6 +45,7 @@ interface ApplyExpression {
45
45
  kind: "Apply";
46
46
  operator: string;
47
47
  args: Expression[];
48
+ argumentCounts?: number[];
48
49
  location: SourceLocation;
49
50
  resolution?: LocalResolution;
50
51
  }
@@ -62,6 +63,7 @@ interface LambdaExpression {
62
63
  interface JunctionExpression {
63
64
  kind: "And" | "Or";
64
65
  operands: Expression[];
66
+ isBulleted?: boolean;
65
67
  location: SourceLocation;
66
68
  }
67
69
  interface PrimeExpression {
@@ -122,6 +124,7 @@ interface QuantifierExpression {
122
124
  }
123
125
  interface UnboundedQuantifierExpression {
124
126
  kind: "UnboundedQuantifier";
127
+ quantifier: "Forall" | "Exists";
125
128
  names: string[];
126
129
  isTemporal?: boolean;
127
130
  body: Expression;
@@ -265,6 +268,7 @@ type Expression = NumberExpression | DecimalExpression | StringExpression | Iden
265
268
  interface OperatorParam {
266
269
  name: string;
267
270
  arity: number;
271
+ location?: SourceLocation;
268
272
  }
269
273
  interface OperatorDefinition {
270
274
  kind: "Operator";
@@ -309,6 +313,8 @@ interface Instance {
309
313
  substitutions: InstanceSubstitution[];
310
314
  isLocal: boolean;
311
315
  location: SourceLocation;
316
+ instanceRange: SourceRange;
317
+ definitionRange?: SourceRange;
312
318
  }
313
319
  interface NewSymbol {
314
320
  kind: "NewSymbol";
@@ -334,16 +340,19 @@ interface UseOrHide {
334
340
  isOnly: boolean;
335
341
  facts: Fact[];
336
342
  defs: Fact[];
343
+ keyword: SourceRange;
337
344
  location: SourceLocation;
338
345
  }
339
346
  type Proof = {
340
347
  kind: "Obvious" | "Omitted";
348
+ keyword: SourceRange;
341
349
  location: SourceLocation;
342
350
  } | {
343
351
  kind: "By";
344
352
  isOnly: boolean;
345
353
  facts: Fact[];
346
354
  defs: Fact[];
355
+ keyword: SourceRange;
347
356
  location: SourceLocation;
348
357
  } | {
349
358
  kind: "Steps";
@@ -383,7 +392,9 @@ type StepBody = UseOrHide | Instance | DefineStep | {
383
392
  };
384
393
  interface ProofStep {
385
394
  name: string | undefined;
395
+ token: string;
386
396
  body: StepBody;
397
+ head: SourceRange;
387
398
  proof: Proof | undefined;
388
399
  location: SourceLocation;
389
400
  }
@@ -393,10 +404,39 @@ interface Theorem {
393
404
  proof: Proof | undefined;
394
405
  location: SourceLocation;
395
406
  }
407
+ type ModuleUnit = {
408
+ kind: "Constants";
409
+ declarations: Declaration[];
410
+ } | {
411
+ kind: "Variables";
412
+ declarations: Declaration[];
413
+ } | {
414
+ kind: "Recursive";
415
+ declarations: Declaration[];
416
+ } | {
417
+ kind: "Definition";
418
+ definition: Definition;
419
+ } | {
420
+ kind: "Instance";
421
+ instance: Instance;
422
+ } | {
423
+ kind: "Assumption";
424
+ assumption: Assumption;
425
+ } | {
426
+ kind: "Theorem";
427
+ theorem: Theorem;
428
+ } | {
429
+ kind: "Use";
430
+ use: UseOrHide;
431
+ } | {
432
+ kind: "Module";
433
+ module: Module;
434
+ };
396
435
  interface Module {
397
436
  name: string;
398
437
  modules: Module[];
399
438
  extends: string[];
439
+ extendsRanges: SourceRange[];
400
440
  constants: Declaration[];
401
441
  variables: Declaration[];
402
442
  definitions: Definition[];
@@ -405,6 +445,7 @@ interface Module {
405
445
  location: SourceLocation;
406
446
  theorems: Theorem[];
407
447
  uses: UseOrHide[];
448
+ units: ModuleUnit[];
408
449
  }
409
450
  type ConfigValue = {
410
451
  kind: "Number";
@@ -456,8 +497,15 @@ export declare const parseConfig: (source: string) => ModelConfig;
456
497
  export declare class TlaError extends Error {
457
498
  constructor(message: string, cause?: unknown);
458
499
  }
500
+ interface SyntaxFailure {
501
+ reason: string;
502
+ line: number;
503
+ column: number;
504
+ isEnd: boolean;
505
+ }
459
506
  export declare class TlaSyntaxError extends TlaError {
460
- constructor(message: string, cause?: unknown);
507
+ failure: SyntaxFailure | undefined;
508
+ constructor(message: string, cause?: unknown, failure?: SyntaxFailure);
461
509
  }
462
510
  export declare class TlaConfigError extends TlaError {
463
511
  constructor(message: string, cause?: unknown);
@@ -471,6 +519,7 @@ export declare class TlaUnsupportedError extends TlaError {
471
519
  interface ModelValue {
472
520
  kind: "ModelValue";
473
521
  name: string;
522
+ type: string | undefined;
474
523
  }
475
524
  interface SetValue {
476
525
  kind: "Set";
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{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};
9
+ import{A as e,C as t,D as n,N as r,P as i,_ as a,j as o,k as s}from"./transfer.js";import{t as c}from"./parallel.js";export{s as TlaConfigError,e as TlaError,o as TlaEvaluationError,r as TlaSyntaxError,i as TlaUnsupportedError,c as check,t as formatValue,n as parseConfig,a as parseModule};
@@ -9,4 +9,4 @@
9
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=>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?.()});
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.T(e.m(n.source,n.config,o));let c=e.w(),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.S(),h=e.t(l.variables.length),g=e.r(),_=e.r(),v=u.isSymmetric?e.r():void 0,y=/* @__PURE__ */ new Int32Array(2),b=r(),x=n.ports.flatMap((e,t)=>e?[{port:e,index:t}]:[]);x.forEach(e=>{e.port.addEventListener(`message`,e=>b.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 S={states:h(n.seed).map(m)},C=(e,t,r)=>n.ports[e]?.postMessage(t,r),w=(t,r,i)=>{let a=Array.from({length:f},()=>({states:[],origins:[],fingerprints:[],fingerprintStates:[]})),o={generated:0},s=new Int32Array(t.length);for(let c=0;c<t.length;c++){let h=t[c],b=e.x(d,h,l,u.spec.scope);if(o.generated+=b.length,b.length===0&&n.config.checkDeadlock)return;for(let t of b){if(u.findViolatedActionProperty(h,t.state))return;if(!u.satisfiesActionConstraints(h,t.state)||v&&(e.a(t.state,y),!v.insert(y[0],y[1])))continue;m(t.state);let n=u.getFingerprintState(t.state);e.a(n,y);let o=e.i(y[1],f);if(o===p){if(!g.insert(y[0],y[1]))continue;if(u.findViolatedInvariant(t.state,h))return;if(!u.satisfiesConstraints(t.state,h)){g.remove(y[0],y[1]);continue}r.push(t.state),i.push(n),s[c]++}else _.insert(y[0],y[1])&&(a[o].states.push(t.state),a[o].origins.push(c),a[o].fingerprints.push(y[0],y[1]),a[o].fingerprintStates.push(n))}}return{pending:a,generated:o.generated,newStates:s}},T=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},E=(e,t,n,r,i)=>{let a=[];for(let o=0;o<t.length;o++){if(t[o]===0)continue;let s=e.states[o],c=S.states[e.origins[o]];if(u.findViolatedInvariant(s,c))return;u.satisfiesConstraints(s,c)?(n.push(s),r.push(e.fingerprintStates[o]),i[e.origins[o]]++):(_.remove(e.fingerprints[o*2],e.fingerprints[o*2+1]),a.push(e.fingerprints[o*2],e.fingerprints[o*2+1]))}return Int32Array.from(a)},D=e=>{for(let t=0;t<e.length;t+=2)g.remove(e[t],e[t+1])},O=async(n,r,i)=>{let a=t(i);if(a.length===0)return!0;let o=new Map(x.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();C(t,{phase:`balance`,level:n,from:p,states:r},[r.words.buffer])}),(await b.receive(`balance`,n,x.length)).forEach(e=>{e.states&&r.push(...h(e.states).map(m))}),!0},k=async t=>{let n=[],r=[],i=w(S.states,n,r);if(!i||e.w()!==c)return;x.forEach(e=>{let n=Int32Array.from(i.pending[e.index].fingerprints);C(e.index,{phase:`query`,level:t,from:p,fingerprints:n},[n.buffer])}),(await b.receive(`query`,t,x.length)).forEach(e=>{let n=T(e.fingerprints??[]);C(e.from,{phase:`answer`,level:t,from:p,bits:n},[n.buffer])});let a=await b.receive(`answer`,t,x.length);for(let e of a){let a=E(i.pending[e.from],e.bits??/* @__PURE__ */ new Uint8Array,n,r,i.newStates);if(!a)return;C(e.from,{phase:`sizes`,level:t,from:p,unmarks:a},[a.buffer])}let o=n.length,s=Array.from({length:32},()=>0);i.newStates.forEach(e=>s[Math.min(e,31)]++);let l=u.getStoredFingerprints(n,r),d=Array.from({length:f},()=>0);if(d[p]=o,x.forEach(e=>C(e.index,{phase:`sizes`,level:t,from:p,size:o},[])),(await b.receive(`sizes`,t,x.length*2)).forEach(e=>{e.unmarks?D(e.unmarks):d[e.from]=e.size??0}),e.w()===c&&await O(t,n,d))return S.states=n,{type:`level`,level:t,generated:i.generated,added:o,outDegrees:s,fingerprints:l}},A=e=>i.postMessage(e,e.type===`level`?[e.fingerprints.buffer]:[]),j=e=>{k(e).then(e=>A(e??{type:`abort`}),()=>A({type:`abort`}))};i.addEventListener(`message`,e=>{let t=e.data;t.type===`level`&&j(t.level)}),A({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?.()});
@@ -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{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(
9
+ import{S as e,T as t,a 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,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?.()});
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);t(o(m.source,m.config,v));let b=d(),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=e(),D=u(x.variables.length),O=c(),k=c(),A=S.isSymmetric?c():void 0,j=/* @__PURE__ */ new Int32Array(2),M=h(),N=m.ports.flatMap((e,t)=>e?[{port:e,index:t}]:[]);N.forEach(e=>{e.port.addEventListener(`message`,e=>M.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 P={states:D(m.seed).map(E)},F=(e,t,n)=>m.ports[e]?.postMessage(t,n),I=(e,t,r)=>{let i=Array.from({length:w},()=>({states:[],origins:[],fingerprints:[],fingerprintStates:[]})),o={generated:0},s=new Int32Array(e.length);for(let c=0;c<e.length;c++){let l=e[c],u=f(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)||A&&(n(e.state,j),!A.insert(j[0],j[1])))continue;E(e.state);let o=S.getFingerprintState(e.state);n(o,j);let u=a(j[1],w);if(u===T){if(!O.insert(j[0],j[1]))continue;if(S.findViolatedInvariant(e.state,l))return;if(!S.satisfiesConstraints(e.state,l)){O.remove(j[0],j[1]);continue}t.push(e.state),r.push(o),s[c]++}else k.insert(j[0],j[1])&&(i[u].states.push(e.state),i[u].origins.push(c),i[u].fingerprints.push(j[0],j[1]),i[u].fingerprintStates.push(o))}}return{pending:i,generated:o.generated,newStates:s}},L=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},R=(e,t,n,r,i)=>{let a=[];for(let o=0;o<t.length;o++){if(t[o]===0)continue;let s=e.states[o],c=P.states[e.origins[o]];if(S.findViolatedInvariant(s,c))return;S.satisfiesConstraints(s,c)?(n.push(s),r.push(e.fingerprintStates[o]),i[e.origins[o]]++):(k.remove(e.fingerprints[o*2],e.fingerprints[o*2+1]),a.push(e.fingerprints[o*2],e.fingerprints[o*2+1]))}return Int32Array.from(a)},z=e=>{for(let t=0;t<e.length;t+=2)O.remove(e[t],e[t+1])},B=async(e,t,n)=>{let r=p(n);if(r.length===0)return!0;let i=new Map(N.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();F(n,{phase:`balance`,level:e,from:T,states:r},[r.words.buffer])}),(await M.receive(`balance`,e,N.length)).forEach(e=>{e.states&&t.push(...D(e.states).map(E))}),!0},V=async e=>{let t=[],n=[],r=I(P.states,t,n);if(!r||d()!==b)return;N.forEach(t=>{let n=Int32Array.from(r.pending[t.index].fingerprints);F(t.index,{phase:`query`,level:e,from:T,fingerprints:n},[n.buffer])}),(await M.receive(`query`,e,N.length)).forEach(t=>{let n=L(t.fingerprints??[]);F(t.from,{phase:`answer`,level:e,from:T,bits:n},[n.buffer])});let i=await M.receive(`answer`,e,N.length);for(let a of i){let i=R(r.pending[a.from],a.bits??/* @__PURE__ */ new Uint8Array,t,n,r.newStates);if(!i)return;F(a.from,{phase:`sizes`,level:e,from:T,unmarks:i},[i.buffer])}let a=t.length,o=Array.from({length:32},()=>0);r.newStates.forEach(e=>o[Math.min(e,31)]++);let s=S.getStoredFingerprints(t,n),c=Array.from({length:w},()=>0);if(c[T]=a,N.forEach(t=>F(t.index,{phase:`sizes`,level:e,from:T,size:a},[])),(await M.receive(`sizes`,e,N.length*2)).forEach(e=>{e.unmarks?z(e.unmarks):c[e.from]=e.size??0}),d()===b&&await B(e,t,c))return P.states=t,{type:`level`,level:e,generated:r.generated,added:a,outDegrees:o,fingerprints:s}},H=e=>g.postMessage(e,e.type===`level`?[e.fingerprints.buffer]:[]),U=e=>{V(e).then(e=>H(e??{type:`abort`}),()=>H({type:`abort`}))};g.addEventListener(`message`,e=>{let t=e.data;t.type===`level`&&U(t.level)}),H({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`,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}});
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.D(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.T(e.m(n.source,r,s));let u=e.w(),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.y(f))return i();let m=e.S(),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.b(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.j))throw t;return i()}if(e.w()!==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{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(
9
+ import{D as e,S as t,T as n,a as r,b as i,c as a,d as o,g as s,h as c,i as l,j as u,m as d,n as f,o as p,r as m,s as h,w 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`,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};
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`?e(y.config):y.config,x=()=>p({...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};n(d(y.source,b,w));let D=g(),O=s(b,{source:y.source,loadModule:w,loadClass:E,print:y.onPrint??console.log,files:{readFile:y.readFile,writeFile:y.writeFile}}),k=O.environment,A=h(b,k,()=>c(y.source,w));if(a(O.assumptions,k)||!A||A.spec.init===void 0||A.spec.next===void 0||A.properties.liveness.length>0||_(k))return x();let j=t(),M=m(),N=/* @__PURE__ */ new Int32Array(2),P=Array.from({length:S},()=>({encoder:f(),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:o(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 n of i(e,k,A.spec.scope)){if(j(n),F.generatedStates++,r(A.getFingerprintState(n),N),!M.insert(N[0],N[1]))continue;if(A.findViolatedInvariant(n)||A.findFailedInitialPredicate(n))return!1;if(!A.satisfiesConstraints(n)){M.remove(N[0],N[1]);continue}let e=P[l(N[1],S)];if(!e.encoder.encode(n))return!1;e.fingerprints.push(N[0],N[1]),t.push(n),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 u))throw e;return x()}if(g()!==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};