diff --git a/src/api/js/src/high-level/types.ts b/src/api/js/src/high-level/types.ts index 37d9c8f21..5a9b3f1b1 100644 --- a/src/api/js/src/high-level/types.ts +++ b/src/api/js/src/high-level/types.ts @@ -3,6 +3,8 @@ import { Z3_ast_map, Z3_ast_vector, Z3_context, + Z3_constructor, + Z3_constructor_list, Z3_decl_kind, Z3_func_decl, Z3_func_entry, @@ -22,7 +24,8 @@ export type AnySort = | BoolSort | ArithSort | BitVecSort - | SMTArraySort; + | SMTArraySort + | DatatypeSort; /** @hidden */ export type AnyExpr = | Expr @@ -32,7 +35,8 @@ export type AnyExpr = | RatNum | BitVec | BitVecNum - | SMTArray; + | SMTArray + | DatatypeExpr; /** @hidden */ export type AnyAst = AnyExpr | AnySort | FuncDecl; @@ -842,7 +846,8 @@ export interface Sort extends Ast { | BoolSort['__typename'] | ArithSort['__typename'] | BitVecSort['__typename'] - | SMTArraySort['__typename']; + | SMTArraySort['__typename'] + | DatatypeSort['__typename']; kind(): Z3_sort_kind; @@ -966,7 +971,8 @@ export interface Expr = AnySo | Bool['__typename'] | Arith['__typename'] | BitVec['__typename'] - | SMTArray['__typename']; + | SMTArray['__typename'] + | DatatypeExpr['__typename']; get sort(): S; @@ -1653,6 +1659,111 @@ export interface SMTSet): Bool; } +////////////////////////////////////////// +// +// Datatypes +// +////////////////////////////////////////// + +/** + * Helper class for declaring Z3 datatypes. + * + * Follows the same pattern as Python Z3 API for declaring constructors + * before creating the actual datatype sort. + * + * @example + * ```typescript + * const List = new ctx.Datatype('List'); + * List.declare('cons', ['car', ctx.Int.sort()], ['cdr', List]); + * List.declare('nil'); + * const ListSort = List.create(); + * ``` + * + * @category Datatypes + */ +export interface Datatype { + readonly ctx: Context; + readonly name: string; + + /** + * Declare a constructor for this datatype. + * + * @param name Constructor name + * @param fields Array of [field_name, field_sort] pairs + */ + declare(name: string, ...fields: Array<[string, AnySort | Datatype]>): this; + + /** + * Create the actual datatype sort from the declared constructors. + * For mutually recursive datatypes, use Context.createDatatypes instead. + */ + create(): DatatypeSort; +} + +/** + * @category Datatypes + */ +export interface DatatypeCreation { + /** + * Create a new datatype declaration helper. + */ + (name: string): Datatype; + + /** + * Create mutually recursive datatypes. + * + * @param datatypes Array of Datatype declarations + * @returns Array of created DatatypeSort instances + */ + createDatatypes(...datatypes: Datatype[]): DatatypeSort[]; +} + +/** + * A Sort representing an algebraic datatype. + * + * After creation, this sort will have constructor, recognizer, and accessor + * functions dynamically attached based on the declared constructors. + * + * @category Datatypes + */ +export interface DatatypeSort extends Sort { + /** @hidden */ + readonly __typename: 'DatatypeSort'; + + /** + * Number of constructors in this datatype + */ + numConstructors(): number; + + /** + * Get the idx'th constructor function declaration + */ + constructor(idx: number): FuncDecl; + + /** + * Get the idx'th recognizer function declaration + */ + recognizer(idx: number): FuncDecl; + + /** + * Get the accessor function declaration for the idx_a'th field of the idx_c'th constructor + */ + accessor(constructorIdx: number, accessorIdx: number): FuncDecl; + + cast(other: CoercibleToExpr): DatatypeExpr; + + cast(other: DatatypeExpr): DatatypeExpr; +} + +/** + * Represents expressions of datatype sorts. + * + * @category Datatypes + */ +export interface DatatypeExpr extends Expr, Z3_ast> { + /** @hidden */ + readonly __typename: 'DatatypeExpr'; +} /** * Defines the expression type of the body of a quantifier expression