z3-solver
Version:
This project provides high-level and low-level TypeScript bindings for the [Z3 theorem prover](https://github.com/Z3Prover/z3). It is available on npm as [z3-solver](https://www.npmjs.com/package/z3-solver).
1,168 lines • 104 kB
TypeScript
import { Z3_ast, Z3_ast_map, Z3_ast_print_mode, Z3_ast_vector, Z3_context, Z3_decl_kind, Z3_fixedpoint, Z3_func_decl, Z3_func_entry, Z3_func_interp, Z3_model, Z3_probe, Z3_solver, Z3_optimize, Z3_sort, Z3_sort_kind, Z3_stats, Z3_tactic, Z3_goal, Z3_apply_result, Z3_goal_prec, Z3_param_descrs, Z3_params, Z3_simplifier } from '../low-level';
/** @hidden */
export type AnySort<Name extends string = 'main'> = Sort<Name> | BoolSort<Name> | ArithSort<Name> | BitVecSort<number, Name> | SMTArraySort<Name> | FPSort<Name> | FPRMSort<Name> | SeqSort<Name> | ReSort<Name>;
/** @hidden */
export type AnyExpr<Name extends string = 'main'> = Expr<Name> | Bool<Name> | Arith<Name> | IntNum<Name> | RatNum<Name> | BitVec<number, Name> | BitVecNum<number, Name> | SMTArray<Name> | FP<Name> | FPNum<Name> | FPRM<Name> | Seq<Name> | Re<Name>;
/** @hidden */
export type AnyAst<Name extends string = 'main'> = AnyExpr<Name> | AnySort<Name> | FuncDecl<Name>;
/** @hidden */
export type SortToExprMap<S extends AnySort<Name>, Name extends string = 'main'> = S extends BoolSort ? Bool<Name> : S extends ArithSort<Name> ? Arith<Name> : S extends BitVecSort<infer Size, Name> ? BitVec<Size, Name> : S extends SMTArraySort<Name, infer DomainSort, infer RangeSort> ? SMTArray<Name, DomainSort, RangeSort> : S extends FPSort<Name> ? FP<Name> : S extends FPRMSort<Name> ? FPRM<Name> : S extends SeqSort<Name> ? Seq<Name> : S extends ReSort<Name> ? Re<Name> : S extends Sort<Name> ? Expr<Name, S, Z3_ast> : never;
/** @hidden */
export type CoercibleFromMap<S extends CoercibleToExpr<Name>, Name extends string = 'main'> = S extends bigint ? Arith<Name> : S extends number | CoercibleRational ? RatNum<Name> : S extends boolean ? Bool<Name> : S extends Expr<Name> ? S : never;
/** @hidden */
export type CoercibleToBitVec<Bits extends number = number, Name extends string = 'main'> = bigint | number | BitVec<Bits, Name>;
/** @hidden */
export type CoercibleToFP<Name extends string = 'main'> = number | FP<Name>;
export type CoercibleRational = {
numerator: bigint | number;
denominator: bigint | number;
};
/** @hidden */
export type CoercibleToExpr<Name extends string = 'main'> = number | string | bigint | boolean | CoercibleRational | Expr<Name>;
/** @hidden */
export type CoercibleToArith<Name extends string = 'main'> = number | string | bigint | CoercibleRational | Arith<Name>;
/** @hidden */
export type CoercibleToMap<T extends AnyExpr<Name>, Name extends string = 'main'> = T extends Bool<Name> ? boolean | Bool<Name> : T extends IntNum<Name> ? bigint | number | IntNum<Name> : T extends RatNum<Name> ? bigint | number | CoercibleRational | RatNum<Name> : T extends Arith<Name> ? CoercibleToArith<Name> : T extends BitVec<infer Size, Name> ? CoercibleToBitVec<Size, Name> : T extends FP<Name> ? CoercibleToFP<Name> : T extends SMTArray<Name, infer DomainSort, infer RangeSort> ? SMTArray<Name, DomainSort, RangeSort> : T extends Expr<Name> ? Expr<Name> : never;
/**
* Used to create a Real constant
*
* ```typescript
* const x = from({ numerator: 1, denominator: 3 })
*
* x
* // 1/3
* isReal(x)
* // true
* isRealVal(x)
* // true
* x.asNumber()
* // 0.3333333333333333
* ```
* @see {@link Context.from}
* @category Global
*/
export declare class Z3Error extends Error {
}
export declare class Z3AssertionError extends Z3Error {
}
/** @category Global */
export type CheckSatResult = 'sat' | 'unsat' | 'unknown';
/** @hidden */
export interface ContextCtor {
<Name extends string>(name: Name, options?: Record<string, any>): Context<Name>;
new <Name extends string>(name: Name, options?: Record<string, any>): Context<Name>;
}
export interface Context<Name extends string = 'main'> {
/** @hidden */
readonly ptr: Z3_context;
/**
* Name of the current Context
*
* ```typescript
* const c = new Context('main')
*
* c.name
* // 'main'
* ```
*/
readonly name: Name;
/** @category Functions */
interrupt(): void;
/**
* Set the pretty printing mode for ASTs.
*
* @param mode - The print mode to use:
* - Z3_PRINT_SMTLIB_FULL (0): Print AST nodes in SMTLIB verbose format.
* - Z3_PRINT_LOW_LEVEL (1): Print AST nodes using a low-level format.
* - Z3_PRINT_SMTLIB2_COMPLIANT (2): Print AST nodes in SMTLIB 2.x compliant format.
*
* @category Functions
*/
setPrintMode(mode: Z3_ast_print_mode): void;
/** @category Functions */
isModel(obj: unknown): obj is Model<Name>;
/** @category Functions */
isAst(obj: unknown): obj is Ast<Name>;
/** @category Functions */
isSort(obj: unknown): obj is Sort<Name>;
/** @category Functions */
isFuncDecl(obj: unknown): obj is FuncDecl<Name>;
/** @category Functions */
isFuncInterp(obj: unknown): obj is FuncInterp<Name>;
/** @category Functions */
isApp(obj: unknown): boolean;
/** @category Functions */
isConst(obj: unknown): boolean;
/** @category Functions */
isExpr(obj: unknown): obj is Expr<Name>;
/** @category Functions */
isVar(obj: unknown): boolean;
/** @category Functions */
isAppOf(obj: unknown, kind: Z3_decl_kind): boolean;
/** @category Functions */
isBool(obj: unknown): obj is Bool<Name>;
/** @category Functions */
isTrue(obj: unknown): boolean;
/** @category Functions */
isFalse(obj: unknown): boolean;
/** @category Functions */
isAnd(obj: unknown): boolean;
/** @category Functions */
isOr(obj: unknown): boolean;
/** @category Functions */
isImplies(obj: unknown): boolean;
/** @category Functions */
isNot(obj: unknown): boolean;
/** @category Functions */
isEq(obj: unknown): boolean;
/** @category Functions */
isDistinct(obj: unknown): boolean;
/** @category Functions */
isQuantifier(obj: unknown): obj is Quantifier<Name>;
/** @category Functions */
isArith(obj: unknown): obj is Arith<Name>;
/** @category Functions */
isArithSort(obj: unknown): obj is ArithSort<Name>;
/** @category Functions */
isInt(obj: unknown): boolean;
/** @category Functions */
isIntVal(obj: unknown): obj is IntNum<Name>;
/** @category Functions */
isIntSort(obj: unknown): boolean;
/** @category Functions */
isReal(obj: unknown): boolean;
/** @category Functions */
isRealVal(obj: unknown): obj is RatNum<Name>;
/** @category Functions */
isRealSort(obj: unknown): boolean;
/** @category Functions */
isRCFNum(obj: unknown): obj is RCFNum<Name>;
/** @category Functions */
isBitVecSort(obj: unknown): obj is BitVecSort<number, Name>;
/** @category Functions */
isBitVec(obj: unknown): obj is BitVec<number, Name>;
/** @category Functions */
isBitVecVal(obj: unknown): obj is BitVecNum<number, Name>;
/** @category Functions */
isArraySort(obj: unknown): obj is SMTArraySort<Name>;
/** @category Functions */
isArray(obj: unknown): obj is SMTArray<Name>;
/** @category Functions */
isConstArray(obj: unknown): boolean;
/** @category Functions */
isFPSort(obj: unknown): obj is FPSort<Name>;
/** @category Functions */
isFP(obj: unknown): obj is FP<Name>;
/** @category Functions */
isFPVal(obj: unknown): obj is FPNum<Name>;
/** @category Functions */
isFPRMSort(obj: unknown): obj is FPRMSort<Name>;
/** @category Functions */
isFPRM(obj: unknown): obj is FPRM<Name>;
/** @category Functions */
isSeqSort(obj: unknown): obj is SeqSort<Name>;
/** @category Functions */
isSeq(obj: unknown): obj is Seq<Name>;
/** @category Functions */
isStringSort(obj: unknown): obj is SeqSort<Name>;
/** @category Functions */
isString(obj: unknown): obj is Seq<Name>;
/** @category Functions */
isProbe(obj: unknown): obj is Probe<Name>;
/** @category Functions */
isTactic(obj: unknown): obj is Tactic<Name>;
/** @category Functions */
isGoal(obj: unknown): obj is Goal<Name>;
/** @category Functions */
isAstVector(obj: unknown): obj is AstVector<Name, AnyAst<Name>>;
/**
* Returns whether two Asts are the same thing
* @category Functions */
eqIdentity(a: Ast<Name>, b: Ast<Name>): boolean;
/** @category Functions */
getVarIndex(obj: Expr<Name>): number;
/**
* Coerce a boolean into a Bool expression
* @category Functions */
from(primitive: boolean): Bool<Name>;
/**
* Coerce a number to an Int or Real expression (integral numbers become Ints)
* @category Functions */
from(primitive: number): IntNum<Name> | RatNum<Name>;
/**
* Coerce a rational into a Real expression
* @category Functions */
from(primitive: CoercibleRational): RatNum<Name>;
/**
* Coerce a big number into a Integer expression
* @category Functions */
from(primitive: bigint): IntNum<Name>;
/**
* Returns whatever expression was given
* @category Functions */
from<E extends Expr<Name>>(expr: E): E;
/** @hidden */
from(value: CoercibleToExpr<Name>): AnyExpr<Name>;
/**
* Sugar function for getting a model for given assertions
*
* ```typescript
* const x = Int.const('x');
* const y = Int.const('y');
* const result = await solve(x.le(y));
* if (isModel(result)) {
* console.log('Z3 found a solution');
* console.log(`x=${result.get(x)}, y=${result.get(y)}`);
* } else {
* console.error('No solution found');
* }
* ```
*
* @see {@link Solver}
* @category Functions */
solve(...assertions: Bool<Name>[]): Promise<Model<Name> | 'unsat' | 'unknown'>;
/**
* Creates a Solver
* @param logic - Optional logic which the solver will use. Creates a general Solver otherwise
* @category Classes
*/
readonly Solver: new (logic?: string) => Solver<Name>;
readonly Optimize: new () => Optimize<Name>;
readonly Fixedpoint: new () => Fixedpoint<Name>;
/**
* Creates an empty Model
* @see {@link Solver.model} for common usage of Model
* @category Classes
*/
readonly Model: new () => Model<Name>;
/** @category Classes */
readonly AstVector: new <Item extends Ast<Name> = AnyAst<Name>>() => AstVector<Name, Item>;
/** @category Classes */
readonly AstMap: new <Key extends Ast<Name> = AnyAst<Name>, Value extends Ast<Name> = AnyAst<Name>>() => AstMap<Name, Key, Value>;
/** @category Classes */
readonly Tactic: new (name: string) => Tactic<Name>;
/** @category Classes */
readonly Goal: new (models?: boolean, unsat_cores?: boolean, proofs?: boolean) => Goal<Name>;
/** @category Classes */
readonly Params: new () => Params<Name>;
/** @category Classes */
readonly Simplifier: new (name: string) => Simplifier<Name>;
/** @category Expressions */
readonly Sort: SortCreation<Name>;
/** @category Expressions */
readonly Function: FuncDeclCreation<Name>;
/** @category Expressions */
readonly RecFunc: RecFuncCreation<Name>;
/** @category Expressions */
readonly Bool: BoolCreation<Name>;
/** @category Expressions */
readonly Int: IntCreation<Name>;
/** @category Expressions */
readonly Real: RealCreation<Name>;
/** @category Expressions */
readonly RCFNum: RCFNumCreation<Name>;
/** @category Expressions */
readonly BitVec: BitVecCreation<Name>;
/** @category Expressions */
readonly Float: FPCreation<Name>;
/** @category Expressions */
readonly FloatRM: FPRMCreation<Name>;
/** @category Expressions */
readonly String: StringCreation<Name>;
/** @category Expressions */
readonly Seq: SeqCreation<Name>;
/** @category Expressions */
readonly Re: ReCreation<Name>;
/** @category Expressions */
readonly Array: SMTArrayCreation<Name>;
/** @category Expressions */
readonly Set: SMTSetCreation<Name>;
/** @category Expressions */
readonly Datatype: DatatypeCreation<Name>;
/** @category Operations */
Const<S extends Sort<Name>>(name: string, sort: S): SortToExprMap<S, Name>;
/** @category Operations */
Consts<S extends Sort<Name>>(name: string | string[], sort: S): SortToExprMap<S, Name>[];
/** @category Operations */
FreshConst<S extends Sort<Name>>(sort: S, prefix?: string): SortToExprMap<S, Name>;
/** @category Operations */
Var<S extends Sort<Name>>(idx: number, sort: S): SortToExprMap<S, Name>;
/** @category Operations */
If(condition: Probe<Name>, onTrue: Tactic<Name>, onFalse: Tactic<Name>): Tactic<Name>;
/** @category Operations */
If<OnTrueRef extends CoercibleToExpr<Name>, OnFalseRef extends CoercibleToExpr<Name>>(condition: Bool<Name> | boolean, onTrue: OnTrueRef, onFalse: OnFalseRef): CoercibleFromMap<OnTrueRef | OnFalseRef, Name>;
/** @category Operations */
Distinct(...args: CoercibleToExpr<Name>[]): Bool<Name>;
/** @category Operations */
Implies(a: Bool<Name> | boolean, b: Bool<Name> | boolean): Bool<Name>;
/** @category Operations */
Iff(a: Bool<Name> | boolean, b: Bool<Name> | boolean): Bool<Name>;
/** @category Operations */
Eq(a: CoercibleToExpr<Name>, b: CoercibleToExpr<Name>): Bool<Name>;
/** @category Operations */
Xor(a: Bool<Name> | boolean, b: Bool<Name> | boolean): Bool<Name>;
/** @category Operations */
Not(a: Probe<Name>): Probe<Name>;
/** @category Operations */
Not(a: Bool<Name> | boolean): Bool<Name>;
/** @category Operations */
And(): Bool<Name>;
/** @category Operations */
And(vector: AstVector<Name, Bool<Name>>): Bool<Name>;
/** @category Operations */
And(...args: (Bool<Name> | boolean)[]): Bool<Name>;
/** @category Operations */
And(...args: Probe<Name>[]): Probe<Name>;
/** @category Operations */
Or(): Bool<Name>;
/** @category Operations */
Or(vector: AstVector<Name, Bool<Name>>): Bool<Name>;
/** @category Operations */
Or(...args: (Bool<Name> | boolean)[]): Bool<Name>;
/** @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>;
/** @category Operations */
AtMost(args: [Bool<Name>, ...Bool<Name>[]], k: number): Bool<Name>;
/** @category Operations */
AtLeast(args: [Bool<Name>, ...Bool<Name>[]], k: number): Bool<Name>;
/**
* Compose two tactics sequentially. Applies t1 to a goal, then t2 to each subgoal.
* @category Tactics
*/
AndThen(t1: Tactic<Name> | string, t2: Tactic<Name> | string, ...ts: (Tactic<Name> | string)[]): Tactic<Name>;
/**
* Create a tactic that applies t1, and if it fails, applies t2.
* @category Tactics
*/
OrElse(t1: Tactic<Name> | string, t2: Tactic<Name> | string, ...ts: (Tactic<Name> | string)[]): Tactic<Name>;
/**
* Repeat a tactic up to max times (default: unbounded).
* @category Tactics
*/
Repeat(t: Tactic<Name> | string, max?: number): Tactic<Name>;
/**
* Apply tactic with a timeout in milliseconds.
* @category Tactics
*/
TryFor(t: Tactic<Name> | string, ms: number): Tactic<Name>;
/**
* Apply tactic only if probe condition is true.
* @category Tactics
*/
When(p: Probe<Name>, t: Tactic<Name> | string): Tactic<Name>;
/**
* Create a tactic that always succeeds and does nothing (skip).
* @category Tactics
*/
Skip(): Tactic<Name>;
/**
* Create a tactic that always fails.
* @category Tactics
*/
Fail(): Tactic<Name>;
/**
* Create a tactic that fails if probe condition is true.
* @category Tactics
*/
FailIf(p: Probe<Name>): Tactic<Name>;
/**
* Apply tactics in parallel and return first successful result.
* @category Tactics
*/
ParOr(...tactics: (Tactic<Name> | string)[]): Tactic<Name>;
/**
* Compose two tactics in parallel (t1 and then t2 in parallel).
* @category Tactics
*/
ParAndThen(t1: Tactic<Name> | string, t2: Tactic<Name> | string): Tactic<Name>;
/**
* Apply tactic with given parameters.
* @category Tactics
*/
With(t: Tactic<Name> | string, params: Record<string, any>): Tactic<Name>;
/** @category Operations */
ForAll<QVarSorts extends NonEmptySortArray<Name>>(quantifiers: ArrayIndexType<Name, QVarSorts>, body: Bool<Name>, weight?: number): Quantifier<Name, QVarSorts, BoolSort<Name>> & Bool<Name>;
/** @category Operations */
Exists<QVarSorts extends NonEmptySortArray<Name>>(quantifiers: ArrayIndexType<Name, QVarSorts>, body: Bool<Name>, weight?: number): Quantifier<Name, QVarSorts, BoolSort<Name>> & Bool<Name>;
/** @category Operations */
Lambda<DomainSort extends NonEmptySortArray<Name>, RangeSort extends Sort<Name>>(quantifiers: ArrayIndexType<Name, DomainSort>, expr: SortToExprMap<RangeSort, Name>): Quantifier<Name, DomainSort, SMTArraySort<Name, DomainSort, RangeSort>> & SMTArray<Name, DomainSort, RangeSort>;
/** @category Operations */
ToReal(expr: Arith<Name> | bigint): Arith<Name>;
/** @category Operations */
ToInt(expr: Arith<Name> | number | CoercibleRational | string): Arith<Name>;
/**
* Create an IsInt Z3 predicate
*
* ```typescript
* const x = Real.const('x');
* await solve(IsInt(x.add("1/2")), x.gt(0), x.lt(1))
* // x = 1/2
* await solve(IsInt(x.add("1/2")), x.gt(0), x.lt(1), x.neq("1/2"))
* // unsat
* ```
* @category Operations */
IsInt(expr: Arith<Name> | number | CoercibleRational | string): Bool<Name>;
/**
* Returns a Z3 expression representing square root of a
*
* ```typescript
* const a = Real.const('a');
*
* Sqrt(a);
* // a**(1/2)
* ```
* @category Operations */
Sqrt(a: CoercibleToArith<Name>): Arith<Name>;
/**
* Returns a Z3 expression representing cubic root of a
*
* ```typescript
* const a = Real.const('a');
*
* Cbrt(a);
* // a**(1/3)
* ```
* @category Operations */
Cbrt(a: CoercibleToArith<Name>): Arith<Name>;
/** @category Operations */
BV2Int(a: BitVec<number, Name>, isSigned: boolean): Arith<Name>;
/** @category Operations */
Int2BV<Bits extends number>(a: Arith<Name> | bigint | number, bits: Bits): BitVec<Bits, Name>;
/** @category Operations */
Concat(...bitvecs: BitVec<number, Name>[]): BitVec<number, Name>;
/** @category Operations */
Cond(probe: Probe<Name>, onTrue: Tactic<Name>, onFalse: Tactic<Name>): Tactic<Name>;
/** @category Operations */
LT(a: Arith<Name>, b: CoercibleToArith<Name>): Bool<Name>;
/** @category Operations */
GT(a: Arith<Name>, b: CoercibleToArith<Name>): Bool<Name>;
/** @category Operations */
LE(a: Arith<Name>, b: CoercibleToArith<Name>): Bool<Name>;
/** @category Operations */
GE(a: Arith<Name>, b: CoercibleToArith<Name>): Bool<Name>;
/** @category Operations */
ULT<Bits extends number>(a: BitVec<Bits, Name>, b: CoercibleToBitVec<Bits, Name>): Bool<Name>;
/** @category Operations */
UGT<Bits extends number>(a: BitVec<Bits, Name>, b: CoercibleToBitVec<Bits, Name>): Bool<Name>;
/** @category Operations */
ULE<Bits extends number>(a: BitVec<Bits, Name>, b: CoercibleToBitVec<Bits, Name>): Bool<Name>;
/** @category Operations */
UGE<Bits extends number>(a: BitVec<Bits, Name>, b: CoercibleToBitVec<Bits, Name>): Bool<Name>;
/** @category Operations */
SLT<Bits extends number>(a: BitVec<Bits, Name>, b: CoercibleToBitVec<Bits, Name>): Bool<Name>;
/** @category Operations */
SGT<Bits extends number>(a: BitVec<Bits, Name>, b: CoercibleToBitVec<Bits, Name>): Bool<Name>;
/** @category Operations */
SGE<Bits extends number>(a: BitVec<Bits, Name>, b: CoercibleToBitVec<Bits, Name>): Bool<Name>;
/** @category Operations */
SLE<Bits extends number>(a: BitVec<Bits, Name>, b: CoercibleToBitVec<Bits, Name>): Bool<Name>;
/** @category Operations */
Sum(arg0: Arith<Name>, ...args: CoercibleToArith<Name>[]): Arith<Name>;
Sum<Bits extends number>(arg0: BitVec<Bits, Name>, ...args: CoercibleToBitVec<Bits, Name>[]): BitVec<Bits, Name>;
Sub(arg0: Arith<Name>, ...args: CoercibleToArith<Name>[]): Arith<Name>;
Sub<Bits extends number>(arg0: BitVec<Bits, Name>, ...args: CoercibleToBitVec<Bits, Name>[]): BitVec<Bits, Name>;
Product(arg0: Arith<Name>, ...args: CoercibleToArith<Name>[]): Arith<Name>;
Product<Bits extends number>(arg0: BitVec<Bits, Name>, ...args: CoercibleToBitVec<Bits, Name>[]): BitVec<Bits, Name>;
Div(arg0: Arith<Name>, arg1: CoercibleToArith<Name>): Arith<Name>;
Div<Bits extends number>(arg0: BitVec<Bits, Name>, arg1: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name>;
BUDiv<Bits extends number>(arg0: BitVec<Bits, Name>, arg1: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name>;
Neg(a: Arith<Name>): Arith<Name>;
Neg<Bits extends number>(a: BitVec<Bits, Name>): BitVec<Bits, Name>;
Mod(a: Arith<Name>, b: CoercibleToArith<Name>): Arith<Name>;
Mod<Bits extends number>(a: BitVec<Bits, Name>, b: CoercibleToBitVec<Bits, Name>): BitVec<Bits, Name>;
/** @category Operations */
Select<DomainSort extends NonEmptySortArray<Name>, RangeSort extends Sort<Name> = Sort<Name>>(array: SMTArray<Name, DomainSort, RangeSort>, ...indices: CoercibleToArrayIndexType<Name, DomainSort>): SortToExprMap<RangeSort, Name>;
/** @category Operations */
Store<DomainSort extends NonEmptySortArray<Name>, RangeSort extends Sort<Name> = Sort<Name>>(array: SMTArray<Name, DomainSort, RangeSort>, ...indicesAndValue: [
...CoercibleToArrayIndexType<Name, DomainSort>,
CoercibleToMap<SortToExprMap<RangeSort, Name>, Name>
]): SMTArray<Name, DomainSort, RangeSort>;
/** @category Operations */
Ext<DomainSort extends NonEmptySortArray<Name>, RangeSort extends Sort<Name> = Sort<Name>>(a: SMTArray<Name, DomainSort, RangeSort>, b: SMTArray<Name, DomainSort, RangeSort>): SortToExprMap<DomainSort[0], Name>;
/** @category Operations */
Extract<Bits extends number>(hi: number, lo: number, val: BitVec<Bits, Name>): BitVec<number, Name>;
/** @category Operations */
ast_from_string(s: string): Ast<Name>;
/** @category Operations */
substitute(t: Expr<Name>, ...substitutions: [Expr<Name>, Expr<Name>][]): Expr<Name>;
/** @category Operations */
substituteVars(t: Expr<Name>, ...to: Expr<Name>[]): Expr<Name>;
/** @category Operations */
substituteFuns(t: Expr<Name>, ...substitutions: [FuncDecl<Name>, Expr<Name>][]): Expr<Name>;
/** @category Operations */
updateField(t: DatatypeExpr<Name>, fieldAccessor: FuncDecl<Name>, newValue: Expr<Name>): DatatypeExpr<Name>;
simplify(expr: Expr<Name>): Promise<Expr<Name>>;
/** @category Operations */
SetUnion<ElemSort extends AnySort<Name>>(...args: SMTSet<Name, ElemSort>[]): SMTSet<Name, ElemSort>;
/** @category Operations */
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 */
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 */
SetComplement<ElemSort extends AnySort<Name>>(set: SMTSet<Name, ElemSort>): SMTSet<Name, ElemSort>;
/** @category Operations */
EmptySet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort>;
/** @category Operations */
FullSet<ElemSort extends AnySort<Name>>(sort: ElemSort): SMTSet<Name, ElemSort>;
/** @category Operations */
isMember<ElemSort extends AnySort<Name>>(elem: CoercibleToMap<SortToExprMap<ElemSort, Name>, Name>, set: SMTSet<Name, ElemSort>): Bool<Name>;
/** @category Operations */
isSubset<ElemSort extends AnySort<Name>>(a: SMTSet<Name, ElemSort>, b: SMTSet<Name, ElemSort>): Bool<Name>;
/** @category RegularExpression */
InRe(seq: Seq<Name> | string, re: Re<Name>): Bool<Name>;
/** @category RegularExpression */
Union<SeqSortRef extends SeqSort<Name>>(...res: Re<Name, SeqSortRef>[]): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Intersect<SeqSortRef extends SeqSort<Name>>(...res: Re<Name, SeqSortRef>[]): Re<Name, SeqSortRef>;
/** @category RegularExpression */
ReConcat<SeqSortRef extends SeqSort<Name>>(...res: Re<Name, SeqSortRef>[]): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Plus<SeqSortRef extends SeqSort<Name>>(re: Re<Name, SeqSortRef>): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Star<SeqSortRef extends SeqSort<Name>>(re: Re<Name, SeqSortRef>): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Option<SeqSortRef extends SeqSort<Name>>(re: Re<Name, SeqSortRef>): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Complement<SeqSortRef extends SeqSort<Name>>(re: Re<Name, SeqSortRef>): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Diff<SeqSortRef extends SeqSort<Name>>(a: Re<Name, SeqSortRef>, b: Re<Name, SeqSortRef>): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Range<SeqSortRef extends SeqSort<Name>>(lo: Seq<Name, SeqSortRef> | string, hi: Seq<Name, SeqSortRef> | string): Re<Name, SeqSortRef>;
/**
* Create a bounded repetition regex
* @param re The regex to repeat
* @param lo Minimum number of repetitions
* @param hi Maximum number of repetitions (0 means unbounded, i.e., at least lo)
* @category RegularExpression
*/
Loop<SeqSortRef extends SeqSort<Name>>(re: Re<Name, SeqSortRef>, lo: number, hi?: number): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Power<SeqSortRef extends SeqSort<Name>>(re: Re<Name, SeqSortRef>, n: number): Re<Name, SeqSortRef>;
/** @category RegularExpression */
AllChar<SeqSortRef extends SeqSort<Name>>(reSort: ReSort<Name, SeqSortRef>): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Empty<SeqSortRef extends SeqSort<Name>>(reSort: ReSort<Name, SeqSortRef>): Re<Name, SeqSortRef>;
/** @category RegularExpression */
Full<SeqSortRef extends SeqSort<Name>>(reSort: ReSort<Name, SeqSortRef>): Re<Name, SeqSortRef>;
/**
* Create a partial order relation over a sort.
* @param sort The sort of the relation
* @param index The index of the relation
* @category Operations
*/
mkPartialOrder(sort: Sort<Name>, index: number): FuncDecl<Name>;
/**
* Create the transitive closure of a binary relation.
* The resulting relation is recursive.
* @param f A binary relation represented as a function declaration
* @category Operations
*/
mkTransitiveClosure(f: FuncDecl<Name>): FuncDecl<Name>;
/**
* Return the nonzero subresultants of p and q with respect to the "variable" x.
* Note that any subterm that cannot be viewed as a polynomial is assumed to be a variable.
* @param p Arithmetic term
* @param q Arithmetic term
* @param x Variable with respect to which subresultants are computed
* @category Operations
*/
polynomialSubresultants(p: Arith<Name>, q: Arith<Name>, x: Arith<Name>): Promise<AstVector<Name, Arith<Name>>>;
}
export interface Ast<Name extends string = 'main', Ptr = unknown> {
/** @hidden */
readonly __typename: 'Ast' | Sort['__typename'] | FuncDecl['__typename'] | Expr['__typename'];
readonly ctx: Context<Name>;
/** @hidden */
readonly ptr: Ptr;
/** @virtual */
get ast(): Z3_ast;
/** @virtual */
id(): number;
eqIdentity(other: Ast<Name>): boolean;
neqIdentity(other: Ast<Name>): boolean;
sexpr(): string;
hash(): number;
}
/** @hidden */
export interface SolverCtor<Name extends string> {
new (): Solver<Name>;
}
export interface Solver<Name extends string = 'main'> {
/** @hidden */
readonly __typename: 'Solver';
readonly ctx: Context<Name>;
readonly ptr: Z3_solver;
set(key: string, value: any): void;
push(): void;
pop(num?: number): void;
numScopes(): number;
reset(): void;
add(...exprs: (Bool<Name> | AstVector<Name, Bool<Name>>)[]): void;
addAndTrack(expr: Bool<Name>, constant: Bool<Name> | string): void;
/**
* Attach a simplifier to the solver for incremental pre-processing.
* The solver will use the simplifier for incremental pre-processing of assertions.
* @param simplifier - The simplifier to attach
*/
addSimplifier(simplifier: Simplifier<Name>): void;
assertions(): AstVector<Name, Bool<Name>>;
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>;
/**
* 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>;
/**
* Retrieve statistics for the solver.
* Returns performance metrics, memory usage, decision counts, and other diagnostic information.
*
* @returns A Statistics object containing solver metrics
*
* @example
* ```typescript
* const solver = new Solver();
* const x = Int.const('x');
* solver.add(x.gt(0));
* await solver.check();
* const stats = solver.statistics();
* console.log('Statistics size:', stats.size());
* for (const entry of stats) {
* console.log(`${entry.key}: ${entry.value}`);
* }
* ```
*/
statistics(): Statistics<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;
/**
* Retrieve the set of literals that were inferred by the solver as unit literals.
* These are boolean literals that the solver has determined must be true in all models.
*
* @returns An AstVector containing the unit literals
*
* @example
* ```typescript
* const solver = new Solver();
* const x = Bool.const('x');
* solver.add(x.or(x)); // simplifies to x
* await solver.check();
* const units = solver.units();
* console.log('Unit literals:', units.length());
* ```
*/
units(): AstVector<Name, Bool<Name>>;
/**
* Retrieve the set of tracked boolean literals that are not unit literals.
*
* @returns An AstVector containing the non-unit literals
*
* @example
* ```typescript
* const solver = new Solver();
* const x = Bool.const('x');
* const y = Bool.const('y');
* solver.add(x.or(y));
* await solver.check();
* const nonUnits = solver.nonUnits();
* ```
*/
nonUnits(): AstVector<Name, Bool<Name>>;
/**
* Retrieve the trail of boolean literals assigned by the solver during solving.
* The trail represents the sequence of decisions and propagations made by the solver.
*
* @returns An AstVector containing the trail of assigned literals
*
* @example
* ```typescript
* const solver = new Solver();
* const x = Bool.const('x');
* const y = Bool.const('y');
* solver.add(x.implies(y));
* solver.add(x);
* await solver.check();
* const trail = solver.trail();
* console.log('Trail length:', trail.length());
* ```
*/
trail(): AstVector<Name, Bool<Name>>;
/**
* Retrieve the root of the congruence class containing the given expression.
* This is useful for understanding equality reasoning in the solver.
*
* Note: This works primarily with SimpleSolver and may not work with terms
* eliminated during preprocessing.
*
* @param expr - The expression to find the congruence root for
* @returns The root expression of the congruence class
*
* @example
* ```typescript
* const solver = new Solver();
* const x = Int.const('x');
* const y = Int.const('y');
* solver.add(x.eq(y));
* await solver.check();
* const root = solver.congruenceRoot(x);
* ```
*/
congruenceRoot(expr: Expr<Name>): Expr<Name>;
/**
* Retrieve the next expression in the congruence class containing the given expression.
* The congruence class forms a circular linked list.
*
* Note: This works primarily with SimpleSolver and may not work with terms
* eliminated during preprocessing.
*
* @param expr - The expression to find the next congruent expression for
* @returns The next expression in the congruence class
*
* @example
* ```typescript
* const solver = new Solver();
* const x = Int.const('x');
* const y = Int.const('y');
* const z = Int.const('z');
* solver.add(x.eq(y));
* solver.add(y.eq(z));
* await solver.check();
* const next = solver.congruenceNext(x);
* ```
*/
congruenceNext(expr: Expr<Name>): Expr<Name>;
/**
* Explain why two expressions are congruent according to the solver's reasoning.
* Returns a proof term explaining the congruence.
*
* Note: This works primarily with SimpleSolver and may not work with terms
* eliminated during preprocessing.
*
* @param a - First expression
* @param b - Second expression
* @returns An expression representing the proof of congruence
*
* @example
* ```typescript
* const solver = new Solver();
* const x = Int.const('x');
* const y = Int.const('y');
* solver.add(x.eq(y));
* await solver.check();
* const explanation = solver.congruenceExplain(x, y);
* ```
*/
congruenceExplain(a: Expr<Name>, b: Expr<Name>): Expr<Name>;
/**
* Load SMT-LIB2 format assertions from a file into the solver.
*
* @param filename - Path to the file containing SMT-LIB2 format assertions
*
* @example
* ```typescript
* const solver = new Solver();
* solver.fromFile('problem.smt2');
* const result = await solver.check();
* ```
*/
fromFile(filename: string): void;
/**
* Convert the solver's assertions to SMT-LIB2 format as a benchmark.
*
* This exports the current set of assertions in the solver as an SMT-LIB2 string,
* which can be used for bug reporting, sharing problems, or benchmarking.
*
* @param status - Status string such as "sat", "unsat", or "unknown" (default: "unknown")
* @returns A string representation of the solver's assertions in SMT-LIB2 format
*
* @example
* ```typescript
* const solver = new Solver();
* const x = Int.const('x');
* const y = Int.const('y');
* solver.add(x.gt(0));
* solver.add(y.eq(x.add(1)));
* const smtlib2 = solver.toSmtlib2('unknown');
* console.log(smtlib2); // Prints SMT-LIB2 formatted problem
* ```
*/
toSmtlib2(status?: string): string;
/**
* Manually decrease the reference count of the solver
* This is automatically done when the solver is garbage collected,
* but calling this eagerly can help release memory sooner.
*/
release(): void;
}
export interface Optimize<Name extends string = 'main'> {
/** @hidden */
readonly __typename: 'Optimize';
readonly ctx: Context<Name>;
readonly ptr: Z3_optimize;
set(key: string, value: any): void;
push(): void;
pop(num?: number): void;
add(...exprs: (Bool<Name> | AstVector<Name, Bool<Name>>)[]): void;
addSoft(expr: Bool<Name>, weight: number | bigint | string | CoercibleRational, id?: number | string): void;
addAndTrack(expr: Bool<Name>, constant: Bool<Name> | string): void;
assertions(): AstVector<Name, Bool<Name>>;
fromString(s: string): void;
maximize(expr: Arith<Name>): void;
minimize(expr: Arith<Name>): void;
check(...exprs: (Bool<Name> | AstVector<Name, Bool<Name>>)[]): Promise<CheckSatResult>;
model(): Model<Name>;
statistics(): Statistics<Name>;
/**
* Manually decrease the reference count of the optimize
* This is automatically done when the optimize is garbage collected,
* but calling this eagerly can help release memory sooner.
*/
release(): void;
}
export interface Fixedpoint<Name extends string = 'main'> {
/** @hidden */
readonly __typename: 'Fixedpoint';
readonly ctx: Context<Name>;
readonly ptr: Z3_fixedpoint;
/**
* Set a configuration option for the fixedpoint solver.
* @param key - Configuration parameter name
* @param value - Configuration parameter value
*/
set(key: string, value: any): void;
/**
* Return a string describing all available options.
*/
help(): string;
/**
* Assert a constraint (or multiple) into the fixedpoint solver as background axioms.
*/
add(...constraints: Bool<Name>[]): void;
/**
* Register a predicate as a recursive relation.
* @param pred - Function declaration to register as a recursive relation
*/
registerRelation(pred: FuncDecl<Name>): void;
/**
* Add a rule (Horn clause) to the fixedpoint solver.
* @param rule - The rule as a Boolean expression (implication)
* @param name - Optional name for the rule
*/
addRule(rule: Bool<Name>, name?: string): void;
/**
* Add a table fact to the fixedpoint solver.
* @param pred - The predicate (function declaration)
* @param args - Arguments to the predicate as integers
*/
addFact(pred: FuncDecl<Name>, ...args: number[]): void;
/**
* Update a named rule in the fixedpoint solver.
* @param rule - The rule as a Boolean expression (implication)
* @param name - Name of the rule to update
*/
updateRule(rule: Bool<Name>, name: string): void;
/**
* Query the fixedpoint solver to determine if the formula is derivable.
* @param query - The query as a Boolean expression
* @returns A promise that resolves to 'sat', 'unsat', or 'unknown'
*/
query(query: Bool<Name>): Promise<CheckSatResult>;
/**
* Query the fixedpoint solver for a set of relations.
* @param relations - Array of function declarations representing relations to query
* @returns A promise that resolves to 'sat', 'unsat', or 'unknown'
*/
queryRelations(...relations: FuncDecl<Name>[]): Promise<CheckSatResult>;
/**
* Retrieve the answer (satisfying instance or proof of unsatisfiability) from the last query.
* @returns Expression containing the answer, or null if not available
*/
getAnswer(): Expr<Name> | null;
/**
* Retrieve the reason why the fixedpoint engine returned 'unknown'.
* @returns A string explaining why the result was unknown
*/
getReasonUnknown(): string;
/**
* Retrieve the number of levels explored for a given predicate.
* @param pred - The predicate function declaration
* @returns The number of levels
*/
getNumLevels(pred: FuncDecl<Name>): number;
/**
* Retrieve the cover of a predicate at a given level.
* @param level - The level to query
* @param pred - The predicate function declaration
* @returns Expression representing the cover, or null if not available
*/
getCoverDelta(level: number, pred: FuncDecl<Name>): Expr<Name> | null;
/**
* Add a property about the predicate at the given level.
* @param level - The level to add the property at
* @param pred - The predicate function declaration
* @param property - The property as an expression
*/
addCover(level: number, pred: FuncDecl<Name>, property: Expr<Name>): void;
/**
* Retrieve set of rules added to the fixedpoint context.
* @returns Vector of rules
*/
getRules(): AstVector<Name, Bool<Name>>;
/**
* Retrieve set of assertions added to the fixedpoint context.
* @returns Vector of assertions
*/
getAssertions(): AstVector<Name, Bool<Name>>;
/**
* Set predicate representation for the Datalog engine.
* @param pred - The predicate function declaration
* @param kinds - Array of representation kinds
*/
setPredicateRepresentation(pred: FuncDecl<Name>, kinds: string[]): void;
/**
* Convert the fixedpoint context to a string.
* @returns String representation of the fixedpoint context
*/
toString(): string;
/**
* Parse an SMT-LIB2 string with fixedpoint rules and add them to the context.
* @param s - SMT-LIB2 string to parse
* @returns Vector of queries from the parsed string
*/
fromString(s: string): AstVector<Name, Bool<Name>>;
/**
* Parse an SMT-LIB2 file with fixedpoint rules and add them to the context.
* @param file - Path to the file to parse
* @returns Vector of queries from the parsed file
*/
fromFile(file: string): AstVector<Name, Bool<Name>>;
/**
* Retrieve statistics for the fixedpoint solver.
* Returns performance metrics and diagnostic information.
* @returns A Statistics object containing solver metrics
*/
statistics(): Statistics<Name>;
/**
* Manually decrease the reference count of the fixedpoint
* This is automatically done when the fixedpoint is garbage collected,
* but calling this eagerly can help release memory sooner.
*/
release(): void;
}
/** @hidden */
export interface ModelCtor<Name extends string> {
new (): Model<Name>;
}
export interface Model<Name extends string = 'main'> extends Iterable<FuncDecl<Name>> {
/** @hidden */
readonly __typename: 'Model';
readonly ctx: Context<Name>;
readonly ptr: Z3_model;
length(): number;
entries(): IterableIterator<[number, FuncDecl<Name>]>;
keys(): IterableIterator<number>;
values(): IterableIterator<FuncDecl<Name>>;
decls(): FuncDecl<Name>[];
sexpr(): string;
eval(expr: Bool<Name>, modelCompletion?: boolean): Bool<Name>;
eval(expr: Arith<Name>, modelCompletion?: boolean): Arith<Name>;
eval<Bits extends number = number>(expr: BitVec<Bits, Name>, modelCompletion?: boolean): BitVecNum<Bits, Name>;
eval(expr: Expr<Name>, modelCompletion?: boolean): Expr<Name>;
get(i: number): FuncDecl<Name>;
get(from: number, to: number): FuncDecl<Name>[];
get(declaration: FuncDecl<Name>): FuncInterp<Name> | Expr<Name>;
get(constant: Expr<Name>): Expr<Name>;
get(sort: Sort<Name>): AstVector<Name, AnyExpr<Name>>;
updateValue(decl: FuncDecl<Name> | Expr<Name>, a: Ast<Name> | FuncInterp<Name>): void;
addFuncInterp<DomainSort extends Sort<Name>[] = Sort<Name>[], RangeSort extends Sort<Name> = Sort<Name>>(decl: FuncDecl<Name, DomainSort, RangeSort>, defaultValue: CoercibleToMap<SortToExprMap<RangeSort, Name>, Name>): FuncInterp<Name>;
/**
* Return the number of uninterpreted sorts that have an interpretation in the model.
*
* @returns The number of uninterpreted sorts
*
* @example
* ```typescript
* const { Solver, Sort } = await init();
* const solver = new Solver();
* const A = Sort.declare('A');
* const x = Const('x', A);
* solver.add(x.eq(x));
* await solver.check();
* const model = solver.model();
* console.log('Number of sorts:', model.numSorts());
* ```
*/
numSorts(): number;
/**
* Return the uninterpreted sort at the given index.
*
* @param i - Index of the sort (must be less than numSorts())
* @returns The sort at the given index
*
* @example
* ```typescript
* const model = solver.model();
* for (let i = 0; i < model.numSorts(); i++) {
* const sort = model.getSort(i);
* console.log('Sort:', sort.toString());
* }
* ```
*/
getSort(i: number): Sort<Name>;
/**
* Return all uninterpreted sorts that have an interpretation in the model.
*
* @returns An array of all uninterpreted sorts
*
* @example
* ```typescript
* const model = solver.model();
* const sorts = model.getSorts();
* for (const sort of sorts) {
* console.log('Sort:', sort.toString());
* const universe = model.sortUniverse(sort);
* console.log('Universe size:', universe.length());
* }
* ```
*/
getSorts(): Sort<Name>[];
/**
* Return the finite set of elements that represent the interpretation for the given sort.
* This is only applicable to uninterpreted sorts with finite interpretations.
*
* @param sort - The sort to get the universe for
* @returns An AstVector containing all elements in the sort's universe
*
* @example
* ```typescript
* const { Solver, Sort, Const } = await init();
* const solver = new Solver();
* const A = Sort.declare('A');
* const x = Const('x', A);
* const y = Const('y', A);
* solver.add(x.neq(y));
* await solver.check();
* const model = solver.model();
* const universe = model.sortUniverse(A);
* console.log('Universe has', universe.length(), 'elements');
* for (let i = 0; i < universe.length(); i++) {
* console.log('Element:', universe.get(i).toString());
* }
* ```
*/
sortUniverse(sort: Sort<Name>): AstVector<Name, AnyExpr<Name>>;
/**
* Manually decrease the reference count of the model
* This is automatically done when the model is garbage collected,
* but calling this eagerly can help release memory sooner.
*/
release(): void;
}
/**
* Statistics entry representing a single key-value pair from solver statistics
*/
export interface StatisticsEntry<Name extends string = 'main'> {
/** @hidden */
readonly __typename: 'StatisticsEntry';
/** The key/name of this statistic */
readonly key: string;
/** The numeric value of this statistic */
readonly value: number;
/** True if this statistic is stored as an unsigned integer */
readonly isUint: boolean;
/** True if this statistic is stored as a double */
readonly isDouble: boolean;
}
export interface StatisticsCtor<Name extends string> {
new (): Statistics<Name>;
}
/**
* Statistics for solver operations
*
* Provides access to performance metrics, memory usage, decision counts,
* and other diagnostic information from solver operations.
*/
export interface Statistics<Name extends string = 'main'> extends Iterable<StatisticsEntry<Name>> {
/** @hidden */
readonly __typename: 'Statistics';
readonly ctx: