@specverse/engines 4.1.15 → 4.1.16
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/dist/inference/index.d.ts +2 -1
- package/dist/inference/index.d.ts.map +1 -1
- package/dist/inference/index.js +2 -1
- package/dist/inference/index.js.map +1 -1
- package/dist/inference/quint-transpiler.d.ts +18 -1
- package/dist/inference/quint-transpiler.d.ts.map +1 -1
- package/dist/inference/quint-transpiler.js +343 -63
- package/dist/inference/quint-transpiler.js.map +1 -1
- package/dist/inference/verification.d.ts +78 -0
- package/dist/inference/verification.d.ts.map +1 -0
- package/dist/inference/verification.js +263 -0
- package/dist/inference/verification.js.map +1 -0
- package/dist/libs/instance-factories/cli/templates/commander/command-generator.js +30 -5
- package/dist/realize/index.d.ts.map +1 -1
- package/dist/realize/index.js +9 -26
- package/dist/realize/index.js.map +1 -1
- package/libs/instance-factories/cli/templates/commander/command-generator.ts +35 -5
- package/package.json +1 -1
|
@@ -8,7 +8,8 @@ export * from './deployment/index.js';
|
|
|
8
8
|
export { ComprehensiveInferenceEngine } from './comprehensive-engine.js';
|
|
9
9
|
export type { ComprehensiveInferenceResult } from './comprehensive-engine.js';
|
|
10
10
|
export { generateDevSpecly } from './dev-specly-generator.js';
|
|
11
|
-
export { transpileEntityGuards, transpileQuintFile, generateGuardsModule, type TranspiledGuard } from './quint-transpiler.js';
|
|
11
|
+
export { transpileEntityGuards, extractStateVariables, transpileQuintFile, generateGuardsModule, type TranspiledGuard } from './quint-transpiler.js';
|
|
12
|
+
export { verifySpec, buildSnapshot, formatVerificationResult, type VerificationResult, type VerificationFailure, type VerificationSkip, type VerificationError, type VerifyOptions } from './verification.js';
|
|
12
13
|
export { transpileActions, generateActionsModule, type TranspiledAction } from './quint-transpiler.js';
|
|
13
14
|
import type { InferenceEngine, EngineInfo, ValidationResult, InferenceOptions, InferenceResult } from '@specverse/types';
|
|
14
15
|
declare class SpecVerseInferenceEngine implements InferenceEngine {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AACzE,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAG9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAS9D,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,cAAc,iBAAiB,CAAC;AAGhC,cAAc,oBAAoB,CAAC;AAGnC,cAAc,uBAAuB,CAAC;AAGtC,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AACzE,YAAY,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAG9E,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAS9D,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACrJ,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,wBAAwB,EAAE,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,KAAK,gBAAgB,EAAE,KAAK,iBAAiB,EAAE,KAAK,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAC9M,OAAO,EAAE,gBAAgB,EAAE,qBAAqB,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAMvG,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGzH,cAAM,wBAAyB,YAAW,eAAe;IACvD,IAAI,SAAe;IACnB,OAAO,SAAW;IAClB,YAAY,WAAyE;IAErF,OAAO,CAAC,OAAO,CAA6C;IAEtD,UAAU,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,GAAG,CAAC;QAAC,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5E,OAAO,IAAI,UAAU;IAIf,SAAS,IAAI,OAAO,CAAC,gBAAgB,CAAC;IAKtC,KAAK,CAAC,GAAG,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,CAAC;CA6I5E;AAED,eAAO,MAAM,MAAM,0BAAiC,CAAC;AACrD,eAAe,MAAM,CAAC"}
|
package/dist/inference/index.js
CHANGED
|
@@ -17,7 +17,8 @@ import { SpeclyConverter } from './core/specly-converter.js';
|
|
|
17
17
|
// Dev specly generator
|
|
18
18
|
import { generateDevSpecly } from './dev-specly-generator.js';
|
|
19
19
|
// Quint → TypeScript transpiler
|
|
20
|
-
export { transpileEntityGuards, transpileQuintFile, generateGuardsModule } from './quint-transpiler.js';
|
|
20
|
+
export { transpileEntityGuards, extractStateVariables, transpileQuintFile, generateGuardsModule } from './quint-transpiler.js';
|
|
21
|
+
export { verifySpec, buildSnapshot, formatVerificationResult } from './verification.js';
|
|
21
22
|
export { transpileActions, generateActionsModule } from './quint-transpiler.js';
|
|
22
23
|
import { ComprehensiveInferenceEngine } from './comprehensive-engine.js';
|
|
23
24
|
class SpecVerseInferenceEngine {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,wBAAwB;AACxB,cAAc,iBAAiB,CAAC;AAEhC,iCAAiC;AACjC,cAAc,oBAAoB,CAAC;AAEnC,oCAAoC;AACpC,cAAc,uBAAuB,CAAC;AAEtC,iCAAiC;AACjC,OAAO,EAAE,4BAA4B,EAAE,MAAM,2BAA2B,CAAC;AAGzE,uBAAuB;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,0BAA0B;AAC1B,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAE7D,uBAAuB;AACvB,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAE9D,gCAAgC;AAChC,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,oBAAoB,EAAwB,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/inference/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -21,19 +21,36 @@ export interface TranspiledGuard {
|
|
|
21
21
|
typescript: string;
|
|
22
22
|
module: string;
|
|
23
23
|
entity: string;
|
|
24
|
+
/**
|
|
25
|
+
* State variables this guard reads from. Used by the verification
|
|
26
|
+
* runner to decide whether the guard is applicable to a given spec
|
|
27
|
+
* snapshot: if any dependency is not present in the snapshot, the
|
|
28
|
+
* guard is skipped (not failed).
|
|
29
|
+
*/
|
|
30
|
+
dependencies: string[];
|
|
24
31
|
}
|
|
25
32
|
/**
|
|
26
33
|
* Transpile all Quint files from entity modules into TypeScript guards.
|
|
27
34
|
*/
|
|
28
35
|
export declare function transpileEntityGuards(entitiesDir: string): TranspiledGuard[];
|
|
36
|
+
/**
|
|
37
|
+
* Scan Quint behaviour files for module-level `var X: ...` declarations.
|
|
38
|
+
* These are the state variables guards read from; the runtime host
|
|
39
|
+
* populates them via `setSpecSnapshot` before invoking any `check_*`.
|
|
40
|
+
*/
|
|
41
|
+
export declare function extractStateVariables(entitiesDir: string): string[];
|
|
29
42
|
/**
|
|
30
43
|
* Transpile a single Quint file into TypeScript guards.
|
|
31
44
|
*/
|
|
32
45
|
export declare function transpileQuintFile(content: string, entity: string, filename: string): TranspiledGuard[];
|
|
33
46
|
/**
|
|
34
47
|
* Generate a TypeScript guards module from transpiled guards.
|
|
48
|
+
*
|
|
49
|
+
* `stateVars` is the list of Quint module-level `var` declarations the
|
|
50
|
+
* guards reference. When omitted, falls back to a minimal hard-coded
|
|
51
|
+
* set — but callers should pass the real list from `extractStateVariables`.
|
|
35
52
|
*/
|
|
36
|
-
export declare function generateGuardsModule(guards: TranspiledGuard[]): string;
|
|
53
|
+
export declare function generateGuardsModule(guards: TranspiledGuard[], stateVars?: string[]): string;
|
|
37
54
|
export interface TranspiledAction {
|
|
38
55
|
name: string;
|
|
39
56
|
params: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"quint-transpiler.d.ts","sourceRoot":"","sources":["../../src/inference/quint-transpiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"quint-transpiler.d.ts","sourceRoot":"","sources":["../../src/inference/quint-transpiler.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAKH,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,UAAU,GAAG,WAAW,CAAC;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf;;;;;OAKG;IACH,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,eAAe,EAAE,CAqB5E;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CA2BnE;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,eAAe,EAAE,CAoFvG;AAqBD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,eAAe,EAAE,EACzB,SAAS,CAAC,EAAE,MAAM,EAAE,GACnB,MAAM,CA+ER;AAID,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE,CA8BtG;AA+HD;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,MAAM,CAiBzE"}
|
|
@@ -39,6 +39,38 @@ export function transpileEntityGuards(entitiesDir) {
|
|
|
39
39
|
}
|
|
40
40
|
return guards;
|
|
41
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Scan Quint behaviour files for module-level `var X: ...` declarations.
|
|
44
|
+
* These are the state variables guards read from; the runtime host
|
|
45
|
+
* populates them via `setSpecSnapshot` before invoking any `check_*`.
|
|
46
|
+
*/
|
|
47
|
+
export function extractStateVariables(entitiesDir) {
|
|
48
|
+
const found = new Set();
|
|
49
|
+
const varRe = /^\s*var\s+(\w+)\s*:/gm;
|
|
50
|
+
for (const category of ['core', 'extensions']) {
|
|
51
|
+
const categoryDir = join(entitiesDir, category);
|
|
52
|
+
if (!existsSync(categoryDir))
|
|
53
|
+
continue;
|
|
54
|
+
for (const entity of readdirSync(categoryDir)) {
|
|
55
|
+
const behaviourDir = join(categoryDir, entity, 'behaviour');
|
|
56
|
+
if (!existsSync(behaviourDir))
|
|
57
|
+
continue;
|
|
58
|
+
for (const file of readdirSync(behaviourDir).filter(f => f.endsWith('.qnt'))) {
|
|
59
|
+
const content = readFileSync(join(behaviourDir, file), 'utf8');
|
|
60
|
+
let m;
|
|
61
|
+
varRe.lastIndex = 0;
|
|
62
|
+
while ((m = varRe.exec(content)) !== null) {
|
|
63
|
+
// Skip `fullyExpanded` and similar pure-inference state vars
|
|
64
|
+
// — they're booleans, not array-of-entity collections.
|
|
65
|
+
if (m[1] === 'fullyExpanded')
|
|
66
|
+
continue;
|
|
67
|
+
found.add(m[1]);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
return [...found].sort();
|
|
73
|
+
}
|
|
42
74
|
/**
|
|
43
75
|
* Transpile a single Quint file into TypeScript guards.
|
|
44
76
|
*/
|
|
@@ -46,6 +78,15 @@ export function transpileQuintFile(content, entity, filename) {
|
|
|
46
78
|
const guards = [];
|
|
47
79
|
const lines = content.split('\n');
|
|
48
80
|
const moduleName = extractModuleName(content) || entity;
|
|
81
|
+
// Collect file-level `var X: ...` declarations so we know which symbols
|
|
82
|
+
// to treat as dependencies (vs local parameters) when scanning guard
|
|
83
|
+
// bodies.
|
|
84
|
+
const fileStateVars = new Set();
|
|
85
|
+
for (const line of lines) {
|
|
86
|
+
const vm = line.match(/^\s*var\s+(\w+)\s*:/);
|
|
87
|
+
if (vm && vm[1] !== 'fullyExpanded')
|
|
88
|
+
fileStateVars.add(vm[1]);
|
|
89
|
+
}
|
|
49
90
|
let i = 0;
|
|
50
91
|
while (i < lines.length) {
|
|
51
92
|
const line = lines[i].trim();
|
|
@@ -64,6 +105,7 @@ export function transpileQuintFile(content, entity, filename) {
|
|
|
64
105
|
typescript: `export function ${name}(${tsParams}): ${tsReturn} {\n ${tsBody}\n}`,
|
|
65
106
|
module: moduleName,
|
|
66
107
|
entity,
|
|
108
|
+
dependencies: extractGuardDependencies(body, fileStateVars),
|
|
67
109
|
});
|
|
68
110
|
i = skipBlock(lines, i);
|
|
69
111
|
continue;
|
|
@@ -79,14 +121,16 @@ export function transpileQuintFile(content, entity, filename) {
|
|
|
79
121
|
body += lines[i].trim() + ' ';
|
|
80
122
|
i++;
|
|
81
123
|
}
|
|
82
|
-
const
|
|
124
|
+
const bodyTrim = body.trim();
|
|
125
|
+
const tsBody = transpileExpression(bodyTrim);
|
|
83
126
|
guards.push({
|
|
84
127
|
name,
|
|
85
128
|
kind: 'invariant',
|
|
86
|
-
quint: `val ${name}: bool = ${
|
|
129
|
+
quint: `val ${name}: bool = ${bodyTrim}`,
|
|
87
130
|
typescript: `export function check_${name}(_data?: any): boolean {\n return ${tsBody};\n}`,
|
|
88
131
|
module: moduleName,
|
|
89
132
|
entity,
|
|
133
|
+
dependencies: extractGuardDependencies(bodyTrim, fileStateVars),
|
|
90
134
|
});
|
|
91
135
|
continue;
|
|
92
136
|
}
|
|
@@ -102,16 +146,41 @@ export function transpileQuintFile(content, entity, filename) {
|
|
|
102
146
|
typescript: `export function check_${name}(data: any): boolean {\n return ${tsExpr};\n}`,
|
|
103
147
|
module: moduleName,
|
|
104
148
|
entity,
|
|
149
|
+
dependencies: extractGuardDependencies(expr.trim(), fileStateVars),
|
|
105
150
|
});
|
|
106
151
|
}
|
|
107
152
|
i++;
|
|
108
153
|
}
|
|
109
154
|
return guards;
|
|
110
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Scan a Quint expression (pre-transpile) and return which file-level
|
|
158
|
+
* state variables it reads. Used to decide whether a guard is applicable
|
|
159
|
+
* to a given spec snapshot: if the snapshot doesn't populate one of the
|
|
160
|
+
* guard's dependencies, verify skips the guard.
|
|
161
|
+
*/
|
|
162
|
+
function extractGuardDependencies(body, fileStateVars) {
|
|
163
|
+
if (!fileStateVars.size)
|
|
164
|
+
return [];
|
|
165
|
+
const deps = new Set();
|
|
166
|
+
// Match bare identifiers not preceded by a word char or dot (so
|
|
167
|
+
// `m.models` — field access on a lambda param — doesn't count, but
|
|
168
|
+
// `models.forall(...)` does).
|
|
169
|
+
for (const v of fileStateVars) {
|
|
170
|
+
const re = new RegExp(`(?<![A-Za-z0-9_.])${v}\\b`);
|
|
171
|
+
if (re.test(body))
|
|
172
|
+
deps.add(v);
|
|
173
|
+
}
|
|
174
|
+
return [...deps].sort();
|
|
175
|
+
}
|
|
111
176
|
/**
|
|
112
177
|
* Generate a TypeScript guards module from transpiled guards.
|
|
178
|
+
*
|
|
179
|
+
* `stateVars` is the list of Quint module-level `var` declarations the
|
|
180
|
+
* guards reference. When omitted, falls back to a minimal hard-coded
|
|
181
|
+
* set — but callers should pass the real list from `extractStateVariables`.
|
|
113
182
|
*/
|
|
114
|
-
export function generateGuardsModule(guards) {
|
|
183
|
+
export function generateGuardsModule(guards, stateVars) {
|
|
115
184
|
if (guards.length === 0)
|
|
116
185
|
return '// No guards generated\nexport {};\n';
|
|
117
186
|
// Deduplicate by name — multiple modules may define the same invariant
|
|
@@ -126,9 +195,19 @@ export function generateGuardsModule(guards) {
|
|
|
126
195
|
});
|
|
127
196
|
const functions = guards.filter(g => g.kind === 'function');
|
|
128
197
|
const invariants = guards.filter(g => g.kind === 'invariant');
|
|
198
|
+
const candidateStateVars = stateVars && stateVars.length > 0
|
|
199
|
+
? stateVars
|
|
200
|
+
: ['models', 'controllers', 'services', 'views', 'events', 'deployments', 'commands', 'conventions', 'measures'];
|
|
201
|
+
// Only declare state vars the surviving guards actually reference —
|
|
202
|
+
// otherwise `noUnusedLocals` flags declarations for vars whose only
|
|
203
|
+
// consumer was a deduplicated guard. Exclude dot-prefixed matches
|
|
204
|
+
// (`d.channels` is a field access on a lambda parameter, not the
|
|
205
|
+
// module-level `channels` state variable).
|
|
206
|
+
const guardBodies = guards.map(g => g.typescript).join('\n');
|
|
207
|
+
const resolvedStateVars = candidateStateVars.filter(v => new RegExp(`(?<![\\w.])${v}\\b`).test(guardBodies));
|
|
208
|
+
const declarations = resolvedStateVars.map(v => `let ${v}: any[] = [];`);
|
|
209
|
+
const assignments = resolvedStateVars.map(v => ` ${v} = snapshot?.${v} ?? [];`);
|
|
129
210
|
const lines = [
|
|
130
|
-
'// @ts-nocheck',
|
|
131
|
-
'/* eslint-disable */',
|
|
132
211
|
'/**',
|
|
133
212
|
' * Runtime Guards — Transpiled from Quint Specifications',
|
|
134
213
|
' *',
|
|
@@ -141,29 +220,14 @@ export function generateGuardsModule(guards) {
|
|
|
141
220
|
' */',
|
|
142
221
|
'',
|
|
143
222
|
'// Quint module-level state variables — initialized via setSpecSnapshot().',
|
|
144
|
-
'// The guards read from these
|
|
145
|
-
'// invoking any check_* function.',
|
|
223
|
+
'// The guards read from these; a host caller populates them before',
|
|
224
|
+
'// invoking any check_* function. Variable set is auto-discovered from',
|
|
225
|
+
'// the guard bodies.',
|
|
146
226
|
'/* eslint-disable @typescript-eslint/no-unused-vars, prefer-const */',
|
|
147
|
-
|
|
148
|
-
'let controllers: any[] = [];',
|
|
149
|
-
'let services: any[] = [];',
|
|
150
|
-
'let views: any[] = [];',
|
|
151
|
-
'let events: any[] = [];',
|
|
152
|
-
'let commands: any[] = [];',
|
|
153
|
-
'let conventions: any[] = [];',
|
|
154
|
-
'let measures: any[] = [];',
|
|
155
|
-
'let deployments: any[] = [];',
|
|
227
|
+
...declarations,
|
|
156
228
|
'',
|
|
157
229
|
'export function setSpecSnapshot(snapshot: any): void {',
|
|
158
|
-
|
|
159
|
-
' controllers = snapshot?.controllers ?? [];',
|
|
160
|
-
' services = snapshot?.services ?? [];',
|
|
161
|
-
' views = snapshot?.views ?? [];',
|
|
162
|
-
' events = snapshot?.events ?? [];',
|
|
163
|
-
' commands = snapshot?.commands ?? [];',
|
|
164
|
-
' conventions = snapshot?.conventions ?? [];',
|
|
165
|
-
' measures = snapshot?.measures ?? [];',
|
|
166
|
-
' deployments = snapshot?.deployments ?? [];',
|
|
230
|
+
...assignments,
|
|
167
231
|
'}',
|
|
168
232
|
'',
|
|
169
233
|
];
|
|
@@ -430,14 +494,7 @@ function transpileBody(body) {
|
|
|
430
494
|
ts = ts.replace(/\}\s*$/, '');
|
|
431
495
|
// Normalize — join multiline into single line, collapse whitespace
|
|
432
496
|
ts = ts.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim();
|
|
433
|
-
|
|
434
|
-
ts = ts.replace(/\band\b/g, '&&');
|
|
435
|
-
ts = ts.replace(/\bor\b/g, '||');
|
|
436
|
-
ts = ts.replace(/\bnot\b/g, '!');
|
|
437
|
-
ts = transpileValBindings(ts);
|
|
438
|
-
ts = transpileImplies(ts);
|
|
439
|
-
ts = ts.replace(/\.forall\(\s*(\w+)\s*=>\s*/g, '.every(($1: any) => ');
|
|
440
|
-
ts = ts.replace(/\.exists\(\s*(\w+)\s*=>\s*/g, '.some(($1: any) => ');
|
|
497
|
+
ts = applyQuintRewrites(ts);
|
|
441
498
|
// Clean up comments
|
|
442
499
|
ts = ts.replace(/\/\/.*?(?=\bif\b|\belse\b|$)/g, '');
|
|
443
500
|
// Replace if/else chains → ternary (from innermost out)
|
|
@@ -451,6 +508,52 @@ function transpileBody(body) {
|
|
|
451
508
|
}
|
|
452
509
|
return `return ${ts.trim()};`;
|
|
453
510
|
}
|
|
511
|
+
/**
|
|
512
|
+
* Apply the full sequence of Quint → TypeScript rewrites to an expression
|
|
513
|
+
* string. Ordering matters: method-name rewrites (forall, exists, keys, get)
|
|
514
|
+
* must run BEFORE `transpileImplies`, because the implies walker scans
|
|
515
|
+
* backward through method chains to find the left operand and needs to see
|
|
516
|
+
* JS-shaped method names.
|
|
517
|
+
*/
|
|
518
|
+
function applyQuintRewrites(ts) {
|
|
519
|
+
// 1. Boolean operators
|
|
520
|
+
ts = ts.replace(/\band\b/g, '&&');
|
|
521
|
+
ts = ts.replace(/\bor\b/g, '||');
|
|
522
|
+
ts = ts.replace(/\bnot\b/g, '!');
|
|
523
|
+
// 2. Local `val` bindings inside blocks
|
|
524
|
+
ts = transpileValBindings(ts);
|
|
525
|
+
// 3. Quint collection operations → JS equivalents
|
|
526
|
+
// These run before implies so the walker sees valid JS method names.
|
|
527
|
+
// forall / exists with lambda → .every / .some
|
|
528
|
+
ts = ts.replace(/\.forall\(\s*(\w+)\s*=>\s*/g, '.every(($1: any) => ');
|
|
529
|
+
ts = ts.replace(/\.exists\(\s*(\w+)\s*=>\s*/g, '.some(($1: any) => ');
|
|
530
|
+
// filter / map / flatMap: keep the method name but type the lambda param
|
|
531
|
+
ts = ts.replace(/\.filter\(\s*(\w+)\s*=>\s*/g, '.filter(($1: any) => ');
|
|
532
|
+
ts = ts.replace(/\.map\(\s*(\w+)\s*=>\s*/g, '.map(($1: any) => ');
|
|
533
|
+
ts = ts.replace(/\.flatMap\(\s*(\w+)\s*=>\s*/g, '.flatMap(($1: any) => ');
|
|
534
|
+
// Set literal: Set("a", "b") → ["a", "b"]
|
|
535
|
+
ts = ts.replace(/\bSet\(([^)]+)\)/g, '[$1]');
|
|
536
|
+
// subseteq (subset of) → runtime check via .every + .includes.
|
|
537
|
+
// `X.subseteq(Y)` becomes `X.every((__v: any) => Y.includes(__v))`.
|
|
538
|
+
// Uses a balanced walker because X can be an array literal or method chain.
|
|
539
|
+
ts = rewriteSubseteq(ts);
|
|
540
|
+
// Map operations on plain-object data:
|
|
541
|
+
// X.keys() → Object.keys(X)
|
|
542
|
+
// X.get(k) → X[k]
|
|
543
|
+
// Quint maps use .keys()/.get(); when the runtime data is a plain object
|
|
544
|
+
// (which is what inference produces), these need JS-equivalent forms.
|
|
545
|
+
ts = rewriteKeysGet(ts);
|
|
546
|
+
// .size() → .length (works on arrays from .keys() and on plain arrays)
|
|
547
|
+
ts = ts.replace(/\.size\(\)/g, '.length');
|
|
548
|
+
// .contains → .includes
|
|
549
|
+
ts = ts.replace(/\.contains\(/g, '.includes(');
|
|
550
|
+
// != → !==, == → ===
|
|
551
|
+
ts = ts.replace(/([^!<>])==(?!=)/g, '$1===');
|
|
552
|
+
ts = ts.replace(/!=(?!=)/g, '!==');
|
|
553
|
+
// 4. implies → (!A || B). Runs LAST so the walker sees JS-shaped methods.
|
|
554
|
+
ts = transpileImplies(ts);
|
|
555
|
+
return ts;
|
|
556
|
+
}
|
|
454
557
|
/**
|
|
455
558
|
* Transpile `A implies B` → `(!(A) || (B))`.
|
|
456
559
|
* A is the boolean expression immediately to the left of `implies`, which may
|
|
@@ -494,9 +597,12 @@ function transpileImplies(ts) {
|
|
|
494
597
|
let kk = k - 1;
|
|
495
598
|
while (kk >= 0 && /[A-Za-z0-9_.]/.test(out[kk]))
|
|
496
599
|
kk--;
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
600
|
+
// If we consumed any chars, it's a method/receiver chain — extend.
|
|
601
|
+
// The consumed range may start with '.' (e.g. `.exists` after `.keys()`)
|
|
602
|
+
// so we can't restrict the first char to a letter.
|
|
603
|
+
if (kk + 1 < k) {
|
|
604
|
+
// Extend through chained receivers: `a.b.c(args)`, `a.b(x).c(y)`
|
|
605
|
+
// (parens), and `[...].c(y)` (array literals).
|
|
500
606
|
let prev = kk;
|
|
501
607
|
while (prev >= 0) {
|
|
502
608
|
const ch = out[prev];
|
|
@@ -504,13 +610,15 @@ function transpileImplies(ts) {
|
|
|
504
610
|
prev--;
|
|
505
611
|
continue;
|
|
506
612
|
}
|
|
507
|
-
if (ch === ')') {
|
|
613
|
+
if (ch === ')' || ch === ']') {
|
|
614
|
+
const close = ch;
|
|
615
|
+
const open = close === ')' ? '(' : '[';
|
|
508
616
|
let d = 1;
|
|
509
617
|
prev--;
|
|
510
618
|
while (prev >= 0 && d > 0) {
|
|
511
|
-
if (out[prev] ===
|
|
619
|
+
if (out[prev] === close)
|
|
512
620
|
d++;
|
|
513
|
-
else if (out[prev] ===
|
|
621
|
+
else if (out[prev] === open)
|
|
514
622
|
d--;
|
|
515
623
|
if (d === 0)
|
|
516
624
|
break;
|
|
@@ -595,6 +703,201 @@ function transpileImplies(ts) {
|
|
|
595
703
|
}
|
|
596
704
|
return out;
|
|
597
705
|
}
|
|
706
|
+
/**
|
|
707
|
+
* Rewrite `X.subseteq(Y)` → `X.every((__v: any) => Y.includes(__v))`.
|
|
708
|
+
* X can be an array literal (including spaces before the dot) or a method
|
|
709
|
+
* chain; walk backward from `.subseteq(` to find its receiver with balanced
|
|
710
|
+
* brackets.
|
|
711
|
+
*/
|
|
712
|
+
function rewriteSubseteq(ts) {
|
|
713
|
+
let out = ts;
|
|
714
|
+
let guard = 50;
|
|
715
|
+
while (guard-- > 0) {
|
|
716
|
+
const m = out.match(/\.\s*subseteq\s*\(/);
|
|
717
|
+
if (!m || m.index === undefined)
|
|
718
|
+
break;
|
|
719
|
+
const dotIdx = m.index;
|
|
720
|
+
const openIdx = dotIdx + m[0].length; // position of `(`
|
|
721
|
+
// Walk backward from dotIdx to find receiver start
|
|
722
|
+
let i = dotIdx - 1;
|
|
723
|
+
// skip whitespace
|
|
724
|
+
while (i >= 0 && /\s/.test(out[i]))
|
|
725
|
+
i--;
|
|
726
|
+
if (i < 0)
|
|
727
|
+
break;
|
|
728
|
+
let receiverStart;
|
|
729
|
+
if (out[i] === ']') {
|
|
730
|
+
// Array literal receiver — balance brackets
|
|
731
|
+
let depth = 1;
|
|
732
|
+
let k = i - 1;
|
|
733
|
+
while (k >= 0 && depth > 0) {
|
|
734
|
+
if (out[k] === ']')
|
|
735
|
+
depth++;
|
|
736
|
+
else if (out[k] === '[')
|
|
737
|
+
depth--;
|
|
738
|
+
if (depth === 0)
|
|
739
|
+
break;
|
|
740
|
+
k--;
|
|
741
|
+
}
|
|
742
|
+
if (depth !== 0)
|
|
743
|
+
break;
|
|
744
|
+
receiverStart = k;
|
|
745
|
+
}
|
|
746
|
+
else if (out[i] === ')') {
|
|
747
|
+
// Call-expression receiver — balance parens
|
|
748
|
+
let depth = 1;
|
|
749
|
+
let k = i - 1;
|
|
750
|
+
while (k >= 0 && depth > 0) {
|
|
751
|
+
if (out[k] === ')')
|
|
752
|
+
depth++;
|
|
753
|
+
else if (out[k] === '(')
|
|
754
|
+
depth--;
|
|
755
|
+
if (depth === 0)
|
|
756
|
+
break;
|
|
757
|
+
k--;
|
|
758
|
+
}
|
|
759
|
+
if (depth !== 0)
|
|
760
|
+
break;
|
|
761
|
+
// Then walk back through any identifier chain preceding the `(`
|
|
762
|
+
let kk = k - 1;
|
|
763
|
+
while (kk >= 0 && /[A-Za-z0-9_.]/.test(out[kk]))
|
|
764
|
+
kk--;
|
|
765
|
+
receiverStart = kk + 1;
|
|
766
|
+
}
|
|
767
|
+
else if (/[A-Za-z0-9_]/.test(out[i])) {
|
|
768
|
+
// Bare identifier receiver
|
|
769
|
+
let k = i;
|
|
770
|
+
while (k >= 0 && /[A-Za-z0-9_.]/.test(out[k]))
|
|
771
|
+
k--;
|
|
772
|
+
receiverStart = k + 1;
|
|
773
|
+
}
|
|
774
|
+
else {
|
|
775
|
+
break;
|
|
776
|
+
}
|
|
777
|
+
const receiver = out.substring(receiverStart, i + 1);
|
|
778
|
+
// Find argument end (balanced parens from openIdx)
|
|
779
|
+
let depth = 1;
|
|
780
|
+
let j = openIdx;
|
|
781
|
+
while (j < out.length && depth > 0) {
|
|
782
|
+
const ch = out[j];
|
|
783
|
+
if (ch === '(')
|
|
784
|
+
depth++;
|
|
785
|
+
else if (ch === ')') {
|
|
786
|
+
depth--;
|
|
787
|
+
if (depth === 0)
|
|
788
|
+
break;
|
|
789
|
+
}
|
|
790
|
+
j++;
|
|
791
|
+
}
|
|
792
|
+
if (depth !== 0)
|
|
793
|
+
break;
|
|
794
|
+
const argStr = out.substring(openIdx, j).trim();
|
|
795
|
+
const replacement = `${receiver}.every((__v: any) => ${argStr}.includes(__v))`;
|
|
796
|
+
out = out.substring(0, receiverStart) + replacement + out.substring(j + 1);
|
|
797
|
+
}
|
|
798
|
+
return out;
|
|
799
|
+
}
|
|
800
|
+
/**
|
|
801
|
+
* Rewrite `X.keys()` → `Object.keys(X)` and `X.get(k)` → `X[k]`.
|
|
802
|
+
* Quint Maps use `.keys()`/`.get()`; when the runtime data is a plain object
|
|
803
|
+
* (which is what the inferred SpecVerse AST produces), these need JS forms.
|
|
804
|
+
* Walks backward from the method to capture the receiver (identifier chain
|
|
805
|
+
* or nested call).
|
|
806
|
+
*/
|
|
807
|
+
function rewriteKeysGet(ts) {
|
|
808
|
+
let out = ts;
|
|
809
|
+
// Handle .keys() — no arguments
|
|
810
|
+
let guard = 100;
|
|
811
|
+
while (guard-- > 0) {
|
|
812
|
+
const m = out.match(/\.\s*keys\s*\(\s*\)/);
|
|
813
|
+
if (!m || m.index === undefined)
|
|
814
|
+
break;
|
|
815
|
+
const dotIdx = m.index;
|
|
816
|
+
const endIdx = dotIdx + m[0].length; // one past closing `)`
|
|
817
|
+
// Walk back to receiver start
|
|
818
|
+
const receiverStart = findReceiverStart(out, dotIdx);
|
|
819
|
+
if (receiverStart === -1)
|
|
820
|
+
break;
|
|
821
|
+
const receiver = out.substring(receiverStart, dotIdx);
|
|
822
|
+
out = out.substring(0, receiverStart) + `Object.keys(${receiver})` + out.substring(endIdx);
|
|
823
|
+
}
|
|
824
|
+
// Handle .get(k) — one argument
|
|
825
|
+
guard = 100;
|
|
826
|
+
while (guard-- > 0) {
|
|
827
|
+
const m = out.match(/\.\s*get\s*\(/);
|
|
828
|
+
if (!m || m.index === undefined)
|
|
829
|
+
break;
|
|
830
|
+
const dotIdx = m.index;
|
|
831
|
+
const openIdx = dotIdx + m[0].length; // position after `(`
|
|
832
|
+
// Find closing paren (balanced)
|
|
833
|
+
let depth = 1;
|
|
834
|
+
let j = openIdx;
|
|
835
|
+
while (j < out.length && depth > 0) {
|
|
836
|
+
const ch = out[j];
|
|
837
|
+
if (ch === '(')
|
|
838
|
+
depth++;
|
|
839
|
+
else if (ch === ')') {
|
|
840
|
+
depth--;
|
|
841
|
+
if (depth === 0)
|
|
842
|
+
break;
|
|
843
|
+
}
|
|
844
|
+
j++;
|
|
845
|
+
}
|
|
846
|
+
if (depth !== 0)
|
|
847
|
+
break;
|
|
848
|
+
const argStr = out.substring(openIdx, j).trim();
|
|
849
|
+
// Walk back to receiver start
|
|
850
|
+
const receiverStart = findReceiverStart(out, dotIdx);
|
|
851
|
+
if (receiverStart === -1)
|
|
852
|
+
break;
|
|
853
|
+
const receiver = out.substring(receiverStart, dotIdx);
|
|
854
|
+
out = out.substring(0, receiverStart) + `${receiver}[${argStr}]` + out.substring(j + 1);
|
|
855
|
+
}
|
|
856
|
+
return out;
|
|
857
|
+
}
|
|
858
|
+
/**
|
|
859
|
+
* Walk backward from `dotIdx` (the position of `.`) to find where the
|
|
860
|
+
* receiver expression starts. Returns the index of the first char of the
|
|
861
|
+
* receiver, or -1 if it can't be parsed.
|
|
862
|
+
*/
|
|
863
|
+
function findReceiverStart(s, dotIdx) {
|
|
864
|
+
let i = dotIdx - 1;
|
|
865
|
+
// Skip whitespace
|
|
866
|
+
while (i >= 0 && /\s/.test(s[i]))
|
|
867
|
+
i--;
|
|
868
|
+
if (i < 0)
|
|
869
|
+
return -1;
|
|
870
|
+
if (s[i] === ')' || s[i] === ']') {
|
|
871
|
+
// Balanced close-bracket — walk back to matching open
|
|
872
|
+
const close = s[i];
|
|
873
|
+
const open = close === ')' ? '(' : '[';
|
|
874
|
+
let depth = 1;
|
|
875
|
+
let k = i - 1;
|
|
876
|
+
while (k >= 0 && depth > 0) {
|
|
877
|
+
if (s[k] === close)
|
|
878
|
+
depth++;
|
|
879
|
+
else if (s[k] === open)
|
|
880
|
+
depth--;
|
|
881
|
+
if (depth === 0)
|
|
882
|
+
break;
|
|
883
|
+
k--;
|
|
884
|
+
}
|
|
885
|
+
if (depth !== 0)
|
|
886
|
+
return -1;
|
|
887
|
+
// Then walk back through any identifier chain
|
|
888
|
+
let kk = k - 1;
|
|
889
|
+
while (kk >= 0 && /[A-Za-z0-9_.]/.test(s[kk]))
|
|
890
|
+
kk--;
|
|
891
|
+
return kk + 1;
|
|
892
|
+
}
|
|
893
|
+
if (/[A-Za-z0-9_]/.test(s[i])) {
|
|
894
|
+
let k = i;
|
|
895
|
+
while (k >= 0 && /[A-Za-z0-9_.]/.test(s[k]))
|
|
896
|
+
k--;
|
|
897
|
+
return k + 1;
|
|
898
|
+
}
|
|
899
|
+
return -1;
|
|
900
|
+
}
|
|
598
901
|
/**
|
|
599
902
|
* Handle Quint local `val` bindings inside a block expression.
|
|
600
903
|
* `{ val X = CALL REST }` → `{ const X = CALL; return REST; }`
|
|
@@ -605,29 +908,6 @@ function transpileValBindings(ts) {
|
|
|
605
908
|
return ts.replace(/\{\s*val\s+(\w+)\s*=\s*([\w.]+\([^()]*\))\s+(.+?)\s*\}/g, '{ const $1 = $2; return $3; }');
|
|
606
909
|
}
|
|
607
910
|
function transpileExpression(expr) {
|
|
608
|
-
|
|
609
|
-
// Quint operators → TypeScript
|
|
610
|
-
ts = ts.replace(/\band\b/g, '&&');
|
|
611
|
-
ts = ts.replace(/\bor\b/g, '||');
|
|
612
|
-
ts = ts.replace(/\bnot\b/g, '!');
|
|
613
|
-
// Handle local `val` bindings inside blocks
|
|
614
|
-
ts = transpileValBindings(ts);
|
|
615
|
-
// implies → (!A || B): walk string finding each `implies` keyword,
|
|
616
|
-
// match its left operand as a balanced-paren expression immediately before
|
|
617
|
-
ts = transpileImplies(ts);
|
|
618
|
-
// forall → .every (accept any preceding non-word char)
|
|
619
|
-
ts = ts.replace(/\.forall\(\s*(\w+)\s*=>\s*/g, '.every(($1: any) => ');
|
|
620
|
-
// exists → .some
|
|
621
|
-
ts = ts.replace(/\.exists\(\s*(\w+)\s*=>\s*/g, '.some(($1: any) => ');
|
|
622
|
-
// .size() → .length or .size
|
|
623
|
-
ts = ts.replace(/\.size\(\)/g, '.length');
|
|
624
|
-
// .contains → .includes (for arrays) or .has (for Sets)
|
|
625
|
-
ts = ts.replace(/\.contains\(/g, '.includes(');
|
|
626
|
-
// Set("a", "b") → ["a", "b"]
|
|
627
|
-
ts = ts.replace(/Set\(([^)]+)\)/g, '[$1]');
|
|
628
|
-
// != → !==, == → ===
|
|
629
|
-
ts = ts.replace(/([^!<>])==/g, '$1===');
|
|
630
|
-
ts = ts.replace(/!=/g, '!==');
|
|
631
|
-
return ts;
|
|
911
|
+
return applyQuintRewrites(expr);
|
|
632
912
|
}
|
|
633
913
|
//# sourceMappingURL=quint-transpiler.js.map
|