edict-lang 0.1.0
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/LICENSE +21 -0
- package/README.md +202 -0
- package/dist/ast/nodes.d.ts +248 -0
- package/dist/ast/nodes.d.ts.map +1 -0
- package/dist/ast/nodes.js +95 -0
- package/dist/ast/nodes.js.map +1 -0
- package/dist/ast/types.d.ts +78 -0
- package/dist/ast/types.d.ts.map +1 -0
- package/dist/ast/types.js +7 -0
- package/dist/ast/types.js.map +1 -0
- package/dist/check.d.ts +19 -0
- package/dist/check.d.ts.map +1 -0
- package/dist/check.js +49 -0
- package/dist/check.js.map +1 -0
- package/dist/checker/check.d.ts +7 -0
- package/dist/checker/check.d.ts.map +1 -0
- package/dist/checker/check.js +548 -0
- package/dist/checker/check.js.map +1 -0
- package/dist/checker/type-env.d.ts +24 -0
- package/dist/checker/type-env.d.ts.map +1 -0
- package/dist/checker/type-env.js +67 -0
- package/dist/checker/type-env.js.map +1 -0
- package/dist/checker/types-equal.d.ts +18 -0
- package/dist/checker/types-equal.d.ts.map +1 -0
- package/dist/checker/types-equal.js +79 -0
- package/dist/checker/types-equal.js.map +1 -0
- package/dist/codegen/builtins.d.ts +27 -0
- package/dist/codegen/builtins.d.ts.map +1 -0
- package/dist/codegen/builtins.js +54 -0
- package/dist/codegen/builtins.js.map +1 -0
- package/dist/codegen/codegen.d.ts +32 -0
- package/dist/codegen/codegen.d.ts.map +1 -0
- package/dist/codegen/codegen.js +1192 -0
- package/dist/codegen/codegen.js.map +1 -0
- package/dist/codegen/runner.d.ts +16 -0
- package/dist/codegen/runner.d.ts.map +1 -0
- package/dist/codegen/runner.js +82 -0
- package/dist/codegen/runner.js.map +1 -0
- package/dist/codegen/string-table.d.ts +35 -0
- package/dist/codegen/string-table.d.ts.map +1 -0
- package/dist/codegen/string-table.js +62 -0
- package/dist/codegen/string-table.js.map +1 -0
- package/dist/compile.d.ts +18 -0
- package/dist/compile.d.ts.map +1 -0
- package/dist/compile.js +40 -0
- package/dist/compile.js.map +1 -0
- package/dist/contracts/translate.d.ts +39 -0
- package/dist/contracts/translate.d.ts.map +1 -0
- package/dist/contracts/translate.js +372 -0
- package/dist/contracts/translate.js.map +1 -0
- package/dist/contracts/verify.d.ts +8 -0
- package/dist/contracts/verify.d.ts.map +1 -0
- package/dist/contracts/verify.js +400 -0
- package/dist/contracts/verify.js.map +1 -0
- package/dist/contracts/z3-context.d.ts +14 -0
- package/dist/contracts/z3-context.d.ts.map +1 -0
- package/dist/contracts/z3-context.js +24 -0
- package/dist/contracts/z3-context.js.map +1 -0
- package/dist/effects/call-graph.d.ts +21 -0
- package/dist/effects/call-graph.d.ts.map +1 -0
- package/dist/effects/call-graph.js +135 -0
- package/dist/effects/call-graph.js.map +1 -0
- package/dist/effects/effect-check.d.ts +13 -0
- package/dist/effects/effect-check.d.ts.map +1 -0
- package/dist/effects/effect-check.js +48 -0
- package/dist/effects/effect-check.js.map +1 -0
- package/dist/errors/structured-errors.d.ts +193 -0
- package/dist/errors/structured-errors.d.ts.map +1 -0
- package/dist/errors/structured-errors.js +96 -0
- package/dist/errors/structured-errors.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +37 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/create-server.d.ts +3 -0
- package/dist/mcp/create-server.d.ts.map +1 -0
- package/dist/mcp/create-server.js +157 -0
- package/dist/mcp/create-server.js.map +1 -0
- package/dist/mcp/handlers.d.ts +44 -0
- package/dist/mcp/handlers.d.ts.map +1 -0
- package/dist/mcp/handlers.js +112 -0
- package/dist/mcp/handlers.js.map +1 -0
- package/dist/mcp/server.d.ts +3 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +129 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/resolver/levenshtein.d.ts +12 -0
- package/dist/resolver/levenshtein.d.ts.map +1 -0
- package/dist/resolver/levenshtein.js +54 -0
- package/dist/resolver/levenshtein.js.map +1 -0
- package/dist/resolver/resolve.d.ts +7 -0
- package/dist/resolver/resolve.d.ts.map +1 -0
- package/dist/resolver/resolve.js +393 -0
- package/dist/resolver/resolve.js.map +1 -0
- package/dist/resolver/scope.d.ts +34 -0
- package/dist/resolver/scope.d.ts.map +1 -0
- package/dist/resolver/scope.js +51 -0
- package/dist/resolver/scope.js.map +1 -0
- package/dist/validator/id-tracker.d.ts +14 -0
- package/dist/validator/id-tracker.d.ts.map +1 -0
- package/dist/validator/id-tracker.js +28 -0
- package/dist/validator/id-tracker.js.map +1 -0
- package/dist/validator/node-validators.d.ts +6 -0
- package/dist/validator/node-validators.d.ts.map +1 -0
- package/dist/validator/node-validators.js +808 -0
- package/dist/validator/node-validators.js.map +1 -0
- package/dist/validator/validate.d.ts +17 -0
- package/dist/validator/validate.d.ts.map +1 -0
- package/dist/validator/validate.js +27 -0
- package/dist/validator/validate.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,400 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Edict Contract Verifier
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Verifies pre/post contracts on functions using Z3 SMT solver.
|
|
5
|
+
// For each postcondition, checks: preconditions ∧ ¬postcondition.
|
|
6
|
+
// - unsat → proven ✓
|
|
7
|
+
// - sat → counterexample → ContractFailureError
|
|
8
|
+
// - unknown → VerificationTimeoutError
|
|
9
|
+
import { contractFailure, verificationTimeout, undecidablePredicate, preconditionNotMet, } from "../errors/structured-errors.js";
|
|
10
|
+
import { getZ3 } from "./z3-context.js";
|
|
11
|
+
import { createParamVariables, translateExpr, translateExprList, } from "./translate.js";
|
|
12
|
+
const TIMEOUT_MS = 5000;
|
|
13
|
+
/**
|
|
14
|
+
* Verify all contracts in the module.
|
|
15
|
+
* Returns StructuredError[] — empty if all contracts are proven.
|
|
16
|
+
*/
|
|
17
|
+
export async function contractVerify(module) {
|
|
18
|
+
// Build function defs map (once)
|
|
19
|
+
const functionDefs = new Map();
|
|
20
|
+
const allFunctions = [];
|
|
21
|
+
for (const def of module.definitions) {
|
|
22
|
+
if (def.kind === "fn") {
|
|
23
|
+
functionDefs.set(def.name, def);
|
|
24
|
+
allFunctions.push(def);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
// Check if ANY function has contracts or call sites worth checking
|
|
28
|
+
const fnsWithContracts = allFunctions.filter(fn => fn.contracts.length > 0);
|
|
29
|
+
const hasPreconditions = fnsWithContracts.some(fn => fn.contracts.some(c => c.kind === "pre"));
|
|
30
|
+
// No contracts at all → nothing to verify
|
|
31
|
+
if (fnsWithContracts.length === 0 && !hasPreconditions)
|
|
32
|
+
return [];
|
|
33
|
+
const ctx = await getZ3();
|
|
34
|
+
const errors = [];
|
|
35
|
+
// Phase 1: Verify postconditions for functions with contracts
|
|
36
|
+
for (const fn of fnsWithContracts) {
|
|
37
|
+
const fnErrors = await verifyFunction(ctx, fn, module);
|
|
38
|
+
errors.push(...fnErrors);
|
|
39
|
+
}
|
|
40
|
+
// Phase 2: Verify callsite preconditions for ALL functions
|
|
41
|
+
if (hasPreconditions) {
|
|
42
|
+
for (const fn of allFunctions) {
|
|
43
|
+
const csErrors = await verifyCallSitePreconditions(ctx, fn, functionDefs, module);
|
|
44
|
+
errors.push(...csErrors);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return errors;
|
|
48
|
+
}
|
|
49
|
+
// ---------------------------------------------------------------------------
|
|
50
|
+
// Per-function verification
|
|
51
|
+
// ---------------------------------------------------------------------------
|
|
52
|
+
async function verifyFunction(ctx, fn, module) {
|
|
53
|
+
const errors = [];
|
|
54
|
+
// Create translation context
|
|
55
|
+
const tctx = {
|
|
56
|
+
ctx,
|
|
57
|
+
variables: new Map(),
|
|
58
|
+
errors: [],
|
|
59
|
+
module,
|
|
60
|
+
};
|
|
61
|
+
// Create Z3 variables for all parameters
|
|
62
|
+
const allParamsSupported = createParamVariables(tctx, fn.params);
|
|
63
|
+
if (!allParamsSupported) {
|
|
64
|
+
// Can't verify functions with unsupported param types — skip silently
|
|
65
|
+
return errors;
|
|
66
|
+
}
|
|
67
|
+
// Translate body to bind `result` (supports multi-expression bodies)
|
|
68
|
+
const firstContract = fn.contracts[0];
|
|
69
|
+
const cachedBodyExpr = translateExprList(tctx, fn.body, firstContract.id, fn.name);
|
|
70
|
+
if (cachedBodyExpr !== null) {
|
|
71
|
+
// Create `result` variable with same sort as the body expression
|
|
72
|
+
const sortName = cachedBodyExpr.sort.name();
|
|
73
|
+
const resultVar = sortName === "Int"
|
|
74
|
+
? ctx.Int.const("result")
|
|
75
|
+
: sortName === "Real"
|
|
76
|
+
? ctx.Real.const("result")
|
|
77
|
+
: sortName === "Bool"
|
|
78
|
+
? ctx.Bool.const("result")
|
|
79
|
+
: null;
|
|
80
|
+
if (resultVar !== null) {
|
|
81
|
+
tctx.variables.set("result", resultVar);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
// Clear translation errors from body translation (they're not contract errors)
|
|
85
|
+
tctx.errors = [];
|
|
86
|
+
// Separate contracts into preconditions and postconditions
|
|
87
|
+
const preconds = [];
|
|
88
|
+
const postconds = [];
|
|
89
|
+
for (const c of fn.contracts) {
|
|
90
|
+
if (c.kind === "pre")
|
|
91
|
+
preconds.push(c);
|
|
92
|
+
else
|
|
93
|
+
postconds.push(c);
|
|
94
|
+
}
|
|
95
|
+
// If no postconditions, nothing to verify
|
|
96
|
+
if (postconds.length === 0)
|
|
97
|
+
return errors;
|
|
98
|
+
// Translate all preconditions
|
|
99
|
+
const translatedPres = [];
|
|
100
|
+
for (const pre of preconds) {
|
|
101
|
+
const z3Pre = translateExpr(tctx, pre.condition, pre.id, fn.name);
|
|
102
|
+
if (z3Pre === null) {
|
|
103
|
+
// Can't translate precondition — all postconditions become undecidable
|
|
104
|
+
for (const post of postconds) {
|
|
105
|
+
errors.push(undecidablePredicate(fn.id, post.id, fn.name, "untranslatable_precondition"));
|
|
106
|
+
}
|
|
107
|
+
flushTranslationErrors(tctx, fn.id, errors);
|
|
108
|
+
return errors;
|
|
109
|
+
}
|
|
110
|
+
translatedPres.push(z3Pre);
|
|
111
|
+
}
|
|
112
|
+
// Create result binding (result == body) using cached body translation
|
|
113
|
+
let resultBinding = null;
|
|
114
|
+
if (cachedBodyExpr !== null && tctx.variables.has("result")) {
|
|
115
|
+
resultBinding = tctx.variables.get("result").eq(cachedBodyExpr);
|
|
116
|
+
}
|
|
117
|
+
// Verify each postcondition
|
|
118
|
+
for (const post of postconds) {
|
|
119
|
+
const z3Post = translateExpr(tctx, post.condition, post.id, fn.name);
|
|
120
|
+
if (z3Post === null) {
|
|
121
|
+
// Flush errors for this contract
|
|
122
|
+
const relevantErrors = tctx.errors.filter(e => e.contractId === post.id);
|
|
123
|
+
for (const te of relevantErrors) {
|
|
124
|
+
errors.push(undecidablePredicate(fn.id, te.contractId, fn.name, te.unsupportedNodeKind));
|
|
125
|
+
}
|
|
126
|
+
tctx.errors = tctx.errors.filter(e => e.contractId !== post.id);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
// Create a fresh solver for each postcondition
|
|
130
|
+
const solver = new ctx.Solver();
|
|
131
|
+
solver.set("timeout", TIMEOUT_MS);
|
|
132
|
+
// Assert preconditions
|
|
133
|
+
for (const pre of translatedPres) {
|
|
134
|
+
solver.add(pre);
|
|
135
|
+
}
|
|
136
|
+
// Assert result binding if available
|
|
137
|
+
if (resultBinding !== null) {
|
|
138
|
+
solver.add(resultBinding);
|
|
139
|
+
}
|
|
140
|
+
// Assert negation of postcondition (must be Bool sort)
|
|
141
|
+
try {
|
|
142
|
+
solver.add(ctx.Not(z3Post));
|
|
143
|
+
}
|
|
144
|
+
catch {
|
|
145
|
+
// z3Post is not a Bool — postcondition is non-boolean → undecidable
|
|
146
|
+
errors.push(undecidablePredicate(fn.id, post.id, fn.name, "non_boolean_postcondition"));
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
// Check
|
|
150
|
+
const result = await solver.check();
|
|
151
|
+
if (result === "sat") {
|
|
152
|
+
// Postcondition violated — extract counterexample
|
|
153
|
+
const model = solver.model();
|
|
154
|
+
const counterexample = {};
|
|
155
|
+
for (const p of fn.params) {
|
|
156
|
+
const v = tctx.variables.get(p.name);
|
|
157
|
+
if (v) {
|
|
158
|
+
try {
|
|
159
|
+
const val = model.eval(v, true);
|
|
160
|
+
counterexample[p.name] = val.toString();
|
|
161
|
+
}
|
|
162
|
+
catch {
|
|
163
|
+
counterexample[p.name] = "?";
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
errors.push(contractFailure(fn.id, post.id, fn.name, "post", counterexample));
|
|
168
|
+
}
|
|
169
|
+
else if (result === "unknown") {
|
|
170
|
+
errors.push(verificationTimeout(fn.id, post.id, fn.name, TIMEOUT_MS));
|
|
171
|
+
}
|
|
172
|
+
// result === "unsat" → proven, no error
|
|
173
|
+
}
|
|
174
|
+
// Flush any remaining translation errors
|
|
175
|
+
flushTranslationErrors(tctx, fn.id, errors);
|
|
176
|
+
return errors;
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Collect all ident-based call sites from an expression list.
|
|
180
|
+
* Returns callee name, call-site node id, and argument expressions.
|
|
181
|
+
*/
|
|
182
|
+
function collectCallSites(exprs) {
|
|
183
|
+
const sites = [];
|
|
184
|
+
function walk(expr, conditions) {
|
|
185
|
+
switch (expr.kind) {
|
|
186
|
+
case "call":
|
|
187
|
+
for (const arg of expr.args)
|
|
188
|
+
walk(arg, conditions);
|
|
189
|
+
if (expr.fn.kind === "ident") {
|
|
190
|
+
sites.push({
|
|
191
|
+
calleeName: expr.fn.name,
|
|
192
|
+
callSiteId: expr.id,
|
|
193
|
+
args: expr.args,
|
|
194
|
+
pathConditions: [...conditions],
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
else {
|
|
198
|
+
walk(expr.fn, conditions);
|
|
199
|
+
}
|
|
200
|
+
break;
|
|
201
|
+
case "if": {
|
|
202
|
+
// Calls in the condition itself don't gain branch info
|
|
203
|
+
walk(expr.condition, conditions);
|
|
204
|
+
// then branch: condition is true
|
|
205
|
+
const thenConds = [...conditions, expr.condition];
|
|
206
|
+
for (const e of expr.then)
|
|
207
|
+
walk(e, thenConds);
|
|
208
|
+
// else branch: condition is false (synthesize not)
|
|
209
|
+
if (expr.else) {
|
|
210
|
+
const elseConds = [...conditions, {
|
|
211
|
+
kind: "unop",
|
|
212
|
+
id: "synth-not",
|
|
213
|
+
op: "not",
|
|
214
|
+
operand: expr.condition,
|
|
215
|
+
}];
|
|
216
|
+
for (const e of expr.else)
|
|
217
|
+
walk(e, elseConds);
|
|
218
|
+
}
|
|
219
|
+
break;
|
|
220
|
+
}
|
|
221
|
+
case "let":
|
|
222
|
+
walk(expr.value, conditions);
|
|
223
|
+
break;
|
|
224
|
+
case "match":
|
|
225
|
+
walk(expr.target, conditions);
|
|
226
|
+
for (const arm of expr.arms)
|
|
227
|
+
for (const e of arm.body)
|
|
228
|
+
walk(e, conditions);
|
|
229
|
+
break;
|
|
230
|
+
case "block":
|
|
231
|
+
for (const e of expr.body)
|
|
232
|
+
walk(e, conditions);
|
|
233
|
+
break;
|
|
234
|
+
case "binop":
|
|
235
|
+
walk(expr.left, conditions);
|
|
236
|
+
walk(expr.right, conditions);
|
|
237
|
+
break;
|
|
238
|
+
case "unop":
|
|
239
|
+
walk(expr.operand, conditions);
|
|
240
|
+
break;
|
|
241
|
+
case "array":
|
|
242
|
+
case "tuple_expr":
|
|
243
|
+
for (const e of expr.elements)
|
|
244
|
+
walk(e, conditions);
|
|
245
|
+
break;
|
|
246
|
+
case "record_expr":
|
|
247
|
+
case "enum_constructor":
|
|
248
|
+
for (const f of expr.fields)
|
|
249
|
+
walk(f.value, conditions);
|
|
250
|
+
break;
|
|
251
|
+
case "access":
|
|
252
|
+
walk(expr.target, conditions);
|
|
253
|
+
break;
|
|
254
|
+
case "lambda":
|
|
255
|
+
case "literal":
|
|
256
|
+
case "ident":
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
for (const expr of exprs)
|
|
261
|
+
walk(expr, []);
|
|
262
|
+
return sites;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Verify that a function's call sites satisfy callee preconditions.
|
|
266
|
+
* For each call f(...args) where f has preconditions, check that
|
|
267
|
+
* the caller's context (params + own preconditions) implies each
|
|
268
|
+
* callee precondition with args substituted for params.
|
|
269
|
+
*/
|
|
270
|
+
async function verifyCallSitePreconditions(ctx, callerFn, functionDefs, module) {
|
|
271
|
+
const errors = [];
|
|
272
|
+
// Find all call sites in the caller's body
|
|
273
|
+
const callSites = collectCallSites(callerFn.body);
|
|
274
|
+
if (callSites.length === 0)
|
|
275
|
+
return errors;
|
|
276
|
+
// Filter to calls with preconditions (self-recursive calls now supported via path conditions)
|
|
277
|
+
const relevantSites = callSites.filter(site => {
|
|
278
|
+
const callee = functionDefs.get(site.calleeName);
|
|
279
|
+
return callee && callee.contracts.some(c => c.kind === "pre");
|
|
280
|
+
});
|
|
281
|
+
if (relevantSites.length === 0)
|
|
282
|
+
return errors;
|
|
283
|
+
// Create translation context for the caller
|
|
284
|
+
const tctx = {
|
|
285
|
+
ctx,
|
|
286
|
+
variables: new Map(),
|
|
287
|
+
errors: [],
|
|
288
|
+
module,
|
|
289
|
+
};
|
|
290
|
+
// Create Z3 variables for caller's params
|
|
291
|
+
const allParamsSupported = createParamVariables(tctx, callerFn.params);
|
|
292
|
+
if (!allParamsSupported)
|
|
293
|
+
return errors;
|
|
294
|
+
// Translate caller's preconditions (assumptions)
|
|
295
|
+
const callerPres = [];
|
|
296
|
+
for (const c of callerFn.contracts) {
|
|
297
|
+
if (c.kind === "pre") {
|
|
298
|
+
const z3Pre = translateExpr(tctx, c.condition, c.id, callerFn.name);
|
|
299
|
+
if (z3Pre !== null)
|
|
300
|
+
callerPres.push(z3Pre);
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
tctx.errors = []; // Clear any translation errors from precond translation
|
|
304
|
+
// Check each relevant call site
|
|
305
|
+
for (const site of relevantSites) {
|
|
306
|
+
const callee = functionDefs.get(site.calleeName);
|
|
307
|
+
const calleePres = callee.contracts.filter(c => c.kind === "pre");
|
|
308
|
+
// Translate call-site arguments in caller's context
|
|
309
|
+
const translatedArgs = [];
|
|
310
|
+
let argsOk = true;
|
|
311
|
+
for (const arg of site.args) {
|
|
312
|
+
const z3Arg = translateExpr(tctx, arg, "callsite", callerFn.name);
|
|
313
|
+
if (z3Arg === null) {
|
|
314
|
+
argsOk = false;
|
|
315
|
+
break;
|
|
316
|
+
}
|
|
317
|
+
translatedArgs.push(z3Arg);
|
|
318
|
+
}
|
|
319
|
+
tctx.errors = []; // Clear arg translation errors
|
|
320
|
+
if (!argsOk)
|
|
321
|
+
continue;
|
|
322
|
+
// Arity check
|
|
323
|
+
if (translatedArgs.length !== callee.params.length)
|
|
324
|
+
continue;
|
|
325
|
+
// For each callee precondition, verify caller satisfies it
|
|
326
|
+
for (const pre of calleePres) {
|
|
327
|
+
// Save variable state
|
|
328
|
+
const savedVars = new Map(tctx.variables);
|
|
329
|
+
// Substitute callee params with translated args
|
|
330
|
+
for (let i = 0; i < callee.params.length; i++) {
|
|
331
|
+
tctx.variables.set(callee.params[i].name, translatedArgs[i]);
|
|
332
|
+
}
|
|
333
|
+
// Translate the precondition with substitutions active
|
|
334
|
+
const z3Pre = translateExpr(tctx, pre.condition, pre.id, callerFn.name);
|
|
335
|
+
// Restore variables
|
|
336
|
+
tctx.variables = savedVars;
|
|
337
|
+
tctx.errors = [];
|
|
338
|
+
if (z3Pre === null)
|
|
339
|
+
continue; // Can't verify this precondition
|
|
340
|
+
// Check: caller_preconds ∧ path_conditions ∧ ¬P[args/params]
|
|
341
|
+
const solver = new ctx.Solver();
|
|
342
|
+
solver.set("timeout", TIMEOUT_MS);
|
|
343
|
+
for (const cp of callerPres)
|
|
344
|
+
solver.add(cp);
|
|
345
|
+
// Assert path conditions from enclosing if branches
|
|
346
|
+
for (const pathCond of site.pathConditions) {
|
|
347
|
+
const z3PathCond = translateExpr(tctx, pathCond, "callsite", callerFn.name);
|
|
348
|
+
tctx.errors = []; // Clear translation errors
|
|
349
|
+
if (z3PathCond !== null) {
|
|
350
|
+
try {
|
|
351
|
+
solver.add(z3PathCond);
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
// Non-boolean path condition — skip
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
try {
|
|
359
|
+
solver.add(ctx.Not(z3Pre));
|
|
360
|
+
}
|
|
361
|
+
catch {
|
|
362
|
+
// z3Pre is not a Bool — can't verify this precondition
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
const result = await solver.check();
|
|
366
|
+
if (result === "sat") {
|
|
367
|
+
const model = solver.model();
|
|
368
|
+
const counterexample = {};
|
|
369
|
+
for (const p of callerFn.params) {
|
|
370
|
+
const v = tctx.variables.get(p.name);
|
|
371
|
+
if (v) {
|
|
372
|
+
try {
|
|
373
|
+
const val = model.eval(v, true);
|
|
374
|
+
counterexample[p.name] = val.toString();
|
|
375
|
+
}
|
|
376
|
+
catch {
|
|
377
|
+
counterexample[p.name] = "?";
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
errors.push(preconditionNotMet(callerFn.id, site.callSiteId, callerFn.name, site.calleeName, pre.id, counterexample));
|
|
382
|
+
}
|
|
383
|
+
else if (result === "unknown") {
|
|
384
|
+
errors.push(verificationTimeout(callerFn.id, pre.id, callerFn.name, TIMEOUT_MS));
|
|
385
|
+
}
|
|
386
|
+
// "unsat" → proven ✔
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
return errors;
|
|
390
|
+
}
|
|
391
|
+
// ---------------------------------------------------------------------------
|
|
392
|
+
// Helpers
|
|
393
|
+
// ---------------------------------------------------------------------------
|
|
394
|
+
function flushTranslationErrors(tctx, nodeId, errors) {
|
|
395
|
+
for (const te of tctx.errors) {
|
|
396
|
+
errors.push(undecidablePredicate(nodeId, te.contractId, te.functionName, te.unsupportedNodeKind));
|
|
397
|
+
}
|
|
398
|
+
tctx.errors = [];
|
|
399
|
+
}
|
|
400
|
+
//# sourceMappingURL=verify.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verify.js","sourceRoot":"","sources":["../../src/contracts/verify.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type Context } from "z3-solver";
|
|
2
|
+
type Z3Context = Context<"main">;
|
|
3
|
+
/**
|
|
4
|
+
* Get or initialize the Z3 context (lazy singleton).
|
|
5
|
+
* Z3 WASM initialization is expensive (~1s), so we cache the context.
|
|
6
|
+
*
|
|
7
|
+
* The returned Context has the high-level API: Int, Bool, Real, Solver,
|
|
8
|
+
* and operations like Not, And, Or, Implies.
|
|
9
|
+
*/
|
|
10
|
+
export declare function getZ3(): Promise<Z3Context>;
|
|
11
|
+
/** Reset the Z3 context (used by tests). */
|
|
12
|
+
export declare function resetZ3(): void;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=z3-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"z3-context.d.ts","sourceRoot":"","sources":["../../src/contracts/z3-context.ts"],"names":[],"mappings":"AAIA,OAAO,EAAQ,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAE/C,KAAK,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;AAIjC;;;;;;GAMG;AACH,wBAAsB,KAAK,IAAI,OAAO,CAAC,SAAS,CAAC,CAMhD;AAED,4CAA4C;AAC5C,wBAAgB,OAAO,IAAI,IAAI,CAE9B"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Z3 Context — Lazy singleton for Z3 WASM initialization + context
|
|
3
|
+
// =============================================================================
|
|
4
|
+
import { init } from "z3-solver";
|
|
5
|
+
let z3Ctx = null;
|
|
6
|
+
/**
|
|
7
|
+
* Get or initialize the Z3 context (lazy singleton).
|
|
8
|
+
* Z3 WASM initialization is expensive (~1s), so we cache the context.
|
|
9
|
+
*
|
|
10
|
+
* The returned Context has the high-level API: Int, Bool, Real, Solver,
|
|
11
|
+
* and operations like Not, And, Or, Implies.
|
|
12
|
+
*/
|
|
13
|
+
export async function getZ3() {
|
|
14
|
+
if (!z3Ctx) {
|
|
15
|
+
const { Context } = await init();
|
|
16
|
+
z3Ctx = Context("main");
|
|
17
|
+
}
|
|
18
|
+
return z3Ctx;
|
|
19
|
+
}
|
|
20
|
+
/** Reset the Z3 context (used by tests). */
|
|
21
|
+
export function resetZ3() {
|
|
22
|
+
z3Ctx = null;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=z3-context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"z3-context.js","sourceRoot":"","sources":["../../src/contracts/z3-context.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,mEAAmE;AACnE,gFAAgF;AAEhF,OAAO,EAAE,IAAI,EAAgB,MAAM,WAAW,CAAC;AAI/C,IAAI,KAAK,GAAqB,IAAI,CAAC;AAEnC;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK;IACvB,IAAI,CAAC,KAAK,EAAE,CAAC;QACT,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;QACjC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,KAAK,CAAC;AACjB,CAAC;AAED,4CAA4C;AAC5C,MAAM,UAAU,OAAO;IACnB,KAAK,GAAG,IAAI,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { EdictModule, Expression, FunctionDef } from "../ast/nodes.js";
|
|
2
|
+
export interface CallEdge {
|
|
3
|
+
calleeName: string;
|
|
4
|
+
callSiteNodeId: string;
|
|
5
|
+
}
|
|
6
|
+
export type CallGraph = Map<string, CallEdge[]>;
|
|
7
|
+
/**
|
|
8
|
+
* Walk expressions and collect all ident-based function calls.
|
|
9
|
+
* Recurses into all expression types except lambda bodies (opaque).
|
|
10
|
+
*/
|
|
11
|
+
export declare function collectCalls(exprs: Expression[]): CallEdge[];
|
|
12
|
+
/**
|
|
13
|
+
* Build the module call graph: edges per function, function defs, and imported names.
|
|
14
|
+
* Only walks FunctionDef.body — contracts are Z3 specs, not runtime code.
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildCallGraph(module: EdictModule): {
|
|
17
|
+
graph: CallGraph;
|
|
18
|
+
functionDefs: Map<string, FunctionDef>;
|
|
19
|
+
importedNames: Set<string>;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=call-graph.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-graph.d.ts","sourceRoot":"","sources":["../../src/effects/call-graph.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EACR,WAAW,EACX,UAAU,EACV,WAAW,EACd,MAAM,iBAAiB,CAAC;AAOzB,MAAM,WAAW,QAAQ;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;AAMhD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,QAAQ,EAAE,CAgF5D;AAMD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG;IACjD,KAAK,EAAE,SAAS,CAAC;IACjB,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACvC,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC9B,CA0CA"}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// =============================================================================
|
|
2
|
+
// Call Graph Builder
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Walks expression trees to discover function call edges for effect checking.
|
|
5
|
+
// Only ident-based calls create edges. Lambdas are opaque.
|
|
6
|
+
import { BUILTIN_FUNCTIONS } from "../codegen/builtins.js";
|
|
7
|
+
// =============================================================================
|
|
8
|
+
// Expression Walker
|
|
9
|
+
// =============================================================================
|
|
10
|
+
/**
|
|
11
|
+
* Walk expressions and collect all ident-based function calls.
|
|
12
|
+
* Recurses into all expression types except lambda bodies (opaque).
|
|
13
|
+
*/
|
|
14
|
+
export function collectCalls(exprs) {
|
|
15
|
+
const edges = [];
|
|
16
|
+
function walk(expr) {
|
|
17
|
+
switch (expr.kind) {
|
|
18
|
+
case "call":
|
|
19
|
+
// Always recurse into args
|
|
20
|
+
for (const arg of expr.args)
|
|
21
|
+
walk(arg);
|
|
22
|
+
if (expr.fn.kind === "ident") {
|
|
23
|
+
// Ident-based call → record edge
|
|
24
|
+
edges.push({
|
|
25
|
+
calleeName: expr.fn.name,
|
|
26
|
+
callSiteNodeId: expr.id,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
// Non-ident fn (e.g., complex expression) → no edge, but walk fn
|
|
31
|
+
walk(expr.fn);
|
|
32
|
+
}
|
|
33
|
+
break;
|
|
34
|
+
case "if":
|
|
35
|
+
walk(expr.condition);
|
|
36
|
+
for (const e of expr.then)
|
|
37
|
+
walk(e);
|
|
38
|
+
if (expr.else) {
|
|
39
|
+
for (const e of expr.else)
|
|
40
|
+
walk(e);
|
|
41
|
+
}
|
|
42
|
+
break;
|
|
43
|
+
case "let":
|
|
44
|
+
walk(expr.value);
|
|
45
|
+
break;
|
|
46
|
+
case "match":
|
|
47
|
+
walk(expr.target);
|
|
48
|
+
for (const arm of expr.arms) {
|
|
49
|
+
for (const e of arm.body)
|
|
50
|
+
walk(e);
|
|
51
|
+
}
|
|
52
|
+
break;
|
|
53
|
+
case "block":
|
|
54
|
+
for (const e of expr.body)
|
|
55
|
+
walk(e);
|
|
56
|
+
break;
|
|
57
|
+
case "binop":
|
|
58
|
+
walk(expr.left);
|
|
59
|
+
walk(expr.right);
|
|
60
|
+
break;
|
|
61
|
+
case "unop":
|
|
62
|
+
walk(expr.operand);
|
|
63
|
+
break;
|
|
64
|
+
case "array":
|
|
65
|
+
case "tuple_expr":
|
|
66
|
+
for (const e of expr.elements)
|
|
67
|
+
walk(e);
|
|
68
|
+
break;
|
|
69
|
+
case "record_expr":
|
|
70
|
+
case "enum_constructor":
|
|
71
|
+
for (const f of expr.fields)
|
|
72
|
+
walk(f.value);
|
|
73
|
+
break;
|
|
74
|
+
case "access":
|
|
75
|
+
walk(expr.target);
|
|
76
|
+
break;
|
|
77
|
+
case "lambda":
|
|
78
|
+
// Opaque — do not recurse into lambda body
|
|
79
|
+
break;
|
|
80
|
+
case "literal":
|
|
81
|
+
case "ident":
|
|
82
|
+
// Leaf nodes — no recursion
|
|
83
|
+
break;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
for (const expr of exprs)
|
|
87
|
+
walk(expr);
|
|
88
|
+
return edges;
|
|
89
|
+
}
|
|
90
|
+
// =============================================================================
|
|
91
|
+
// Call Graph Builder
|
|
92
|
+
// =============================================================================
|
|
93
|
+
/**
|
|
94
|
+
* Build the module call graph: edges per function, function defs, and imported names.
|
|
95
|
+
* Only walks FunctionDef.body — contracts are Z3 specs, not runtime code.
|
|
96
|
+
*/
|
|
97
|
+
export function buildCallGraph(module) {
|
|
98
|
+
const graph = new Map();
|
|
99
|
+
const functionDefs = new Map();
|
|
100
|
+
const importedNames = new Set();
|
|
101
|
+
// Register builtins as synthetic function defs so effect checker
|
|
102
|
+
// can verify callers declare the correct effects.
|
|
103
|
+
for (const [name, builtin] of BUILTIN_FUNCTIONS) {
|
|
104
|
+
functionDefs.set(name, {
|
|
105
|
+
kind: "fn",
|
|
106
|
+
id: `builtin-${name}`,
|
|
107
|
+
name,
|
|
108
|
+
params: [],
|
|
109
|
+
returnType: builtin.type.returnType,
|
|
110
|
+
effects: [...builtin.effects],
|
|
111
|
+
contracts: [],
|
|
112
|
+
body: [],
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
// Collect imported names
|
|
116
|
+
for (const imp of module.imports) {
|
|
117
|
+
for (const name of imp.names) {
|
|
118
|
+
importedNames.add(name);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// Collect function definitions
|
|
122
|
+
for (const def of module.definitions) {
|
|
123
|
+
if (def.kind === "fn") {
|
|
124
|
+
functionDefs.set(def.name, def);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Build edges for each user function (not builtins)
|
|
128
|
+
for (const def of module.definitions) {
|
|
129
|
+
if (def.kind === "fn") {
|
|
130
|
+
graph.set(def.name, collectCalls(def.body));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return { graph, functionDefs, importedNames };
|
|
134
|
+
}
|
|
135
|
+
//# sourceMappingURL=call-graph.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"call-graph.js","sourceRoot":"","sources":["../../src/effects/call-graph.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { EdictModule } from "../ast/nodes.js";
|
|
2
|
+
import type { StructuredError } from "../errors/structured-errors.js";
|
|
3
|
+
/**
|
|
4
|
+
* Check effect consistency across all functions in the module.
|
|
5
|
+
*
|
|
6
|
+
* For each function, iterates its call edges (skipping imports):
|
|
7
|
+
* - If caller is `pure`: any callee with non-pure effects → `effect_in_pure` error
|
|
8
|
+
* - If caller is not `pure`: missing caller effects → `effect_violation` error
|
|
9
|
+
*
|
|
10
|
+
* Returns an empty array if all effects are consistent.
|
|
11
|
+
*/
|
|
12
|
+
export declare function effectCheck(module: EdictModule): StructuredError[];
|
|
13
|
+
//# sourceMappingURL=effect-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"effect-check.d.ts","sourceRoot":"","sources":["../../src/effects/effect-check.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AAItE;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,eAAe,EAAE,CA4ClE"}
|