3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

New OCaml API

This commit is contained in:
Christoph M. Wintersteiger 2016-02-13 22:09:45 +00:00
parent 8fc58e1ace
commit 824169da0a
7 changed files with 2134 additions and 2537 deletions

File diff suppressed because it is too large Load diff

View file

@ -244,33 +244,12 @@ sig
(** Translates (copies) the AST to another context.
@return A copy of the AST which is associated with the other context. *)
val translate : ast -> context -> ast
(** Unwraps an AST.
This function is used for transitions between native and
managed objects. It returns the native pointer to the AST. Note that
AST objects are reference counted and unwrapping an AST disables automatic
reference counting, i.e., all references to the IntPtr that is returned
must be handled externally and through native calls (see e.g.,
[Z3native.inc_ref]).
{!wrap_ast} *)
val unwrap_ast : ast -> Z3native.ptr
(** Wraps an AST.
This function is used for transitions between native and
managed objects. Note that the native ast that is passed must be a
native object obtained from Z3 (e.g., through {!unwrap_ast})
and that it must have a correct reference count (see e.g.,
[Z3native.inc_ref]). *)
val wrap_ast : context -> Z3native.z3_ast -> ast
end
(** The Sort module implements type information for ASTs *)
and Sort :
sig
type sort = Sort of AST.ast
val ast_of_sort : sort -> AST.ast
type sort
(** Comparison operator.
@return True if the two sorts are from the same context
@ -299,9 +278,7 @@ end
(** Function declarations *)
and FuncDecl :
sig
type func_decl = FuncDecl of AST.ast
val ast_of_func_decl : FuncDecl.func_decl -> AST.ast
type func_decl
(** Parameters of Func_Decls *)
module Parameter :
@ -473,7 +450,7 @@ end
(** General Expressions (terms) *)
and Expr :
sig
type expr = Expr of AST.ast
type expr
val ast_of_expr : Expr.expr -> AST.ast
val expr_of_ast : AST.ast -> Expr.expr
@ -662,7 +639,7 @@ end
(** Quantifier expressions *)
module Quantifier :
sig
type quantifier = Quantifier of Expr.expr
type quantifier
val expr_of_quantifier : quantifier -> Expr.expr
val quantifier_of_expr : Expr.expr -> quantifier
@ -674,10 +651,7 @@ sig
also called a multi-pattern. *)
module Pattern :
sig
type pattern = Pattern of AST.ast
val ast_of_pattern : pattern -> AST.ast
val pattern_of_ast : AST.ast -> pattern
type pattern
(** The number of terms in the pattern. *)
val get_num_terms : pattern -> int
@ -1078,7 +1052,6 @@ sig
(** Create mutually recursive data-types. *)
val mk_sorts_s : context -> string list -> Constructor.constructor list list -> Sort.sort list
(** The number of constructors of the datatype sort. *)
val get_num_constructors : Sort.sort -> int
@ -3241,8 +3214,7 @@ end
module Optimize :
sig
type optimize
type handle
type handle
(** Create a Optimize context. *)
val mk_opt : context -> optimize
@ -3250,31 +3222,25 @@ sig
(** A string that describes all available optimize solver parameters. *)
val get_help : optimize -> string
(** Sets the optimize solver parameters. *)
val set_parameters : optimize -> Params.params -> unit
(** Retrieves parameter descriptions for Optimize solver. *)
val get_param_descrs : optimize -> Params.ParamDescrs.param_descrs
(** Assert a constraints into the optimize solver. *)
val add : optimize -> Expr.expr list -> unit
(** Asssert a soft constraint.
Supply integer weight and string that identifies a group
of soft constraints.
*)
val add_soft : optimize -> Expr.expr -> string -> Symbol.symbol -> handle
(** Add maximization objective.
*)
val maximize : optimize -> Expr.expr -> handle
(** Add minimization objective.
*)
val minimize : optimize -> Expr.expr -> handle
@ -3283,38 +3249,30 @@ sig
*)
val check : optimize -> Solver.status
(** Retrieve model from satisfiable context *)
val get_model : optimize -> Model.model option
(** Retrieve lower bound in current model for handle *)
val get_lower : handle -> int -> Expr.expr
(** Retrieve upper bound in current model for handle *)
val get_upper : handle -> int -> Expr.expr
(** Creates a backtracking point.
{!pop} *)
val push : optimize -> unit
(** Backtrack one backtracking point.
Note that an exception is thrown if Pop is called without a corresponding [Push]
{!push} *)
val pop : optimize -> unit
(** Retrieve explanation why optimize engine returned status Unknown. *)
val get_reason_unknown : optimize -> string
(** Retrieve SMT-LIB string representation of optimize object. *)
val to_string : optimize -> string
(** Retrieve statistics information from the last call to check *)
val get_statistics : optimize -> Statistics.statistics
end

107
src/api/ml/z3native.ml.pre Normal file
View file

@ -0,0 +1,107 @@
(** The native (raw) interface to the dynamic Z3 library. *)
open Z3enums
(**/**)
type ptr
and symbol = ptr
and config = ptr
and context = ptr
and ast = ptr
and app = ast
and sort = ast
and func_decl = ast
and pattern = ast
and model = ptr
and literals = ptr
and constructor = ptr
and constructor_list = ptr
and solver = ptr
and goal = ptr
and tactic = ptr
and params = ptr
and probe = ptr
and stats = ptr
and ast_vector = ptr
and ast_map = ptr
and apply_result = ptr
and func_interp = ptr
and func_entry = ptr
and fixedpoint = ptr
and optimize = ptr
and param_descrs = ptr
and rcf_num = ptr
external is_null : ptr -> bool
= "n_is_null"
external mk_null : unit -> ptr
= "n_mk_null"
external set_internal_error_handler : ptr -> unit
= "n_set_internal_error_handler"
external context_of_symbol : symbol -> context
= "n_context_of_symbol"
external context_of_constructor : constructor -> context
= "n_context_of_constructor"
external context_of_constructor_list : constructor_list -> context
= "n_context_of_constructor_list"
external context_of_rcf_num : rcf_num -> context
= "n_context_of_rcf_num"
external context_of_ast : ast -> context
= "n_context_of_ast"
external context_of_params : params -> context
= "n_context_of_params"
external context_of_param_descrs : param_descrs -> context
= "n_context_of_param_descrs"
external context_of_model : model -> context
= "n_context_of_model"
external context_of_func_interp : func_interp -> context
= "n_context_of_func_interp"
external context_of_func_entry : func_entry -> context
= "n_context_of_func_entry"
external context_of_goal : goal -> context
= "n_context_of_goal"
external context_of_tactic : tactic -> context
= "n_context_of_tactic"
external context_of_probe : probe -> context
= "n_context_of_probe"
external context_of_apply_result : apply_result -> context
= "n_context_of_apply_result"
external context_of_solver : solver -> context
= "n_context_of_solver"
external context_of_stats : stats -> context
= "n_context_of_stats"
external context_of_ast_vector : ast_vector -> context
= "n_context_of_ast_vector"
external context_of_ast_map : ast_map -> context
= "n_context_of_ast_map"
external context_of_fixedpoint : fixedpoint -> context
= "n_context_of_fixedpoint"
external context_of_optimize : optimize -> context
= "n_context_of_optimize"
exception Exception of string

View file

@ -0,0 +1,384 @@
#include <stddef.h>
#include <string.h>
#include <assert.h>
#ifdef __cplusplus
extern "C" {
#endif
#include <caml/mlvalues.h>
#include <caml/memory.h>
#include <caml/alloc.h>
#include <caml/fail.h>
#include <caml/callback.h>
#ifdef Custom_tag
#include <caml/custom.h>
#include <caml/bigarray.h>
#endif
#ifdef __cplusplus
}
#endif
#include <z3.h>
#include <z3native_stubs.h>
#define CAMLlocal6(X1,X2,X3,X4,X5,X6) \
CAMLlocal5(X1,X2,X3,X4,X5); \
CAMLlocal1(X6)
#define CAMLlocal7(X1,X2,X3,X4,X5,X6,X7) \
CAMLlocal5(X1,X2,X3,X4,X5); \
CAMLlocal2(X6,X7)
#define CAMLlocal8(X1,X2,X3,X4,X5,X6,X7,X8) \
CAMLlocal5(X1,X2,X3,X4,X5); \
CAMLlocal3(X6,X7,X8)
#define CAMLparam7(X1,X2,X3,X4,X5,X6,X7) \
CAMLparam5(X1,X2,X3,X4,X5); \
CAMLxparam2(X6,X7)
#define CAMLparam8(X1,X2,X3,X4,X5,X6,X7,X8) \
CAMLparam5(X1,X2,X3,X4,X5); \
CAMLxparam3(X6,X7,X8)
#define CAMLparam9(X1,X2,X3,X4,X5,X6,X7,X8,X9) \
CAMLparam5(X1,X2,X3,X4,X5); \
CAMLxparam4(X6,X7,X8,X9)
#define CAMLparam12(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12) \
CAMLparam5(X1,X2,X3,X4,X5); \
CAMLxparam5(X6,X7,X8,X9,X10); \
CAMLxparam2(X11,X12)
#define CAMLparam13(X1,X2,X3,X4,X5,X6,X7,X8,X9,X10,X11,X12,X13) \
CAMLparam5(X1,X2,X3,X4,X5); \
CAMLxparam5(X6,X7,X8,X9,X10); \
CAMLxparam3(X11,X12,X13)
static struct custom_operations default_custom_ops = {
(char*) "default handling",
custom_finalize_default,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
custom_deserialize_default,
custom_compare_ext_default,
};
#define MK_CTX_OF(X) \
Z3_context_plus * n_context_of_ ## X(Z3_ ## X ## _plus * p) { return p->cp; }
// Context objects
typedef struct {
Z3_context ctx;
unsigned long ast_count;
} Z3_context_plus;
Z3_context_plus Z3_context_plus_mk(Z3_context c) {
Z3_context_plus r;
r.ctx = c;
r.ast_count = 0;
printf("ctx++\n");
return r;
}
Z3_context Z3_context_plus_raw(Z3_context_plus * cp) {
return cp->ctx;
}
void Z3_context_finalize(value v) {
Z3_context_plus * cp = (Z3_context_plus*)Data_custom_val(v);
printf("ctx--; cnt=%lu\n", cp->ast_count);
Z3_del_context(cp->ctx);
}
static struct custom_operations Z3_context_plus_custom_ops = {
(char*) "Z3_context ops",
Z3_context_finalize,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
custom_deserialize_default,
custom_compare_ext_default,
};
// Symbol objects
typedef struct {
Z3_context_plus * cp;
Z3_symbol s;
} Z3_symbol_plus;
Z3_symbol_plus Z3_symbol_plus_mk(Z3_context_plus * cp, Z3_symbol s) {
Z3_symbol_plus r;
r.cp = cp;
r.s = s;
return r;
}
Z3_symbol Z3_symbol_plus_raw(Z3_symbol_plus * sp) {
return sp->s;
}
static struct custom_operations Z3_symbol_plus_custom_ops = {
(char*) "Z3_symbol ops",
custom_finalize_default,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
custom_deserialize_default,
custom_compare_ext_default,
};
MK_CTX_OF(symbol)
// AST objects
typedef struct {
Z3_context_plus * cp;
Z3_ast a;
} Z3_ast_plus;
Z3_ast_plus Z3_ast_plus_mk(Z3_context_plus * cp, Z3_ast a) {
Z3_ast_plus r;
r.cp = cp;
r.a = a;
printf("++\n");
Z3_inc_ref(cp->ctx, a);
cp->ast_count++;
return r;
}
Z3_ast Z3_ast_plus_raw(Z3_ast_plus * ap) {
return ap->a;
}
void Z3_ast_finalize(value v) {
printf("--\n");
Z3_ast_plus * ap = (Z3_ast_plus*)(Data_custom_val(v));
Z3_dec_ref(ap->cp->ctx, ap->a);
ap->cp->ast_count--;
}
int Z3_ast_compare(value v1, value v2) {
Z3_ast_plus * a1 = (Z3_ast_plus*)Data_custom_val(v1);
Z3_ast_plus * a2 = (Z3_ast_plus*)Data_custom_val(v2);
assert(a1->cp->ctx == a2->cp->ctx);
unsigned id1 = Z3_get_ast_id(a1->cp->ctx, a1->a);
unsigned id2 = Z3_get_ast_id(a2->cp->ctx, a2->a);
if (id1 == id2)
return 0;
else if (id1 < id2)
return -1;
else
return +1;
}
int Z3_ast_compare_ext(value v1, value v2) {
Z3_ast_plus * a1 = (Z3_ast_plus*)Data_custom_val(v1);
unsigned id1 = Z3_get_ast_id(a1->cp->ctx, a1->a);
int id2 = Val_int(v2);
if (id1 == id2)
return 0;
else if (id1 < id2)
return -1;
else
return +1;
}
intnat Z3_ast_hash(value v) {
Z3_ast_plus * ap = (Z3_ast_plus*)Data_custom_val(v);
return Z3_get_ast_hash(ap->cp->ctx, ap->a);
}
static struct custom_operations Z3_ast_plus_custom_ops = {
(char*) "Z3_ast ops",
Z3_ast_finalize,
Z3_ast_compare,
Z3_ast_hash,
custom_serialize_default,
custom_deserialize_default,
Z3_ast_compare_ext
};
MK_CTX_OF(ast)
// Constructor objects
typedef struct {
Z3_context_plus * cp;
Z3_constructor c;
} Z3_constructor_plus;
Z3_constructor_plus Z3_constructor_plus_mk(Z3_context_plus * cp, Z3_constructor c) {
Z3_constructor_plus r;
r.cp = cp;
r.c = c;
return r;
}
Z3_constructor Z3_constructor_plus_raw(Z3_constructor_plus * cp) {
return cp->c;
}
static struct custom_operations Z3_constructor_plus_custom_ops = {
(char*) "Z3_constructor ops",
custom_finalize_default,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
custom_deserialize_default,
custom_compare_ext_default,
};
MK_CTX_OF(constructor)
// constructor_list objects
typedef struct {
Z3_context_plus * cp;
Z3_constructor_list c;
} Z3_constructor_list_plus;
Z3_constructor_list_plus Z3_constructor_list_plus_mk(Z3_context_plus * cp, Z3_constructor_list c) {
Z3_constructor_list_plus r;
r.cp = cp;
r.c = c;
return r;
}
Z3_constructor_list Z3_constructor_list_plus_raw(Z3_constructor_list_plus * cp) {
return cp->c;
}
static struct custom_operations Z3_constructor_list_plus_custom_ops = {
(char*) "Z3_constructor_list ops",
custom_finalize_default,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
custom_deserialize_default,
custom_compare_ext_default,
};
MK_CTX_OF(constructor_list)
// rcf_num objects
typedef struct {
Z3_context_plus * cp;
Z3_rcf_num c;
} Z3_rcf_num_plus;
Z3_rcf_num_plus Z3_rcf_num_plus_mk(Z3_context_plus * cp, Z3_rcf_num c) {
Z3_rcf_num_plus r;
r.cp = cp;
r.c = c;
return r;
}
Z3_rcf_num Z3_rcf_num_plus_raw(Z3_rcf_num_plus * cp) {
return cp->c;
}
static struct custom_operations Z3_rcf_num_plus_custom_ops = {
(char*) "Z3_rcf_num ops",
custom_finalize_default,
custom_compare_default,
custom_hash_default,
custom_serialize_default,
custom_deserialize_default,
custom_compare_ext_default,
};
MK_CTX_OF(rcf_num)
#define MK_PLUS_OBJ(X) \
typedef struct { \
Z3_context_plus * cp; \
Z3_ ## X p; \
} Z3_ ## X ## _plus; \
\
Z3_ ## X ## _plus Z3_ ## X ## _plus_mk(Z3_context_plus * cp, Z3_ ## X p) { \
Z3_ ## X ## _plus r; \
r.cp = cp; \
r.p = p; \
Z3_ ## X ## _inc_ref(cp->ctx, p); \
return r; \
} \
\
Z3_ ## X Z3_ ## X ## _plus_raw(Z3_ ## X ## _plus * pp) { \
return pp->p; \
} \
\
void Z3_ ## X ## _finalize(value v) { \
Z3_ ## X ## _plus * pp = (Z3_ ## X ## _plus*)Data_custom_val(v); \
Z3_ ## X ## _dec_ref(pp->cp->ctx, pp->p); \
} \
\
static struct custom_operations Z3_ ## X ## _plus_custom_ops = { \
(char*) "Z3_" #X " ops", \
Z3_ ## X ## _finalize, \
custom_compare_default, \
custom_hash_default, \
custom_serialize_default, \
custom_deserialize_default, \
custom_compare_ext_default, \
}; \
\
MK_CTX_OF(X)
MK_PLUS_OBJ(params)
MK_PLUS_OBJ(param_descrs)
MK_PLUS_OBJ(model)
MK_PLUS_OBJ(func_interp)
MK_PLUS_OBJ(func_entry)
MK_PLUS_OBJ(goal)
MK_PLUS_OBJ(tactic)
MK_PLUS_OBJ(probe)
MK_PLUS_OBJ(apply_result)
MK_PLUS_OBJ(solver)
MK_PLUS_OBJ(stats)
MK_PLUS_OBJ(ast_map)
MK_PLUS_OBJ(ast_vector)
MK_PLUS_OBJ(fixedpoint)
MK_PLUS_OBJ(optimize)
#ifdef __cplusplus
extern "C" {
#endif
CAMLprim DLL_PUBLIC value n_is_null(value p) {
void * t = * (void**) Data_custom_val(p);
return Val_bool(t == 0);
}
CAMLprim DLL_PUBLIC value n_mk_null( void ) {
CAMLparam0();
CAMLlocal1(result);
void * z3_result = 0;
result = caml_alloc_custom(&default_custom_ops, sizeof(void*), 0, 1);
memcpy( Data_custom_val(result), &z3_result, sizeof(void*));
CAMLreturn (result);
}
void MLErrorHandler(Z3_context c, Z3_error_code e)
{
// Internal do-nothing error handler. This is required to avoid that Z3 calls exit()
// upon errors, but the actual error handling is done by throwing exceptions in the
// wrappers below.
}
void DLL_PUBLIC n_set_internal_error_handler(value a0)
{
Z3_context _a0 = * (Z3_context*) Data_custom_val(a0);
Z3_set_error_handler(_a0, MLErrorHandler);
}