Skip to content

Commit

Permalink
js: Add pseudo-boolean high-level functions
Browse files Browse the repository at this point in the history
  • Loading branch information
HalfdanJ committed Oct 19, 2024
1 parent a23a8cd commit b28c861
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/api/js/src/high-level/high-level.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ describe('high-level', () => {
});

describe('booleans', () => {
it('can use pseudo-boolean constraints', async () => {
const { Bool, PbEq, Solver } = api.Context('main');
const x = Bool.const('x');
const y = Bool.const('y');

const solver = new Solver();
solver.add(PbEq([x, y], [1, 1], 1));
expect(await solver.check()).toStrictEqual('sat');

solver.add(x.eq(y));
expect(await solver.check()).toStrictEqual('unsat');
});

it("proves De Morgan's Law", async () => {
const { Bool, Not, And, Eq, Or } = api.Context('main');
const [x, y] = [Bool.const('x'), Bool.const('y')];
Expand Down
45 changes: 45 additions & 0 deletions src/api/js/src/high-level/high-level.ts
Original file line number Diff line number Diff line change
Expand Up @@ -957,6 +957,48 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
}
}

function PbEq(args: [Bool<Name>, ...Bool<Name>[]], coeffs: [number, ...number[]], k: number): Bool<Name> {
_assertContext(...args);
return new BoolImpl(
check(
Z3.mk_pbeq(
contextPtr,
args.map(arg => arg.ast),
coeffs,
k,
),
),
);
}

function PbGe(args: [Bool<Name>, ...Bool<Name>[]], coeffs: [number, ...number[]], k: number): Bool<Name> {
_assertContext(...args);
return new BoolImpl(
check(
Z3.mk_pbge(
contextPtr,
args.map(arg => arg.ast),
coeffs,
k,
),
),
);
}

function PbLe(args: [Bool<Name>, ...Bool<Name>[]], coeffs: [number, ...number[]], k: number): Bool<Name> {
_assertContext(...args);
return new BoolImpl(
check(
Z3.mk_pble(
contextPtr,
args.map(arg => arg.ast),
coeffs,
k,
),
),
);
}

function ForAll<QVarSorts extends NonEmptySortArray<Name>>(
quantifiers: ArrayIndexType<Name, QVarSorts>,
body: Bool<Name>,
Expand Down Expand Up @@ -2849,6 +2891,9 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
Not,
And,
Or,
PbEq,
PbGe,
PbLe,
ForAll,
Exists,
Lambda,
Expand Down
9 changes: 9 additions & 0 deletions src/api/js/src/high-level/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,15 @@ export interface Context<Name extends string = 'main'> {
/** @category Operations */
Or(...args: Probe<Name>[]): Probe<Name>;

/** @category Operations */
PbEq(args: [Bool<Name>, ...Bool<Name>[]], coeffs: [number, ...number[]], k: number): Bool<Name>;

/** @category Operations */
PbGe(args: [Bool<Name>, ...Bool<Name>[]], coeffs: [number, ...number[]], k: number): Bool<Name>;

/** @category Operations */
PbLe(args: [Bool<Name>, ...Bool<Name>[]], coeffs: [number, ...number[]], k: number): Bool<Name>;

// Quantifiers

/** @category Operations */
Expand Down

0 comments on commit b28c861

Please sign in to comment.