mirror of
https://github.com/Z3Prover/z3
synced 2026-07-06 15:26:15 +00:00
Add AtMost, AtLeast, unsatCore, and reasonUnknown to JS/TS API (#8118)
* Initial plan * Add AtMost, AtLeast, checkAssumptions, and unsatCore methods to JS/TS API Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Format code with prettier Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Add comprehensive documentation for Solver.check, checkAssumptions, and unsatCore methods Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Remove redundant checkAssumptions method, use check() for assumptions Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Enable unsat_core tracking in test to fix 'unknown' result Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> * Add reasonUnknown() method and use it in test to debug unknown results Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: NikolajBjorner <3085284+NikolajBjorner@users.noreply.github.com> Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
b524f63957
commit
c9528cc74e
3 changed files with 300 additions and 88 deletions
|
|
@ -559,7 +559,10 @@ describe('high-level', () => {
|
||||||
const set = Z3.Set.const('set', Z3.Int.sort());
|
const set = Z3.Set.const('set', Z3.Int.sort());
|
||||||
const [a, b] = Z3.Int.consts('a b');
|
const [a, b] = Z3.Int.consts('a b');
|
||||||
|
|
||||||
const conjecture = set.contains(a).and(set.contains(b)).implies(Z3.Set.val([a, b], Z3.Int.sort()).subsetOf(set));
|
const conjecture = set
|
||||||
|
.contains(a)
|
||||||
|
.and(set.contains(b))
|
||||||
|
.implies(Z3.Set.val([a, b], Z3.Int.sort()).subsetOf(set));
|
||||||
await prove(conjecture);
|
await prove(conjecture);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -569,7 +572,10 @@ describe('high-level', () => {
|
||||||
const set = Z3.Set.const('set', Z3.Int.sort());
|
const set = Z3.Set.const('set', Z3.Int.sort());
|
||||||
const [a, b] = Z3.Int.consts('a b');
|
const [a, b] = Z3.Int.consts('a b');
|
||||||
|
|
||||||
const conjecture = set.contains(a).and(set.contains(b)).and(Z3.Set.val([a, b], Z3.Int.sort()).eq(set));
|
const conjecture = set
|
||||||
|
.contains(a)
|
||||||
|
.and(set.contains(b))
|
||||||
|
.and(Z3.Set.val([a, b], Z3.Int.sort()).eq(set));
|
||||||
await solve(conjecture);
|
await solve(conjecture);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -583,7 +589,7 @@ describe('high-level', () => {
|
||||||
const conjecture = set.intersect(abset).subsetOf(abset);
|
const conjecture = set.intersect(abset).subsetOf(abset);
|
||||||
await prove(conjecture);
|
await prove(conjecture);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Intersection 2', async () => {
|
it('Intersection 2', async () => {
|
||||||
const Z3 = api.Context('main');
|
const Z3 = api.Context('main');
|
||||||
|
|
||||||
|
|
@ -605,7 +611,7 @@ describe('high-level', () => {
|
||||||
const conjecture = set.subsetOf(set.union(abset));
|
const conjecture = set.subsetOf(set.union(abset));
|
||||||
await prove(conjecture);
|
await prove(conjecture);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Union 2', async () => {
|
it('Union 2', async () => {
|
||||||
const Z3 = api.Context('main');
|
const Z3 = api.Context('main');
|
||||||
|
|
||||||
|
|
@ -616,14 +622,14 @@ describe('high-level', () => {
|
||||||
const conjecture = set.union(abset).subsetOf(abset);
|
const conjecture = set.union(abset).subsetOf(abset);
|
||||||
await solve(conjecture);
|
await solve(conjecture);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Complement 1', async () => {
|
it('Complement 1', async () => {
|
||||||
const Z3 = api.Context('main');
|
const Z3 = api.Context('main');
|
||||||
|
|
||||||
const set = Z3.Set.const('set', Z3.Int.sort());
|
const set = Z3.Set.const('set', Z3.Int.sort());
|
||||||
const a = Z3.Int.const('a');
|
const a = Z3.Int.const('a');
|
||||||
|
|
||||||
const conjecture = set.complement().complement().eq(set)
|
const conjecture = set.complement().complement().eq(set);
|
||||||
await prove(conjecture);
|
await prove(conjecture);
|
||||||
});
|
});
|
||||||
it('Complement 2', async () => {
|
it('Complement 2', async () => {
|
||||||
|
|
@ -632,28 +638,28 @@ describe('high-level', () => {
|
||||||
const set = Z3.Set.const('set', Z3.Int.sort());
|
const set = Z3.Set.const('set', Z3.Int.sort());
|
||||||
const a = Z3.Int.const('a');
|
const a = Z3.Int.const('a');
|
||||||
|
|
||||||
const conjecture = set.contains(a).implies(Z3.Not(set.complement().contains(a)))
|
const conjecture = set.contains(a).implies(Z3.Not(set.complement().contains(a)));
|
||||||
await prove(conjecture);
|
await prove(conjecture);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Difference', async () => {
|
it('Difference', async () => {
|
||||||
const Z3 = api.Context('main');
|
const Z3 = api.Context('main');
|
||||||
|
|
||||||
const [set1, set2] = Z3.Set.consts('set1 set2', Z3.Int.sort());
|
const [set1, set2] = Z3.Set.consts('set1 set2', Z3.Int.sort());
|
||||||
const a = Z3.Int.const('a');
|
const a = Z3.Int.const('a');
|
||||||
|
|
||||||
const conjecture = set1.contains(a).implies(Z3.Not(set2.diff(set1).contains(a)))
|
const conjecture = set1.contains(a).implies(Z3.Not(set2.diff(set1).contains(a)));
|
||||||
|
|
||||||
await prove(conjecture);
|
await prove(conjecture);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('FullSet', async () => {
|
it('FullSet', async () => {
|
||||||
const Z3 = api.Context('main');
|
const Z3 = api.Context('main');
|
||||||
|
|
||||||
const set = Z3.Set.const('set', Z3.Int.sort());
|
const set = Z3.Set.const('set', Z3.Int.sort());
|
||||||
|
|
||||||
const conjecture = set.complement().eq(Z3.FullSet(Z3.Int.sort()).diff(set));
|
const conjecture = set.complement().eq(Z3.FullSet(Z3.Int.sort()).diff(set));
|
||||||
|
|
||||||
await prove(conjecture);
|
await prove(conjecture);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -664,7 +670,7 @@ describe('high-level', () => {
|
||||||
const [a, b] = Z3.Int.consts('a b');
|
const [a, b] = Z3.Int.consts('a b');
|
||||||
|
|
||||||
const conjecture = empty.add(a).add(b).del(a).del(b).eq(empty);
|
const conjecture = empty.add(a).add(b).del(a).del(b).eq(empty);
|
||||||
|
|
||||||
await prove(conjecture);
|
await prove(conjecture);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -793,6 +799,31 @@ describe('high-level', () => {
|
||||||
});
|
});
|
||||||
expect(results).toStrictEqual([1n, 2n, 3n, 4n, 5n]);
|
expect(results).toStrictEqual([1n, 2n, 3n, 4n, 5n]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('can use check with assumptions and unsatCore', async () => {
|
||||||
|
const { Solver, Bool } = api.Context('main');
|
||||||
|
const solver = new Solver();
|
||||||
|
solver.set('unsat_core', true);
|
||||||
|
const x = Bool.const('x');
|
||||||
|
const y = Bool.const('y');
|
||||||
|
const z = Bool.const('z');
|
||||||
|
|
||||||
|
// Add conflicting assertions
|
||||||
|
solver.add(x.or(y));
|
||||||
|
solver.add(x.or(z));
|
||||||
|
|
||||||
|
// Check with assumptions that create a conflict
|
||||||
|
const result = await solver.check(x.not(), y.not(), z.not());
|
||||||
|
if (result === 'unknown') {
|
||||||
|
console.log('Solver returned unknown. Reason:', solver.reasonUnknown());
|
||||||
|
}
|
||||||
|
expect(result).toStrictEqual('unsat');
|
||||||
|
|
||||||
|
// Get the unsat core
|
||||||
|
const core = solver.unsatCore();
|
||||||
|
expect(core.length()).toBeGreaterThan(0);
|
||||||
|
expect(core.length()).toBeLessThanOrEqual(3);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('AstVector', () => {
|
describe('AstVector', () => {
|
||||||
|
|
@ -923,14 +954,14 @@ describe('high-level', () => {
|
||||||
Color.declare('red');
|
Color.declare('red');
|
||||||
Color.declare('green');
|
Color.declare('green');
|
||||||
Color.declare('blue');
|
Color.declare('blue');
|
||||||
|
|
||||||
const ColorSort = Color.create();
|
const ColorSort = Color.create();
|
||||||
|
|
||||||
// Test that we can access the constructors
|
// Test that we can access the constructors
|
||||||
expect(typeof (ColorSort as any).red).not.toBe('undefined');
|
expect(typeof (ColorSort as any).red).not.toBe('undefined');
|
||||||
expect(typeof (ColorSort as any).green).not.toBe('undefined');
|
expect(typeof (ColorSort as any).green).not.toBe('undefined');
|
||||||
expect(typeof (ColorSort as any).blue).not.toBe('undefined');
|
expect(typeof (ColorSort as any).blue).not.toBe('undefined');
|
||||||
|
|
||||||
// Test that we can access the recognizers
|
// Test that we can access the recognizers
|
||||||
expect(typeof (ColorSort as any).is_red).not.toBe('undefined');
|
expect(typeof (ColorSort as any).is_red).not.toBe('undefined');
|
||||||
expect(typeof (ColorSort as any).is_green).not.toBe('undefined');
|
expect(typeof (ColorSort as any).is_green).not.toBe('undefined');
|
||||||
|
|
@ -944,9 +975,9 @@ describe('high-level', () => {
|
||||||
const List = Datatype('List');
|
const List = Datatype('List');
|
||||||
List.declare('cons', ['car', Int.sort()], ['cdr', List]);
|
List.declare('cons', ['car', Int.sort()], ['cdr', List]);
|
||||||
List.declare('nil');
|
List.declare('nil');
|
||||||
|
|
||||||
const ListSort = List.create();
|
const ListSort = List.create();
|
||||||
|
|
||||||
// Test that constructors and accessors exist
|
// Test that constructors and accessors exist
|
||||||
expect(typeof (ListSort as any).cons).not.toBe('undefined');
|
expect(typeof (ListSort as any).cons).not.toBe('undefined');
|
||||||
expect(typeof (ListSort as any).nil).not.toBe('undefined');
|
expect(typeof (ListSort as any).nil).not.toBe('undefined');
|
||||||
|
|
@ -962,20 +993,20 @@ describe('high-level', () => {
|
||||||
// Create mutually recursive Tree and TreeList datatypes
|
// Create mutually recursive Tree and TreeList datatypes
|
||||||
const Tree = Datatype('Tree');
|
const Tree = Datatype('Tree');
|
||||||
const TreeList = Datatype('TreeList');
|
const TreeList = Datatype('TreeList');
|
||||||
|
|
||||||
Tree.declare('leaf', ['value', Int.sort()]);
|
Tree.declare('leaf', ['value', Int.sort()]);
|
||||||
Tree.declare('node', ['children', TreeList]);
|
Tree.declare('node', ['children', TreeList]);
|
||||||
TreeList.declare('nil');
|
TreeList.declare('nil');
|
||||||
TreeList.declare('cons', ['car', Tree], ['cdr', TreeList]);
|
TreeList.declare('cons', ['car', Tree], ['cdr', TreeList]);
|
||||||
|
|
||||||
const [TreeSort, TreeListSort] = Datatype.createDatatypes(Tree, TreeList);
|
const [TreeSort, TreeListSort] = Datatype.createDatatypes(Tree, TreeList);
|
||||||
|
|
||||||
// Test that both datatypes have their constructors
|
// Test that both datatypes have their constructors
|
||||||
expect(typeof (TreeSort as any).leaf).not.toBe('undefined');
|
expect(typeof (TreeSort as any).leaf).not.toBe('undefined');
|
||||||
expect(typeof (TreeSort as any).node).not.toBe('undefined');
|
expect(typeof (TreeSort as any).node).not.toBe('undefined');
|
||||||
expect(typeof (TreeListSort as any).nil).not.toBe('undefined');
|
expect(typeof (TreeListSort as any).nil).not.toBe('undefined');
|
||||||
expect(typeof (TreeListSort as any).cons).not.toBe('undefined');
|
expect(typeof (TreeListSort as any).cons).not.toBe('undefined');
|
||||||
|
|
||||||
// Test accessors exist
|
// Test accessors exist
|
||||||
expect(typeof (TreeSort as any).value).not.toBe('undefined');
|
expect(typeof (TreeSort as any).value).not.toBe('undefined');
|
||||||
expect(typeof (TreeSort as any).children).not.toBe('undefined');
|
expect(typeof (TreeSort as any).children).not.toBe('undefined');
|
||||||
|
|
|
||||||
|
|
@ -808,12 +808,12 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
sort<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSetSort<Name, ElemSort> {
|
sort<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSetSort<Name, ElemSort> {
|
||||||
return Array.sort(sort, Bool.sort());
|
return Array.sort(sort, Bool.sort());
|
||||||
},
|
},
|
||||||
const<ElemSort extends AnySort<Name>>(name: string, sort: ElemSort) : SMTSet<Name, ElemSort> {
|
const<ElemSort extends AnySort<Name>>(name: string, sort: ElemSort): SMTSet<Name, ElemSort> {
|
||||||
return new SetImpl<ElemSort>(
|
return new SetImpl<ElemSort>(
|
||||||
check(Z3.mk_const(contextPtr, _toSymbol(name), Array.sort(sort, Bool.sort()).ptr)),
|
check(Z3.mk_const(contextPtr, _toSymbol(name), Array.sort(sort, Bool.sort()).ptr)),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
consts<ElemSort extends AnySort<Name>>(names: string | string[], sort: ElemSort) : SMTSet<Name, ElemSort>[] {
|
consts<ElemSort extends AnySort<Name>>(names: string | string[], sort: ElemSort): SMTSet<Name, ElemSort>[] {
|
||||||
if (typeof names === 'string') {
|
if (typeof names === 'string') {
|
||||||
names = names.split(' ');
|
names = names.split(' ');
|
||||||
}
|
}
|
||||||
|
|
@ -822,14 +822,17 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
empty<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort> {
|
empty<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort> {
|
||||||
return EmptySet(sort);
|
return EmptySet(sort);
|
||||||
},
|
},
|
||||||
val<ElemSort extends AnySort<Name>>(values: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>[], sort: ElemSort): SMTSet<Name, ElemSort> {
|
val<ElemSort extends AnySort<Name>>(
|
||||||
|
values: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>[],
|
||||||
|
sort: ElemSort,
|
||||||
|
): SMTSet<Name, ElemSort> {
|
||||||
var result = EmptySet(sort);
|
var result = EmptySet(sort);
|
||||||
for (const value of values) {
|
for (const value of values) {
|
||||||
result = SetAdd(result, value);
|
result = SetAdd(result, value);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
},
|
||||||
}
|
};
|
||||||
|
|
||||||
const Datatype = Object.assign(
|
const Datatype = Object.assign(
|
||||||
(name: string): DatatypeImpl => {
|
(name: string): DatatypeImpl => {
|
||||||
|
|
@ -838,8 +841,8 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
{
|
{
|
||||||
createDatatypes(...datatypes: DatatypeImpl[]): DatatypeSortImpl[] {
|
createDatatypes(...datatypes: DatatypeImpl[]): DatatypeSortImpl[] {
|
||||||
return createDatatypes(...datatypes);
|
return createDatatypes(...datatypes);
|
||||||
}
|
},
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
////////////////
|
////////////////
|
||||||
|
|
@ -1058,6 +1061,32 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AtMost(args: [Bool<Name>, ...Bool<Name>[]], k: number): Bool<Name> {
|
||||||
|
_assertContext(...args);
|
||||||
|
return new BoolImpl(
|
||||||
|
check(
|
||||||
|
Z3.mk_atmost(
|
||||||
|
contextPtr,
|
||||||
|
args.map(arg => arg.ast),
|
||||||
|
k,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function AtLeast(args: [Bool<Name>, ...Bool<Name>[]], k: number): Bool<Name> {
|
||||||
|
_assertContext(...args);
|
||||||
|
return new BoolImpl(
|
||||||
|
check(
|
||||||
|
Z3.mk_atleast(
|
||||||
|
contextPtr,
|
||||||
|
args.map(arg => arg.ast),
|
||||||
|
k,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
function ForAll<QVarSorts extends NonEmptySortArray<Name>>(
|
function ForAll<QVarSorts extends NonEmptySortArray<Name>>(
|
||||||
quantifiers: ArrayIndexType<Name, QVarSorts>,
|
quantifiers: ArrayIndexType<Name, QVarSorts>,
|
||||||
body: Bool<Name>,
|
body: Bool<Name>,
|
||||||
|
|
@ -1296,41 +1325,69 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
}
|
}
|
||||||
|
|
||||||
function SetUnion<ElemSort extends AnySort<Name>>(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort> {
|
function SetUnion<ElemSort extends AnySort<Name>>(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort> {
|
||||||
return new SetImpl<ElemSort>(check(Z3.mk_set_union(contextPtr, args.map(arg => arg.ast))));
|
return new SetImpl<ElemSort>(
|
||||||
|
check(
|
||||||
|
Z3.mk_set_union(
|
||||||
|
contextPtr,
|
||||||
|
args.map(arg => arg.ast),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SetIntersect<ElemSort extends AnySort<Name>>(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort> {
|
function SetIntersect<ElemSort extends AnySort<Name>>(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort> {
|
||||||
return new SetImpl<ElemSort>(check(Z3.mk_set_intersect(contextPtr, args.map(arg => arg.ast))));
|
return new SetImpl<ElemSort>(
|
||||||
|
check(
|
||||||
|
Z3.mk_set_intersect(
|
||||||
|
contextPtr,
|
||||||
|
args.map(arg => arg.ast),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function SetDifference<ElemSort extends AnySort<Name>>(a: SMTSet<Name, ElemSort>, b: SMTSet<Name, ElemSort>): SMTSet<Name, ElemSort> {
|
function SetDifference<ElemSort extends AnySort<Name>>(
|
||||||
|
a: SMTSet<Name, ElemSort>,
|
||||||
|
b: SMTSet<Name, ElemSort>,
|
||||||
|
): SMTSet<Name, ElemSort> {
|
||||||
return new SetImpl<ElemSort>(check(Z3.mk_set_difference(contextPtr, a.ast, b.ast)));
|
return new SetImpl<ElemSort>(check(Z3.mk_set_difference(contextPtr, a.ast, b.ast)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function SetAdd<ElemSort extends AnySort<Name>>(set: SMTSet<Name, ElemSort>, elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): SMTSet<Name, ElemSort> {
|
function SetAdd<ElemSort extends AnySort<Name>>(
|
||||||
|
set: SMTSet<Name, ElemSort>,
|
||||||
|
elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>,
|
||||||
|
): SMTSet<Name, ElemSort> {
|
||||||
const arg = set.elemSort().cast(elem as any);
|
const arg = set.elemSort().cast(elem as any);
|
||||||
return new SetImpl<ElemSort>(check(Z3.mk_set_add(contextPtr, set.ast, arg.ast)));
|
return new SetImpl<ElemSort>(check(Z3.mk_set_add(contextPtr, set.ast, arg.ast)));
|
||||||
}
|
}
|
||||||
function SetDel<ElemSort extends AnySort<Name>>(set: SMTSet<Name, ElemSort>, elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): SMTSet<Name, ElemSort> {
|
function SetDel<ElemSort extends AnySort<Name>>(
|
||||||
|
set: SMTSet<Name, ElemSort>,
|
||||||
|
elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>,
|
||||||
|
): SMTSet<Name, ElemSort> {
|
||||||
const arg = set.elemSort().cast(elem as any);
|
const arg = set.elemSort().cast(elem as any);
|
||||||
return new SetImpl<ElemSort>(check(Z3.mk_set_del(contextPtr, set.ast, arg.ast)));
|
return new SetImpl<ElemSort>(check(Z3.mk_set_del(contextPtr, set.ast, arg.ast)));
|
||||||
}
|
}
|
||||||
function SetComplement<ElemSort extends AnySort<Name>>(set: SMTSet<Name, ElemSort>): SMTSet<Name, ElemSort> {
|
function SetComplement<ElemSort extends AnySort<Name>>(set: SMTSet<Name, ElemSort>): SMTSet<Name, ElemSort> {
|
||||||
return new SetImpl<ElemSort>(check(Z3.mk_set_complement(contextPtr, set.ast)));
|
return new SetImpl<ElemSort>(check(Z3.mk_set_complement(contextPtr, set.ast)));
|
||||||
}
|
}
|
||||||
|
|
||||||
function EmptySet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort> {
|
function EmptySet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort> {
|
||||||
return new SetImpl<ElemSort>(check(Z3.mk_empty_set(contextPtr, sort.ptr)));
|
return new SetImpl<ElemSort>(check(Z3.mk_empty_set(contextPtr, sort.ptr)));
|
||||||
}
|
}
|
||||||
function FullSet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort> {
|
function FullSet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort> {
|
||||||
return new SetImpl<ElemSort>(check(Z3.mk_full_set(contextPtr, sort.ptr)));
|
return new SetImpl<ElemSort>(check(Z3.mk_full_set(contextPtr, sort.ptr)));
|
||||||
}
|
}
|
||||||
function isMember<ElemSort extends AnySort<Name>>(elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>, set: SMTSet<Name, ElemSort>): Bool<Name> {
|
function isMember<ElemSort extends AnySort<Name>>(
|
||||||
|
elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>,
|
||||||
|
set: SMTSet<Name, ElemSort>,
|
||||||
|
): Bool<Name> {
|
||||||
const arg = set.elemSort().cast(elem as any);
|
const arg = set.elemSort().cast(elem as any);
|
||||||
return new BoolImpl(check(Z3.mk_set_member(contextPtr, arg.ast, set.ast)));
|
return new BoolImpl(check(Z3.mk_set_member(contextPtr, arg.ast, set.ast)));
|
||||||
}
|
}
|
||||||
function isSubset<ElemSort extends AnySort<Name>>(a: SMTSet<Name, ElemSort>, b: SMTSet<Name, ElemSort>): Bool<Name> {
|
function isSubset<ElemSort extends AnySort<Name>>(
|
||||||
|
a: SMTSet<Name, ElemSort>,
|
||||||
|
b: SMTSet<Name, ElemSort>,
|
||||||
|
): Bool<Name> {
|
||||||
return new BoolImpl(check(Z3.mk_set_subset(contextPtr, a.ast, b.ast)));
|
return new BoolImpl(check(Z3.mk_set_subset(contextPtr, a.ast, b.ast)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1459,12 +1516,16 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsatCore(): AstVector<Name, Bool<Name>> {
|
||||||
|
return new AstVectorImpl(check(Z3.solver_get_unsat_core(contextPtr, this.ptr)));
|
||||||
|
}
|
||||||
|
|
||||||
model() {
|
model() {
|
||||||
return new ModelImpl(check(Z3.solver_get_model(contextPtr, this.ptr)));
|
return new ModelImpl(check(Z3.solver_get_model(contextPtr, this.ptr)));
|
||||||
}
|
}
|
||||||
|
|
||||||
unsatCore(): AstVector<Name, Bool<Name>> {
|
reasonUnknown(): string {
|
||||||
return new AstVectorImpl(check(Z3.solver_get_unsat_core(contextPtr, this.ptr)));
|
return check(Z3.solver_get_reason_unknown(contextPtr, this.ptr));
|
||||||
}
|
}
|
||||||
|
|
||||||
toString() {
|
toString() {
|
||||||
|
|
@ -2629,7 +2690,10 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SetImpl<ElemSort extends Sort<Name>> extends ExprImpl<Z3_ast, ArraySortImpl<[ElemSort], BoolSort<Name>>> implements SMTSet<Name, ElemSort> {
|
class SetImpl<ElemSort extends Sort<Name>>
|
||||||
|
extends ExprImpl<Z3_ast, ArraySortImpl<[ElemSort], BoolSort<Name>>>
|
||||||
|
implements SMTSet<Name, ElemSort>
|
||||||
|
{
|
||||||
declare readonly __typename: 'Array';
|
declare readonly __typename: 'Array';
|
||||||
|
|
||||||
elemSort(): ElemSort {
|
elemSort(): ElemSort {
|
||||||
|
|
@ -2757,7 +2821,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
|
|
||||||
for (const [fieldName, fieldSort] of fields) {
|
for (const [fieldName, fieldSort] of fields) {
|
||||||
fieldNames.push(fieldName);
|
fieldNames.push(fieldName);
|
||||||
|
|
||||||
if (fieldSort instanceof DatatypeImpl) {
|
if (fieldSort instanceof DatatypeImpl) {
|
||||||
// Reference to another datatype being defined
|
// Reference to another datatype being defined
|
||||||
const refIndex = datatypes.indexOf(fieldSort);
|
const refIndex = datatypes.indexOf(fieldSort);
|
||||||
|
|
@ -2780,7 +2844,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
Z3.mk_string_symbol(contextPtr, `is_${constructorName}`),
|
Z3.mk_string_symbol(contextPtr, `is_${constructorName}`),
|
||||||
fieldNames.map(name => Z3.mk_string_symbol(contextPtr, name)),
|
fieldNames.map(name => Z3.mk_string_symbol(contextPtr, name)),
|
||||||
fieldSorts,
|
fieldSorts,
|
||||||
fieldRefs
|
fieldRefs,
|
||||||
);
|
);
|
||||||
constructors.push(constructor);
|
constructors.push(constructor);
|
||||||
scopedConstructors.push(constructor);
|
scopedConstructors.push(constructor);
|
||||||
|
|
@ -2798,14 +2862,14 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
const results: DatatypeSortImpl[] = [];
|
const results: DatatypeSortImpl[] = [];
|
||||||
for (let i = 0; i < resultSorts.length; i++) {
|
for (let i = 0; i < resultSorts.length; i++) {
|
||||||
const sortImpl = new DatatypeSortImpl(resultSorts[i]);
|
const sortImpl = new DatatypeSortImpl(resultSorts[i]);
|
||||||
|
|
||||||
// Attach constructor, recognizer, and accessor functions dynamically
|
// Attach constructor, recognizer, and accessor functions dynamically
|
||||||
const numConstructors = sortImpl.numConstructors();
|
const numConstructors = sortImpl.numConstructors();
|
||||||
for (let j = 0; j < numConstructors; j++) {
|
for (let j = 0; j < numConstructors; j++) {
|
||||||
const constructor = sortImpl.constructorDecl(j);
|
const constructor = sortImpl.constructorDecl(j);
|
||||||
const recognizer = sortImpl.recognizer(j);
|
const recognizer = sortImpl.recognizer(j);
|
||||||
const constructorName = constructor.name().toString();
|
const constructorName = constructor.name().toString();
|
||||||
|
|
||||||
// Attach constructor function
|
// Attach constructor function
|
||||||
if (constructor.arity() === 0) {
|
if (constructor.arity() === 0) {
|
||||||
// Nullary constructor (constant)
|
// Nullary constructor (constant)
|
||||||
|
|
@ -2813,10 +2877,10 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
} else {
|
} else {
|
||||||
(sortImpl as any)[constructorName] = constructor;
|
(sortImpl as any)[constructorName] = constructor;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Attach recognizer function
|
// Attach recognizer function
|
||||||
(sortImpl as any)[`is_${constructorName}`] = recognizer;
|
(sortImpl as any)[`is_${constructorName}`] = recognizer;
|
||||||
|
|
||||||
// Attach accessor functions
|
// Attach accessor functions
|
||||||
for (let k = 0; k < constructor.arity(); k++) {
|
for (let k = 0; k < constructor.arity(); k++) {
|
||||||
const accessor = sortImpl.accessor(j, k);
|
const accessor = sortImpl.accessor(j, k);
|
||||||
|
|
@ -2824,7 +2888,7 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
(sortImpl as any)[accessorName] = accessor;
|
(sortImpl as any)[accessorName] = accessor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
results.push(sortImpl);
|
results.push(sortImpl);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -2841,9 +2905,9 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
}
|
}
|
||||||
|
|
||||||
class QuantifierImpl<
|
class QuantifierImpl<
|
||||||
QVarSorts extends NonEmptySortArray<Name>,
|
QVarSorts extends NonEmptySortArray<Name>,
|
||||||
QSort extends BoolSort<Name> | SMTArraySort<Name, QVarSorts>,
|
QSort extends BoolSort<Name> | SMTArraySort<Name, QVarSorts>,
|
||||||
>
|
>
|
||||||
extends ExprImpl<Z3_ast, QSort>
|
extends ExprImpl<Z3_ast, QSort>
|
||||||
implements Quantifier<Name, QVarSorts, QSort>
|
implements Quantifier<Name, QVarSorts, QSort>
|
||||||
{
|
{
|
||||||
|
|
@ -3243,6 +3307,8 @@ export function createApi(Z3: Z3Core): Z3HighLevel {
|
||||||
PbEq,
|
PbEq,
|
||||||
PbGe,
|
PbGe,
|
||||||
PbLe,
|
PbLe,
|
||||||
|
AtMost,
|
||||||
|
AtLeast,
|
||||||
ForAll,
|
ForAll,
|
||||||
Exists,
|
Exists,
|
||||||
Lambda,
|
Lambda,
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,13 @@ export type CoercibleToBitVec<Bits extends number = number, Name extends string
|
||||||
export type CoercibleRational = { numerator: bigint | number; denominator: bigint | number };
|
export type CoercibleRational = { numerator: bigint | number; denominator: bigint | number };
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
export type CoercibleToExpr<Name extends string = 'main'> = number | string | bigint | boolean | CoercibleRational | Expr<Name>;
|
export type CoercibleToExpr<Name extends string = 'main'> =
|
||||||
|
| number
|
||||||
|
| string
|
||||||
|
| bigint
|
||||||
|
| boolean
|
||||||
|
| CoercibleRational
|
||||||
|
| Expr<Name>;
|
||||||
|
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
export type CoercibleToArith<Name extends string = 'main'> = number | string | bigint | CoercibleRational | Arith<Name>;
|
export type CoercibleToArith<Name extends string = 'main'> = number | string | bigint | CoercibleRational | Arith<Name>;
|
||||||
|
|
@ -448,6 +454,12 @@ export interface Context<Name extends string = 'main'> {
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
PbLe(args: [Bool<Name>, ...Bool<Name>[]], coeffs: [number, ...number[]], k: number): Bool<Name>;
|
PbLe(args: [Bool<Name>, ...Bool<Name>[]], coeffs: [number, ...number[]], k: number): Bool<Name>;
|
||||||
|
|
||||||
|
/** @category Operations */
|
||||||
|
AtMost(args: [Bool<Name>, ...Bool<Name>[]], k: number): Bool<Name>;
|
||||||
|
|
||||||
|
/** @category Operations */
|
||||||
|
AtLeast(args: [Bool<Name>, ...Bool<Name>[]], k: number): Bool<Name>;
|
||||||
|
|
||||||
// Quantifiers
|
// Quantifiers
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
|
|
@ -621,33 +633,45 @@ export interface Context<Name extends string = 'main'> {
|
||||||
substitute(t: Expr<Name>, ...substitutions: [Expr<Name>, Expr<Name>][]): Expr<Name>;
|
substitute(t: Expr<Name>, ...substitutions: [Expr<Name>, Expr<Name>][]): Expr<Name>;
|
||||||
|
|
||||||
simplify(expr: Expr<Name>): Promise<Expr<Name>>;
|
simplify(expr: Expr<Name>): Promise<Expr<Name>>;
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
SetUnion<ElemSort extends AnySort<Name>>(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort>;
|
SetUnion<ElemSort extends AnySort<Name>>(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
SetIntersect<ElemSort extends AnySort<Name>>(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort>;
|
SetIntersect<ElemSort extends AnySort<Name>>(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
/** @category Operations */
|
|
||||||
SetDifference<ElemSort extends AnySort<Name>>(a: SMTSet<Name, ElemSort>, b: SMTSet<Name, ElemSort>): SMTSet<Name, ElemSort>;
|
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
SetAdd<ElemSort extends AnySort<Name>>(set: SMTSet<Name, ElemSort>, elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): SMTSet<Name, ElemSort>;
|
SetDifference<ElemSort extends AnySort<Name>>(
|
||||||
|
a: SMTSet<Name, ElemSort>,
|
||||||
|
b: SMTSet<Name, ElemSort>,
|
||||||
|
): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
SetDel<ElemSort extends AnySort<Name>>(set: SMTSet<Name, ElemSort>, elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): SMTSet<Name, ElemSort>;
|
SetAdd<ElemSort extends AnySort<Name>>(
|
||||||
|
set: SMTSet<Name, ElemSort>,
|
||||||
|
elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>,
|
||||||
|
): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
|
/** @category Operations */
|
||||||
|
SetDel<ElemSort extends AnySort<Name>>(
|
||||||
|
set: SMTSet<Name, ElemSort>,
|
||||||
|
elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>,
|
||||||
|
): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
SetComplement<ElemSort extends AnySort<Name>>(set: SMTSet<Name, ElemSort>): SMTSet<Name, ElemSort>;
|
SetComplement<ElemSort extends AnySort<Name>>(set: SMTSet<Name, ElemSort>): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
EmptySet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort>;
|
EmptySet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
FullSet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort>;
|
FullSet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
isMember<ElemSort extends AnySort<Name>>(elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>, set: SMTSet<Name, ElemSort>): Bool<Name>;
|
isMember<ElemSort extends AnySort<Name>>(
|
||||||
|
elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>,
|
||||||
|
set: SMTSet<Name, ElemSort>,
|
||||||
|
): Bool<Name>;
|
||||||
|
|
||||||
/** @category Operations */
|
/** @category Operations */
|
||||||
isSubset<ElemSort extends AnySort<Name>>(a: SMTSet<Name, ElemSort>, b: SMTSet<Name, ElemSort>): Bool<Name>;
|
isSubset<ElemSort extends AnySort<Name>>(a: SMTSet<Name, ElemSort>, b: SMTSet<Name, ElemSort>): Bool<Name>;
|
||||||
|
|
@ -709,12 +733,90 @@ export interface Solver<Name extends string = 'main'> {
|
||||||
|
|
||||||
fromString(s: string): void;
|
fromString(s: string): void;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check whether the assertions in the solver are consistent or not.
|
||||||
|
*
|
||||||
|
* Optionally, you can provide additional boolean expressions as assumptions.
|
||||||
|
* These assumptions are temporary and only used for this check - they are not
|
||||||
|
* permanently added to the solver.
|
||||||
|
*
|
||||||
|
* @param exprs - Optional assumptions to check in addition to the solver's assertions.
|
||||||
|
* These are temporary and do not modify the solver state.
|
||||||
|
* @returns A promise resolving to:
|
||||||
|
* - `'sat'` if the assertions (plus assumptions) are satisfiable
|
||||||
|
* - `'unsat'` if they are unsatisfiable
|
||||||
|
* - `'unknown'` if Z3 cannot determine satisfiability
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const solver = new Solver();
|
||||||
|
* const x = Int.const('x');
|
||||||
|
* solver.add(x.gt(0));
|
||||||
|
*
|
||||||
|
* // Check without assumptions
|
||||||
|
* await solver.check(); // 'sat'
|
||||||
|
*
|
||||||
|
* // Check with temporary assumption (doesn't modify solver)
|
||||||
|
* await solver.check(x.lt(0)); // 'unsat'
|
||||||
|
* await solver.check(); // still 'sat' - assumption was temporary
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @see {@link unsatCore} - Retrieve unsat core after checking with assumptions
|
||||||
|
*/
|
||||||
check(...exprs: (Bool<Name> | AstVector<Name, Bool<Name>>)[]): Promise<CheckSatResult>;
|
check(...exprs: (Bool<Name> | AstVector<Name, Bool<Name>>)[]): Promise<CheckSatResult>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the unsat core after a check that returned `'unsat'`.
|
||||||
|
*
|
||||||
|
* The unsat core is a (typically small) subset of the assumptions that were
|
||||||
|
* sufficient to determine unsatisfiability. This is useful for understanding
|
||||||
|
* which assumptions are conflicting.
|
||||||
|
*
|
||||||
|
* Note: To use unsat cores effectively, you should call {@link check} with
|
||||||
|
* assumptions (not just assertions added via {@link add}).
|
||||||
|
*
|
||||||
|
* @returns An AstVector containing the subset of assumptions that caused UNSAT
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const solver = new Solver();
|
||||||
|
* const x = Bool.const('x');
|
||||||
|
* const y = Bool.const('y');
|
||||||
|
* const z = Bool.const('z');
|
||||||
|
* solver.add(x.or(y));
|
||||||
|
* solver.add(x.or(z));
|
||||||
|
*
|
||||||
|
* const result = await solver.check(x.not(), y.not(), z.not());
|
||||||
|
* if (result === 'unsat') {
|
||||||
|
* const core = solver.unsatCore();
|
||||||
|
* // core will contain a minimal set of conflicting assumptions
|
||||||
|
* console.log('UNSAT core size:', core.length());
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*
|
||||||
|
* @see {@link check} - Check with assumptions to use with unsat core
|
||||||
|
*/
|
||||||
|
unsatCore(): AstVector<Name, Bool<Name>>;
|
||||||
|
|
||||||
model(): Model<Name>;
|
model(): Model<Name>;
|
||||||
|
|
||||||
unsatCore(): AstVector<Name, Bool<Name>>;
|
unsatCore(): AstVector<Name, Bool<Name>>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a string describing why the last call to {@link check} returned `'unknown'`.
|
||||||
|
*
|
||||||
|
* @returns A string explaining the reason, or an empty string if the last check didn't return unknown
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* ```typescript
|
||||||
|
* const result = await solver.check();
|
||||||
|
* if (result === 'unknown') {
|
||||||
|
* console.log('Reason:', solver.reasonUnknown());
|
||||||
|
* }
|
||||||
|
* ```
|
||||||
|
*/
|
||||||
|
reasonUnknown(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manually decrease the reference count of the solver
|
* Manually decrease the reference count of the solver
|
||||||
* This is automatically done when the solver is garbage collected,
|
* This is automatically done when the solver is garbage collected,
|
||||||
|
|
@ -963,8 +1065,10 @@ export interface FuncDecl<
|
||||||
call(...args: CoercibleToArrayIndexType<Name, DomainSort>): SortToExprMap<RangeSort, Name>;
|
call(...args: CoercibleToArrayIndexType<Name, DomainSort>): SortToExprMap<RangeSort, Name>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Expr<Name extends string = 'main', S extends Sort<Name> = AnySort<Name>, Ptr = unknown>
|
export interface Expr<Name extends string = 'main', S extends Sort<Name> = AnySort<Name>, Ptr = unknown> extends Ast<
|
||||||
extends Ast<Name, Ptr> {
|
Name,
|
||||||
|
Ptr
|
||||||
|
> {
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
readonly __typename:
|
readonly __typename:
|
||||||
| 'Expr'
|
| 'Expr'
|
||||||
|
|
@ -1263,8 +1367,11 @@ export interface BitVecCreation<Name extends string> {
|
||||||
* Represents Bit Vector expression
|
* Represents Bit Vector expression
|
||||||
* @category Bit Vectors
|
* @category Bit Vectors
|
||||||
*/
|
*/
|
||||||
export interface BitVec<Bits extends number = number, Name extends string = 'main'>
|
export interface BitVec<Bits extends number = number, Name extends string = 'main'> extends Expr<
|
||||||
extends Expr<Name, BitVecSort<Bits, Name>, Z3_ast> {
|
Name,
|
||||||
|
BitVecSort<Bits, Name>,
|
||||||
|
Z3_ast
|
||||||
|
> {
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
readonly __typename: 'BitVec' | BitVecNum['__typename'];
|
readonly __typename: 'BitVec' | BitVecNum['__typename'];
|
||||||
|
|
||||||
|
|
@ -1614,12 +1721,15 @@ export interface SMTArray<
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set Implemented using Arrays
|
* Set Implemented using Arrays
|
||||||
*
|
*
|
||||||
* @typeParam ElemSort The sort of the element of the set
|
* @typeParam ElemSort The sort of the element of the set
|
||||||
* @category Sets
|
* @category Sets
|
||||||
*/
|
*/
|
||||||
export type SMTSetSort<Name extends string = 'main', ElemSort extends AnySort<Name> = Sort<Name>> = SMTArraySort<Name, [ElemSort], BoolSort<Name>>;
|
export type SMTSetSort<Name extends string = 'main', ElemSort extends AnySort<Name> = Sort<Name>> = SMTArraySort<
|
||||||
|
Name,
|
||||||
|
[ElemSort],
|
||||||
|
BoolSort<Name>
|
||||||
|
>;
|
||||||
|
|
||||||
/** @category Sets*/
|
/** @category Sets*/
|
||||||
export interface SMTSetCreation<Name extends string> {
|
export interface SMTSetCreation<Name extends string> {
|
||||||
|
|
@ -1628,10 +1738,13 @@ export interface SMTSetCreation<Name extends string> {
|
||||||
const<ElemSort extends AnySort<Name>>(name: string, elemSort: ElemSort): SMTSet<Name, ElemSort>;
|
const<ElemSort extends AnySort<Name>>(name: string, elemSort: ElemSort): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
consts<ElemSort extends AnySort<Name>>(names: string | string[], elemSort: ElemSort): SMTSet<Name, ElemSort>[];
|
consts<ElemSort extends AnySort<Name>>(names: string | string[], elemSort: ElemSort): SMTSet<Name, ElemSort>[];
|
||||||
|
|
||||||
empty<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort>;
|
empty<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
val<ElemSort extends AnySort<Name>>(values: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>[], sort: ElemSort): SMTSet<Name, ElemSort>;
|
val<ElemSort extends AnySort<Name>>(
|
||||||
|
values: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>[],
|
||||||
|
sort: ElemSort,
|
||||||
|
): SMTSet<Name, ElemSort>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -1640,23 +1753,25 @@ export interface SMTSetCreation<Name extends string> {
|
||||||
* @typeParam ElemSort The sort of the element of the set
|
* @typeParam ElemSort The sort of the element of the set
|
||||||
* @category Arrays
|
* @category Arrays
|
||||||
*/
|
*/
|
||||||
export interface SMTSet<Name extends string = 'main', ElemSort extends AnySort<Name> = Sort<Name>> extends Expr<Name, SMTSetSort<Name, ElemSort>, Z3_ast> {
|
export interface SMTSet<Name extends string = 'main', ElemSort extends AnySort<Name> = Sort<Name>> extends Expr<
|
||||||
|
Name,
|
||||||
|
SMTSetSort<Name, ElemSort>,
|
||||||
|
Z3_ast
|
||||||
|
> {
|
||||||
readonly __typename: 'Array';
|
readonly __typename: 'Array';
|
||||||
|
|
||||||
elemSort(): ElemSort;
|
elemSort(): ElemSort;
|
||||||
|
|
||||||
union(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort>;
|
union(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort>;
|
||||||
intersect(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort>;
|
intersect(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort>;
|
||||||
diff(b: SMTSet<Name, ElemSort>): SMTSet<Name, ElemSort>;
|
diff(b: SMTSet<Name, ElemSort>): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
|
|
||||||
add(elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): SMTSet<Name, ElemSort>;
|
add(elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): SMTSet<Name, ElemSort>;
|
||||||
del(elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): SMTSet<Name, ElemSort>;
|
del(elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): SMTSet<Name, ElemSort>;
|
||||||
complement(): SMTSet<Name, ElemSort>;
|
complement(): SMTSet<Name, ElemSort>;
|
||||||
|
|
||||||
contains(elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): Bool<Name>;
|
contains(elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>): Bool<Name>;
|
||||||
subsetOf(b: SMTSet<Name, ElemSort>): Bool<Name>;
|
subsetOf(b: SMTSet<Name, ElemSort>): Bool<Name>;
|
||||||
|
|
||||||
}
|
}
|
||||||
//////////////////////////////////////////
|
//////////////////////////////////////////
|
||||||
//
|
//
|
||||||
|
|
@ -1666,10 +1781,10 @@ export interface SMTSet<Name extends string = 'main', ElemSort extends AnySort<N
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper class for declaring Z3 datatypes.
|
* Helper class for declaring Z3 datatypes.
|
||||||
*
|
*
|
||||||
* Follows the same pattern as Python Z3 API for declaring constructors
|
* Follows the same pattern as Python Z3 API for declaring constructors
|
||||||
* before creating the actual datatype sort.
|
* before creating the actual datatype sort.
|
||||||
*
|
*
|
||||||
* @example
|
* @example
|
||||||
* ```typescript
|
* ```typescript
|
||||||
* const List = new ctx.Datatype('List');
|
* const List = new ctx.Datatype('List');
|
||||||
|
|
@ -1677,7 +1792,7 @@ export interface SMTSet<Name extends string = 'main', ElemSort extends AnySort<N
|
||||||
* List.declare('nil');
|
* List.declare('nil');
|
||||||
* const ListSort = List.create();
|
* const ListSort = List.create();
|
||||||
* ```
|
* ```
|
||||||
*
|
*
|
||||||
* @category Datatypes
|
* @category Datatypes
|
||||||
*/
|
*/
|
||||||
export interface Datatype<Name extends string = 'main'> {
|
export interface Datatype<Name extends string = 'main'> {
|
||||||
|
|
@ -1686,7 +1801,7 @@ export interface Datatype<Name extends string = 'main'> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Declare a constructor for this datatype.
|
* Declare a constructor for this datatype.
|
||||||
*
|
*
|
||||||
* @param name Constructor name
|
* @param name Constructor name
|
||||||
* @param fields Array of [field_name, field_sort] pairs
|
* @param fields Array of [field_name, field_sort] pairs
|
||||||
*/
|
*/
|
||||||
|
|
@ -1710,7 +1825,7 @@ export interface DatatypeCreation<Name extends string> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create mutually recursive datatypes.
|
* Create mutually recursive datatypes.
|
||||||
*
|
*
|
||||||
* @param datatypes Array of Datatype declarations
|
* @param datatypes Array of Datatype declarations
|
||||||
* @returns Array of created DatatypeSort instances
|
* @returns Array of created DatatypeSort instances
|
||||||
*/
|
*/
|
||||||
|
|
@ -1719,10 +1834,10 @@ export interface DatatypeCreation<Name extends string> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Sort representing an algebraic datatype.
|
* A Sort representing an algebraic datatype.
|
||||||
*
|
*
|
||||||
* After creation, this sort will have constructor, recognizer, and accessor
|
* After creation, this sort will have constructor, recognizer, and accessor
|
||||||
* functions dynamically attached based on the declared constructors.
|
* functions dynamically attached based on the declared constructors.
|
||||||
*
|
*
|
||||||
* @category Datatypes
|
* @category Datatypes
|
||||||
*/
|
*/
|
||||||
export interface DatatypeSort<Name extends string = 'main'> extends Sort<Name> {
|
export interface DatatypeSort<Name extends string = 'main'> extends Sort<Name> {
|
||||||
|
|
@ -1756,8 +1871,8 @@ export interface DatatypeSort<Name extends string = 'main'> extends Sort<Name> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents expressions of datatype sorts.
|
* Represents expressions of datatype sorts.
|
||||||
*
|
*
|
||||||
* @category Datatypes
|
* @category Datatypes
|
||||||
*/
|
*/
|
||||||
export interface DatatypeExpr<Name extends string = 'main'> extends Expr<Name, DatatypeSort<Name>, Z3_ast> {
|
export interface DatatypeExpr<Name extends string = 'main'> extends Expr<Name, DatatypeSort<Name>, Z3_ast> {
|
||||||
/** @hidden */
|
/** @hidden */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue