Skip to content

Commit ede9e5f

Browse files
authored
[WIP] More TS Binding Features (Z3Prover#6412)
* feat: basic quantfier support * feat: added isQuantifier * feat: expanded functions * wip: (lambda broken) * temp fix to LambdaImpl typing issue * feat: function type inference * formatting with prettier * fix: imported from invalid module * fix isBool bug and dumping to smtlib * substitution and model.updateValue * api to add custom func interps to model * fix: building * properly handling uint32 -> number conversion in z3 TS wrapper * added simplify * remame Add->Sum and Mul->Product * formatting
1 parent 5e30323 commit ede9e5f

File tree

9 files changed

+1381
-330
lines changed

9 files changed

+1381
-330
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// @ts-ignore we're not going to bother with types for this
2+
import process from 'process';
3+
import { init } from '../../build/node';
4+
import assert from 'assert';
5+
6+
(async () => {
7+
let { Context, em } = await init();
8+
let z3 = Context('main');
9+
10+
const x = z3.BitVec.const('x', 256);
11+
const y = z3.BitVec.const('y', 256);
12+
const z = z3.BitVec.const('z', 256);
13+
const xPlusY = x.add(y);
14+
const xPlusZ = x.add(z);
15+
const expr = xPlusY.mul(xPlusZ);
16+
17+
const to_check = expr.eq(z3.Const('test', expr.sort));
18+
19+
const solver = new z3.Solver();
20+
solver.add(to_check);
21+
const cr = await solver.check();
22+
console.log(cr);
23+
assert(cr === 'sat');
24+
25+
const model = solver.model();
26+
let modelStr = model.sexpr();
27+
modelStr = modelStr.replace(/\n/g, ' ');
28+
console.log("Model: ", modelStr);
29+
30+
const exprs = z3.ast_from_string(modelStr);
31+
console.log(exprs);
32+
33+
})().catch(e => {
34+
console.error('error', e);
35+
process.exit(1);
36+
});

src/api/js/examples/low-level/example-raw.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// @ts-ignore we're not going to bother with types for this
12
import process from 'process';
23
import { init, Z3_error_code } from '../../build/node';
34

src/api/js/package-lock.json

+15-29
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/api/js/package.json

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{
22
"name": "z3-solver",
3+
"version": "0.1.0",
34
"keywords": [
45
"Z3",
56
"theorem",
@@ -26,8 +27,8 @@
2627
"build:ts:generate": "ts-node --transpileOnly scripts/make-ts-wrapper.ts src/low-level/wrapper.__GENERATED__.ts src/low-level/types.__GENERATED__.ts",
2728
"build:wasm": "ts-node --transpileOnly ./scripts/build-wasm.ts",
2829
"clean": "rimraf build 'src/**/*.__GENERATED__.*'",
29-
"lint": "prettier -c '{,src/,scripts/,examples}*.{js,ts}'",
30-
"format": "prettier --write '{,src/,scripts/}*.{js,ts}'",
30+
"lint": "prettier -c '{./,src/,scripts/,examples/}**/*.{js,ts}'",
31+
"format": "prettier --write '{./,src/,scripts/}**/*.{js,ts}'",
3132
"test": "jest",
3233
"docs": "typedoc",
3334
"check-engine": "check-engine"
@@ -53,8 +54,8 @@
5354
"ts-expect": "^1.3.0",
5455
"ts-jest": "^28.0.3",
5556
"ts-node": "^10.8.0",
56-
"typedoc": "^0.22.17",
57-
"typescript": "^4.5.4"
57+
"typedoc": "^0.23.16",
58+
"typescript": "^4.8.4"
5859
},
5960
"license": "MIT",
6061
"dependencies": {

src/api/js/scripts/make-ts-wrapper.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ function makeTsWrapper() {
7676
}
7777

7878
const isInParam = (p: FuncParam) => p.kind !== undefined && ['in', 'in_array'].includes(p.kind);
79+
7980
function wrapFunction(fn: Func) {
8081
if (CUSTOM_IMPLEMENTATIONS.includes(fn.name)) {
8182
return null;
@@ -104,7 +105,7 @@ function makeTsWrapper() {
104105

105106
let isAsync = asyncFuncs.includes(fn.name);
106107
let trivial =
107-
!['string', 'boolean'].includes(fn.ret) &&
108+
!['string', 'boolean', 'unsigned'].includes(fn.ret) &&
108109
!fn.nullableRet &&
109110
outParams.length === 0 &&
110111
!inParams.some(p => p.type === 'string' || p.isArray || p.nullable);
@@ -234,6 +235,7 @@ function makeTsWrapper() {
234235
function setArg() {
235236
args[outParam.idx] = memIdx === 0 ? 'outAddress' : `outAddress + ${memIdx * 4}`;
236237
}
238+
237239
let read, type;
238240
if (outParam.type === 'string') {
239241
read = `Mod.UTF8ToString(getOutUint(${memIdx}))`;
@@ -330,11 +332,15 @@ function makeTsWrapper() {
330332
if (ret === 0) {
331333
return null;
332334
}
333-
`.trim();
335+
`.trim();
336+
} else if (fn.ret === 'unsigned') {
337+
infix += `
338+
ret = (new Uint32Array([ret]))[0];
339+
`.trim();
334340
}
335341

336342
// prettier-ignore
337-
let invocation = `Mod.ccall('${isAsync ? 'async_' : ''}${fn.name}', '${cReturnType}', ${JSON.stringify(ctypes)}, [${args.map(toEm).join(', ')}])`;
343+
let invocation = `Mod.ccall('${isAsync ? "async_" : ""}${fn.name}', '${cReturnType}', ${JSON.stringify(ctypes)}, [${args.map(toEm).join(", ")}])`;
338344

339345
if (isAsync) {
340346
invocation = `await Mod.async_call(() => ${invocation})`;

src/api/js/scripts/parse-api.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ const types = {
4545
__proto__: null,
4646

4747
// these are function types I can't be bothered to parse
48-
// NSB: They can be extracted automatically from z3_api.h thanks to the use
48+
// NSB: They can be extracted automatically from z3_api.h thanks to the use
4949
// of a macro.
5050
Z3_error_handler: 'Z3_error_handler',
5151
Z3_push_eh: 'Z3_push_eh',

0 commit comments

Comments
 (0)