mirror of
https://github.com/Z3Prover/z3
synced 2025-06-06 22:23:22 +00:00
Integrated structured branch into unstable branch (the official 'working in progress' branch)
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
commit
3da69a4f1b
1502 changed files with 2524 additions and 5113 deletions
219
src/api/api_arith.cpp
Normal file
219
src/api/api_arith.cpp
Normal file
|
@ -0,0 +1,219 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_arith.cpp
|
||||
|
||||
Abstract:
|
||||
API for arith theory
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"algebraic_numbers.h"
|
||||
|
||||
#define MK_ARITH_OP(NAME, OP) MK_NARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP)
|
||||
#define MK_BINARY_ARITH_OP(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP)
|
||||
#define MK_ARITH_PRED(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_arith_fid(), OP, SKIP)
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_sort Z3_API Z3_mk_int_sort(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_int_sort(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_sort r = of_sort(mk_c(c)->m().mk_sort(mk_c(c)->get_arith_fid(), INT_SORT));
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_real_sort(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_real_sort(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_sort r = of_sort(mk_c(c)->m().mk_sort(mk_c(c)->get_arith_fid(), REAL_SORT));
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_real(__in Z3_context c, int num, int den) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_real(c, num, den);
|
||||
RESET_ERROR_CODE();
|
||||
if (den == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
sort* s = mk_c(c)->m().mk_sort(mk_c(c)->get_arith_fid(), REAL_SORT);
|
||||
ast* a = mk_c(c)->mk_numeral_core(rational(num, den), s);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
MK_ARITH_OP(Z3_mk_add, OP_ADD);
|
||||
MK_ARITH_OP(Z3_mk_mul, OP_MUL);
|
||||
MK_BINARY_ARITH_OP(Z3_mk_power, OP_POWER);
|
||||
MK_BINARY_ARITH_OP(Z3_mk_mod, OP_MOD);
|
||||
MK_BINARY_ARITH_OP(Z3_mk_rem, OP_REM);
|
||||
|
||||
Z3_ast Z3_API Z3_mk_div(Z3_context c, Z3_ast n1, Z3_ast n2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_div(c, n1, n2);
|
||||
RESET_ERROR_CODE();
|
||||
decl_kind k = OP_IDIV;
|
||||
sort* ty = mk_c(c)->m().get_sort(to_expr(n1));
|
||||
sort* real_ty = mk_c(c)->m().mk_sort(mk_c(c)->get_arith_fid(), REAL_SORT);
|
||||
if (ty == real_ty) {
|
||||
k = OP_DIV;
|
||||
}
|
||||
expr * args[2] = { to_expr(n1), to_expr(n2) };
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_arith_fid(), k, 0, 0, 2, args);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
MK_ARITH_PRED(Z3_mk_lt, OP_LT);
|
||||
MK_ARITH_PRED(Z3_mk_gt, OP_GT);
|
||||
MK_ARITH_PRED(Z3_mk_le, OP_LE);
|
||||
MK_ARITH_PRED(Z3_mk_ge, OP_GE);
|
||||
MK_UNARY(Z3_mk_int2real, mk_c(c)->get_arith_fid(), OP_TO_REAL, SKIP);
|
||||
MK_UNARY(Z3_mk_real2int, mk_c(c)->get_arith_fid(), OP_TO_INT, SKIP);
|
||||
MK_UNARY(Z3_mk_is_int, mk_c(c)->get_arith_fid(), OP_IS_INT, SKIP);
|
||||
|
||||
Z3_ast Z3_API Z3_mk_sub(Z3_context c, unsigned num_args, Z3_ast const args[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_sub(c, num_args, args);
|
||||
RESET_ERROR_CODE();
|
||||
if (num_args == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
if (mk_c(c)->fparams().m_pre_simplify_expr) {
|
||||
// Do not use logging here... the function is implemented using API primitives
|
||||
Z3_ast m1 = Z3_mk_int(c, -1, Z3_get_sort(c, args[0]));
|
||||
Z3_ast args1[2] = { args[0], 0 };
|
||||
for (unsigned i = 1; i < num_args; ++i) {
|
||||
Z3_ast args2[3] = { m1, args[i] };
|
||||
args1[1] = Z3_mk_mul(c, 2, args2);
|
||||
args1[0] = Z3_mk_add(c, 2, args1);
|
||||
}
|
||||
RETURN_Z3(args1[0]);
|
||||
}
|
||||
else {
|
||||
expr* r = to_expr(args[0]);
|
||||
for (unsigned i = 1; i < num_args; ++i) {
|
||||
expr* args1[2] = { r, to_expr(args[i]) };
|
||||
r = mk_c(c)->m().mk_app(mk_c(c)->get_arith_fid(), OP_SUB, 0, 0, 2, args1);
|
||||
check_sorts(c, r);
|
||||
}
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_unary_minus(Z3_context c, Z3_ast n) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_unary_minus(c, n);
|
||||
RESET_ERROR_CODE();
|
||||
if (mk_c(c)->fparams().m_pre_simplify_expr) {
|
||||
Z3_ast m1 = Z3_mk_int(c, -1, Z3_get_sort(c, n));
|
||||
Z3_ast args[2] = { m1, n };
|
||||
Z3_ast r = Z3_mk_mul(c, 2, args);
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
MK_UNARY_BODY(Z3_mk_unary_minus, mk_c(c)->get_arith_fid(), OP_UMINUS, SKIP);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_algebraic_number(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_is_algebraic_number(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
expr * e = to_expr(a);
|
||||
return mk_c(c)->autil().is_irrational_algebraic_numeral(e);
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_algebraic_number_lower(Z3_context c, Z3_ast a, unsigned precision) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_algebraic_number_lower(c, a, precision);
|
||||
RESET_ERROR_CODE();
|
||||
if (!Z3_is_algebraic_number(c, a)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
expr * e = to_expr(a);
|
||||
algebraic_numbers::anum const & val = mk_c(c)->autil().to_irrational_algebraic_numeral(e);
|
||||
rational l;
|
||||
mk_c(c)->autil().am().get_lower(val, l, precision);
|
||||
expr * r = mk_c(c)->autil().mk_numeral(l, false);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_algebraic_number_upper(Z3_context c, Z3_ast a, unsigned precision) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_algebraic_number_upper(c, a, precision);
|
||||
RESET_ERROR_CODE();
|
||||
if (!Z3_is_algebraic_number(c, a)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
expr * e = to_expr(a);
|
||||
algebraic_numbers::anum const & val = mk_c(c)->autil().to_irrational_algebraic_numeral(e);
|
||||
rational l;
|
||||
mk_c(c)->autil().am().get_upper(val, l, precision);
|
||||
expr * r = mk_c(c)->autil().mk_numeral(l, false);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_numerator(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_numerator(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
rational val;
|
||||
ast * _a = to_ast(a);
|
||||
if (!is_expr(_a) || !mk_c(c)->autil().is_numeral(to_expr(_a), val)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
expr * r = mk_c(c)->autil().mk_numeral(numerator(val), true);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_denominator(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_denominator(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
rational val;
|
||||
ast * _a = to_ast(a);
|
||||
if (!is_expr(_a) || !mk_c(c)->autil().is_numeral(to_expr(_a), val)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
expr * r = mk_c(c)->autil().mk_numeral(denominator(val), true);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
};
|
233
src/api/api_array.cpp
Normal file
233
src/api/api_array.cpp
Normal file
|
@ -0,0 +1,233 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_array.cpp
|
||||
|
||||
Abstract:
|
||||
API for array theory
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"array_decl_plugin.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_sort Z3_API Z3_mk_array_sort(Z3_context c, Z3_sort domain, Z3_sort range) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_array_sort(c, domain, range);
|
||||
RESET_ERROR_CODE();
|
||||
parameter params[2] = { parameter(to_sort(domain)), parameter(to_sort(range)) };
|
||||
sort * ty = mk_c(c)->m().mk_sort(mk_c(c)->get_array_fid(), ARRAY_SORT, 2, params);
|
||||
mk_c(c)->save_ast_trail(ty);
|
||||
RETURN_Z3(of_sort(ty));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_select(Z3_context c, Z3_ast a, Z3_ast i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_select(c, a, i);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _a = to_expr(a);
|
||||
expr * _i = to_expr(i);
|
||||
sort * a_ty = m.get_sort(_a);
|
||||
sort * i_ty = m.get_sort(_i);
|
||||
if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
sort * domain[2] = {a_ty, i_ty};
|
||||
func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_SELECT, 2, a_ty->get_parameters(), 2, domain);
|
||||
expr * args[2] = {_a, _i};
|
||||
app * r = m.mk_app(d, 2, args);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_store(Z3_context c, Z3_ast a, Z3_ast i, Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_store(c, a, i, v);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _a = to_expr(a);
|
||||
expr * _i = to_expr(i);
|
||||
expr * _v = to_expr(v);
|
||||
sort * a_ty = m.get_sort(_a);
|
||||
sort * i_ty = m.get_sort(_i);
|
||||
sort * v_ty = m.get_sort(_v);
|
||||
if (a_ty->get_family_id() != mk_c(c)->get_array_fid()) {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
sort * domain[3] = {a_ty, i_ty, v_ty};
|
||||
func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_STORE, 2, a_ty->get_parameters(), 3, domain);
|
||||
expr * args[3] = {_a, _i, _v};
|
||||
app * r = m.mk_app(d, 3, args);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_map(__in Z3_context c, __in Z3_func_decl f, unsigned n, __in Z3_ast const* args) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_map(c, f, n, args);
|
||||
RESET_ERROR_CODE();
|
||||
if (n == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
func_decl* _f = to_func_decl(f);
|
||||
expr* const* _args = to_exprs(args);
|
||||
|
||||
ptr_vector<sort> domain;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
domain.push_back(m.get_sort(_args[i]));
|
||||
}
|
||||
parameter param(_f);
|
||||
func_decl * d = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_ARRAY_MAP, 1, ¶m, n, domain.c_ptr());
|
||||
app* r = m.mk_app(d, n, _args);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_const_array(__in Z3_context c, __in Z3_sort domain, __in Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_const_array(c, domain, v);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _v = to_expr(v);
|
||||
sort * _range = m.get_sort(_v);
|
||||
sort * _domain = to_sort(domain);
|
||||
parameter params[2] = { parameter(_domain), parameter(_range) };
|
||||
sort * a_ty = mk_c(c)->m().mk_sort(mk_c(c)->get_array_fid(), ARRAY_SORT, 2, params);
|
||||
parameter param(a_ty);
|
||||
func_decl* cd = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_CONST_ARRAY, 1, ¶m, 1, &_range);
|
||||
app * r = m.mk_app(cd, 1, &_v);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_array_default(__in Z3_context c, __in Z3_ast array) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_array_default(c, array);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _a = to_expr(array);
|
||||
|
||||
func_decl * f = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_ARRAY_DEFAULT, 0, 0, 1, &_a);
|
||||
app * r = m.mk_app(f, 1, &_a);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast mk_app_array_core(__in Z3_context c, __in Z3_sort domain, __in Z3_ast v) {
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
expr * _v = to_expr(v);
|
||||
sort * _range = m.get_sort(_v);
|
||||
sort * _domain = to_sort(domain);
|
||||
parameter params[2] = { parameter(_domain), parameter(_range) };
|
||||
sort * a_ty = mk_c(c)->m().mk_sort(mk_c(c)->get_array_fid(), ARRAY_SORT, 2, params);
|
||||
parameter param(a_ty);
|
||||
func_decl * cd = m.mk_func_decl(mk_c(c)->get_array_fid(), OP_CONST_ARRAY, 1, ¶m, 1, &_range);
|
||||
app * r = m.mk_app(cd, 1, &_v);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
check_sorts(c, r);
|
||||
return of_ast(r);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_set_sort(__in Z3_context c, __in Z3_sort ty) {
|
||||
Z3_TRY;
|
||||
return Z3_mk_array_sort(c, ty, Z3_mk_bool_sort(c));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_empty_set(__in Z3_context c, __in Z3_sort domain) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_empty_set(c, domain);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast r = mk_app_array_core(c, domain, Z3_mk_false(c));
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_full_set(__in Z3_context c, __in Z3_sort domain) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_full_set(c, domain);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast r = mk_app_array_core(c, domain, Z3_mk_true(c));
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
MK_NARY(Z3_mk_set_union, mk_c(c)->get_array_fid(), OP_SET_UNION, SKIP);
|
||||
MK_NARY(Z3_mk_set_intersect, mk_c(c)->get_array_fid(), OP_SET_INTERSECT, SKIP);
|
||||
MK_BINARY(Z3_mk_set_difference, mk_c(c)->get_array_fid(), OP_SET_DIFFERENCE, SKIP);
|
||||
MK_UNARY(Z3_mk_set_complement, mk_c(c)->get_array_fid(), OP_SET_COMPLEMENT, SKIP);
|
||||
MK_BINARY(Z3_mk_set_subset, mk_c(c)->get_array_fid(), OP_SET_SUBSET, SKIP);
|
||||
|
||||
Z3_ast Z3_mk_set_member(__in Z3_context c, __in Z3_ast elem, __in Z3_ast set) {
|
||||
return Z3_mk_select(c, set, elem);
|
||||
}
|
||||
|
||||
Z3_ast Z3_mk_set_add(__in Z3_context c, __in Z3_ast set, __in Z3_ast elem) {
|
||||
return Z3_mk_store(c, set, elem, Z3_mk_true(c));
|
||||
}
|
||||
|
||||
Z3_ast Z3_mk_set_del(__in Z3_context c, __in Z3_ast set, __in Z3_ast elem) {
|
||||
return Z3_mk_store(c, set, elem, Z3_mk_false(c));
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_get_array_sort_domain(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_array_sort_domain(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT) {
|
||||
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(0).get_ast());
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_get_array_sort_range(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_array_sort_range(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_array_fid() &&
|
||||
to_sort(t)->get_decl_kind() == ARRAY_SORT) {
|
||||
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(1).get_ast());
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
};
|
1156
src/api/api_ast.cpp
Normal file
1156
src/api/api_ast.cpp
Normal file
File diff suppressed because it is too large
Load diff
169
src/api/api_ast_map.cpp
Normal file
169
src/api/api_ast_map.cpp
Normal file
|
@ -0,0 +1,169 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_ast_map.cpp
|
||||
|
||||
Abstract:
|
||||
API for creating AST maps
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-09.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_ast_map.h"
|
||||
#include"api_ast_vector.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"dec_ref_util.h"
|
||||
|
||||
Z3_ast_map_ref::~Z3_ast_map_ref() {
|
||||
dec_ref_key_values(m, m_map);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_ast_map Z3_API Z3_mk_ast_map(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_ast_map(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast_map_ref * m = alloc(Z3_ast_map_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(m);
|
||||
Z3_ast_map r = of_ast_map(m);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_map_inc_ref(Z3_context c, Z3_ast_map m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_inc_ref(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
to_ast_map(m)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_map_dec_ref(Z3_context c, Z3_ast_map m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_dec_ref(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
to_ast_map(m)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_ast_map_contains(Z3_context c, Z3_ast_map m, Z3_ast k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_contains(c, m, k);
|
||||
RESET_ERROR_CODE();
|
||||
return to_ast_map_ref(m).contains(to_ast(k));
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_ast_map_find(Z3_context c, Z3_ast_map m, Z3_ast k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_find(c, m, k);
|
||||
RESET_ERROR_CODE();
|
||||
obj_map<ast, ast*>::obj_map_entry * entry = to_ast_map_ref(m).find_core(to_ast(k));
|
||||
if (entry == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
else {
|
||||
ast * r = entry->get_data().m_value;
|
||||
RETURN_Z3(of_ast(r));
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_map_insert(Z3_context c, Z3_ast_map m, Z3_ast k, Z3_ast v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_insert(c, m, k, v);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & mng = to_ast_map(m)->m;
|
||||
obj_map<ast, ast*>::obj_map_entry * entry = to_ast_map_ref(m).insert_if_not_there2(to_ast(k), 0);
|
||||
if (entry->get_data().m_value == 0) {
|
||||
// new entry
|
||||
mng.inc_ref(to_ast(k));
|
||||
mng.inc_ref(to_ast(v));
|
||||
entry->get_data().m_value = to_ast(v);
|
||||
}
|
||||
else {
|
||||
// replacing entry
|
||||
mng.inc_ref(to_ast(v));
|
||||
mng.dec_ref(entry->get_data().m_value);
|
||||
entry->get_data().m_value = to_ast(v);
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_map_reset(Z3_context c, Z3_ast_map m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_reset(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
dec_ref_key_values(to_ast_map(m)->m, to_ast_map_ref(m));
|
||||
SASSERT(to_ast_map_ref(m).empty());
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_map_erase(Z3_context c, Z3_ast_map m, Z3_ast k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_erase(c, m, k);
|
||||
RESET_ERROR_CODE();
|
||||
ast * v = 0;
|
||||
if (to_ast_map_ref(m).find(to_ast(k), v)) {
|
||||
to_ast_map_ref(m).erase(to_ast(k));
|
||||
ast_manager & mng = to_ast_map(m)->m;
|
||||
mng.dec_ref(to_ast(k));
|
||||
mng.dec_ref(v);
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_ast_map_size(Z3_context c, Z3_ast_map m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_size(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
return to_ast_map_ref(m).size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_ast_map_keys(Z3_context c, Z3_ast_map m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_keys(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, to_ast_map(m)->m);
|
||||
mk_c(c)->save_object(v);
|
||||
obj_map<ast, ast*>::iterator it = to_ast_map_ref(m).begin();
|
||||
obj_map<ast, ast*>::iterator end = to_ast_map_ref(m).end();
|
||||
for (; it != end; ++it) {
|
||||
v->m_ast_vector.push_back(it->m_key);
|
||||
}
|
||||
Z3_ast_vector r = of_ast_vector(v);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_ast_map_to_string(Z3_context c, Z3_ast_map m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_map_to_string(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
ast_manager & mng = to_ast_map(m)->m;
|
||||
buffer << "(ast-map";
|
||||
obj_map<ast, ast*>::iterator it = to_ast_map_ref(m).begin();
|
||||
obj_map<ast, ast*>::iterator end = to_ast_map_ref(m).end();
|
||||
for (; it != end; ++it) {
|
||||
buffer << "\n (" << mk_ismt2_pp(it->m_key, mng, 3) << "\n " << mk_ismt2_pp(it->m_value, mng, 3) << ")";
|
||||
}
|
||||
buffer << ")";
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
};
|
35
src/api/api_ast_map.h
Normal file
35
src/api/api_ast_map.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_ast_map.h
|
||||
|
||||
Abstract:
|
||||
API for creating AST maps
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-09.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_AST_MAP_H_
|
||||
#define _API_AST_MAP_H_
|
||||
|
||||
#include"api_util.h"
|
||||
#include"obj_hashtable.h"
|
||||
|
||||
struct Z3_ast_map_ref : public api::object {
|
||||
ast_manager & m;
|
||||
obj_map<ast, ast*> m_map;
|
||||
Z3_ast_map_ref(ast_manager & _m):m(_m) {}
|
||||
virtual ~Z3_ast_map_ref();
|
||||
};
|
||||
|
||||
inline Z3_ast_map_ref * to_ast_map(Z3_ast_map v) { return reinterpret_cast<Z3_ast_map_ref *>(v); }
|
||||
inline Z3_ast_map of_ast_map(Z3_ast_map_ref * v) { return reinterpret_cast<Z3_ast_map>(v); }
|
||||
inline obj_map<ast, ast*> & to_ast_map_ref(Z3_ast_map v) { return to_ast_map(v)->m_map; }
|
||||
|
||||
#endif
|
140
src/api/api_ast_vector.cpp
Normal file
140
src/api/api_ast_vector.cpp
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_ast_vector.cpp
|
||||
|
||||
Abstract:
|
||||
API for creating AST vectors
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-09.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_ast_vector.h"
|
||||
#include"ast_translation.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_ast_vector Z3_API Z3_mk_ast_vector(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_ast_vector(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
Z3_ast_vector r = of_ast_vector(v);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_vector_inc_ref(Z3_context c, Z3_ast_vector v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_vector_inc_ref(c, v);
|
||||
RESET_ERROR_CODE();
|
||||
to_ast_vector(v)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_vector_dec_ref(Z3_context c, Z3_ast_vector v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_vector_dec_ref(c, v);
|
||||
RESET_ERROR_CODE();
|
||||
to_ast_vector(v)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_ast_vector_size(Z3_context c, Z3_ast_vector v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_vector_size(c, v);
|
||||
RESET_ERROR_CODE();
|
||||
return to_ast_vector_ref(v).size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_ast_vector_get(Z3_context c, Z3_ast_vector v, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_vector_get(c, v, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (i >= to_ast_vector_ref(v).size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
// Remark: Don't need to invoke save_object.
|
||||
ast * r = to_ast_vector_ref(v).get(i);
|
||||
RETURN_Z3(of_ast(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_vector_set(Z3_context c, Z3_ast_vector v, unsigned i, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_vector_set(c, v, i, a);
|
||||
RESET_ERROR_CODE();
|
||||
if (i >= to_ast_vector_ref(v).size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return;
|
||||
}
|
||||
to_ast_vector_ref(v).set(i, to_ast(a));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_vector_resize(Z3_context c, Z3_ast_vector v, unsigned n) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_vector_resize(c, v, n);
|
||||
RESET_ERROR_CODE();
|
||||
to_ast_vector_ref(v).resize(n);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_ast_vector_push(Z3_context c, Z3_ast_vector v, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_vector_push(c, v, a);
|
||||
RESET_ERROR_CODE();
|
||||
to_ast_vector_ref(v).push_back(to_ast(a));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_ast_vector_translate(Z3_context c, Z3_ast_vector v, Z3_context t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_vector_translate(c, v, t);
|
||||
RESET_ERROR_CODE();
|
||||
if (c == t) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ast_translation translator(mk_c(c)->m(), mk_c(t)->m());
|
||||
Z3_ast_vector_ref * new_v = alloc(Z3_ast_vector_ref, mk_c(t)->m());
|
||||
mk_c(t)->save_object(new_v);
|
||||
unsigned sz = to_ast_vector_ref(v).size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
ast * new_ast = translator(to_ast_vector_ref(v).get(i));
|
||||
new_v->m_ast_vector.push_back(new_ast);
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(new_v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_ast_vector_to_string(Z3_context c, Z3_ast_vector v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_ast_vector_to_string(c, v);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
buffer << "(ast-vector";
|
||||
unsigned sz = to_ast_vector_ref(v).size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
buffer << "\n " << mk_ismt2_pp(to_ast_vector_ref(v).get(i), mk_c(c)->m(), 2);
|
||||
}
|
||||
buffer << ")";
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
};
|
33
src/api/api_ast_vector.h
Normal file
33
src/api/api_ast_vector.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_ast_vector.h
|
||||
|
||||
Abstract:
|
||||
API for creating AST vectors
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-09.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_AST_VECTOR_H_
|
||||
#define _API_AST_VECTOR_H_
|
||||
|
||||
#include"api_util.h"
|
||||
|
||||
struct Z3_ast_vector_ref : public api::object {
|
||||
ast_ref_vector m_ast_vector;
|
||||
Z3_ast_vector_ref(ast_manager & m):m_ast_vector(m) {}
|
||||
virtual ~Z3_ast_vector_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_ast_vector_ref * to_ast_vector(Z3_ast_vector v) { return reinterpret_cast<Z3_ast_vector_ref *>(v); }
|
||||
inline Z3_ast_vector of_ast_vector(Z3_ast_vector_ref * v) { return reinterpret_cast<Z3_ast_vector>(v); }
|
||||
inline ast_ref_vector & to_ast_vector_ref(Z3_ast_vector v) { return to_ast_vector(v)->m_ast_vector; }
|
||||
|
||||
#endif
|
320
src/api/api_bv.cpp
Normal file
320
src/api/api_bv.cpp
Normal file
|
@ -0,0 +1,320 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_bv.cpp
|
||||
|
||||
Abstract:
|
||||
API for bv theory
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"bv_decl_plugin.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_sort Z3_API Z3_mk_bv_sort(Z3_context c, unsigned sz) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bv_sort(c, sz);
|
||||
RESET_ERROR_CODE();
|
||||
if (sz == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
}
|
||||
parameter p(sz);
|
||||
Z3_sort r = of_sort(mk_c(c)->m().mk_sort(mk_c(c)->get_bv_fid(), BV_SORT, 1, &p));
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
#define MK_BV_UNARY(NAME, OP) MK_UNARY(NAME, mk_c(c)->get_bv_fid(), OP, SKIP)
|
||||
#define MK_BV_BINARY(NAME, OP) MK_BINARY(NAME, mk_c(c)->get_bv_fid(), OP, SKIP)
|
||||
|
||||
MK_BV_UNARY(Z3_mk_bvnot, OP_BNOT);
|
||||
MK_BV_UNARY(Z3_mk_bvredand, OP_BREDAND);
|
||||
MK_BV_UNARY(Z3_mk_bvredor, OP_BREDOR);
|
||||
MK_BV_BINARY(Z3_mk_bvand, OP_BAND);
|
||||
MK_BV_BINARY(Z3_mk_bvor, OP_BOR);
|
||||
MK_BV_BINARY(Z3_mk_bvxor, OP_BXOR);
|
||||
MK_BV_BINARY(Z3_mk_bvnand, OP_BNAND);
|
||||
MK_BV_BINARY(Z3_mk_bvnor, OP_BNOR);
|
||||
MK_BV_BINARY(Z3_mk_bvxnor, OP_BXNOR);
|
||||
MK_BV_BINARY(Z3_mk_bvadd, OP_BADD);
|
||||
MK_BV_BINARY(Z3_mk_bvmul, OP_BMUL);
|
||||
MK_BV_BINARY(Z3_mk_bvudiv, OP_BUDIV);
|
||||
MK_BV_BINARY(Z3_mk_bvsdiv, OP_BSDIV);
|
||||
MK_BV_BINARY(Z3_mk_bvurem, OP_BUREM);
|
||||
MK_BV_BINARY(Z3_mk_bvsrem, OP_BSREM);
|
||||
MK_BV_BINARY(Z3_mk_bvsmod, OP_BSMOD);
|
||||
MK_BV_BINARY(Z3_mk_bvule, OP_ULEQ);
|
||||
MK_BV_BINARY(Z3_mk_bvsle, OP_SLEQ);
|
||||
MK_BV_BINARY(Z3_mk_bvuge, OP_UGEQ);
|
||||
MK_BV_BINARY(Z3_mk_bvsge, OP_SGEQ);
|
||||
MK_BV_BINARY(Z3_mk_bvult, OP_ULT);
|
||||
MK_BV_BINARY(Z3_mk_bvslt, OP_SLT);
|
||||
MK_BV_BINARY(Z3_mk_bvugt, OP_UGT);
|
||||
MK_BV_BINARY(Z3_mk_bvsgt, OP_SGT);
|
||||
MK_BV_BINARY(Z3_mk_concat, OP_CONCAT);
|
||||
MK_BV_BINARY(Z3_mk_bvshl, OP_BSHL);
|
||||
MK_BV_BINARY(Z3_mk_bvlshr, OP_BLSHR);
|
||||
MK_BV_BINARY(Z3_mk_bvashr, OP_BASHR);
|
||||
MK_BV_BINARY(Z3_mk_ext_rotate_left, OP_EXT_ROTATE_LEFT);
|
||||
MK_BV_BINARY(Z3_mk_ext_rotate_right, OP_EXT_ROTATE_RIGHT);
|
||||
|
||||
Z3_ast mk_extract_core(Z3_context c, unsigned high, unsigned low, Z3_ast n) {
|
||||
expr * _n = to_expr(n);
|
||||
parameter params[2] = { parameter(high), parameter(low) };
|
||||
expr * a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_EXTRACT, 2, params, 1, &_n);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
return of_ast(a);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_extract(Z3_context c, unsigned high, unsigned low, Z3_ast n) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_extract(c, high, low, n);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast r = mk_extract_core(c, high, low, n);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
#define MK_BV_PUNARY(NAME, OP) \
|
||||
Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
|
||||
Z3_TRY; \
|
||||
LOG_ ## NAME(c, i, n); \
|
||||
RESET_ERROR_CODE(); \
|
||||
expr * _n = to_expr(n); \
|
||||
parameter p(i); \
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP, 1, &p, 1, &_n); \
|
||||
mk_c(c)->save_ast_trail(a); \
|
||||
check_sorts(c, a); \
|
||||
RETURN_Z3(of_ast(a)); \
|
||||
Z3_CATCH_RETURN(0); \
|
||||
}
|
||||
|
||||
MK_BV_PUNARY(Z3_mk_sign_ext, OP_SIGN_EXT);
|
||||
MK_BV_PUNARY(Z3_mk_zero_ext, OP_ZERO_EXT);
|
||||
MK_BV_PUNARY(Z3_mk_repeat, OP_REPEAT);
|
||||
MK_BV_PUNARY(Z3_mk_rotate_left, OP_ROTATE_LEFT);
|
||||
MK_BV_PUNARY(Z3_mk_rotate_right, OP_ROTATE_RIGHT);
|
||||
MK_BV_PUNARY(Z3_mk_int2bv, OP_INT2BV);
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bv2int(Z3_context c, Z3_ast n, Z3_bool is_signed) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bv2int(c, n, is_signed);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_sort int_s = Z3_mk_int_sort(c);
|
||||
if (is_signed) {
|
||||
Z3_ast r = Z3_mk_bv2int(c, n, false);
|
||||
Z3_sort s = Z3_get_sort(c, n);
|
||||
unsigned sz = Z3_get_bv_sort_size(c, s);
|
||||
rational max_bound = power(rational(2), sz);
|
||||
Z3_ast bound = Z3_mk_numeral(c, max_bound.to_string().c_str(), int_s);
|
||||
Z3_ast pred = Z3_mk_bvslt(c, n, Z3_mk_int(c, 0, s));
|
||||
// if n <_sigend 0 then r - s^sz else r
|
||||
Z3_ast args[2] = { r, bound };
|
||||
Z3_ast res = Z3_mk_ite(c, pred, Z3_mk_sub(c, 2, args), r);
|
||||
RETURN_Z3(res);
|
||||
}
|
||||
else {
|
||||
expr * _n = to_expr(n);
|
||||
parameter p(to_sort(int_s));
|
||||
ast* a = mk_c(c)->m().mk_app(mk_c(c)->get_bv_fid(), OP_BV2INT, 1, &p, 1, &_n);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
check_sorts(c, a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief \mlh mk_bvmsb c s \endmlh
|
||||
Create a bit-vector of sort \s with 1 in the most significant bit position.
|
||||
|
||||
The sort \s must be a bit-vector sort.
|
||||
|
||||
This function is a shorthand for <tt>shl(1, N-1)</tt>
|
||||
where <tt>N</tt> are the number of bits of \c s.
|
||||
*/
|
||||
Z3_ast Z3_API Z3_mk_bvmsb(__in Z3_context c, __in Z3_sort s) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
// Not logging this one, since it is just syntax sugar.
|
||||
unsigned sz = Z3_get_bv_sort_size(c, s);
|
||||
if (sz == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return Z3_mk_bvshl(c, Z3_mk_int64(c, 1, s), Z3_mk_int64(c, sz - 1, s));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_mk_bvsmin(__in Z3_context c, __in Z3_sort s) {
|
||||
return Z3_mk_bvmsb(c, s);
|
||||
}
|
||||
|
||||
Z3_ast Z3_mk_bvsmax(__in Z3_context c, __in Z3_sort s) {
|
||||
return Z3_mk_bvnot(c, Z3_mk_bvmsb(c, s));
|
||||
}
|
||||
|
||||
Z3_ast Z3_mk_bvumax(__in Z3_context c, __in Z3_sort s) {
|
||||
return Z3_mk_int(c, -1, s);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bvadd_no_overflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2, Z3_bool is_signed) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
if (is_signed) {
|
||||
Z3_ast zero = Z3_mk_int(c, 0, Z3_get_sort(c, t1));
|
||||
Z3_ast r = Z3_mk_bvadd(c, t1, t2);
|
||||
Z3_ast args[2] = { Z3_mk_bvslt(c, zero, t1), Z3_mk_bvslt(c, zero, t2) };
|
||||
Z3_ast args_pos = Z3_mk_and(c, 2, args);
|
||||
return Z3_mk_implies(c, args_pos, Z3_mk_bvslt(c, zero, r));
|
||||
}
|
||||
else {
|
||||
unsigned sz = Z3_get_bv_sort_size(c, Z3_get_sort(c, t1));
|
||||
t1 = Z3_mk_zero_ext(c, 1, t1);
|
||||
t2 = Z3_mk_zero_ext(c, 1, t2);
|
||||
Z3_ast r = Z3_mk_bvadd(c, t1, t2);
|
||||
return Z3_mk_eq(c, Z3_mk_extract(c, sz, sz, r), Z3_mk_int(c, 0, Z3_mk_bv_sort(c, 1)));
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
// only for signed machine integers
|
||||
Z3_ast Z3_API Z3_mk_bvadd_no_underflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast zero = Z3_mk_int(c, 0, Z3_get_sort(c, t1));
|
||||
Z3_ast r = Z3_mk_bvadd(c, t1, t2);
|
||||
Z3_ast args[2] = { Z3_mk_bvslt(c, t1, zero), Z3_mk_bvslt(c, t2, zero) };
|
||||
Z3_ast args_neg = Z3_mk_and(c, 2, args);
|
||||
return Z3_mk_implies(c, args_neg, Z3_mk_bvslt(c, r, zero));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
// only for signed machine integers
|
||||
Z3_ast Z3_API Z3_mk_bvsub_no_overflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
Z3_sort s = Z3_get_sort(c, t2);
|
||||
Z3_ast minus_t2 = Z3_mk_bvneg(c, t2);
|
||||
Z3_ast min = Z3_mk_bvsmin(c, s);
|
||||
return Z3_mk_ite(c, Z3_mk_eq(c, t2, min),
|
||||
Z3_mk_bvslt(c, t1, Z3_mk_int(c, 0, s)),
|
||||
Z3_mk_bvadd_no_overflow(c, t1, minus_t2, true));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bvsub_no_underflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2, Z3_bool is_signed) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
if (is_signed) {
|
||||
Z3_ast zero = Z3_mk_int(c, 0, Z3_get_sort(c, t1));
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
Z3_ast minus_t2 = Z3_mk_bvneg(c, t2);
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
return Z3_mk_implies(c, Z3_mk_bvslt(c, zero, t2), Z3_mk_bvadd_no_underflow(c, t1, minus_t2));
|
||||
}
|
||||
else {
|
||||
return Z3_mk_bvule(c, t2, t1);
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bvmul_no_overflow(__in Z3_context c, __in Z3_ast n1, __in Z3_ast n2, Z3_bool is_signed) {
|
||||
LOG_Z3_mk_bvmul_no_overflow(c, n1, n2, is_signed);
|
||||
RESET_ERROR_CODE();
|
||||
if (is_signed) {
|
||||
MK_BINARY_BODY(Z3_mk_bvmul_no_overflow, mk_c(c)->get_bv_fid(), OP_BSMUL_NO_OVFL, SKIP);
|
||||
}
|
||||
else {
|
||||
MK_BINARY_BODY(Z3_mk_bvmul_no_overflow, mk_c(c)->get_bv_fid(), OP_BUMUL_NO_OVFL, SKIP);
|
||||
}
|
||||
}
|
||||
|
||||
// only for signed machine integers
|
||||
Z3_ast Z3_API Z3_mk_bvmul_no_underflow(__in Z3_context c, __in Z3_ast n1, __in Z3_ast n2) {
|
||||
LOG_Z3_mk_bvmul_no_underflow(c, n1, n2);
|
||||
MK_BINARY_BODY(Z3_mk_bvmul_no_underflow, mk_c(c)->get_bv_fid(), OP_BSMUL_NO_UDFL, SKIP);
|
||||
}
|
||||
|
||||
// only for signed machine integers
|
||||
Z3_ast Z3_API Z3_mk_bvneg_no_overflow(__in Z3_context c, __in Z3_ast t) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast min = Z3_mk_bvsmin(c, Z3_get_sort(c, t));
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
Z3_ast eq = Z3_mk_eq(c, t, min);
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
return Z3_mk_not(c, eq);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
// only for signed machine integers
|
||||
Z3_ast Z3_API Z3_mk_bvsdiv_no_overflow(__in Z3_context c, __in Z3_ast t1, __in Z3_ast t2) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
Z3_sort s = Z3_get_sort(c, t1);
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
Z3_ast min = Z3_mk_bvmsb(c, s);
|
||||
if (Z3_get_error_code(c) != Z3_OK) return 0;
|
||||
Z3_ast args[2] = { Z3_mk_eq(c, t1, min),
|
||||
Z3_mk_eq(c, t2, Z3_mk_int(c, -1, s)) };
|
||||
return Z3_mk_not(c, Z3_mk_and(c, 2, args));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bvsub(Z3_context c, Z3_ast n1, Z3_ast n2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bvsub(c, n1, n2);
|
||||
RESET_ERROR_CODE();
|
||||
// TODO: Do we really need this pre_simplifier hack?
|
||||
if (mk_c(c)->fparams().m_pre_simplify_expr) {
|
||||
Z3_ast m1 = Z3_mk_int(c, -1, Z3_get_sort(c, n2));
|
||||
Z3_ast r = Z3_mk_bvadd(c, n1, Z3_mk_bvmul(c, m1, n2));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
MK_BINARY_BODY(Z3_mk_bvsub, mk_c(c)->get_bv_fid(), OP_BSUB, SKIP);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bvneg(Z3_context c, Z3_ast n) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bvneg(c, n);
|
||||
RESET_ERROR_CODE();
|
||||
// TODO: Do we really need this pre_simplifier hack?
|
||||
if (mk_c(c)->fparams().m_pre_simplify_expr) {
|
||||
Z3_ast m1 = Z3_mk_int(c, -1, Z3_get_sort(c, n));
|
||||
Z3_ast r = Z3_mk_bvmul(c, m1, n);
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
MK_UNARY_BODY(Z3_mk_bvneg, mk_c(c)->get_bv_fid(), OP_BNEG, SKIP);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_bv_sort_size(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_bv_sort_size(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
if (to_sort(t)->get_family_id() == mk_c(c)->get_bv_fid() && to_sort(t)->get_decl_kind() == BV_SORT) {
|
||||
return to_sort(t)->get_parameter(0).get_int();
|
||||
}
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
};
|
3525
src/api/api_commands.cpp
Normal file
3525
src/api/api_commands.cpp
Normal file
File diff suppressed because it is too large
Load diff
122
src/api/api_config_params.cpp
Normal file
122
src/api/api_config_params.cpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_config_params.cpp
|
||||
|
||||
Abstract:
|
||||
Configuration parameters
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"z3.h"
|
||||
#include"api_context.h"
|
||||
#include"api_config_params.h"
|
||||
#include"pp.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_util.h"
|
||||
#include"symbol.h"
|
||||
|
||||
namespace api {
|
||||
|
||||
config_params::config_params():
|
||||
m_ini(false /* do not abort on errors */) {
|
||||
register_verbosity_level(m_ini);
|
||||
register_warning(m_ini);
|
||||
m_params.register_params(m_ini);
|
||||
register_pp_params(m_ini);
|
||||
}
|
||||
|
||||
config_params::config_params(front_end_params const & p):m_params(p) {
|
||||
register_verbosity_level(m_ini);
|
||||
register_warning(m_ini);
|
||||
register_pp_params(m_ini);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern std::string smt_keyword2opt_name(symbol const & opt);
|
||||
|
||||
extern "C" {
|
||||
Z3_config Z3_API Z3_mk_config() {
|
||||
LOG_Z3_mk_config();
|
||||
memory::initialize(0);
|
||||
Z3_config r = reinterpret_cast<Z3_config>(alloc(api::config_params));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
|
||||
void Z3_API Z3_del_config(Z3_config c) {
|
||||
LOG_Z3_del_config(c);
|
||||
dealloc((reinterpret_cast<api::config_params*>(c)));
|
||||
}
|
||||
|
||||
void Z3_API Z3_set_param_value(Z3_config c, char const * param_id, char const * param_value) {
|
||||
try {
|
||||
LOG_Z3_set_param_value(c, param_id, param_value);
|
||||
api::config_params* p = reinterpret_cast<api::config_params*>(c);
|
||||
if (param_id != 0 && param_id[0] == ':') {
|
||||
// Allow SMT2 style paramater names such as :model, :relevancy, etc
|
||||
std::string new_param_id = smt_keyword2opt_name(symbol(param_id));
|
||||
p->m_ini.set_param_value(new_param_id.c_str(), param_value);
|
||||
}
|
||||
else {
|
||||
p->m_ini.set_param_value(param_id, param_value);
|
||||
}
|
||||
}
|
||||
catch (set_get_param_exception & ex) {
|
||||
// The error handler was not set yet.
|
||||
// Just throw a warning.
|
||||
std::ostringstream buffer;
|
||||
buffer << "Error setting " << param_id << ", " << ex.get_msg();
|
||||
warning_msg(buffer.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
void Z3_API Z3_update_param_value(Z3_context c, Z3_string param_id, Z3_string param_value) {
|
||||
LOG_Z3_update_param_value(c, param_id, param_value);
|
||||
RESET_ERROR_CODE();
|
||||
ini_params ini;
|
||||
mk_c(c)->fparams().register_params(ini);
|
||||
register_pp_params(ini);
|
||||
register_verbosity_level(ini);
|
||||
register_warning(ini);
|
||||
if (mk_c(c)->has_solver()) {
|
||||
ini.freeze();
|
||||
}
|
||||
if (param_id != 0 && param_id[0] == ':') {
|
||||
// Allow SMT2 style paramater names such as :model, :relevancy, etc
|
||||
std::string new_param_id = smt_keyword2opt_name(symbol(param_id));
|
||||
ini.set_param_value(new_param_id.c_str(), param_value);
|
||||
}
|
||||
else {
|
||||
ini.set_param_value(param_id, param_value);
|
||||
}
|
||||
memory::set_high_watermark(static_cast<size_t>(mk_c(c)->fparams().m_memory_high_watermark)*1024*1024);
|
||||
memory::set_max_size(static_cast<size_t>(mk_c(c)->fparams().m_memory_max_size)*1024*1024);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_get_param_value(Z3_context c, Z3_string param_id, Z3_string* param_value) {
|
||||
LOG_Z3_get_param_value(c, param_id, param_value);
|
||||
ini_params ini;
|
||||
mk_c(c)->fparams().register_params(ini);
|
||||
register_verbosity_level(ini);
|
||||
register_pp_params(ini);
|
||||
register_warning(ini);
|
||||
std::string param_value_s;
|
||||
if (!ini.get_param_value(param_id, param_value_s)) {
|
||||
if (param_value) *param_value = 0;
|
||||
return false;
|
||||
}
|
||||
if (param_value) {
|
||||
*param_value = mk_c(c)->mk_external_string(param_value_s);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
};
|
36
src/api/api_config_params.h
Normal file
36
src/api/api_config_params.h
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_config_params.h
|
||||
|
||||
Abstract:
|
||||
Configuration parameters
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_CONFIG_PARAMS_H_
|
||||
#define _API_CONFIG_PARAMS_H_
|
||||
|
||||
#include"ini_file.h"
|
||||
#include"front_end_params.h"
|
||||
|
||||
namespace api {
|
||||
|
||||
class config_params {
|
||||
public:
|
||||
ini_params m_ini;
|
||||
front_end_params m_params;
|
||||
config_params();
|
||||
config_params(front_end_params const & p);
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif
|
572
src/api/api_context.cpp
Normal file
572
src/api/api_context.cpp
Normal file
|
@ -0,0 +1,572 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_context.cpp
|
||||
|
||||
Abstract:
|
||||
Interface of Z3 with "external world".
|
||||
|
||||
It was called _Z3_context
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"api_context.h"
|
||||
#include"api_config_params.h"
|
||||
#include"smtparser.h"
|
||||
#include"version.h"
|
||||
#include"ast_pp.h"
|
||||
#include"ast_ll_pp.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_util.h"
|
||||
#include"install_tactics.h"
|
||||
#include"reg_decl_plugins.h"
|
||||
|
||||
namespace api {
|
||||
|
||||
static void default_error_handler(Z3_context, Z3_error_code c) {
|
||||
printf("Error: %s\n", Z3_get_error_msg(c));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
Z3_search_failure mk_Z3_search_failure(smt::failure f) {
|
||||
switch(f) {
|
||||
case smt::OK: return Z3_NO_FAILURE;
|
||||
case smt::UNKNOWN: return Z3_UNKNOWN;
|
||||
case smt::TIMEOUT: return Z3_TIMEOUT;
|
||||
case smt::MEMOUT: return Z3_MEMOUT_WATERMARK;
|
||||
case smt::CANCELED: return Z3_CANCELED;
|
||||
case smt::NUM_CONFLICTS: return Z3_NUM_CONFLICTS;
|
||||
case smt::THEORY: return Z3_THEORY;
|
||||
case smt::QUANTIFIERS: return Z3_QUANTIFIERS;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
return static_cast<Z3_search_failure>(f);
|
||||
}
|
||||
|
||||
context::param_ini::param_ini(front_end_params & p) : m_params(p) {
|
||||
p.open_trace_file();
|
||||
}
|
||||
|
||||
context::param_ini::~param_ini() {
|
||||
m_params.close_trace_file();
|
||||
}
|
||||
|
||||
context::add_plugins::add_plugins(ast_manager & m) {
|
||||
reg_decl_plugins(m);
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
//
|
||||
// Core
|
||||
//
|
||||
// ------------------------
|
||||
|
||||
context::set_interruptable::set_interruptable(context & ctx, event_handler & i):
|
||||
m_ctx(ctx) {
|
||||
#pragma omp critical (set_interruptable)
|
||||
{
|
||||
SASSERT(m_ctx.m_interruptable == 0);
|
||||
m_ctx.m_interruptable = &i;
|
||||
}
|
||||
}
|
||||
|
||||
context::set_interruptable::~set_interruptable() {
|
||||
#pragma omp critical (set_interruptable)
|
||||
{
|
||||
m_ctx.m_interruptable = 0;
|
||||
}
|
||||
}
|
||||
|
||||
context::context(config_params * p, bool user_ref_count):
|
||||
m_params(p ? p->m_params : front_end_params()),
|
||||
m_param_ini(m_params),
|
||||
m_user_ref_count(user_ref_count),
|
||||
m_manager(m_params.m_proof_mode, m_params.m_trace_stream),
|
||||
m_plugins(m_manager),
|
||||
m_arith_util(m_manager),
|
||||
m_bv_util(m_manager),
|
||||
m_datalog_util(m_manager),
|
||||
m_last_result(m_manager),
|
||||
m_ast_trail(m_manager),
|
||||
m_replay_stack() {
|
||||
|
||||
m_solver = 0;
|
||||
m_error_code = Z3_OK;
|
||||
m_print_mode = Z3_PRINT_SMTLIB_FULL;
|
||||
m_searching = false;
|
||||
|
||||
m_interruptable = 0;
|
||||
|
||||
m_smtlib_parser = 0;
|
||||
m_smtlib_parser_has_decls = false;
|
||||
|
||||
z3_bound_num_procs();
|
||||
//
|
||||
// Configuration parameter settings.
|
||||
//
|
||||
memory::set_high_watermark(static_cast<size_t>(m_params.m_memory_high_watermark)*1024*1024);
|
||||
memory::set_max_size(static_cast<size_t>(m_params.m_memory_max_size)*1024*1024);
|
||||
if (m_params.m_debug_ref_count) {
|
||||
m_manager.debug_ref_count();
|
||||
}
|
||||
|
||||
m_error_handler = &default_error_handler;
|
||||
|
||||
m_basic_fid = m_manager.get_basic_family_id();
|
||||
m_arith_fid = m_manager.get_family_id("arith");
|
||||
m_bv_fid = m_manager.get_family_id("bv");
|
||||
m_array_fid = m_manager.get_family_id("array");
|
||||
m_dt_fid = m_manager.get_family_id("datatype");
|
||||
m_datalog_fid = m_manager.get_family_id("datalog_relation");
|
||||
m_dt_plugin = static_cast<datatype_decl_plugin*>(m_manager.get_plugin(m_dt_fid));
|
||||
|
||||
if (!m_user_ref_count) {
|
||||
m_replay_stack.push_back(0);
|
||||
}
|
||||
|
||||
install_tactics(*this);
|
||||
}
|
||||
|
||||
|
||||
context::~context() {
|
||||
m_last_obj = 0;
|
||||
if (!m_user_ref_count) {
|
||||
for (unsigned i = 0; i < m_replay_stack.size(); ++i) {
|
||||
dealloc(m_replay_stack[i]);
|
||||
}
|
||||
}
|
||||
reset_parser();
|
||||
dealloc(m_solver);
|
||||
}
|
||||
|
||||
void context::interrupt() {
|
||||
#pragma omp critical (set_interruptable)
|
||||
{
|
||||
if (m_interruptable)
|
||||
(*m_interruptable)();
|
||||
}
|
||||
}
|
||||
|
||||
void context::set_error_code(Z3_error_code err) {
|
||||
m_error_code = err;
|
||||
if (err != Z3_OK)
|
||||
invoke_error_handler(err);
|
||||
}
|
||||
|
||||
void context::check_searching() {
|
||||
if (m_searching) {
|
||||
set_error_code(Z3_INVALID_USAGE); // TBD: error code could be fixed.
|
||||
}
|
||||
}
|
||||
|
||||
char * context::mk_external_string(char const * str) {
|
||||
m_string_buffer = str;
|
||||
return const_cast<char *>(m_string_buffer.c_str());
|
||||
}
|
||||
|
||||
char * context::mk_external_string(std::string const & str) {
|
||||
m_string_buffer = str;
|
||||
return const_cast<char *>(m_string_buffer.c_str());
|
||||
}
|
||||
|
||||
expr * context::mk_numeral_core(rational const & n, sort * s) {
|
||||
expr* e = 0;
|
||||
family_id fid = s->get_family_id();
|
||||
if (fid == m_arith_fid) {
|
||||
e = m_arith_util.mk_numeral(n, s);
|
||||
}
|
||||
else if (fid == m_bv_fid) {
|
||||
e = m_bv_util.mk_numeral(n, s);
|
||||
}
|
||||
else if (fid == get_datalog_fid() && n.is_uint64()) {
|
||||
uint64 sz;
|
||||
if (m_datalog_util.try_get_size(s, sz) &&
|
||||
sz <= n.get_uint64()) {
|
||||
invoke_error_handler(Z3_INVALID_ARG);
|
||||
}
|
||||
e = m_datalog_util.mk_numeral(n.get_uint64(), s);
|
||||
}
|
||||
else {
|
||||
invoke_error_handler(Z3_INVALID_ARG);
|
||||
}
|
||||
save_ast_trail(e);
|
||||
return e;
|
||||
}
|
||||
|
||||
expr * context::mk_and(unsigned num_exprs, expr * const * exprs) {
|
||||
switch(num_exprs) {
|
||||
case 0:
|
||||
return m_manager.mk_true();
|
||||
case 1:
|
||||
save_ast_trail(exprs[0]);
|
||||
return exprs[0];
|
||||
default: {
|
||||
expr * a = m_manager.mk_and(num_exprs, exprs);
|
||||
save_ast_trail(a);
|
||||
return a;
|
||||
} }
|
||||
}
|
||||
|
||||
void context::persist_ast(ast * n, unsigned num_scopes) {
|
||||
// persist_ast is irrelevant when m_user_ref_count == true
|
||||
if (m_user_ref_count)
|
||||
return;
|
||||
if (num_scopes > m_ast_lim.size()) {
|
||||
num_scopes = m_ast_lim.size();
|
||||
}
|
||||
SASSERT(m_replay_stack.size() > num_scopes);
|
||||
unsigned j = m_replay_stack.size() - num_scopes - 1;
|
||||
if (!m_replay_stack[j]) {
|
||||
m_replay_stack[j] = alloc(ast_ref_vector, m_manager);
|
||||
}
|
||||
m_replay_stack[j]->push_back(n);
|
||||
}
|
||||
|
||||
void context::save_ast_trail(ast * n) {
|
||||
SASSERT(m().contains(n));
|
||||
if (m_user_ref_count) {
|
||||
// Corner case bug: n may be in m_last_result, and this is the only reference to n.
|
||||
// When, we execute reset() it is deleted
|
||||
// To avoid this bug, I bump the reference counter before reseting m_last_result
|
||||
m().inc_ref(n);
|
||||
m_last_result.reset();
|
||||
m_last_result.push_back(n);
|
||||
m().dec_ref(n);
|
||||
}
|
||||
else {
|
||||
m_ast_trail.push_back(n);
|
||||
}
|
||||
}
|
||||
|
||||
void context::save_multiple_ast_trail(ast * n) {
|
||||
if (m_user_ref_count)
|
||||
m_last_result.push_back(n);
|
||||
else
|
||||
m_ast_trail.push_back(n);
|
||||
}
|
||||
|
||||
void context::reset_last_result() {
|
||||
if (m_user_ref_count)
|
||||
m_last_result.reset();
|
||||
m_last_obj = 0;
|
||||
}
|
||||
|
||||
void context::save_object(object * r) {
|
||||
m_last_obj = r;
|
||||
}
|
||||
|
||||
void context::handle_exception(z3_exception & ex) {
|
||||
if (ex.has_error_code()) {
|
||||
switch(ex.error_code()) {
|
||||
case ERR_MEMOUT:
|
||||
set_error_code(Z3_MEMOUT_FAIL);
|
||||
break;
|
||||
case ERR_PARSER:
|
||||
set_error_code(Z3_PARSER_ERROR);
|
||||
break;
|
||||
case ERR_INI_FILE:
|
||||
set_error_code(Z3_INVALID_ARG);
|
||||
break;
|
||||
case ERR_OPEN_FILE:
|
||||
set_error_code(Z3_FILE_ACCESS_ERROR);
|
||||
break;
|
||||
default:
|
||||
set_error_code(Z3_INTERNAL_FATAL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_exception_msg = ex.msg();
|
||||
set_error_code(Z3_EXCEPTION);
|
||||
}
|
||||
}
|
||||
|
||||
void context::invoke_error_handler(Z3_error_code c) {
|
||||
if (m_error_handler) {
|
||||
if (g_z3_log) {
|
||||
// error handler can do crazy stuff such as longjmp
|
||||
g_z3_log_enabled = true;
|
||||
}
|
||||
m_error_handler(reinterpret_cast<Z3_context>(this), c);
|
||||
}
|
||||
}
|
||||
|
||||
void context::check_sorts(ast * n) {
|
||||
if (!m().check_sorts(n)) {
|
||||
switch(n->get_kind()) {
|
||||
case AST_APP: {
|
||||
std::ostringstream buffer;
|
||||
app * a = to_app(n);
|
||||
buffer << mk_pp(a->get_decl(), m()) << " applied to: ";
|
||||
if (a->get_num_args() > 1) buffer << "\n";
|
||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
||||
buffer << mk_bounded_pp(a->get_arg(i), m(), 3) << " of sort ";
|
||||
buffer << mk_pp(m().get_sort(a->get_arg(i)), m()) << "\n";
|
||||
}
|
||||
warning_msg("%s",buffer.str().c_str());
|
||||
break;
|
||||
}
|
||||
case AST_VAR:
|
||||
case AST_QUANTIFIER:
|
||||
case AST_SORT:
|
||||
case AST_FUNC_DECL:
|
||||
break;
|
||||
}
|
||||
set_error_code(Z3_SORT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
//
|
||||
// Solver interface for backward compatibility
|
||||
//
|
||||
// ------------------------
|
||||
|
||||
smt::solver & context::get_solver() {
|
||||
if (!m_solver) {
|
||||
m_solver = alloc(smt::solver, m_manager, m_params);
|
||||
}
|
||||
return *m_solver;
|
||||
}
|
||||
|
||||
void context::assert_cnstr(expr * a) {
|
||||
get_solver().assert_expr(a);
|
||||
}
|
||||
|
||||
lbool context::check(model_ref & m) {
|
||||
flet<bool> searching(m_searching, true);
|
||||
lbool r;
|
||||
r = get_solver().check();
|
||||
if (r != l_false)
|
||||
get_solver().get_model(m);
|
||||
return r;
|
||||
}
|
||||
|
||||
void context::push() {
|
||||
get_solver().push();
|
||||
if (!m_user_ref_count) {
|
||||
m_ast_lim.push_back(m_ast_trail.size());
|
||||
m_replay_stack.push_back(0);
|
||||
}
|
||||
}
|
||||
|
||||
void context::pop(unsigned num_scopes) {
|
||||
for (unsigned i = 0; i < num_scopes; ++i) {
|
||||
if (!m_user_ref_count) {
|
||||
unsigned sz = m_ast_lim.back();
|
||||
m_ast_lim.pop_back();
|
||||
dealloc(m_replay_stack.back());
|
||||
m_replay_stack.pop_back();
|
||||
while (m_ast_trail.size() > sz) {
|
||||
m_ast_trail.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
get_solver().pop(num_scopes);
|
||||
}
|
||||
|
||||
// ------------------------
|
||||
//
|
||||
// Parser interface for backward compatibility
|
||||
//
|
||||
// ------------------------
|
||||
|
||||
void context::reset_parser() {
|
||||
if (m_smtlib_parser) {
|
||||
dealloc(m_smtlib_parser);
|
||||
m_smtlib_parser = 0;
|
||||
m_smtlib_parser_has_decls = false;
|
||||
m_smtlib_parser_decls.reset();
|
||||
m_smtlib_parser_sorts.reset();
|
||||
}
|
||||
SASSERT(!m_smtlib_parser_has_decls);
|
||||
}
|
||||
|
||||
void context::extract_smtlib_parser_decls() {
|
||||
if (m_smtlib_parser) {
|
||||
if (!m_smtlib_parser_has_decls) {
|
||||
smtlib::symtable * table = m_smtlib_parser->get_benchmark()->get_symtable();
|
||||
table->get_func_decls(m_smtlib_parser_decls);
|
||||
table->get_sorts(m_smtlib_parser_sorts);
|
||||
m_smtlib_parser_has_decls = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_smtlib_parser_decls.reset();
|
||||
m_smtlib_parser_sorts.reset();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// ------------------------
|
||||
//
|
||||
// Context creation API
|
||||
//
|
||||
// ------------------------
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_context Z3_API Z3_mk_context(Z3_config c) {
|
||||
LOG_Z3_mk_context(c);
|
||||
memory::initialize(0);
|
||||
Z3_context r = reinterpret_cast<Z3_context>(alloc(api::context, reinterpret_cast<api::config_params*>(c), false));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
|
||||
Z3_context Z3_API Z3_mk_context_rc(Z3_config c) {
|
||||
LOG_Z3_mk_context_rc(c);
|
||||
memory::initialize(0);
|
||||
Z3_context r = reinterpret_cast<Z3_context>(alloc(api::context, reinterpret_cast<api::config_params*>(c), true));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
|
||||
void Z3_API Z3_del_context(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_del_context(c);
|
||||
RESET_ERROR_CODE();
|
||||
dealloc(mk_c(c));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_interrupt(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_interrupt(c);
|
||||
mk_c(c)->interrupt();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_toggle_warning_messages(Z3_bool enabled) {
|
||||
LOG_Z3_toggle_warning_messages(enabled);
|
||||
enable_warning_messages(enabled != 0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_inc_ref(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_inc_ref(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->m().inc_ref(to_ast(a));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_dec_ref(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_dec_ref(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
if (to_ast(a)->get_ref_count() == 0) {
|
||||
SET_ERROR_CODE(Z3_DEC_REF_ERROR);
|
||||
return;
|
||||
}
|
||||
mk_c(c)->m().dec_ref(to_ast(a));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_set_logic(Z3_context c, Z3_string logic) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_set_logic(c, logic);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->get_solver().set_logic(symbol(logic));
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
void Z3_API Z3_get_version(unsigned * major,
|
||||
unsigned * minor,
|
||||
unsigned * build_number,
|
||||
unsigned * revision_number) {
|
||||
LOG_Z3_get_version(major, minor, build_number, revision_number);
|
||||
*major = Z3_MAJOR_VERSION;
|
||||
*minor = Z3_MINOR_VERSION;
|
||||
*build_number = Z3_BUILD_NUMBER;
|
||||
*revision_number = Z3_REVISION_NUMBER;
|
||||
}
|
||||
|
||||
void Z3_API Z3_reset_memory(void) {
|
||||
LOG_Z3_reset_memory();
|
||||
memory::finalize();
|
||||
memory::initialize(0);
|
||||
}
|
||||
|
||||
Z3_error_code Z3_API Z3_get_error_code(Z3_context c) {
|
||||
LOG_Z3_get_error_code(c);
|
||||
return mk_c(c)->get_error_code();
|
||||
}
|
||||
|
||||
void Z3_API Z3_set_error_handler(Z3_context c, Z3_error_handler h) {
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->set_error_handler(h);
|
||||
// [Leo]: using exception handling, we don't need global error handlers anymore
|
||||
}
|
||||
|
||||
void Z3_API Z3_set_error(__in Z3_context c, __in Z3_error_code e) {
|
||||
SET_ERROR_CODE(e);
|
||||
}
|
||||
|
||||
static char const * _get_error_msg_ex(Z3_context c, Z3_error_code err) {
|
||||
switch(err) {
|
||||
case Z3_OK: return "ok";
|
||||
case Z3_SORT_ERROR: return "type error";
|
||||
case Z3_IOB: return "index out of bounds";
|
||||
case Z3_INVALID_ARG: return "invalid argument";
|
||||
case Z3_PARSER_ERROR: return "parser error";
|
||||
case Z3_NO_PARSER: return "parser (data) is not available";
|
||||
case Z3_INVALID_PATTERN: return "invalid pattern";
|
||||
case Z3_MEMOUT_FAIL: return "out of memory";
|
||||
case Z3_FILE_ACCESS_ERROR: return "file access error";
|
||||
case Z3_INTERNAL_FATAL: return "internal error";
|
||||
case Z3_INVALID_USAGE: return "invalid usage";
|
||||
case Z3_DEC_REF_ERROR: return "invalid dec_ref command";
|
||||
case Z3_EXCEPTION: return c == 0 ? "Z3 exception" : mk_c(c)->get_exception_msg();
|
||||
default: return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
char const * Z3_API Z3_get_error_msg(Z3_error_code err) {
|
||||
LOG_Z3_get_error_msg(err);
|
||||
return _get_error_msg_ex(0, err);
|
||||
}
|
||||
|
||||
char const * Z3_API Z3_get_error_msg_ex(Z3_context c, Z3_error_code err) {
|
||||
LOG_Z3_get_error_msg_ex(c, err);
|
||||
return _get_error_msg_ex(c, err);
|
||||
}
|
||||
|
||||
void Z3_API Z3_persist_ast(Z3_context c, Z3_ast n, unsigned num_scopes) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_persist_ast(c, n, num_scopes);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(to_ast(n), );
|
||||
mk_c(c)->persist_ast(to_ast(n), num_scopes);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_set_ast_print_mode(Z3_context c, Z3_ast_print_mode mode) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_set_ast_print_mode(c, mode);
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->set_print_mode(mode);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
ast_manager & Z3_API Z3_get_manager(__in Z3_context c) {
|
||||
return mk_c(c)->m();
|
||||
}
|
||||
|
||||
front_end_params& Z3_API Z3_get_parameters(__in Z3_context c) {
|
||||
return mk_c(c)->fparams();
|
||||
}
|
||||
|
||||
Z3_context Z3_mk_context_from_params(front_end_params const& p) {
|
||||
api::config_params cp(p);
|
||||
return reinterpret_cast<Z3_context>(alloc(api::context, &cp));
|
||||
}
|
216
src/api/api_context.h
Normal file
216
src/api/api_context.h
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_context.h
|
||||
|
||||
Abstract:
|
||||
Interface of Z3 with "external world".
|
||||
|
||||
It was called _Z3_context
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_CONTEXT_H_
|
||||
#define _API_CONTEXT_H_
|
||||
|
||||
#include"z3.h"
|
||||
#include"ast.h"
|
||||
#include"api_util.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"bv_decl_plugin.h"
|
||||
#include"datatype_decl_plugin.h"
|
||||
#include"dl_decl_plugin.h"
|
||||
#include"smt_solver.h"
|
||||
#include"front_end_params.h"
|
||||
#include"event_handler.h"
|
||||
#include"tactic_manager.h"
|
||||
|
||||
namespace smtlib {
|
||||
class parser;
|
||||
};
|
||||
|
||||
namespace api {
|
||||
class config_params;
|
||||
|
||||
Z3_search_failure mk_Z3_search_failure(smt::failure f);
|
||||
|
||||
|
||||
class context : public tactic_manager {
|
||||
class param_ini {
|
||||
front_end_params & m_params;
|
||||
public:
|
||||
param_ini(front_end_params & p);
|
||||
~param_ini();
|
||||
};
|
||||
|
||||
struct add_plugins { add_plugins(ast_manager & m); };
|
||||
|
||||
front_end_params m_params;
|
||||
param_ini m_param_ini;
|
||||
bool m_user_ref_count; //!< if true, the user is responsible for managing referenc counters.
|
||||
ast_manager m_manager;
|
||||
add_plugins m_plugins;
|
||||
|
||||
arith_util m_arith_util;
|
||||
bv_util m_bv_util;
|
||||
datalog::dl_decl_util m_datalog_util;
|
||||
|
||||
smt::solver * m_solver; // General purpose solver for backward compatibility
|
||||
|
||||
ast_ref_vector m_last_result; //!< used when m_user_ref_count == true
|
||||
ast_ref_vector m_ast_trail; //!< used when m_user_ref_count == false
|
||||
unsigned_vector m_ast_lim;
|
||||
ptr_vector<ast_ref_vector> m_replay_stack;
|
||||
|
||||
ref<api::object> m_last_obj; //!< reference to the last API object returned by the APIs
|
||||
|
||||
family_id m_basic_fid;
|
||||
family_id m_array_fid;
|
||||
family_id m_arith_fid;
|
||||
family_id m_bv_fid;
|
||||
family_id m_dt_fid;
|
||||
family_id m_datalog_fid;
|
||||
datatype_decl_plugin * m_dt_plugin;
|
||||
|
||||
std::string m_string_buffer; // temporary buffer used to cache strings sent to the "external" world.
|
||||
|
||||
Z3_error_code m_error_code;
|
||||
Z3_error_handler * m_error_handler;
|
||||
std::string m_exception_msg; // catch the message associated with a Z3 exception
|
||||
bool m_searching;
|
||||
Z3_ast_print_mode m_print_mode;
|
||||
|
||||
event_handler * m_interruptable; // Reference to an object that can be interrupted by Z3_interrupt
|
||||
public:
|
||||
// Scoped obj for setting m_interruptable
|
||||
class set_interruptable {
|
||||
context & m_ctx;
|
||||
public:
|
||||
set_interruptable(context & ctx, event_handler & i);
|
||||
~set_interruptable();
|
||||
};
|
||||
|
||||
// ------------------------
|
||||
//
|
||||
// Core
|
||||
//
|
||||
// ------------------------
|
||||
|
||||
context(config_params * p, bool user_ref_count = false);
|
||||
~context();
|
||||
|
||||
front_end_params & fparams() { return m_params; }
|
||||
ast_manager & m() { return m_manager; }
|
||||
arith_util & autil() { return m_arith_util; }
|
||||
bv_util & bvutil() { return m_bv_util; }
|
||||
datalog::dl_decl_util & datalog_util() { return m_datalog_util; }
|
||||
family_id get_basic_fid() const { return m_basic_fid; }
|
||||
family_id get_array_fid() const { return m_array_fid; }
|
||||
family_id get_arith_fid() const { return m_arith_fid; }
|
||||
family_id get_bv_fid() const { return m_bv_fid; }
|
||||
family_id get_dt_fid() const { return m_dt_fid; }
|
||||
family_id get_datalog_fid() const { return m_datalog_fid; }
|
||||
datatype_decl_plugin * get_dt_plugin() const { return m_dt_plugin; }
|
||||
|
||||
Z3_error_code get_error_code() const { return m_error_code; }
|
||||
void reset_error_code() { m_error_code = Z3_OK; }
|
||||
void set_error_code(Z3_error_code err);
|
||||
void set_error_handler(Z3_error_handler h) { m_error_handler = h; }
|
||||
// Sign an error if solver is searching
|
||||
void check_searching();
|
||||
|
||||
Z3_ast_print_mode get_print_mode() const { return m_print_mode; }
|
||||
void set_print_mode(Z3_ast_print_mode m) { m_print_mode = m; }
|
||||
|
||||
// Store a copy of str in m_string_buffer, and return a reference to it.
|
||||
// This method is used to communicate local/internal strings with the "external world"
|
||||
char * mk_external_string(char const * str);
|
||||
char * mk_external_string(std::string const & str);
|
||||
|
||||
// Create a numeral of the given sort
|
||||
expr * mk_numeral_core(rational const & n, sort * s);
|
||||
|
||||
// Return a conjuction that will be exposed to the "external" world.
|
||||
expr * mk_and(unsigned num_exprs, expr * const * exprs);
|
||||
|
||||
// Hack for preventing an AST for being GC when ref-count is not used
|
||||
void persist_ast(ast * n, unsigned num_scopes);
|
||||
|
||||
// "Save" an AST that will exposed to the "external" world.
|
||||
void save_ast_trail(ast * n);
|
||||
|
||||
// Similar to previous method, but it "adds" n to the result.
|
||||
void save_multiple_ast_trail(ast * n);
|
||||
|
||||
// Reset the cache that stores the ASTs exposed in the previous call.
|
||||
// This is a NOOP if ref-count is disabled.
|
||||
void reset_last_result();
|
||||
|
||||
// "Save" a reference to an object that is exposed by the API
|
||||
void save_object(object * r);
|
||||
|
||||
// Process exception: save message and set error code.
|
||||
void handle_exception(z3_exception & ex);
|
||||
char const * get_exception_msg() const { return m_exception_msg.c_str(); }
|
||||
|
||||
// Interrupt the current interruptable object
|
||||
void interrupt();
|
||||
|
||||
void invoke_error_handler(Z3_error_code c);
|
||||
|
||||
static void out_of_memory_handler(void * _ctx);
|
||||
|
||||
void check_sorts(ast * n);
|
||||
// ------------------------
|
||||
//
|
||||
// Solver interface for backward compatibility
|
||||
//
|
||||
// ------------------------
|
||||
|
||||
bool has_solver() const { return m_solver != 0; }
|
||||
smt::solver & get_solver();
|
||||
void assert_cnstr(expr * a);
|
||||
lbool check(model_ref & m);
|
||||
void push();
|
||||
void pop(unsigned num_scopes);
|
||||
unsigned get_num_scopes() const { return m_ast_lim.size(); }
|
||||
|
||||
// ------------------------
|
||||
//
|
||||
// Parser interface for backward compatibility
|
||||
//
|
||||
// ------------------------
|
||||
|
||||
// TODO: move to a "parser" object visible to the external world.
|
||||
std::string m_smtlib_error_buffer;
|
||||
smtlib::parser * m_smtlib_parser;
|
||||
bool m_smtlib_parser_has_decls;
|
||||
ptr_vector<func_decl> m_smtlib_parser_decls;
|
||||
ptr_vector<sort> m_smtlib_parser_sorts;
|
||||
|
||||
void reset_parser();
|
||||
void extract_smtlib_parser_decls();
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
inline api::context * mk_c(Z3_context c) { return reinterpret_cast<api::context*>(c); }
|
||||
#define RESET_ERROR_CODE() { mk_c(c)->reset_error_code(); }
|
||||
#define SET_ERROR_CODE(ERR) { mk_c(c)->set_error_code(ERR); }
|
||||
#define CHECK_NON_NULL(_p_,_ret_) { if (_p_ == 0) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
|
||||
#define CHECK_VALID_AST(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
|
||||
#define CHECK_SEARCHING(c) mk_c(c)->check_searching();
|
||||
inline bool is_expr(Z3_ast a) { return is_expr(to_ast(a)); }
|
||||
inline bool is_bool_expr(Z3_context c, Z3_ast a) { return is_expr(a) && mk_c(c)->m().is_bool(to_expr(a)); }
|
||||
#define CHECK_FORMULA(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_) || !is_bool_expr(c, _a_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
|
||||
inline void check_sorts(Z3_context c, ast * n) { mk_c(c)->check_sorts(n); }
|
||||
|
||||
#endif
|
561
src/api/api_datalog.cpp
Normal file
561
src/api/api_datalog.cpp
Normal file
|
@ -0,0 +1,561 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_datalog.cpp
|
||||
|
||||
Abstract:
|
||||
Datalog API
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"api_datalog.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"dl_context.h"
|
||||
#include"ast_pp.h"
|
||||
#include"api_ast_vector.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_stats.h"
|
||||
#include"datalog_parser.h"
|
||||
#include"cancel_eh.h"
|
||||
#include"scoped_timer.h"
|
||||
|
||||
namespace api {
|
||||
|
||||
fixedpoint_context::fixedpoint_context(ast_manager& m, front_end_params& p) :
|
||||
m_state(0),
|
||||
m_reduce_app(0),
|
||||
m_reduce_assign(0),
|
||||
m_context(m, p),
|
||||
m_trail(m) {}
|
||||
|
||||
|
||||
void fixedpoint_context::set_state(void* state) {
|
||||
SASSERT(!m_state);
|
||||
m_state = state;
|
||||
symbol name("datalog_relation");
|
||||
ast_manager& m = m_context.get_manager();
|
||||
if (!m.has_plugin(name)) {
|
||||
m.register_plugin(name, alloc(datalog::dl_decl_plugin));
|
||||
}
|
||||
datalog::relation_manager& r = m_context.get_rmanager();
|
||||
r.register_plugin(alloc(datalog::external_relation_plugin, *this, r));
|
||||
}
|
||||
|
||||
void fixedpoint_context::reduce(func_decl* f, unsigned num_args, expr * const* args, expr_ref& result) {
|
||||
expr* r = 0;
|
||||
if (m_reduce_app) {
|
||||
m_reduce_app(m_state, f, num_args, args, &r);
|
||||
result = r;
|
||||
m_trail.push_back(f);
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
m_trail.push_back(args[i]);
|
||||
}
|
||||
m_trail.push_back(r);
|
||||
}
|
||||
// allow fallthrough.
|
||||
if (r == 0) {
|
||||
ast_manager& m = m_context.get_manager();
|
||||
result = m.mk_app(f, num_args, args);
|
||||
}
|
||||
}
|
||||
|
||||
// overwrite terms passed in outs vector with values computed by function.
|
||||
void fixedpoint_context::reduce_assign(func_decl* f, unsigned num_args, expr * const* args, unsigned num_out, expr* const* outs) {
|
||||
if (m_reduce_assign) {
|
||||
m_trail.push_back(f);
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
m_trail.push_back(args[i]);
|
||||
}
|
||||
m_reduce_assign(m_state, f, num_args, args, num_out, outs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fixedpoint_context::add_rule(expr* rule, symbol const& name) {
|
||||
m_context.add_rule(rule, name);
|
||||
}
|
||||
|
||||
void fixedpoint_context::update_rule(expr* rule, symbol const& name) {
|
||||
m_context.update_rule(rule, name);
|
||||
}
|
||||
|
||||
void fixedpoint_context::add_table_fact(func_decl* r, unsigned num_args, unsigned args[]) {
|
||||
m_context.add_table_fact(r, num_args, args);
|
||||
}
|
||||
|
||||
unsigned fixedpoint_context::get_num_levels(func_decl* pred) {
|
||||
return m_context.get_num_levels(pred);
|
||||
}
|
||||
|
||||
expr_ref fixedpoint_context::get_cover_delta(int level, func_decl* pred) {
|
||||
return m_context.get_cover_delta(level, pred);
|
||||
}
|
||||
|
||||
void fixedpoint_context::add_cover(int level, func_decl* pred, expr* predicate) {
|
||||
m_context.add_cover(level, pred, predicate);
|
||||
}
|
||||
|
||||
std::string fixedpoint_context::get_last_status() {
|
||||
datalog::execution_result status = m_context.get_status();
|
||||
switch(status) {
|
||||
case datalog::INPUT_ERROR:
|
||||
return "input error";
|
||||
case datalog::OK:
|
||||
return "ok";
|
||||
case datalog::TIMEOUT:
|
||||
return "timeout";
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
std::string fixedpoint_context::to_string(unsigned num_queries, expr*const* queries) {
|
||||
std::stringstream str;
|
||||
m_context.display_smt2(num_queries, queries, str);
|
||||
return str.str();
|
||||
}
|
||||
|
||||
void fixedpoint_context::simplify_rules(
|
||||
unsigned num_rules, expr* const* rules,
|
||||
unsigned num_outputs, func_decl* const* outputs, expr_ref_vector& result) {
|
||||
ast_manager& m = m_context.get_manager();
|
||||
|
||||
datalog::context ctx(m, m_context.get_fparams());
|
||||
datalog::rule_manager& rm = ctx.get_rule_manager();
|
||||
for (unsigned i = 0; i < num_rules; ++i) {
|
||||
expr* rule = rules[i], *body, *head;
|
||||
while (true) {
|
||||
if (is_quantifier(rule)) {
|
||||
rule = to_quantifier(rule)->get_expr();
|
||||
}
|
||||
else if (m.is_implies(rule, body, head)) {
|
||||
rule = head;
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (is_app(rule)) {
|
||||
func_decl* r = to_app(rule)->get_decl();
|
||||
if (!ctx.is_predicate(r)) {
|
||||
ctx.register_predicate(r);
|
||||
if (num_outputs == 0) {
|
||||
ctx.set_output_predicate(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (unsigned i = 0; i < num_outputs; ++i) {
|
||||
ctx.set_output_predicate(outputs[i]);
|
||||
}
|
||||
for (unsigned i = 0; i < num_rules; ++i) {
|
||||
expr* rule = rules[i];
|
||||
ctx.add_rule(rule, symbol::null);
|
||||
}
|
||||
model_converter_ref mc; // not exposed.
|
||||
proof_converter_ref pc; // not exposed.
|
||||
ctx.apply_default_transformation(mc, pc);
|
||||
datalog::rule_set const& new_rules = ctx.get_rules();
|
||||
datalog::rule_set::iterator it = new_rules.begin(), end = new_rules.end();
|
||||
for (; it != end; ++it) {
|
||||
datalog::rule* r = *it;
|
||||
expr_ref fml(m);
|
||||
r->to_formula(fml);
|
||||
result.push_back(fml);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
extern "C" {
|
||||
|
||||
////////////////////////////////////
|
||||
// Datalog utilities
|
||||
//
|
||||
|
||||
|
||||
unsigned Z3_API Z3_get_relation_arity(Z3_context c, Z3_sort s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_relation_arity(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
sort * r = to_sort(s);
|
||||
if (Z3_get_sort_kind(c, s) != Z3_RELATION_SORT) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return r->get_num_parameters();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_get_relation_column(Z3_context c, Z3_sort s, unsigned col) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_relation_column(c, s, col);
|
||||
RESET_ERROR_CODE();
|
||||
sort * r = to_sort(s);
|
||||
if (Z3_get_sort_kind(c, s) != Z3_RELATION_SORT) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
if (col >= r->get_num_parameters()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
parameter const& p = r->get_parameter(col);
|
||||
if (!p.is_ast() || !is_sort(p.get_ast())) {
|
||||
UNREACHABLE();
|
||||
warning_msg("Sort parameter expected at %d", col);
|
||||
SET_ERROR_CODE(Z3_INTERNAL_FATAL);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_sort res = of_sort(to_sort(p.get_ast()));
|
||||
RETURN_Z3(res);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_finite_domain_sort(Z3_context c, Z3_symbol name, unsigned __int64 size) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_finite_domain_sort(c, name, size);
|
||||
RESET_ERROR_CODE();
|
||||
sort* s = mk_c(c)->datalog_util().mk_sort(to_symbol(name), size);
|
||||
mk_c(c)->save_ast_trail(s);
|
||||
RETURN_Z3(of_sort(s));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_get_finite_domain_sort_size(Z3_context c, Z3_sort s, unsigned __int64 * out) {
|
||||
Z3_TRY;
|
||||
if (out) {
|
||||
*out = 0;
|
||||
}
|
||||
if (Z3_get_sort_kind(c, s) != Z3_FINITE_DOMAIN_SORT) {
|
||||
return Z3_FALSE;
|
||||
}
|
||||
if (!out) {
|
||||
return Z3_FALSE;
|
||||
}
|
||||
// must start loggging here, since function uses Z3_get_sort_kind above
|
||||
LOG_Z3_get_finite_domain_sort_size(c, s, out);
|
||||
RESET_ERROR_CODE();
|
||||
VERIFY(mk_c(c)->datalog_util().try_get_size(to_sort(s), *out));
|
||||
return Z3_TRUE;
|
||||
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_fixedpoint Z3_API Z3_mk_fixedpoint(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_fixedpoint(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_fixedpoint_ref * d = alloc(Z3_fixedpoint_ref);
|
||||
d->m_datalog = alloc(api::fixedpoint_context, mk_c(c)->m(), mk_c(c)->fparams());
|
||||
mk_c(c)->save_object(d);
|
||||
Z3_fixedpoint r = of_datalog(d);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_inc_ref(Z3_context c, Z3_fixedpoint s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_inc_ref(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
to_fixedpoint(s)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_dec_ref(Z3_context c, Z3_fixedpoint s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_dec_ref(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
to_fixedpoint(s)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_assert(Z3_context c, Z3_fixedpoint d, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_assert(c, d, a);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_FORMULA(a,);
|
||||
to_fixedpoint_ref(d)->ctx().assert_expr(to_expr(a));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_add_rule(Z3_context c, Z3_fixedpoint d, Z3_ast a, Z3_symbol name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_add_rule(c, d, a, name);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_FORMULA(a,);
|
||||
to_fixedpoint_ref(d)->add_rule(to_expr(a), to_symbol(name));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_add_fact(Z3_context c, Z3_fixedpoint d,
|
||||
Z3_func_decl r, unsigned num_args, unsigned args[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_add_fact(c, d, r, num_args, args);
|
||||
RESET_ERROR_CODE();
|
||||
to_fixedpoint_ref(d)->add_table_fact(to_func_decl(r), num_args, args);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_lbool Z3_API Z3_fixedpoint_query(Z3_context c,Z3_fixedpoint d, Z3_ast q) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_query(c, d, q);
|
||||
RESET_ERROR_CODE();
|
||||
lbool r = l_undef;
|
||||
cancel_eh<api::fixedpoint_context> eh(*to_fixedpoint_ref(d));
|
||||
unsigned timeout = to_fixedpoint(d)->m_params.get_uint(":timeout", UINT_MAX);
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_timer timer(timeout, &eh);
|
||||
try {
|
||||
r = to_fixedpoint_ref(d)->ctx().query(to_expr(q));
|
||||
}
|
||||
catch (z3_exception& ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
r = l_undef;
|
||||
}
|
||||
to_fixedpoint_ref(d)->ctx().cleanup();
|
||||
}
|
||||
return of_lbool(r);
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_lbool Z3_API Z3_fixedpoint_query_relations(
|
||||
__in Z3_context c,__in Z3_fixedpoint d,
|
||||
__in unsigned num_relations, Z3_func_decl const relations[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_query_relations(c, d, num_relations, relations);
|
||||
RESET_ERROR_CODE();
|
||||
lbool r = l_undef;
|
||||
unsigned timeout = to_fixedpoint(d)->m_params.get_uint(":timeout", UINT_MAX);
|
||||
cancel_eh<api::fixedpoint_context> eh(*to_fixedpoint_ref(d));
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_timer timer(timeout, &eh);
|
||||
try {
|
||||
r = to_fixedpoint_ref(d)->ctx().dl_query(num_relations, to_func_decls(relations));
|
||||
}
|
||||
catch (z3_exception& ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
r = l_undef;
|
||||
}
|
||||
to_fixedpoint_ref(d)->ctx().cleanup();
|
||||
}
|
||||
return of_lbool(r);
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_fixedpoint_get_answer(Z3_context c, Z3_fixedpoint d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_answer(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
expr* e = to_fixedpoint_ref(d)->ctx().get_answer_as_formula();
|
||||
mk_c(c)->save_ast_trail(e);
|
||||
RETURN_Z3(of_expr(e));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_fixedpoint_get_reason_unknown(Z3_context c,Z3_fixedpoint d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_reason_unknown(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->mk_external_string(to_fixedpoint_ref(d)->get_last_status());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_fixedpoint_to_string(
|
||||
Z3_context c,
|
||||
Z3_fixedpoint d,
|
||||
unsigned num_queries,
|
||||
Z3_ast _queries[]) {
|
||||
Z3_TRY;
|
||||
expr*const* queries = to_exprs(_queries);
|
||||
LOG_Z3_fixedpoint_to_string(c, d, num_queries, _queries);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->mk_external_string(to_fixedpoint_ref(d)->to_string(num_queries, queries));
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_stats Z3_API Z3_fixedpoint_get_statistics(Z3_context c,Z3_fixedpoint d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_statistics(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_stats_ref * st = alloc(Z3_stats_ref);
|
||||
to_fixedpoint_ref(d)->ctx().collect_statistics(st->m_stats);
|
||||
mk_c(c)->save_object(st);
|
||||
Z3_stats r = of_stats(st);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_register_relation(Z3_context c,Z3_fixedpoint d, Z3_func_decl f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_register_relation(c, d, f);
|
||||
to_fixedpoint_ref(d)->ctx().register_predicate(to_func_decl(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_set_predicate_representation(
|
||||
Z3_context c,
|
||||
Z3_fixedpoint d,
|
||||
Z3_func_decl f,
|
||||
unsigned num_relations,
|
||||
Z3_symbol const relation_kinds[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_set_predicate_representation(c, d, f, num_relations, relation_kinds);
|
||||
svector<symbol> kinds;
|
||||
for (unsigned i = 0; i < num_relations; ++i) {
|
||||
kinds.push_back(to_symbol(relation_kinds[i]));
|
||||
}
|
||||
to_fixedpoint_ref(d)->ctx().set_predicate_representation(to_func_decl(f), num_relations, kinds.c_ptr());
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_set_reduce_assign_callback(
|
||||
Z3_context c, Z3_fixedpoint d, Z3_fixedpoint_reduce_assign_callback_fptr f) {
|
||||
Z3_TRY;
|
||||
// no logging
|
||||
to_fixedpoint_ref(d)->set_reduce_assign((reduce_assign_callback_fptr)f);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_set_reduce_app_callback(
|
||||
Z3_context c, Z3_fixedpoint d, Z3_fixedpoint_reduce_app_callback_fptr f) {
|
||||
Z3_TRY;
|
||||
// no logging
|
||||
to_fixedpoint_ref(d)->set_reduce_app((reduce_app_callback_fptr)f);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_fixedpoint_simplify_rules(
|
||||
Z3_context c,
|
||||
Z3_fixedpoint d,
|
||||
unsigned num_rules,
|
||||
Z3_ast _rules[],
|
||||
unsigned num_outputs,
|
||||
Z3_func_decl _outputs[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_simplify_rules(c, d, num_rules, _rules, num_outputs, _outputs);
|
||||
RESET_ERROR_CODE();
|
||||
expr** rules = (expr**)_rules;
|
||||
func_decl** outputs = (func_decl**)_outputs;
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
expr_ref_vector result(m);
|
||||
to_fixedpoint_ref(d)->simplify_rules(num_rules, rules, num_outputs, outputs, result);
|
||||
Z3_ast_vector_ref* v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
for (unsigned i = 0; i < result.size(); ++i) {
|
||||
v->m_ast_vector.push_back(result[i].get());
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0)
|
||||
}
|
||||
|
||||
|
||||
void Z3_API Z3_fixedpoint_init(Z3_context c,Z3_fixedpoint d, void* state) {
|
||||
Z3_TRY;
|
||||
// not logged
|
||||
to_fixedpoint_ref(d)->set_state(state);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
|
||||
void Z3_API Z3_fixedpoint_update_rule(Z3_context c, Z3_fixedpoint d, Z3_ast a, Z3_symbol name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_update_rule(c, d, a, name);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_FORMULA(a,);
|
||||
to_fixedpoint_ref(d)->update_rule(to_expr(a), to_symbol(name));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_fixedpoint_get_num_levels(Z3_context c, Z3_fixedpoint d, Z3_func_decl pred) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_num_levels(c, d, pred);
|
||||
RESET_ERROR_CODE();
|
||||
return to_fixedpoint_ref(d)->get_num_levels(to_func_decl(pred));
|
||||
Z3_CATCH_RETURN(0)
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_fixedpoint_get_cover_delta(Z3_context c, Z3_fixedpoint d, int level, Z3_func_decl pred) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_cover_delta(c, d, level, pred);
|
||||
RESET_ERROR_CODE();
|
||||
expr_ref r = to_fixedpoint_ref(d)->get_cover_delta(level, to_func_decl(pred));
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
RETURN_Z3(of_expr(r.get()));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_add_cover(Z3_context c, Z3_fixedpoint d, int level, Z3_func_decl pred, Z3_ast property) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_add_cover(c, d, level, pred, property);
|
||||
RESET_ERROR_CODE();
|
||||
to_fixedpoint_ref(d)->add_cover(level, to_func_decl(pred), to_expr(property));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_fixedpoint_get_help(Z3_context c, Z3_fixedpoint d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_help(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
param_descrs descrs;
|
||||
to_fixedpoint_ref(d)->collect_param_descrs(descrs);
|
||||
descrs.display(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_param_descrs Z3_API Z3_fixedpoint_get_param_descrs(Z3_context c, Z3_fixedpoint f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_get_param_descrs(c, f);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
|
||||
mk_c(c)->save_object(d);
|
||||
to_fixedpoint_ref(f)->collect_param_descrs(d->m_descrs);
|
||||
Z3_param_descrs r = of_param_descrs(d);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_set_params(Z3_context c, Z3_fixedpoint d, Z3_params p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_set_params(c, d, p);
|
||||
RESET_ERROR_CODE();
|
||||
param_descrs descrs;
|
||||
to_fixedpoint_ref(d)->collect_param_descrs(descrs);
|
||||
to_params(p)->m_params.validate(descrs);
|
||||
to_fixedpoint_ref(d)->updt_params(to_param_ref(p));
|
||||
to_fixedpoint(d)->m_params = to_param_ref(p);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_push(Z3_context c,Z3_fixedpoint d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_push(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
to_fixedpoint_ref(d)->ctx().push();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_fixedpoint_pop(Z3_context c,Z3_fixedpoint d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_fixedpoint_pop(c, d);
|
||||
RESET_ERROR_CODE();
|
||||
to_fixedpoint_ref(d)->ctx().pop();
|
||||
Z3_CATCH;
|
||||
|
||||
}
|
||||
|
||||
|
||||
};
|
84
src/api/api_datalog.h
Normal file
84
src/api/api_datalog.h
Normal file
|
@ -0,0 +1,84 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_datalog.h
|
||||
|
||||
Abstract:
|
||||
Datalog API
|
||||
old external_relation_context_impl
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_DATALOG_H_
|
||||
#define _API_DATALOG_H_
|
||||
|
||||
#include"z3.h"
|
||||
#include"ast.h"
|
||||
#include"front_end_params.h"
|
||||
#include"dl_external_relation.h"
|
||||
#include"dl_decl_plugin.h"
|
||||
#include"smt_solver.h"
|
||||
#include"api_util.h"
|
||||
#include"dl_context.h"
|
||||
|
||||
typedef void (*reduce_app_callback_fptr)(void*, func_decl*, unsigned, expr*const*, expr**);
|
||||
typedef void (*reduce_assign_callback_fptr)(void*, func_decl*, unsigned, expr*const*, unsigned, expr*const*);
|
||||
|
||||
namespace api {
|
||||
|
||||
class fixedpoint_context : public datalog::external_relation_context {
|
||||
void * m_state;
|
||||
reduce_app_callback_fptr m_reduce_app;
|
||||
reduce_assign_callback_fptr m_reduce_assign;
|
||||
datalog::context m_context;
|
||||
ast_ref_vector m_trail;
|
||||
public:
|
||||
fixedpoint_context(ast_manager& m, front_end_params& p);
|
||||
virtual ~fixedpoint_context() {}
|
||||
family_id get_family_id() const { return const_cast<datalog::context&>(m_context).get_decl_util().get_family_id(); }
|
||||
void set_state(void* state);
|
||||
void set_reduce_app(reduce_app_callback_fptr f) { m_reduce_app = f; }
|
||||
void set_reduce_assign(reduce_assign_callback_fptr f) { m_reduce_assign = f; }
|
||||
virtual void reduce(func_decl* f, unsigned num_args, expr * const* args, expr_ref& result);
|
||||
virtual void reduce_assign(func_decl* f, unsigned num_args, expr * const* args, unsigned num_out, expr* const* outs);
|
||||
datalog::context& ctx() { return m_context; }
|
||||
void add_rule(expr* rule, symbol const& name);
|
||||
void update_rule(expr* rule, symbol const& name);
|
||||
void add_table_fact(func_decl* r, unsigned num_args, unsigned args[]);
|
||||
std::string get_last_status();
|
||||
std::string to_string(unsigned num_queries, expr*const* queries);
|
||||
void cancel() { m_context.cancel(); }
|
||||
|
||||
unsigned get_num_levels(func_decl* pred);
|
||||
expr_ref get_cover_delta(int level, func_decl* pred);
|
||||
void add_cover(int level, func_decl* pred, expr* predicate);
|
||||
void collect_param_descrs(param_descrs & p) { m_context.collect_params(p); }
|
||||
void updt_params(params_ref const& p) { m_context.updt_params(p); }
|
||||
|
||||
void simplify_rules(
|
||||
unsigned num_rules, expr* const* rules,
|
||||
unsigned num_outputs, func_decl* const* outputs, expr_ref_vector& result);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
struct Z3_fixedpoint_ref : public api::object {
|
||||
api::fixedpoint_context * m_datalog;
|
||||
params_ref m_params;
|
||||
Z3_fixedpoint_ref():m_datalog(0) {}
|
||||
virtual ~Z3_fixedpoint_ref() { dealloc(m_datalog); }
|
||||
};
|
||||
|
||||
inline Z3_fixedpoint_ref * to_fixedpoint(Z3_fixedpoint s) { return reinterpret_cast<Z3_fixedpoint_ref *>(s); }
|
||||
inline Z3_fixedpoint of_datalog(Z3_fixedpoint_ref * s) { return reinterpret_cast<Z3_fixedpoint>(s); }
|
||||
inline api::fixedpoint_context * to_fixedpoint_ref(Z3_fixedpoint s) { return to_fixedpoint(s)->m_datalog; }
|
||||
|
||||
|
||||
#endif
|
621
src/api/api_datatype.cpp
Normal file
621
src/api/api_datatype.cpp
Normal file
|
@ -0,0 +1,621 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_datatype.cpp
|
||||
|
||||
Abstract:
|
||||
API for datatype theory
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"datatype_decl_plugin.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_sort Z3_API Z3_mk_tuple_sort(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned num_fields,
|
||||
Z3_symbol const field_names[],
|
||||
Z3_sort const field_sorts[],
|
||||
Z3_func_decl * mk_tuple_decl,
|
||||
Z3_func_decl proj_decls[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_tuple_sort(c, name, num_fields, field_names, field_sorts, mk_tuple_decl, proj_decls);
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->reset_last_result();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
datatype_util dt_util(m);
|
||||
|
||||
sort_ref_vector tuples(m);
|
||||
sort* tuple;
|
||||
std::string recognizer_s("is_");
|
||||
recognizer_s += to_symbol(name).str();
|
||||
symbol recognizer(recognizer_s.c_str());
|
||||
|
||||
ptr_vector<accessor_decl> acc;
|
||||
for (unsigned i = 0; i < num_fields; ++i) {
|
||||
acc.push_back(mk_accessor_decl(to_symbol(field_names[i]), type_ref(to_sort(field_sorts[i]))));
|
||||
}
|
||||
|
||||
constructor_decl* constrs[1] = { mk_constructor_decl(to_symbol(name), recognizer, acc.size(), acc.c_ptr()) };
|
||||
|
||||
{
|
||||
datatype_decl * dt = mk_datatype_decl(to_symbol(name), 1, constrs);
|
||||
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, tuples);
|
||||
del_datatype_decl(dt);
|
||||
|
||||
if (!is_ok) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
}
|
||||
|
||||
// create tuple type
|
||||
SASSERT(tuples.size() == 1);
|
||||
tuple = tuples[0].get();
|
||||
mk_c(c)->save_multiple_ast_trail(tuple);
|
||||
|
||||
// create constructor
|
||||
SASSERT(dt_util.is_datatype(tuple));
|
||||
SASSERT(!dt_util.is_recursive(tuple));
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple);
|
||||
func_decl* decl = (*decls)[0];
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
*mk_tuple_decl = of_func_decl(decl);
|
||||
|
||||
// Create projections
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors(decl);
|
||||
if (!accs) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const & _accs = *accs;
|
||||
SASSERT(_accs.size() == num_fields);
|
||||
for (unsigned i = 0; i < _accs.size(); i++) {
|
||||
mk_c(c)->save_multiple_ast_trail(_accs[i]);
|
||||
proj_decls[i] = of_func_decl(_accs[i]);
|
||||
}
|
||||
RETURN_Z3_mk_tuple_sort(of_sort(tuple));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_enumeration_sort(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned n,
|
||||
Z3_symbol const enum_names[],
|
||||
Z3_func_decl enum_consts[],
|
||||
Z3_func_decl enum_testers[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_enumeration_sort(c, name, n, enum_names, enum_consts, enum_testers);
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->reset_last_result();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
datatype_util dt_util(m);
|
||||
|
||||
sort_ref_vector sorts(m);
|
||||
sort* e;
|
||||
|
||||
ptr_vector<constructor_decl> constrs;
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
symbol e_name(to_symbol(enum_names[i]));
|
||||
std::string recognizer_s("is_");
|
||||
recognizer_s += e_name.str();
|
||||
symbol recognizer(recognizer_s.c_str());
|
||||
|
||||
constrs.push_back(mk_constructor_decl(e_name, recognizer, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
{
|
||||
datatype_decl * dt = mk_datatype_decl(to_symbol(name), n, constrs.c_ptr());
|
||||
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &dt, sorts);
|
||||
del_datatype_decl(dt);
|
||||
|
||||
if (!is_ok) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
}
|
||||
|
||||
// create enum type.
|
||||
SASSERT(sorts.size() == 1);
|
||||
e = sorts[0].get();
|
||||
mk_c(c)->save_multiple_ast_trail(e);
|
||||
|
||||
// create constructor
|
||||
SASSERT(dt_util.is_datatype(e));
|
||||
SASSERT(!dt_util.is_recursive(e));
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(e);
|
||||
SASSERT(decls && decls->size() == n);
|
||||
for (unsigned i = 0; i < n; ++i) {
|
||||
func_decl* decl = (*decls)[i];
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
enum_consts[i] = of_func_decl(decl);
|
||||
decl = dt_util.get_constructor_recognizer(decl);
|
||||
mk_c(c)->save_multiple_ast_trail(decl);
|
||||
enum_testers[i] = of_func_decl(decl);
|
||||
}
|
||||
|
||||
RETURN_Z3_mk_enumeration_sort(of_sort(e));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_list_sort(Z3_context c,
|
||||
Z3_symbol name,
|
||||
Z3_sort elem_sort,
|
||||
Z3_func_decl* nil_decl,
|
||||
Z3_func_decl* is_nil_decl,
|
||||
Z3_func_decl* cons_decl,
|
||||
Z3_func_decl* is_cons_decl,
|
||||
Z3_func_decl* head_decl,
|
||||
Z3_func_decl* tail_decl
|
||||
) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_list_sort(c, name, elem_sort, nil_decl, is_nil_decl, cons_decl, is_cons_decl, head_decl, tail_decl);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
mk_c(c)->reset_last_result();
|
||||
datatype_util data_util(m);
|
||||
accessor_decl* head_tail[2] = {
|
||||
mk_accessor_decl(symbol("head"), type_ref(to_sort(elem_sort))),
|
||||
mk_accessor_decl(symbol("tail"), type_ref(0))
|
||||
};
|
||||
constructor_decl* constrs[2] = {
|
||||
mk_constructor_decl(symbol("nil"), symbol("is_nil"), 0, 0),
|
||||
// Leo: SMT 2.0 document uses 'insert' instead of cons
|
||||
mk_constructor_decl(symbol("cons"), symbol("is_cons"), 2, head_tail)
|
||||
};
|
||||
|
||||
sort_ref_vector sorts(m);
|
||||
{
|
||||
datatype_decl * decl = mk_datatype_decl(to_symbol(name), 2, constrs);
|
||||
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &decl, sorts);
|
||||
del_datatype_decl(decl);
|
||||
|
||||
if (!is_ok) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
}
|
||||
sort * s = sorts.get(0);
|
||||
|
||||
mk_c(c)->save_multiple_ast_trail(s);
|
||||
ptr_vector<func_decl> const& cnstrs = *data_util.get_datatype_constructors(s);
|
||||
SASSERT(cnstrs.size() == 2);
|
||||
func_decl* f;
|
||||
if (nil_decl) {
|
||||
f = cnstrs[0];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*nil_decl = of_func_decl(f);
|
||||
}
|
||||
if (is_nil_decl) {
|
||||
f = data_util.get_constructor_recognizer(cnstrs[0]);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*is_nil_decl = of_func_decl(f);
|
||||
}
|
||||
if (cons_decl) {
|
||||
f = cnstrs[1];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*cons_decl = of_func_decl(f);
|
||||
}
|
||||
if (is_cons_decl) {
|
||||
f = data_util.get_constructor_recognizer(cnstrs[1]);
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*is_cons_decl = of_func_decl(f);
|
||||
}
|
||||
if (head_decl) {
|
||||
ptr_vector<func_decl> const* acc = data_util.get_constructor_accessors(cnstrs[1]);
|
||||
SASSERT(acc);
|
||||
SASSERT(acc->size() == 2);
|
||||
f = (*acc)[0];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*head_decl = of_func_decl(f);
|
||||
}
|
||||
if (tail_decl) {
|
||||
ptr_vector<func_decl> const* acc = data_util.get_constructor_accessors(cnstrs[1]);
|
||||
SASSERT(acc);
|
||||
SASSERT(acc->size() == 2);
|
||||
f = (*acc)[1];
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*tail_decl = of_func_decl(f);
|
||||
}
|
||||
RETURN_Z3_mk_list_sort(of_sort(s));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
struct constructor {
|
||||
symbol m_name;
|
||||
symbol m_tester;
|
||||
svector<symbol> m_field_names;
|
||||
sort_ref_vector m_sorts;
|
||||
unsigned_vector m_sort_refs;
|
||||
func_decl_ref m_constructor;
|
||||
constructor(ast_manager& m) : m_sorts(m), m_constructor(m) {}
|
||||
};
|
||||
|
||||
Z3_constructor Z3_API Z3_mk_constructor(Z3_context c,
|
||||
Z3_symbol name,
|
||||
Z3_symbol tester,
|
||||
unsigned num_fields,
|
||||
Z3_symbol const field_names[],
|
||||
Z3_sort const sorts[],
|
||||
unsigned sort_refs[]
|
||||
) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_constructor(c, name, tester, num_fields, field_names, sorts, sort_refs);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
constructor* cnstr = alloc(constructor, m);
|
||||
cnstr->m_name = to_symbol(name);
|
||||
cnstr->m_tester = to_symbol(tester);
|
||||
for (unsigned i = 0; i < num_fields; ++i) {
|
||||
cnstr->m_field_names.push_back(to_symbol(field_names[i]));
|
||||
cnstr->m_sorts.push_back(to_sort(sorts[i]));
|
||||
cnstr->m_sort_refs.push_back(sort_refs[i]);
|
||||
}
|
||||
RETURN_Z3(reinterpret_cast<Z3_constructor>(cnstr));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
void Z3_API Z3_query_constructor(Z3_context c,
|
||||
Z3_constructor constr,
|
||||
unsigned num_fields,
|
||||
Z3_func_decl* constructor_decl,
|
||||
Z3_func_decl* tester,
|
||||
Z3_func_decl accessors[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_query_constructor(c, constr, num_fields, constructor_decl, tester, accessors);
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->reset_last_result();
|
||||
if (!constr) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
datatype_util data_util(m);
|
||||
func_decl* f = reinterpret_cast<constructor*>(constr)->m_constructor.get();
|
||||
|
||||
if (!f) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
if (constructor_decl) {
|
||||
mk_c(c)->save_multiple_ast_trail(f);
|
||||
*constructor_decl = of_func_decl(f);
|
||||
}
|
||||
if (tester) {
|
||||
func_decl* f2 = data_util.get_constructor_recognizer(f);
|
||||
mk_c(c)->save_multiple_ast_trail(f2);
|
||||
*tester = of_func_decl(f2);
|
||||
}
|
||||
|
||||
ptr_vector<func_decl> const* accs = data_util.get_constructor_accessors(f);
|
||||
if (!accs && num_fields > 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
for (unsigned i = 0; i < num_fields; ++i) {
|
||||
func_decl* f2 = (*accs)[i];
|
||||
mk_c(c)->save_multiple_ast_trail(f2);
|
||||
accessors[i] = of_func_decl(f2);
|
||||
}
|
||||
RETURN_Z3_query_constructor;
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_del_constructor(Z3_context c, Z3_constructor constr) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_del_constructor(c, constr);
|
||||
RESET_ERROR_CODE();
|
||||
dealloc(reinterpret_cast<constructor*>(constr));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
static datatype_decl* mk_datatype_decl(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned num_constructors,
|
||||
Z3_constructor constructors[]) {
|
||||
ptr_vector<constructor_decl> constrs;
|
||||
for (unsigned i = 0; i < num_constructors; ++i) {
|
||||
constructor* cn = reinterpret_cast<constructor*>(constructors[i]);
|
||||
ptr_vector<accessor_decl> acc;
|
||||
for (unsigned j = 0; j < cn->m_sorts.size(); ++j) {
|
||||
if (cn->m_sorts[j].get()) {
|
||||
acc.push_back(mk_accessor_decl(cn->m_field_names[j], type_ref(cn->m_sorts[j].get())));
|
||||
}
|
||||
else {
|
||||
acc.push_back(mk_accessor_decl(cn->m_field_names[j], type_ref(cn->m_sort_refs[j])));
|
||||
}
|
||||
}
|
||||
constrs.push_back(mk_constructor_decl(cn->m_name, cn->m_tester, acc.size(), acc.c_ptr()));
|
||||
}
|
||||
return mk_datatype_decl(to_symbol(name), num_constructors, constrs.c_ptr());
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_mk_datatype(Z3_context c,
|
||||
Z3_symbol name,
|
||||
unsigned num_constructors,
|
||||
Z3_constructor constructors[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_datatype(c, name, num_constructors, constructors);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
datatype_util data_util(m);
|
||||
|
||||
sort_ref_vector sorts(m);
|
||||
{
|
||||
datatype_decl * data = mk_datatype_decl(c, name, num_constructors, constructors);
|
||||
bool is_ok = mk_c(c)->get_dt_plugin()->mk_datatypes(1, &data, sorts);
|
||||
del_datatype_decl(data);
|
||||
|
||||
if (!is_ok) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
}
|
||||
sort * s = sorts.get(0);
|
||||
|
||||
mk_c(c)->save_ast_trail(s);
|
||||
ptr_vector<func_decl> const* cnstrs = data_util.get_datatype_constructors(s);
|
||||
|
||||
for (unsigned i = 0; i < num_constructors; ++i) {
|
||||
constructor* cn = reinterpret_cast<constructor*>(constructors[i]);
|
||||
cn->m_constructor = (*cnstrs)[i];
|
||||
}
|
||||
RETURN_Z3_mk_datatype(of_sort(s));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
typedef ptr_vector<constructor> constructor_list;
|
||||
|
||||
Z3_constructor_list Z3_API Z3_mk_constructor_list(Z3_context c,
|
||||
unsigned num_constructors,
|
||||
Z3_constructor const constructors[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_constructor_list(c, num_constructors, constructors);
|
||||
RESET_ERROR_CODE();
|
||||
constructor_list* result = alloc(ptr_vector<constructor>);
|
||||
for (unsigned i = 0; i < num_constructors; ++i) {
|
||||
result->push_back(reinterpret_cast<constructor*>(constructors[i]));
|
||||
}
|
||||
RETURN_Z3(reinterpret_cast<Z3_constructor_list>(result));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_del_constructor_list(Z3_context c, Z3_constructor_list clist) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_del_constructor_list(c, clist);
|
||||
RESET_ERROR_CODE();
|
||||
dealloc(reinterpret_cast<constructor_list*>(clist));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_mk_datatypes(Z3_context c,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol const sort_names[],
|
||||
Z3_sort sorts[],
|
||||
Z3_constructor_list constructor_lists[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_datatypes(c, num_sorts, sort_names, sorts, constructor_lists);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
mk_c(c)->reset_last_result();
|
||||
datatype_util data_util(m);
|
||||
|
||||
ptr_vector<datatype_decl> datas;
|
||||
for (unsigned i = 0; i < num_sorts; ++i) {
|
||||
constructor_list* cl = reinterpret_cast<constructor_list*>(constructor_lists[i]);
|
||||
datas.push_back(mk_datatype_decl(c,sort_names[i], cl->size(), reinterpret_cast<Z3_constructor*>(cl->c_ptr())));
|
||||
}
|
||||
sort_ref_vector _sorts(m);
|
||||
bool ok = mk_c(c)->get_dt_plugin()->mk_datatypes(datas.size(), datas.c_ptr(), _sorts);
|
||||
del_datatype_decls(datas.size(), datas.c_ptr());
|
||||
|
||||
if (!ok) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
|
||||
SASSERT(_sorts.size() == num_sorts);
|
||||
for (unsigned i = 0; i < _sorts.size(); ++i) {
|
||||
sort* s = _sorts[i].get();
|
||||
mk_c(c)->save_multiple_ast_trail(s);
|
||||
sorts[i] = of_sort(s);
|
||||
constructor_list* cl = reinterpret_cast<constructor_list*>(constructor_lists[i]);
|
||||
ptr_vector<func_decl> const* cnstrs = data_util.get_datatype_constructors(s);
|
||||
for (unsigned j = 0; j < cl->size(); ++j) {
|
||||
constructor* cn = (*cl)[j];
|
||||
cn->m_constructor = (*cnstrs)[j];
|
||||
}
|
||||
}
|
||||
RETURN_Z3_mk_datatypes;
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_datatype_sort_num_constructors(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_datatype_sort_num_constructors(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util dt_util(mk_c(c)->m());
|
||||
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (!decls) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return decls->size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl get_datatype_sort_constructor_core(Z3_context c, Z3_sort t, unsigned idx) {
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_VALID_AST(t, 0);
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util dt_util(mk_c(c)->m());
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (!decls || idx >= decls->size()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
func_decl* decl = (*decls)[idx];
|
||||
mk_c(c)->save_ast_trail(decl);
|
||||
return of_func_decl(decl);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor(Z3_context c, Z3_sort t, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_datatype_sort_constructor(c, t, idx);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_func_decl r = get_datatype_sort_constructor_core(c, t, idx);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_datatype_sort_recognizer(Z3_context c, Z3_sort t, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_datatype_sort_recognizer(c, t, idx);
|
||||
RESET_ERROR_CODE();
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util dt_util(mk_c(c)->m());
|
||||
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (!decls || idx >= decls->size()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
func_decl* decl = (*decls)[idx];
|
||||
decl = dt_util.get_constructor_recognizer(decl);
|
||||
mk_c(c)->save_ast_trail(decl);
|
||||
RETURN_Z3(of_func_decl(decl));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_datatype_sort_constructor_accessor(Z3_context c, Z3_sort t, unsigned idx_c, unsigned idx_a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_datatype_sort_constructor_accessor(c, t, idx_c, idx_a);
|
||||
RESET_ERROR_CODE();
|
||||
sort * _t = to_sort(t);
|
||||
datatype_util dt_util(mk_c(c)->m());
|
||||
|
||||
if (!dt_util.is_datatype(_t)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(_t);
|
||||
if (!decls || idx_c >= decls->size()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
func_decl* decl = (*decls)[idx_c];
|
||||
if (decl->get_arity() <= idx_a) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors(decl);
|
||||
SASSERT(accs && accs->size() == decl->get_arity());
|
||||
if (!accs || accs->size() <= idx_a) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
decl = (*accs)[idx_a];
|
||||
mk_c(c)->save_ast_trail(decl);
|
||||
RETURN_Z3(of_func_decl(decl));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_tuple_sort_mk_decl(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tuple_sort_mk_decl(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
sort * tuple = to_sort(t);
|
||||
datatype_util dt_util(mk_c(c)->m());
|
||||
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_func_decl r = get_datatype_sort_constructor_core(c, t, 0);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_tuple_sort_num_fields(Z3_context c, Z3_sort t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tuple_sort_num_fields(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
sort * tuple = to_sort(t);
|
||||
datatype_util dt_util(mk_c(c)->m());
|
||||
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple);
|
||||
if (!decls || decls->size() != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors((*decls)[0]);
|
||||
if (!accs) {
|
||||
return 0;
|
||||
}
|
||||
return accs->size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_tuple_sort_field_decl(Z3_context c, Z3_sort t, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tuple_sort_field_decl(c, t, i);
|
||||
RESET_ERROR_CODE();
|
||||
sort * tuple = to_sort(t);
|
||||
datatype_util dt_util(mk_c(c)->m());
|
||||
if (!dt_util.is_datatype(tuple) || dt_util.is_recursive(tuple) || dt_util.get_datatype_num_constructors(tuple) != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * decls = dt_util.get_datatype_constructors(tuple);
|
||||
if (!decls || decls->size() != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<func_decl> const * accs = dt_util.get_constructor_accessors((*decls)[0]);
|
||||
if (!accs) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
if (accs->size() <= i) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
func_decl* acc = (*accs)[i];
|
||||
mk_c(c)->save_ast_trail(acc);
|
||||
RETURN_Z3(of_func_decl(acc));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
};
|
181
src/api/api_goal.cpp
Normal file
181
src/api/api_goal.cpp
Normal file
|
@ -0,0 +1,181 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_goal.cpp
|
||||
|
||||
Abstract:
|
||||
API for creating goals
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-06.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_goal.h"
|
||||
#include"ast_translation.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_goal Z3_API Z3_mk_goal(Z3_context c, Z3_bool models, Z3_bool unsat_cores, Z3_bool proofs) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_goal(c, models, unsat_cores, proofs);
|
||||
RESET_ERROR_CODE();
|
||||
if (proofs != 0 && !mk_c(c)->m().proofs_enabled()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_goal_ref * g = alloc(Z3_goal_ref);
|
||||
g->m_goal = alloc(goal, mk_c(c)->m(), proofs != 0, models != 0, unsat_cores != 0);
|
||||
mk_c(c)->save_object(g);
|
||||
Z3_goal r = of_goal(g);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_goal_inc_ref(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_inc_ref(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
to_goal(g)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_goal_dec_ref(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_dec_ref(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
to_goal(g)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_goal_prec Z3_API Z3_goal_precision(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_precision(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
switch (to_goal_ref(g)->prec()) {
|
||||
case goal::PRECISE: return Z3_GOAL_PRECISE;
|
||||
case goal::UNDER: return Z3_GOAL_UNDER;
|
||||
case goal::OVER: return Z3_GOAL_OVER;
|
||||
case goal::UNDER_OVER: return Z3_GOAL_UNDER_OVER;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return Z3_GOAL_UNDER_OVER;
|
||||
}
|
||||
Z3_CATCH_RETURN(Z3_GOAL_UNDER_OVER);
|
||||
}
|
||||
|
||||
void Z3_API Z3_goal_assert(Z3_context c, Z3_goal g, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_assert(c, g, a);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_FORMULA(a,);
|
||||
to_goal_ref(g)->assert_expr(to_expr(a));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_goal_inconsistent(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_inconsistent(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
return to_goal_ref(g)->inconsistent();
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_goal_depth(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_depth(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
return to_goal_ref(g)->depth();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_goal_reset(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_reset(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
to_goal_ref(g)->reset();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_goal_size(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_size(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
return to_goal_ref(g)->size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_goal_formula(Z3_context c, Z3_goal g, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_formula(c, g, idx);
|
||||
RESET_ERROR_CODE();
|
||||
if (idx >= to_goal_ref(g)->size()) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
expr * result = to_goal_ref(g)->form(idx);
|
||||
mk_c(c)->save_ast_trail(result);
|
||||
RETURN_Z3(of_ast(result));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_goal_num_exprs(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_num_exprs(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
return to_goal_ref(g)->num_exprs();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_goal_is_decided_sat(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_is_decided_sat(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
return to_goal_ref(g)->is_decided_sat();
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_goal_is_decided_unsat(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_is_decided_unsat(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
return to_goal_ref(g)->is_decided_unsat();
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_goal Z3_API Z3_goal_translate(Z3_context c, Z3_goal g, Z3_context target) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_translate(c, g, target);
|
||||
RESET_ERROR_CODE();
|
||||
ast_translation translator(mk_c(c)->m(), mk_c(target)->m());
|
||||
Z3_goal_ref * _r = alloc(Z3_goal_ref);
|
||||
_r->m_goal = to_goal_ref(g)->translate(translator);
|
||||
mk_c(target)->save_object(_r);
|
||||
Z3_goal r = of_goal(_r);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_goal_to_string(Z3_context c, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_goal_to_string(c, g);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
to_goal_ref(g)->display(buffer);
|
||||
// Hack for removing the trailing '\n'
|
||||
std::string result = buffer.str();
|
||||
SASSERT(result.size() > 0);
|
||||
result.resize(result.size()-1);
|
||||
return mk_c(c)->mk_external_string(result);
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
};
|
33
src/api/api_goal.h
Normal file
33
src/api/api_goal.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_goal.h
|
||||
|
||||
Abstract:
|
||||
API for creating goals
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-06.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_GOAL_H_
|
||||
#define _API_GOAL_H_
|
||||
|
||||
#include"api_util.h"
|
||||
#include"goal.h"
|
||||
|
||||
struct Z3_goal_ref : public api::object {
|
||||
goal_ref m_goal;
|
||||
virtual ~Z3_goal_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_goal_ref * to_goal(Z3_goal g) { return reinterpret_cast<Z3_goal_ref *>(g); }
|
||||
inline Z3_goal of_goal(Z3_goal_ref * g) { return reinterpret_cast<Z3_goal>(g); }
|
||||
inline goal_ref to_goal_ref(Z3_goal g) { return g == 0 ? goal_ref() : to_goal(g)->m_goal; }
|
||||
|
||||
#endif
|
54
src/api/api_log.cpp
Normal file
54
src/api/api_log.cpp
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_log.cpp
|
||||
|
||||
Abstract:
|
||||
API for creating logs
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include<fstream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"util.h"
|
||||
|
||||
std::ostream * g_z3_log = 0;
|
||||
bool g_z3_log_enabled = false;
|
||||
|
||||
extern "C" {
|
||||
Z3_bool Z3_API Z3_open_log(Z3_string filename) {
|
||||
if (g_z3_log != 0)
|
||||
Z3_close_log();
|
||||
g_z3_log = alloc(std::ofstream, filename);
|
||||
g_z3_log_enabled = true;
|
||||
if (g_z3_log->bad() || g_z3_log->fail()) {
|
||||
dealloc(g_z3_log);
|
||||
g_z3_log = 0;
|
||||
return Z3_FALSE;
|
||||
}
|
||||
return Z3_TRUE;
|
||||
}
|
||||
|
||||
void Z3_API Z3_append_log(Z3_string str) {
|
||||
if (g_z3_log == 0)
|
||||
return;
|
||||
_Z3_append_log(static_cast<char const *>(str));
|
||||
}
|
||||
|
||||
void Z3_API Z3_close_log() {
|
||||
if (g_z3_log != 0) {
|
||||
dealloc(g_z3_log);
|
||||
g_z3_log_enabled = false;
|
||||
g_z3_log = 0;
|
||||
}
|
||||
}
|
||||
}
|
3355
src/api/api_log_macros.cpp
Normal file
3355
src/api/api_log_macros.cpp
Normal file
File diff suppressed because it is too large
Load diff
989
src/api/api_log_macros.h
Normal file
989
src/api/api_log_macros.h
Normal file
|
@ -0,0 +1,989 @@
|
|||
// Automatically generated file, generator: update_api.py
|
||||
#include"z3.h"
|
||||
extern std::ostream * g_z3_log;
|
||||
extern bool g_z3_log_enabled;
|
||||
class z3_log_ctx { bool m_prev; public: z3_log_ctx():m_prev(g_z3_log_enabled) { g_z3_log_enabled = false; } ~z3_log_ctx() { g_z3_log_enabled = m_prev; } bool enabled() const { return m_prev; } };
|
||||
inline void SetR(void * obj) { *g_z3_log << "= " << obj << "\n"; }
|
||||
inline void SetO(void * obj, unsigned pos) { *g_z3_log << "* " << obj << " " << pos << "\n"; }
|
||||
inline void SetAO(void * obj, unsigned pos, unsigned idx) { *g_z3_log << "@ " << obj << " " << pos << " " << idx << "\n"; }
|
||||
#define RETURN_Z3(Z3RES) if (_LOG_CTX.enabled()) { SetR(Z3RES); } return Z3RES
|
||||
void _Z3_append_log(char const * msg);
|
||||
void log_Z3_mk_config();
|
||||
#define LOG_Z3_mk_config() z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_config(); }
|
||||
void log_Z3_del_config(Z3_config a0);
|
||||
#define LOG_Z3_del_config(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_del_config(_ARG0); }
|
||||
void log_Z3_set_param_value(Z3_config a0, Z3_string a1, Z3_string a2);
|
||||
#define LOG_Z3_set_param_value(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_set_param_value(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_context(Z3_config a0);
|
||||
#define LOG_Z3_mk_context(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_context(_ARG0); }
|
||||
void log_Z3_mk_context_rc(Z3_config a0);
|
||||
#define LOG_Z3_mk_context_rc(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_context_rc(_ARG0); }
|
||||
void log_Z3_del_context(Z3_context a0);
|
||||
#define LOG_Z3_del_context(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_del_context(_ARG0); }
|
||||
void log_Z3_inc_ref(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_dec_ref(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_update_param_value(Z3_context a0, Z3_string a1, Z3_string a2);
|
||||
#define LOG_Z3_update_param_value(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_update_param_value(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_param_value(Z3_context a0, Z3_string a1, Z3_string* a2);
|
||||
#define LOG_Z3_get_param_value(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_param_value(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_interrupt(Z3_context a0);
|
||||
#define LOG_Z3_interrupt(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_interrupt(_ARG0); }
|
||||
void log_Z3_mk_params(Z3_context a0);
|
||||
#define LOG_Z3_mk_params(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_params(_ARG0); }
|
||||
void log_Z3_params_inc_ref(Z3_context a0, Z3_params a1);
|
||||
#define LOG_Z3_params_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_params_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_params_dec_ref(Z3_context a0, Z3_params a1);
|
||||
#define LOG_Z3_params_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_params_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_params_set_bool(Z3_context a0, Z3_params a1, Z3_symbol a2, Z3_bool a3);
|
||||
#define LOG_Z3_params_set_bool(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_params_set_bool(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_params_set_uint(Z3_context a0, Z3_params a1, Z3_symbol a2, unsigned a3);
|
||||
#define LOG_Z3_params_set_uint(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_params_set_uint(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_params_set_double(Z3_context a0, Z3_params a1, Z3_symbol a2, double a3);
|
||||
#define LOG_Z3_params_set_double(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_params_set_double(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_params_set_symbol(Z3_context a0, Z3_params a1, Z3_symbol a2, Z3_symbol a3);
|
||||
#define LOG_Z3_params_set_symbol(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_params_set_symbol(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_params_to_string(Z3_context a0, Z3_params a1);
|
||||
#define LOG_Z3_params_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_params_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_params_validate(Z3_context a0, Z3_params a1, Z3_param_descrs a2);
|
||||
#define LOG_Z3_params_validate(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_params_validate(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_param_descrs_inc_ref(Z3_context a0, Z3_param_descrs a1);
|
||||
#define LOG_Z3_param_descrs_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_param_descrs_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_param_descrs_dec_ref(Z3_context a0, Z3_param_descrs a1);
|
||||
#define LOG_Z3_param_descrs_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_param_descrs_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_param_descrs_get_kind(Z3_context a0, Z3_param_descrs a1, Z3_symbol a2);
|
||||
#define LOG_Z3_param_descrs_get_kind(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_param_descrs_get_kind(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_param_descrs_size(Z3_context a0, Z3_param_descrs a1);
|
||||
#define LOG_Z3_param_descrs_size(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_param_descrs_size(_ARG0, _ARG1); }
|
||||
void log_Z3_param_descrs_get_name(Z3_context a0, Z3_param_descrs a1, unsigned a2);
|
||||
#define LOG_Z3_param_descrs_get_name(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_param_descrs_get_name(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_param_descrs_to_string(Z3_context a0, Z3_param_descrs a1);
|
||||
#define LOG_Z3_param_descrs_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_param_descrs_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_int_symbol(Z3_context a0, int a1);
|
||||
#define LOG_Z3_mk_int_symbol(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_int_symbol(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_string_symbol(Z3_context a0, Z3_string a1);
|
||||
#define LOG_Z3_mk_string_symbol(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_string_symbol(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_uninterpreted_sort(Z3_context a0, Z3_symbol a1);
|
||||
#define LOG_Z3_mk_uninterpreted_sort(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_uninterpreted_sort(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_bool_sort(Z3_context a0);
|
||||
#define LOG_Z3_mk_bool_sort(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bool_sort(_ARG0); }
|
||||
void log_Z3_mk_int_sort(Z3_context a0);
|
||||
#define LOG_Z3_mk_int_sort(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_int_sort(_ARG0); }
|
||||
void log_Z3_mk_real_sort(Z3_context a0);
|
||||
#define LOG_Z3_mk_real_sort(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_real_sort(_ARG0); }
|
||||
void log_Z3_mk_bv_sort(Z3_context a0, unsigned a1);
|
||||
#define LOG_Z3_mk_bv_sort(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bv_sort(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_finite_domain_sort(Z3_context a0, Z3_symbol a1, __uint64 a2);
|
||||
#define LOG_Z3_mk_finite_domain_sort(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_finite_domain_sort(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_array_sort(Z3_context a0, Z3_sort a1, Z3_sort a2);
|
||||
#define LOG_Z3_mk_array_sort(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_array_sort(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_tuple_sort(Z3_context a0, Z3_symbol a1, unsigned a2, Z3_symbol const * a3, Z3_sort const * a4, Z3_func_decl* a5, Z3_func_decl* a6);
|
||||
#define LOG_Z3_mk_tuple_sort(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6) z3_log_ctx _LOG_CTX; Z3_func_decl* Z3ARG5; unsigned Z3ARG2; Z3_func_decl* Z3ARG6; if (_LOG_CTX.enabled()) { log_Z3_mk_tuple_sort(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6); Z3ARG5 = _ARG5; Z3ARG2 = _ARG2; Z3ARG6 = _ARG6; }
|
||||
#define RETURN_Z3_mk_tuple_sort(Z3RES) if (_LOG_CTX.enabled()) { SetR(Z3RES); SetO((Z3ARG5 == 0 ? 0 : *Z3ARG5), 5); for (unsigned i = 0; i < Z3ARG2; i++) { SetAO(Z3ARG6[i], 6, i); } } return Z3RES
|
||||
void log_Z3_mk_enumeration_sort(Z3_context a0, Z3_symbol a1, unsigned a2, Z3_symbol const * a3, Z3_func_decl* a4, Z3_func_decl* a5);
|
||||
#define LOG_Z3_mk_enumeration_sort(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5) z3_log_ctx _LOG_CTX; unsigned Z3ARG2; Z3_func_decl* Z3ARG4; Z3_func_decl* Z3ARG5; if (_LOG_CTX.enabled()) { log_Z3_mk_enumeration_sort(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5); Z3ARG2 = _ARG2; Z3ARG4 = _ARG4; Z3ARG5 = _ARG5; }
|
||||
#define RETURN_Z3_mk_enumeration_sort(Z3RES) if (_LOG_CTX.enabled()) { SetR(Z3RES); for (unsigned i = 0; i < Z3ARG2; i++) { SetAO(Z3ARG4[i], 4, i); } for (unsigned i = 0; i < Z3ARG2; i++) { SetAO(Z3ARG5[i], 5, i); } } return Z3RES
|
||||
void log_Z3_mk_list_sort(Z3_context a0, Z3_symbol a1, Z3_sort a2, Z3_func_decl* a3, Z3_func_decl* a4, Z3_func_decl* a5, Z3_func_decl* a6, Z3_func_decl* a7, Z3_func_decl* a8);
|
||||
#define LOG_Z3_mk_list_sort(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7, _ARG8) z3_log_ctx _LOG_CTX; Z3_func_decl* Z3ARG3; Z3_func_decl* Z3ARG4; Z3_func_decl* Z3ARG5; Z3_func_decl* Z3ARG6; Z3_func_decl* Z3ARG7; Z3_func_decl* Z3ARG8; if (_LOG_CTX.enabled()) { log_Z3_mk_list_sort(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7, _ARG8); Z3ARG3 = _ARG3; Z3ARG4 = _ARG4; Z3ARG5 = _ARG5; Z3ARG6 = _ARG6; Z3ARG7 = _ARG7; Z3ARG8 = _ARG8; }
|
||||
#define RETURN_Z3_mk_list_sort(Z3RES) if (_LOG_CTX.enabled()) { SetR(Z3RES); SetO((Z3ARG3 == 0 ? 0 : *Z3ARG3), 3); SetO((Z3ARG4 == 0 ? 0 : *Z3ARG4), 4); SetO((Z3ARG5 == 0 ? 0 : *Z3ARG5), 5); SetO((Z3ARG6 == 0 ? 0 : *Z3ARG6), 6); SetO((Z3ARG7 == 0 ? 0 : *Z3ARG7), 7); SetO((Z3ARG8 == 0 ? 0 : *Z3ARG8), 8); } return Z3RES
|
||||
void log_Z3_mk_constructor(Z3_context a0, Z3_symbol a1, Z3_symbol a2, unsigned a3, Z3_symbol const * a4, Z3_sort const * a5, unsigned const * a6);
|
||||
#define LOG_Z3_mk_constructor(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_constructor(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6); }
|
||||
void log_Z3_del_constructor(Z3_context a0, Z3_constructor a1);
|
||||
#define LOG_Z3_del_constructor(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_del_constructor(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_datatype(Z3_context a0, Z3_symbol a1, unsigned a2, Z3_constructor* a3);
|
||||
#define LOG_Z3_mk_datatype(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; unsigned Z3ARG2; Z3_constructor* Z3ARG3; if (_LOG_CTX.enabled()) { log_Z3_mk_datatype(_ARG0, _ARG1, _ARG2, _ARG3); Z3ARG2 = _ARG2; Z3ARG3 = _ARG3; }
|
||||
#define RETURN_Z3_mk_datatype(Z3RES) if (_LOG_CTX.enabled()) { SetR(Z3RES); for (unsigned i = 0; i < Z3ARG2; i++) { SetAO(Z3ARG3[i], 3, i); } } return Z3RES
|
||||
void log_Z3_mk_constructor_list(Z3_context a0, unsigned a1, Z3_constructor const * a2);
|
||||
#define LOG_Z3_mk_constructor_list(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_constructor_list(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_del_constructor_list(Z3_context a0, Z3_constructor_list a1);
|
||||
#define LOG_Z3_del_constructor_list(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_del_constructor_list(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_datatypes(Z3_context a0, unsigned a1, Z3_symbol const * a2, Z3_sort* a3, Z3_constructor_list* a4);
|
||||
#define LOG_Z3_mk_datatypes(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; unsigned Z3ARG1; Z3_sort* Z3ARG3; Z3_constructor_list* Z3ARG4; if (_LOG_CTX.enabled()) { log_Z3_mk_datatypes(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); Z3ARG1 = _ARG1; Z3ARG3 = _ARG3; Z3ARG4 = _ARG4; }
|
||||
#define RETURN_Z3_mk_datatypes if (_LOG_CTX.enabled()) { for (unsigned i = 0; i < Z3ARG1; i++) { SetAO(Z3ARG3[i], 3, i); } for (unsigned i = 0; i < Z3ARG1; i++) { SetAO(Z3ARG4[i], 4, i); } } return
|
||||
void log_Z3_query_constructor(Z3_context a0, Z3_constructor a1, unsigned a2, Z3_func_decl* a3, Z3_func_decl* a4, Z3_func_decl* a5);
|
||||
#define LOG_Z3_query_constructor(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5) z3_log_ctx _LOG_CTX; Z3_func_decl* Z3ARG3; Z3_func_decl* Z3ARG4; unsigned Z3ARG2; Z3_func_decl* Z3ARG5; if (_LOG_CTX.enabled()) { log_Z3_query_constructor(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5); Z3ARG3 = _ARG3; Z3ARG4 = _ARG4; Z3ARG2 = _ARG2; Z3ARG5 = _ARG5; }
|
||||
#define RETURN_Z3_query_constructor if (_LOG_CTX.enabled()) { SetO((Z3ARG3 == 0 ? 0 : *Z3ARG3), 3); SetO((Z3ARG4 == 0 ? 0 : *Z3ARG4), 4); for (unsigned i = 0; i < Z3ARG2; i++) { SetAO(Z3ARG5[i], 5, i); } } return
|
||||
void log_Z3_mk_func_decl(Z3_context a0, Z3_symbol a1, unsigned a2, Z3_sort const * a3, Z3_sort a4);
|
||||
#define LOG_Z3_mk_func_decl(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_func_decl(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); }
|
||||
void log_Z3_mk_app(Z3_context a0, Z3_func_decl a1, unsigned a2, Z3_ast const * a3);
|
||||
#define LOG_Z3_mk_app(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_app(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_mk_const(Z3_context a0, Z3_symbol a1, Z3_sort a2);
|
||||
#define LOG_Z3_mk_const(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_const(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_fresh_func_decl(Z3_context a0, Z3_string a1, unsigned a2, Z3_sort const * a3, Z3_sort a4);
|
||||
#define LOG_Z3_mk_fresh_func_decl(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_fresh_func_decl(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); }
|
||||
void log_Z3_mk_fresh_const(Z3_context a0, Z3_string a1, Z3_sort a2);
|
||||
#define LOG_Z3_mk_fresh_const(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_fresh_const(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_true(Z3_context a0);
|
||||
#define LOG_Z3_mk_true(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_true(_ARG0); }
|
||||
void log_Z3_mk_false(Z3_context a0);
|
||||
#define LOG_Z3_mk_false(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_false(_ARG0); }
|
||||
void log_Z3_mk_eq(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_eq(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_eq(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_distinct(Z3_context a0, unsigned a1, Z3_ast const * a2);
|
||||
#define LOG_Z3_mk_distinct(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_distinct(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_not(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_not(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_not(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_ite(Z3_context a0, Z3_ast a1, Z3_ast a2, Z3_ast a3);
|
||||
#define LOG_Z3_mk_ite(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_ite(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_mk_iff(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_iff(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_iff(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_implies(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_implies(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_implies(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_xor(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_xor(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_xor(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_and(Z3_context a0, unsigned a1, Z3_ast const * a2);
|
||||
#define LOG_Z3_mk_and(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_and(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_or(Z3_context a0, unsigned a1, Z3_ast const * a2);
|
||||
#define LOG_Z3_mk_or(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_or(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_add(Z3_context a0, unsigned a1, Z3_ast const * a2);
|
||||
#define LOG_Z3_mk_add(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_add(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_mul(Z3_context a0, unsigned a1, Z3_ast const * a2);
|
||||
#define LOG_Z3_mk_mul(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_mul(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_sub(Z3_context a0, unsigned a1, Z3_ast const * a2);
|
||||
#define LOG_Z3_mk_sub(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_sub(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_unary_minus(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_unary_minus(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_unary_minus(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_div(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_div(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_div(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_mod(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_mod(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_mod(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_rem(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_rem(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_rem(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_power(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_power(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_power(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_lt(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_lt(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_lt(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_le(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_le(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_le(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_gt(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_gt(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_gt(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_ge(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_ge(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_ge(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_int2real(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_int2real(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_int2real(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_real2int(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_real2int(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_real2int(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_is_int(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_is_int(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_is_int(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_bvnot(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_bvnot(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvnot(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_bvredand(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_bvredand(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvredand(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_bvredor(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_bvredor(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvredor(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_bvand(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvand(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvand(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvor(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvor(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvor(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvxor(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvxor(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvxor(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvnand(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvnand(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvnand(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvnor(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvnor(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvnor(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvxnor(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvxnor(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvxnor(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvneg(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_bvneg(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvneg(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_bvadd(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvadd(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvadd(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvsub(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvsub(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsub(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvmul(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvmul(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvmul(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvudiv(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvudiv(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvudiv(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvsdiv(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvsdiv(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsdiv(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvurem(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvurem(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvurem(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvsrem(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvsrem(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsrem(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvsmod(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvsmod(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsmod(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvult(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvult(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvult(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvslt(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvslt(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvslt(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvule(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvule(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvule(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvsle(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvsle(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsle(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvuge(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvuge(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvuge(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvsge(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvsge(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsge(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvugt(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvugt(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvugt(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvsgt(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvsgt(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsgt(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_concat(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_concat(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_concat(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_extract(Z3_context a0, unsigned a1, unsigned a2, Z3_ast a3);
|
||||
#define LOG_Z3_mk_extract(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_extract(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_mk_sign_ext(Z3_context a0, unsigned a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_sign_ext(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_sign_ext(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_zero_ext(Z3_context a0, unsigned a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_zero_ext(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_zero_ext(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_repeat(Z3_context a0, unsigned a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_repeat(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_repeat(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvshl(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvshl(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvshl(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvlshr(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvlshr(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvlshr(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvashr(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvashr(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvashr(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_rotate_left(Z3_context a0, unsigned a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_rotate_left(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_rotate_left(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_rotate_right(Z3_context a0, unsigned a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_rotate_right(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_rotate_right(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_ext_rotate_left(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_ext_rotate_left(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_ext_rotate_left(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_ext_rotate_right(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_ext_rotate_right(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_ext_rotate_right(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_int2bv(Z3_context a0, unsigned a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_int2bv(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_int2bv(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bv2int(Z3_context a0, Z3_ast a1, Z3_bool a2);
|
||||
#define LOG_Z3_mk_bv2int(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bv2int(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvadd_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2, Z3_bool a3);
|
||||
#define LOG_Z3_mk_bvadd_no_overflow(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvadd_no_overflow(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_mk_bvadd_no_underflow(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvadd_no_underflow(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvadd_no_underflow(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvsub_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvsub_no_overflow(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsub_no_overflow(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvsub_no_underflow(Z3_context a0, Z3_ast a1, Z3_ast a2, Z3_bool a3);
|
||||
#define LOG_Z3_mk_bvsub_no_underflow(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsub_no_underflow(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_mk_bvsdiv_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvsdiv_no_overflow(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvsdiv_no_overflow(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bvneg_no_overflow(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_bvneg_no_overflow(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvneg_no_overflow(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_bvmul_no_overflow(Z3_context a0, Z3_ast a1, Z3_ast a2, Z3_bool a3);
|
||||
#define LOG_Z3_mk_bvmul_no_overflow(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvmul_no_overflow(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_mk_bvmul_no_underflow(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_bvmul_no_underflow(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bvmul_no_underflow(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_select(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_select(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_select(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_store(Z3_context a0, Z3_ast a1, Z3_ast a2, Z3_ast a3);
|
||||
#define LOG_Z3_mk_store(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_store(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_mk_const_array(Z3_context a0, Z3_sort a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_const_array(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_const_array(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_map(Z3_context a0, Z3_func_decl a1, unsigned a2, Z3_ast const * a3);
|
||||
#define LOG_Z3_mk_map(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_map(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_mk_array_default(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_array_default(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_array_default(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_set_sort(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_mk_set_sort(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_set_sort(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_empty_set(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_mk_empty_set(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_empty_set(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_full_set(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_mk_full_set(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_full_set(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_set_add(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_set_add(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_set_add(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_set_del(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_set_del(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_set_del(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_set_union(Z3_context a0, unsigned a1, Z3_ast const * a2);
|
||||
#define LOG_Z3_mk_set_union(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_set_union(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_set_intersect(Z3_context a0, unsigned a1, Z3_ast const * a2);
|
||||
#define LOG_Z3_mk_set_intersect(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_set_intersect(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_set_difference(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_set_difference(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_set_difference(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_set_complement(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_mk_set_complement(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_set_complement(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_set_member(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_set_member(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_set_member(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_set_subset(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_mk_set_subset(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_set_subset(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_numeral(Z3_context a0, Z3_string a1, Z3_sort a2);
|
||||
#define LOG_Z3_mk_numeral(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_numeral(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_real(Z3_context a0, int a1, int a2);
|
||||
#define LOG_Z3_mk_real(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_real(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_int(Z3_context a0, int a1, Z3_sort a2);
|
||||
#define LOG_Z3_mk_int(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_int(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_unsigned_int(Z3_context a0, unsigned a1, Z3_sort a2);
|
||||
#define LOG_Z3_mk_unsigned_int(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_unsigned_int(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_int64(Z3_context a0, __int64 a1, Z3_sort a2);
|
||||
#define LOG_Z3_mk_int64(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_int64(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_unsigned_int64(Z3_context a0, __uint64 a1, Z3_sort a2);
|
||||
#define LOG_Z3_mk_unsigned_int64(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_unsigned_int64(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_pattern(Z3_context a0, unsigned a1, Z3_ast const * a2);
|
||||
#define LOG_Z3_mk_pattern(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_pattern(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_bound(Z3_context a0, unsigned a1, Z3_sort a2);
|
||||
#define LOG_Z3_mk_bound(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_bound(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_forall(Z3_context a0, unsigned a1, unsigned a2, Z3_pattern const * a3, unsigned a4, Z3_sort const * a5, Z3_symbol const * a6, Z3_ast a7);
|
||||
#define LOG_Z3_mk_forall(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_forall(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7); }
|
||||
void log_Z3_mk_exists(Z3_context a0, unsigned a1, unsigned a2, Z3_pattern const * a3, unsigned a4, Z3_sort const * a5, Z3_symbol const * a6, Z3_ast a7);
|
||||
#define LOG_Z3_mk_exists(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_exists(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7); }
|
||||
void log_Z3_mk_quantifier(Z3_context a0, Z3_bool a1, unsigned a2, unsigned a3, Z3_pattern const * a4, unsigned a5, Z3_sort const * a6, Z3_symbol const * a7, Z3_ast a8);
|
||||
#define LOG_Z3_mk_quantifier(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7, _ARG8) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_quantifier(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7, _ARG8); }
|
||||
void log_Z3_mk_quantifier_ex(Z3_context a0, Z3_bool a1, unsigned a2, Z3_symbol a3, Z3_symbol a4, unsigned a5, Z3_pattern const * a6, unsigned a7, Z3_ast const * a8, unsigned a9, Z3_sort const * a10, Z3_symbol const * a11, Z3_ast a12);
|
||||
#define LOG_Z3_mk_quantifier_ex(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7, _ARG8, _ARG9, _ARG10, _ARG11, _ARG12) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_quantifier_ex(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7, _ARG8, _ARG9, _ARG10, _ARG11, _ARG12); }
|
||||
void log_Z3_mk_forall_const(Z3_context a0, unsigned a1, unsigned a2, Z3_app const * a3, unsigned a4, Z3_pattern const * a5, Z3_ast a6);
|
||||
#define LOG_Z3_mk_forall_const(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_forall_const(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6); }
|
||||
void log_Z3_mk_exists_const(Z3_context a0, unsigned a1, unsigned a2, Z3_app const * a3, unsigned a4, Z3_pattern const * a5, Z3_ast a6);
|
||||
#define LOG_Z3_mk_exists_const(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_exists_const(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6); }
|
||||
void log_Z3_mk_quantifier_const(Z3_context a0, Z3_bool a1, unsigned a2, unsigned a3, Z3_app const * a4, unsigned a5, Z3_pattern const * a6, Z3_ast a7);
|
||||
#define LOG_Z3_mk_quantifier_const(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_quantifier_const(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7); }
|
||||
void log_Z3_mk_quantifier_const_ex(Z3_context a0, Z3_bool a1, unsigned a2, Z3_symbol a3, Z3_symbol a4, unsigned a5, Z3_app const * a6, unsigned a7, Z3_pattern const * a8, unsigned a9, Z3_ast const * a10, Z3_ast a11);
|
||||
#define LOG_Z3_mk_quantifier_const_ex(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7, _ARG8, _ARG9, _ARG10, _ARG11) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_quantifier_const_ex(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7, _ARG8, _ARG9, _ARG10, _ARG11); }
|
||||
void log_Z3_get_symbol_kind(Z3_context a0, Z3_symbol a1);
|
||||
#define LOG_Z3_get_symbol_kind(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_symbol_kind(_ARG0, _ARG1); }
|
||||
void log_Z3_get_symbol_int(Z3_context a0, Z3_symbol a1);
|
||||
#define LOG_Z3_get_symbol_int(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_symbol_int(_ARG0, _ARG1); }
|
||||
void log_Z3_get_symbol_string(Z3_context a0, Z3_symbol a1);
|
||||
#define LOG_Z3_get_symbol_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_symbol_string(_ARG0, _ARG1); }
|
||||
void log_Z3_get_sort_name(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_sort_name(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_sort_name(_ARG0, _ARG1); }
|
||||
void log_Z3_get_sort_id(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_sort_id(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_sort_id(_ARG0, _ARG1); }
|
||||
void log_Z3_sort_to_ast(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_sort_to_ast(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_sort_to_ast(_ARG0, _ARG1); }
|
||||
void log_Z3_is_eq_sort(Z3_context a0, Z3_sort a1, Z3_sort a2);
|
||||
#define LOG_Z3_is_eq_sort(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_eq_sort(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_sort_kind(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_sort_kind(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_sort_kind(_ARG0, _ARG1); }
|
||||
void log_Z3_get_bv_sort_size(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_bv_sort_size(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_bv_sort_size(_ARG0, _ARG1); }
|
||||
void log_Z3_get_finite_domain_sort_size(Z3_context a0, Z3_sort a1, __uint64* a2);
|
||||
#define LOG_Z3_get_finite_domain_sort_size(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_finite_domain_sort_size(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_array_sort_domain(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_array_sort_domain(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_array_sort_domain(_ARG0, _ARG1); }
|
||||
void log_Z3_get_array_sort_range(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_array_sort_range(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_array_sort_range(_ARG0, _ARG1); }
|
||||
void log_Z3_get_tuple_sort_mk_decl(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_tuple_sort_mk_decl(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_tuple_sort_mk_decl(_ARG0, _ARG1); }
|
||||
void log_Z3_get_tuple_sort_num_fields(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_tuple_sort_num_fields(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_tuple_sort_num_fields(_ARG0, _ARG1); }
|
||||
void log_Z3_get_tuple_sort_field_decl(Z3_context a0, Z3_sort a1, unsigned a2);
|
||||
#define LOG_Z3_get_tuple_sort_field_decl(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_tuple_sort_field_decl(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_datatype_sort_num_constructors(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_datatype_sort_num_constructors(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_datatype_sort_num_constructors(_ARG0, _ARG1); }
|
||||
void log_Z3_get_datatype_sort_constructor(Z3_context a0, Z3_sort a1, unsigned a2);
|
||||
#define LOG_Z3_get_datatype_sort_constructor(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_datatype_sort_constructor(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_datatype_sort_recognizer(Z3_context a0, Z3_sort a1, unsigned a2);
|
||||
#define LOG_Z3_get_datatype_sort_recognizer(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_datatype_sort_recognizer(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_datatype_sort_constructor_accessor(Z3_context a0, Z3_sort a1, unsigned a2, unsigned a3);
|
||||
#define LOG_Z3_get_datatype_sort_constructor_accessor(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_datatype_sort_constructor_accessor(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_get_relation_arity(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_get_relation_arity(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_relation_arity(_ARG0, _ARG1); }
|
||||
void log_Z3_get_relation_column(Z3_context a0, Z3_sort a1, unsigned a2);
|
||||
#define LOG_Z3_get_relation_column(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_relation_column(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_func_decl_to_ast(Z3_context a0, Z3_func_decl a1);
|
||||
#define LOG_Z3_func_decl_to_ast(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_decl_to_ast(_ARG0, _ARG1); }
|
||||
void log_Z3_is_eq_func_decl(Z3_context a0, Z3_func_decl a1, Z3_func_decl a2);
|
||||
#define LOG_Z3_is_eq_func_decl(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_eq_func_decl(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_func_decl_id(Z3_context a0, Z3_func_decl a1);
|
||||
#define LOG_Z3_get_func_decl_id(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_func_decl_id(_ARG0, _ARG1); }
|
||||
void log_Z3_get_decl_name(Z3_context a0, Z3_func_decl a1);
|
||||
#define LOG_Z3_get_decl_name(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_name(_ARG0, _ARG1); }
|
||||
void log_Z3_get_decl_kind(Z3_context a0, Z3_func_decl a1);
|
||||
#define LOG_Z3_get_decl_kind(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_kind(_ARG0, _ARG1); }
|
||||
void log_Z3_get_domain_size(Z3_context a0, Z3_func_decl a1);
|
||||
#define LOG_Z3_get_domain_size(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_domain_size(_ARG0, _ARG1); }
|
||||
void log_Z3_get_arity(Z3_context a0, Z3_func_decl a1);
|
||||
#define LOG_Z3_get_arity(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_arity(_ARG0, _ARG1); }
|
||||
void log_Z3_get_domain(Z3_context a0, Z3_func_decl a1, unsigned a2);
|
||||
#define LOG_Z3_get_domain(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_domain(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_range(Z3_context a0, Z3_func_decl a1);
|
||||
#define LOG_Z3_get_range(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_range(_ARG0, _ARG1); }
|
||||
void log_Z3_get_decl_num_parameters(Z3_context a0, Z3_func_decl a1);
|
||||
#define LOG_Z3_get_decl_num_parameters(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_num_parameters(_ARG0, _ARG1); }
|
||||
void log_Z3_get_decl_parameter_kind(Z3_context a0, Z3_func_decl a1, unsigned a2);
|
||||
#define LOG_Z3_get_decl_parameter_kind(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_parameter_kind(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_decl_int_parameter(Z3_context a0, Z3_func_decl a1, unsigned a2);
|
||||
#define LOG_Z3_get_decl_int_parameter(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_int_parameter(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_decl_double_parameter(Z3_context a0, Z3_func_decl a1, unsigned a2);
|
||||
#define LOG_Z3_get_decl_double_parameter(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_double_parameter(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_decl_symbol_parameter(Z3_context a0, Z3_func_decl a1, unsigned a2);
|
||||
#define LOG_Z3_get_decl_symbol_parameter(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_symbol_parameter(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_decl_sort_parameter(Z3_context a0, Z3_func_decl a1, unsigned a2);
|
||||
#define LOG_Z3_get_decl_sort_parameter(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_sort_parameter(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_decl_ast_parameter(Z3_context a0, Z3_func_decl a1, unsigned a2);
|
||||
#define LOG_Z3_get_decl_ast_parameter(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_ast_parameter(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_decl_func_decl_parameter(Z3_context a0, Z3_func_decl a1, unsigned a2);
|
||||
#define LOG_Z3_get_decl_func_decl_parameter(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_func_decl_parameter(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_decl_rational_parameter(Z3_context a0, Z3_func_decl a1, unsigned a2);
|
||||
#define LOG_Z3_get_decl_rational_parameter(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_decl_rational_parameter(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_app_to_ast(Z3_context a0, Z3_app a1);
|
||||
#define LOG_Z3_app_to_ast(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_app_to_ast(_ARG0, _ARG1); }
|
||||
void log_Z3_get_app_decl(Z3_context a0, Z3_app a1);
|
||||
#define LOG_Z3_get_app_decl(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_app_decl(_ARG0, _ARG1); }
|
||||
void log_Z3_get_app_num_args(Z3_context a0, Z3_app a1);
|
||||
#define LOG_Z3_get_app_num_args(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_app_num_args(_ARG0, _ARG1); }
|
||||
void log_Z3_get_app_arg(Z3_context a0, Z3_app a1, unsigned a2);
|
||||
#define LOG_Z3_get_app_arg(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_app_arg(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_is_eq_ast(Z3_context a0, Z3_ast a1, Z3_ast a2);
|
||||
#define LOG_Z3_is_eq_ast(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_eq_ast(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_ast_id(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_ast_id(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_ast_id(_ARG0, _ARG1); }
|
||||
void log_Z3_get_ast_hash(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_ast_hash(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_ast_hash(_ARG0, _ARG1); }
|
||||
void log_Z3_get_sort(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_sort(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_sort(_ARG0, _ARG1); }
|
||||
void log_Z3_is_well_sorted(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_is_well_sorted(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_well_sorted(_ARG0, _ARG1); }
|
||||
void log_Z3_get_bool_value(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_bool_value(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_bool_value(_ARG0, _ARG1); }
|
||||
void log_Z3_get_ast_kind(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_ast_kind(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_ast_kind(_ARG0, _ARG1); }
|
||||
void log_Z3_is_app(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_is_app(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_app(_ARG0, _ARG1); }
|
||||
void log_Z3_is_numeral_ast(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_is_numeral_ast(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_numeral_ast(_ARG0, _ARG1); }
|
||||
void log_Z3_is_algebraic_number(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_is_algebraic_number(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_algebraic_number(_ARG0, _ARG1); }
|
||||
void log_Z3_to_app(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_to_app(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_to_app(_ARG0, _ARG1); }
|
||||
void log_Z3_to_func_decl(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_to_func_decl(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_to_func_decl(_ARG0, _ARG1); }
|
||||
void log_Z3_get_numeral_string(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_numeral_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_numeral_string(_ARG0, _ARG1); }
|
||||
void log_Z3_get_numeral_decimal_string(Z3_context a0, Z3_ast a1, unsigned a2);
|
||||
#define LOG_Z3_get_numeral_decimal_string(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_numeral_decimal_string(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_numerator(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_numerator(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_numerator(_ARG0, _ARG1); }
|
||||
void log_Z3_get_denominator(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_denominator(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_denominator(_ARG0, _ARG1); }
|
||||
void log_Z3_get_numeral_small(Z3_context a0, Z3_ast a1, __int64* a2, __int64* a3);
|
||||
#define LOG_Z3_get_numeral_small(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_numeral_small(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_get_numeral_int(Z3_context a0, Z3_ast a1, int* a2);
|
||||
#define LOG_Z3_get_numeral_int(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_numeral_int(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_numeral_uint(Z3_context a0, Z3_ast a1, unsigned* a2);
|
||||
#define LOG_Z3_get_numeral_uint(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_numeral_uint(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_numeral_uint64(Z3_context a0, Z3_ast a1, __uint64* a2);
|
||||
#define LOG_Z3_get_numeral_uint64(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_numeral_uint64(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_numeral_int64(Z3_context a0, Z3_ast a1, __int64* a2);
|
||||
#define LOG_Z3_get_numeral_int64(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_numeral_int64(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_numeral_rational_int64(Z3_context a0, Z3_ast a1, __int64* a2, __int64* a3);
|
||||
#define LOG_Z3_get_numeral_rational_int64(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_numeral_rational_int64(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_get_algebraic_number_lower(Z3_context a0, Z3_ast a1, unsigned a2);
|
||||
#define LOG_Z3_get_algebraic_number_lower(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_algebraic_number_lower(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_algebraic_number_upper(Z3_context a0, Z3_ast a1, unsigned a2);
|
||||
#define LOG_Z3_get_algebraic_number_upper(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_algebraic_number_upper(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_pattern_to_ast(Z3_context a0, Z3_pattern a1);
|
||||
#define LOG_Z3_pattern_to_ast(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_pattern_to_ast(_ARG0, _ARG1); }
|
||||
void log_Z3_get_pattern_num_terms(Z3_context a0, Z3_pattern a1);
|
||||
#define LOG_Z3_get_pattern_num_terms(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_pattern_num_terms(_ARG0, _ARG1); }
|
||||
void log_Z3_get_pattern(Z3_context a0, Z3_pattern a1, unsigned a2);
|
||||
#define LOG_Z3_get_pattern(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_pattern(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_index_value(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_index_value(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_index_value(_ARG0, _ARG1); }
|
||||
void log_Z3_is_quantifier_forall(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_is_quantifier_forall(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_quantifier_forall(_ARG0, _ARG1); }
|
||||
void log_Z3_get_quantifier_weight(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_quantifier_weight(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_quantifier_weight(_ARG0, _ARG1); }
|
||||
void log_Z3_get_quantifier_num_patterns(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_quantifier_num_patterns(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_quantifier_num_patterns(_ARG0, _ARG1); }
|
||||
void log_Z3_get_quantifier_pattern_ast(Z3_context a0, Z3_ast a1, unsigned a2);
|
||||
#define LOG_Z3_get_quantifier_pattern_ast(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_quantifier_pattern_ast(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_quantifier_num_no_patterns(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_quantifier_num_no_patterns(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_quantifier_num_no_patterns(_ARG0, _ARG1); }
|
||||
void log_Z3_get_quantifier_no_pattern_ast(Z3_context a0, Z3_ast a1, unsigned a2);
|
||||
#define LOG_Z3_get_quantifier_no_pattern_ast(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_quantifier_no_pattern_ast(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_quantifier_num_bound(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_quantifier_num_bound(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_quantifier_num_bound(_ARG0, _ARG1); }
|
||||
void log_Z3_get_quantifier_bound_name(Z3_context a0, Z3_ast a1, unsigned a2);
|
||||
#define LOG_Z3_get_quantifier_bound_name(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_quantifier_bound_name(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_quantifier_bound_sort(Z3_context a0, Z3_ast a1, unsigned a2);
|
||||
#define LOG_Z3_get_quantifier_bound_sort(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_quantifier_bound_sort(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_quantifier_body(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_quantifier_body(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_quantifier_body(_ARG0, _ARG1); }
|
||||
void log_Z3_simplify(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_simplify(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_simplify(_ARG0, _ARG1); }
|
||||
void log_Z3_simplify_ex(Z3_context a0, Z3_ast a1, Z3_params a2);
|
||||
#define LOG_Z3_simplify_ex(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_simplify_ex(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_simplify_get_help(Z3_context a0);
|
||||
#define LOG_Z3_simplify_get_help(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_simplify_get_help(_ARG0); }
|
||||
void log_Z3_simplify_get_param_descrs(Z3_context a0);
|
||||
#define LOG_Z3_simplify_get_param_descrs(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_simplify_get_param_descrs(_ARG0); }
|
||||
void log_Z3_update_term(Z3_context a0, Z3_ast a1, unsigned a2, Z3_ast const * a3);
|
||||
#define LOG_Z3_update_term(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_update_term(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_substitute(Z3_context a0, Z3_ast a1, unsigned a2, Z3_ast const * a3, Z3_ast const * a4);
|
||||
#define LOG_Z3_substitute(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_substitute(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); }
|
||||
void log_Z3_substitute_vars(Z3_context a0, Z3_ast a1, unsigned a2, Z3_ast const * a3);
|
||||
#define LOG_Z3_substitute_vars(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_substitute_vars(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_translate(Z3_context a0, Z3_ast a1, Z3_context a2);
|
||||
#define LOG_Z3_translate(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_translate(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_model_inc_ref(Z3_context a0, Z3_model a1);
|
||||
#define LOG_Z3_model_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_model_dec_ref(Z3_context a0, Z3_model a1);
|
||||
#define LOG_Z3_model_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_model_eval(Z3_context a0, Z3_model a1, Z3_ast a2, Z3_bool a3, Z3_ast* a4);
|
||||
#define LOG_Z3_model_eval(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; Z3_ast* Z3ARG4; if (_LOG_CTX.enabled()) { log_Z3_model_eval(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); Z3ARG4 = _ARG4; }
|
||||
#define RETURN_Z3_model_eval if (_LOG_CTX.enabled()) { SetO((Z3ARG4 == 0 ? 0 : *Z3ARG4), 4); } return
|
||||
void log_Z3_model_get_const_interp(Z3_context a0, Z3_model a1, Z3_func_decl a2);
|
||||
#define LOG_Z3_model_get_const_interp(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_get_const_interp(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_model_get_func_interp(Z3_context a0, Z3_model a1, Z3_func_decl a2);
|
||||
#define LOG_Z3_model_get_func_interp(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_get_func_interp(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_model_get_num_consts(Z3_context a0, Z3_model a1);
|
||||
#define LOG_Z3_model_get_num_consts(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_get_num_consts(_ARG0, _ARG1); }
|
||||
void log_Z3_model_get_const_decl(Z3_context a0, Z3_model a1, unsigned a2);
|
||||
#define LOG_Z3_model_get_const_decl(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_get_const_decl(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_model_get_num_funcs(Z3_context a0, Z3_model a1);
|
||||
#define LOG_Z3_model_get_num_funcs(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_get_num_funcs(_ARG0, _ARG1); }
|
||||
void log_Z3_model_get_func_decl(Z3_context a0, Z3_model a1, unsigned a2);
|
||||
#define LOG_Z3_model_get_func_decl(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_get_func_decl(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_model_get_num_sorts(Z3_context a0, Z3_model a1);
|
||||
#define LOG_Z3_model_get_num_sorts(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_get_num_sorts(_ARG0, _ARG1); }
|
||||
void log_Z3_model_get_sort(Z3_context a0, Z3_model a1, unsigned a2);
|
||||
#define LOG_Z3_model_get_sort(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_get_sort(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_model_get_sort_universe(Z3_context a0, Z3_model a1, Z3_sort a2);
|
||||
#define LOG_Z3_model_get_sort_universe(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_get_sort_universe(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_is_as_array(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_is_as_array(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_as_array(_ARG0, _ARG1); }
|
||||
void log_Z3_get_as_array_func_decl(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_get_as_array_func_decl(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_as_array_func_decl(_ARG0, _ARG1); }
|
||||
void log_Z3_func_interp_inc_ref(Z3_context a0, Z3_func_interp a1);
|
||||
#define LOG_Z3_func_interp_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_interp_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_func_interp_dec_ref(Z3_context a0, Z3_func_interp a1);
|
||||
#define LOG_Z3_func_interp_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_interp_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_func_interp_get_num_entries(Z3_context a0, Z3_func_interp a1);
|
||||
#define LOG_Z3_func_interp_get_num_entries(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_interp_get_num_entries(_ARG0, _ARG1); }
|
||||
void log_Z3_func_interp_get_entry(Z3_context a0, Z3_func_interp a1, unsigned a2);
|
||||
#define LOG_Z3_func_interp_get_entry(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_interp_get_entry(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_func_interp_get_else(Z3_context a0, Z3_func_interp a1);
|
||||
#define LOG_Z3_func_interp_get_else(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_interp_get_else(_ARG0, _ARG1); }
|
||||
void log_Z3_func_interp_get_arity(Z3_context a0, Z3_func_interp a1);
|
||||
#define LOG_Z3_func_interp_get_arity(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_interp_get_arity(_ARG0, _ARG1); }
|
||||
void log_Z3_func_entry_inc_ref(Z3_context a0, Z3_func_entry a1);
|
||||
#define LOG_Z3_func_entry_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_entry_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_func_entry_dec_ref(Z3_context a0, Z3_func_entry a1);
|
||||
#define LOG_Z3_func_entry_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_entry_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_func_entry_get_value(Z3_context a0, Z3_func_entry a1);
|
||||
#define LOG_Z3_func_entry_get_value(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_entry_get_value(_ARG0, _ARG1); }
|
||||
void log_Z3_func_entry_get_num_args(Z3_context a0, Z3_func_entry a1);
|
||||
#define LOG_Z3_func_entry_get_num_args(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_entry_get_num_args(_ARG0, _ARG1); }
|
||||
void log_Z3_func_entry_get_arg(Z3_context a0, Z3_func_entry a1, unsigned a2);
|
||||
#define LOG_Z3_func_entry_get_arg(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_entry_get_arg(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_toggle_warning_messages(Z3_bool a0);
|
||||
#define LOG_Z3_toggle_warning_messages(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_toggle_warning_messages(_ARG0); }
|
||||
void log_Z3_set_ast_print_mode(Z3_context a0, Z3_ast_print_mode a1);
|
||||
#define LOG_Z3_set_ast_print_mode(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_set_ast_print_mode(_ARG0, _ARG1); }
|
||||
void log_Z3_ast_to_string(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_ast_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_pattern_to_string(Z3_context a0, Z3_pattern a1);
|
||||
#define LOG_Z3_pattern_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_pattern_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_sort_to_string(Z3_context a0, Z3_sort a1);
|
||||
#define LOG_Z3_sort_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_sort_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_func_decl_to_string(Z3_context a0, Z3_func_decl a1);
|
||||
#define LOG_Z3_func_decl_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_func_decl_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_model_to_string(Z3_context a0, Z3_model a1);
|
||||
#define LOG_Z3_model_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_model_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_benchmark_to_smtlib_string(Z3_context a0, Z3_string a1, Z3_string a2, Z3_string a3, Z3_string a4, unsigned a5, Z3_ast const * a6, Z3_ast a7);
|
||||
#define LOG_Z3_benchmark_to_smtlib_string(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_benchmark_to_smtlib_string(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7); }
|
||||
void log_Z3_parse_smtlib2_string(Z3_context a0, Z3_string a1, unsigned a2, Z3_symbol const * a3, Z3_sort const * a4, unsigned a5, Z3_symbol const * a6, Z3_func_decl const * a7);
|
||||
#define LOG_Z3_parse_smtlib2_string(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_parse_smtlib2_string(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7); }
|
||||
void log_Z3_parse_smtlib2_file(Z3_context a0, Z3_string a1, unsigned a2, Z3_symbol const * a3, Z3_sort const * a4, unsigned a5, Z3_symbol const * a6, Z3_func_decl const * a7);
|
||||
#define LOG_Z3_parse_smtlib2_file(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_parse_smtlib2_file(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7); }
|
||||
void log_Z3_parse_smtlib_string(Z3_context a0, Z3_string a1, unsigned a2, Z3_symbol const * a3, Z3_sort const * a4, unsigned a5, Z3_symbol const * a6, Z3_func_decl const * a7);
|
||||
#define LOG_Z3_parse_smtlib_string(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_parse_smtlib_string(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7); }
|
||||
void log_Z3_parse_smtlib_file(Z3_context a0, Z3_string a1, unsigned a2, Z3_symbol const * a3, Z3_sort const * a4, unsigned a5, Z3_symbol const * a6, Z3_func_decl const * a7);
|
||||
#define LOG_Z3_parse_smtlib_file(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_parse_smtlib_file(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6, _ARG7); }
|
||||
void log_Z3_get_smtlib_num_formulas(Z3_context a0);
|
||||
#define LOG_Z3_get_smtlib_num_formulas(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_smtlib_num_formulas(_ARG0); }
|
||||
void log_Z3_get_smtlib_formula(Z3_context a0, unsigned a1);
|
||||
#define LOG_Z3_get_smtlib_formula(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_smtlib_formula(_ARG0, _ARG1); }
|
||||
void log_Z3_get_smtlib_num_assumptions(Z3_context a0);
|
||||
#define LOG_Z3_get_smtlib_num_assumptions(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_smtlib_num_assumptions(_ARG0); }
|
||||
void log_Z3_get_smtlib_assumption(Z3_context a0, unsigned a1);
|
||||
#define LOG_Z3_get_smtlib_assumption(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_smtlib_assumption(_ARG0, _ARG1); }
|
||||
void log_Z3_get_smtlib_num_decls(Z3_context a0);
|
||||
#define LOG_Z3_get_smtlib_num_decls(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_smtlib_num_decls(_ARG0); }
|
||||
void log_Z3_get_smtlib_decl(Z3_context a0, unsigned a1);
|
||||
#define LOG_Z3_get_smtlib_decl(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_smtlib_decl(_ARG0, _ARG1); }
|
||||
void log_Z3_get_smtlib_num_sorts(Z3_context a0);
|
||||
#define LOG_Z3_get_smtlib_num_sorts(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_smtlib_num_sorts(_ARG0); }
|
||||
void log_Z3_get_smtlib_sort(Z3_context a0, unsigned a1);
|
||||
#define LOG_Z3_get_smtlib_sort(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_smtlib_sort(_ARG0, _ARG1); }
|
||||
void log_Z3_get_smtlib_error(Z3_context a0);
|
||||
#define LOG_Z3_get_smtlib_error(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_smtlib_error(_ARG0); }
|
||||
void log_Z3_parse_z3_string(Z3_context a0, Z3_string a1);
|
||||
#define LOG_Z3_parse_z3_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_parse_z3_string(_ARG0, _ARG1); }
|
||||
void log_Z3_parse_z3_file(Z3_context a0, Z3_string a1);
|
||||
#define LOG_Z3_parse_z3_file(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_parse_z3_file(_ARG0, _ARG1); }
|
||||
void log_Z3_get_error_code(Z3_context a0);
|
||||
#define LOG_Z3_get_error_code(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_error_code(_ARG0); }
|
||||
void log_Z3_set_error(Z3_context a0, Z3_error_code a1);
|
||||
#define LOG_Z3_set_error(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_set_error(_ARG0, _ARG1); }
|
||||
void log_Z3_get_error_msg(Z3_error_code a0);
|
||||
#define LOG_Z3_get_error_msg(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_error_msg(_ARG0); }
|
||||
void log_Z3_get_error_msg_ex(Z3_context a0, Z3_error_code a1);
|
||||
#define LOG_Z3_get_error_msg_ex(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_error_msg_ex(_ARG0, _ARG1); }
|
||||
void log_Z3_get_version(unsigned* a0, unsigned* a1, unsigned* a2, unsigned* a3);
|
||||
#define LOG_Z3_get_version(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_version(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_reset_memory();
|
||||
#define LOG_Z3_reset_memory() z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_reset_memory(); }
|
||||
void log_Z3_mk_fixedpoint(Z3_context a0);
|
||||
#define LOG_Z3_mk_fixedpoint(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_fixedpoint(_ARG0); }
|
||||
void log_Z3_fixedpoint_inc_ref(Z3_context a0, Z3_fixedpoint a1);
|
||||
#define LOG_Z3_fixedpoint_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_fixedpoint_dec_ref(Z3_context a0, Z3_fixedpoint a1);
|
||||
#define LOG_Z3_fixedpoint_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_fixedpoint_add_rule(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2, Z3_symbol a3);
|
||||
#define LOG_Z3_fixedpoint_add_rule(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_add_rule(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_fixedpoint_add_fact(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2, unsigned a3, unsigned const * a4);
|
||||
#define LOG_Z3_fixedpoint_add_fact(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_add_fact(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); }
|
||||
void log_Z3_fixedpoint_assert(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2);
|
||||
#define LOG_Z3_fixedpoint_assert(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_assert(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_fixedpoint_query(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2);
|
||||
#define LOG_Z3_fixedpoint_query(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_query(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_fixedpoint_query_relations(Z3_context a0, Z3_fixedpoint a1, unsigned a2, Z3_func_decl const * a3);
|
||||
#define LOG_Z3_fixedpoint_query_relations(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_query_relations(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_fixedpoint_get_answer(Z3_context a0, Z3_fixedpoint a1);
|
||||
#define LOG_Z3_fixedpoint_get_answer(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_get_answer(_ARG0, _ARG1); }
|
||||
void log_Z3_fixedpoint_get_reason_unknown(Z3_context a0, Z3_fixedpoint a1);
|
||||
#define LOG_Z3_fixedpoint_get_reason_unknown(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_get_reason_unknown(_ARG0, _ARG1); }
|
||||
void log_Z3_fixedpoint_update_rule(Z3_context a0, Z3_fixedpoint a1, Z3_ast a2, Z3_symbol a3);
|
||||
#define LOG_Z3_fixedpoint_update_rule(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_update_rule(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_fixedpoint_get_num_levels(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2);
|
||||
#define LOG_Z3_fixedpoint_get_num_levels(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_get_num_levels(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_fixedpoint_get_cover_delta(Z3_context a0, Z3_fixedpoint a1, int a2, Z3_func_decl a3);
|
||||
#define LOG_Z3_fixedpoint_get_cover_delta(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_get_cover_delta(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_fixedpoint_add_cover(Z3_context a0, Z3_fixedpoint a1, int a2, Z3_func_decl a3, Z3_ast a4);
|
||||
#define LOG_Z3_fixedpoint_add_cover(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_add_cover(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); }
|
||||
void log_Z3_fixedpoint_get_statistics(Z3_context a0, Z3_fixedpoint a1);
|
||||
#define LOG_Z3_fixedpoint_get_statistics(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_get_statistics(_ARG0, _ARG1); }
|
||||
void log_Z3_fixedpoint_register_relation(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2);
|
||||
#define LOG_Z3_fixedpoint_register_relation(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_register_relation(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_fixedpoint_set_predicate_representation(Z3_context a0, Z3_fixedpoint a1, Z3_func_decl a2, unsigned a3, Z3_symbol const * a4);
|
||||
#define LOG_Z3_fixedpoint_set_predicate_representation(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_set_predicate_representation(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); }
|
||||
void log_Z3_fixedpoint_simplify_rules(Z3_context a0, Z3_fixedpoint a1, unsigned a2, Z3_ast const * a3, unsigned a4, Z3_func_decl const * a5);
|
||||
#define LOG_Z3_fixedpoint_simplify_rules(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_simplify_rules(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5); }
|
||||
void log_Z3_fixedpoint_set_params(Z3_context a0, Z3_fixedpoint a1, Z3_params a2);
|
||||
#define LOG_Z3_fixedpoint_set_params(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_set_params(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_fixedpoint_get_help(Z3_context a0, Z3_fixedpoint a1);
|
||||
#define LOG_Z3_fixedpoint_get_help(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_get_help(_ARG0, _ARG1); }
|
||||
void log_Z3_fixedpoint_get_param_descrs(Z3_context a0, Z3_fixedpoint a1);
|
||||
#define LOG_Z3_fixedpoint_get_param_descrs(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_get_param_descrs(_ARG0, _ARG1); }
|
||||
void log_Z3_fixedpoint_to_string(Z3_context a0, Z3_fixedpoint a1, unsigned a2, Z3_ast const * a3);
|
||||
#define LOG_Z3_fixedpoint_to_string(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_to_string(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_fixedpoint_push(Z3_context a0, Z3_fixedpoint a1);
|
||||
#define LOG_Z3_fixedpoint_push(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_push(_ARG0, _ARG1); }
|
||||
void log_Z3_fixedpoint_pop(Z3_context a0, Z3_fixedpoint a1);
|
||||
#define LOG_Z3_fixedpoint_pop(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_fixedpoint_pop(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_ast_vector(Z3_context a0);
|
||||
#define LOG_Z3_mk_ast_vector(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_ast_vector(_ARG0); }
|
||||
void log_Z3_ast_vector_inc_ref(Z3_context a0, Z3_ast_vector a1);
|
||||
#define LOG_Z3_ast_vector_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_vector_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_ast_vector_dec_ref(Z3_context a0, Z3_ast_vector a1);
|
||||
#define LOG_Z3_ast_vector_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_vector_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_ast_vector_size(Z3_context a0, Z3_ast_vector a1);
|
||||
#define LOG_Z3_ast_vector_size(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_vector_size(_ARG0, _ARG1); }
|
||||
void log_Z3_ast_vector_get(Z3_context a0, Z3_ast_vector a1, unsigned a2);
|
||||
#define LOG_Z3_ast_vector_get(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_vector_get(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_ast_vector_set(Z3_context a0, Z3_ast_vector a1, unsigned a2, Z3_ast a3);
|
||||
#define LOG_Z3_ast_vector_set(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_vector_set(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_ast_vector_resize(Z3_context a0, Z3_ast_vector a1, unsigned a2);
|
||||
#define LOG_Z3_ast_vector_resize(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_vector_resize(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_ast_vector_push(Z3_context a0, Z3_ast_vector a1, Z3_ast a2);
|
||||
#define LOG_Z3_ast_vector_push(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_vector_push(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_ast_vector_translate(Z3_context a0, Z3_ast_vector a1, Z3_context a2);
|
||||
#define LOG_Z3_ast_vector_translate(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_vector_translate(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_ast_vector_to_string(Z3_context a0, Z3_ast_vector a1);
|
||||
#define LOG_Z3_ast_vector_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_vector_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_ast_map(Z3_context a0);
|
||||
#define LOG_Z3_mk_ast_map(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_ast_map(_ARG0); }
|
||||
void log_Z3_ast_map_inc_ref(Z3_context a0, Z3_ast_map a1);
|
||||
#define LOG_Z3_ast_map_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_ast_map_dec_ref(Z3_context a0, Z3_ast_map a1);
|
||||
#define LOG_Z3_ast_map_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_ast_map_contains(Z3_context a0, Z3_ast_map a1, Z3_ast a2);
|
||||
#define LOG_Z3_ast_map_contains(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_contains(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_ast_map_find(Z3_context a0, Z3_ast_map a1, Z3_ast a2);
|
||||
#define LOG_Z3_ast_map_find(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_find(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_ast_map_insert(Z3_context a0, Z3_ast_map a1, Z3_ast a2, Z3_ast a3);
|
||||
#define LOG_Z3_ast_map_insert(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_insert(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_ast_map_erase(Z3_context a0, Z3_ast_map a1, Z3_ast a2);
|
||||
#define LOG_Z3_ast_map_erase(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_erase(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_ast_map_reset(Z3_context a0, Z3_ast_map a1);
|
||||
#define LOG_Z3_ast_map_reset(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_reset(_ARG0, _ARG1); }
|
||||
void log_Z3_ast_map_size(Z3_context a0, Z3_ast_map a1);
|
||||
#define LOG_Z3_ast_map_size(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_size(_ARG0, _ARG1); }
|
||||
void log_Z3_ast_map_keys(Z3_context a0, Z3_ast_map a1);
|
||||
#define LOG_Z3_ast_map_keys(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_keys(_ARG0, _ARG1); }
|
||||
void log_Z3_ast_map_to_string(Z3_context a0, Z3_ast_map a1);
|
||||
#define LOG_Z3_ast_map_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_ast_map_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_goal(Z3_context a0, Z3_bool a1, Z3_bool a2, Z3_bool a3);
|
||||
#define LOG_Z3_mk_goal(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_goal(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_goal_inc_ref(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_dec_ref(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_precision(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_precision(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_precision(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_assert(Z3_context a0, Z3_goal a1, Z3_ast a2);
|
||||
#define LOG_Z3_goal_assert(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_assert(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_goal_inconsistent(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_inconsistent(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_inconsistent(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_depth(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_depth(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_depth(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_reset(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_reset(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_reset(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_size(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_size(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_size(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_formula(Z3_context a0, Z3_goal a1, unsigned a2);
|
||||
#define LOG_Z3_goal_formula(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_formula(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_goal_num_exprs(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_num_exprs(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_num_exprs(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_is_decided_sat(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_is_decided_sat(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_is_decided_sat(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_is_decided_unsat(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_is_decided_unsat(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_is_decided_unsat(_ARG0, _ARG1); }
|
||||
void log_Z3_goal_translate(Z3_context a0, Z3_goal a1, Z3_context a2);
|
||||
#define LOG_Z3_goal_translate(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_translate(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_goal_to_string(Z3_context a0, Z3_goal a1);
|
||||
#define LOG_Z3_goal_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_goal_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_tactic(Z3_context a0, Z3_string a1);
|
||||
#define LOG_Z3_mk_tactic(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_tactic(_ARG0, _ARG1); }
|
||||
void log_Z3_tactic_inc_ref(Z3_context a0, Z3_tactic a1);
|
||||
#define LOG_Z3_tactic_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_tactic_dec_ref(Z3_context a0, Z3_tactic a1);
|
||||
#define LOG_Z3_tactic_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_probe(Z3_context a0, Z3_string a1);
|
||||
#define LOG_Z3_mk_probe(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_probe(_ARG0, _ARG1); }
|
||||
void log_Z3_probe_inc_ref(Z3_context a0, Z3_probe a1);
|
||||
#define LOG_Z3_probe_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_probe_dec_ref(Z3_context a0, Z3_probe a1);
|
||||
#define LOG_Z3_probe_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_tactic_and_then(Z3_context a0, Z3_tactic a1, Z3_tactic a2);
|
||||
#define LOG_Z3_tactic_and_then(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_and_then(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_tactic_or_else(Z3_context a0, Z3_tactic a1, Z3_tactic a2);
|
||||
#define LOG_Z3_tactic_or_else(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_or_else(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_tactic_par_or(Z3_context a0, unsigned a1, Z3_tactic const * a2);
|
||||
#define LOG_Z3_tactic_par_or(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_par_or(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_tactic_par_and_then(Z3_context a0, Z3_tactic a1, Z3_tactic a2);
|
||||
#define LOG_Z3_tactic_par_and_then(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_par_and_then(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_tactic_try_for(Z3_context a0, Z3_tactic a1, unsigned a2);
|
||||
#define LOG_Z3_tactic_try_for(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_try_for(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_tactic_when(Z3_context a0, Z3_probe a1, Z3_tactic a2);
|
||||
#define LOG_Z3_tactic_when(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_when(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_tactic_cond(Z3_context a0, Z3_probe a1, Z3_tactic a2, Z3_tactic a3);
|
||||
#define LOG_Z3_tactic_cond(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_cond(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_tactic_repeat(Z3_context a0, Z3_tactic a1, unsigned a2);
|
||||
#define LOG_Z3_tactic_repeat(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_repeat(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_tactic_skip(Z3_context a0);
|
||||
#define LOG_Z3_tactic_skip(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_skip(_ARG0); }
|
||||
void log_Z3_tactic_fail(Z3_context a0);
|
||||
#define LOG_Z3_tactic_fail(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_fail(_ARG0); }
|
||||
void log_Z3_tactic_fail_if(Z3_context a0, Z3_probe a1);
|
||||
#define LOG_Z3_tactic_fail_if(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_fail_if(_ARG0, _ARG1); }
|
||||
void log_Z3_tactic_fail_if_not_decided(Z3_context a0);
|
||||
#define LOG_Z3_tactic_fail_if_not_decided(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_fail_if_not_decided(_ARG0); }
|
||||
void log_Z3_tactic_using_params(Z3_context a0, Z3_tactic a1, Z3_params a2);
|
||||
#define LOG_Z3_tactic_using_params(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_using_params(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_probe_const(Z3_context a0, double a1);
|
||||
#define LOG_Z3_probe_const(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_const(_ARG0, _ARG1); }
|
||||
void log_Z3_probe_lt(Z3_context a0, Z3_probe a1, Z3_probe a2);
|
||||
#define LOG_Z3_probe_lt(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_lt(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_probe_gt(Z3_context a0, Z3_probe a1, Z3_probe a2);
|
||||
#define LOG_Z3_probe_gt(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_gt(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_probe_le(Z3_context a0, Z3_probe a1, Z3_probe a2);
|
||||
#define LOG_Z3_probe_le(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_le(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_probe_ge(Z3_context a0, Z3_probe a1, Z3_probe a2);
|
||||
#define LOG_Z3_probe_ge(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_ge(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_probe_eq(Z3_context a0, Z3_probe a1, Z3_probe a2);
|
||||
#define LOG_Z3_probe_eq(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_eq(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_probe_and(Z3_context a0, Z3_probe a1, Z3_probe a2);
|
||||
#define LOG_Z3_probe_and(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_and(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_probe_or(Z3_context a0, Z3_probe a1, Z3_probe a2);
|
||||
#define LOG_Z3_probe_or(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_or(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_probe_not(Z3_context a0, Z3_probe a1);
|
||||
#define LOG_Z3_probe_not(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_not(_ARG0, _ARG1); }
|
||||
void log_Z3_get_num_tactics(Z3_context a0);
|
||||
#define LOG_Z3_get_num_tactics(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_num_tactics(_ARG0); }
|
||||
void log_Z3_get_tactic_name(Z3_context a0, unsigned a1);
|
||||
#define LOG_Z3_get_tactic_name(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_tactic_name(_ARG0, _ARG1); }
|
||||
void log_Z3_get_num_probes(Z3_context a0);
|
||||
#define LOG_Z3_get_num_probes(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_num_probes(_ARG0); }
|
||||
void log_Z3_get_probe_name(Z3_context a0, unsigned a1);
|
||||
#define LOG_Z3_get_probe_name(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_probe_name(_ARG0, _ARG1); }
|
||||
void log_Z3_tactic_get_help(Z3_context a0, Z3_tactic a1);
|
||||
#define LOG_Z3_tactic_get_help(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_get_help(_ARG0, _ARG1); }
|
||||
void log_Z3_tactic_get_param_descrs(Z3_context a0, Z3_tactic a1);
|
||||
#define LOG_Z3_tactic_get_param_descrs(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_get_param_descrs(_ARG0, _ARG1); }
|
||||
void log_Z3_tactic_get_descr(Z3_context a0, Z3_string a1);
|
||||
#define LOG_Z3_tactic_get_descr(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_get_descr(_ARG0, _ARG1); }
|
||||
void log_Z3_probe_get_descr(Z3_context a0, Z3_string a1);
|
||||
#define LOG_Z3_probe_get_descr(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_get_descr(_ARG0, _ARG1); }
|
||||
void log_Z3_probe_apply(Z3_context a0, Z3_probe a1, Z3_goal a2);
|
||||
#define LOG_Z3_probe_apply(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_probe_apply(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_tactic_apply(Z3_context a0, Z3_tactic a1, Z3_goal a2);
|
||||
#define LOG_Z3_tactic_apply(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_apply(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_tactic_apply_ex(Z3_context a0, Z3_tactic a1, Z3_goal a2, Z3_params a3);
|
||||
#define LOG_Z3_tactic_apply_ex(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_tactic_apply_ex(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_apply_result_inc_ref(Z3_context a0, Z3_apply_result a1);
|
||||
#define LOG_Z3_apply_result_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_apply_result_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_apply_result_dec_ref(Z3_context a0, Z3_apply_result a1);
|
||||
#define LOG_Z3_apply_result_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_apply_result_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_apply_result_to_string(Z3_context a0, Z3_apply_result a1);
|
||||
#define LOG_Z3_apply_result_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_apply_result_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_apply_result_get_num_subgoals(Z3_context a0, Z3_apply_result a1);
|
||||
#define LOG_Z3_apply_result_get_num_subgoals(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_apply_result_get_num_subgoals(_ARG0, _ARG1); }
|
||||
void log_Z3_apply_result_get_subgoal(Z3_context a0, Z3_apply_result a1, unsigned a2);
|
||||
#define LOG_Z3_apply_result_get_subgoal(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_apply_result_get_subgoal(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_apply_result_convert_model(Z3_context a0, Z3_apply_result a1, unsigned a2, Z3_model a3);
|
||||
#define LOG_Z3_apply_result_convert_model(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_apply_result_convert_model(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_mk_solver(Z3_context a0);
|
||||
#define LOG_Z3_mk_solver(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_solver(_ARG0); }
|
||||
void log_Z3_mk_simple_solver(Z3_context a0);
|
||||
#define LOG_Z3_mk_simple_solver(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_simple_solver(_ARG0); }
|
||||
void log_Z3_mk_solver_for_logic(Z3_context a0, Z3_symbol a1);
|
||||
#define LOG_Z3_mk_solver_for_logic(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_solver_for_logic(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_solver_from_tactic(Z3_context a0, Z3_tactic a1);
|
||||
#define LOG_Z3_mk_solver_from_tactic(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_solver_from_tactic(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_get_help(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_get_help(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_get_help(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_get_param_descrs(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_get_param_descrs(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_get_param_descrs(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_set_params(Z3_context a0, Z3_solver a1, Z3_params a2);
|
||||
#define LOG_Z3_solver_set_params(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_set_params(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_solver_inc_ref(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_dec_ref(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_push(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_push(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_push(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_pop(Z3_context a0, Z3_solver a1, unsigned a2);
|
||||
#define LOG_Z3_solver_pop(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_pop(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_solver_reset(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_reset(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_reset(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_get_num_scopes(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_get_num_scopes(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_get_num_scopes(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_assert(Z3_context a0, Z3_solver a1, Z3_ast a2);
|
||||
#define LOG_Z3_solver_assert(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_assert(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_solver_get_assertions(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_get_assertions(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_get_assertions(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_check(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_check(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_check(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_check_assumptions(Z3_context a0, Z3_solver a1, unsigned a2, Z3_ast const * a3);
|
||||
#define LOG_Z3_solver_check_assumptions(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_check_assumptions(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_solver_get_model(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_get_model(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_get_model(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_get_proof(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_get_proof(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_get_proof(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_get_unsat_core(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_get_unsat_core(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_get_unsat_core(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_get_reason_unknown(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_get_reason_unknown(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_get_reason_unknown(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_get_statistics(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_get_statistics(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_get_statistics(_ARG0, _ARG1); }
|
||||
void log_Z3_solver_to_string(Z3_context a0, Z3_solver a1);
|
||||
#define LOG_Z3_solver_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_solver_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_stats_to_string(Z3_context a0, Z3_stats a1);
|
||||
#define LOG_Z3_stats_to_string(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_stats_to_string(_ARG0, _ARG1); }
|
||||
void log_Z3_stats_inc_ref(Z3_context a0, Z3_stats a1);
|
||||
#define LOG_Z3_stats_inc_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_stats_inc_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_stats_dec_ref(Z3_context a0, Z3_stats a1);
|
||||
#define LOG_Z3_stats_dec_ref(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_stats_dec_ref(_ARG0, _ARG1); }
|
||||
void log_Z3_stats_size(Z3_context a0, Z3_stats a1);
|
||||
#define LOG_Z3_stats_size(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_stats_size(_ARG0, _ARG1); }
|
||||
void log_Z3_stats_get_key(Z3_context a0, Z3_stats a1, unsigned a2);
|
||||
#define LOG_Z3_stats_get_key(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_stats_get_key(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_stats_is_uint(Z3_context a0, Z3_stats a1, unsigned a2);
|
||||
#define LOG_Z3_stats_is_uint(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_stats_is_uint(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_stats_is_double(Z3_context a0, Z3_stats a1, unsigned a2);
|
||||
#define LOG_Z3_stats_is_double(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_stats_is_double(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_stats_get_uint_value(Z3_context a0, Z3_stats a1, unsigned a2);
|
||||
#define LOG_Z3_stats_get_uint_value(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_stats_get_uint_value(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_stats_get_double_value(Z3_context a0, Z3_stats a1, unsigned a2);
|
||||
#define LOG_Z3_stats_get_double_value(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_stats_get_double_value(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_mk_injective_function(Z3_context a0, Z3_symbol a1, unsigned a2, Z3_sort const * a3, Z3_sort a4);
|
||||
#define LOG_Z3_mk_injective_function(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_injective_function(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); }
|
||||
void log_Z3_set_logic(Z3_context a0, Z3_string a1);
|
||||
#define LOG_Z3_set_logic(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_set_logic(_ARG0, _ARG1); }
|
||||
void log_Z3_push(Z3_context a0);
|
||||
#define LOG_Z3_push(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_push(_ARG0); }
|
||||
void log_Z3_pop(Z3_context a0, unsigned a1);
|
||||
#define LOG_Z3_pop(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_pop(_ARG0, _ARG1); }
|
||||
void log_Z3_get_num_scopes(Z3_context a0);
|
||||
#define LOG_Z3_get_num_scopes(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_num_scopes(_ARG0); }
|
||||
void log_Z3_persist_ast(Z3_context a0, Z3_ast a1, unsigned a2);
|
||||
#define LOG_Z3_persist_ast(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_persist_ast(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_assert_cnstr(Z3_context a0, Z3_ast a1);
|
||||
#define LOG_Z3_assert_cnstr(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_assert_cnstr(_ARG0, _ARG1); }
|
||||
void log_Z3_check_and_get_model(Z3_context a0, Z3_model* a1);
|
||||
#define LOG_Z3_check_and_get_model(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; Z3_model* Z3ARG1; if (_LOG_CTX.enabled()) { log_Z3_check_and_get_model(_ARG0, _ARG1); Z3ARG1 = _ARG1; }
|
||||
#define RETURN_Z3_check_and_get_model if (_LOG_CTX.enabled()) { SetO((Z3ARG1 == 0 ? 0 : *Z3ARG1), 1); } return
|
||||
void log_Z3_check(Z3_context a0);
|
||||
#define LOG_Z3_check(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_check(_ARG0); }
|
||||
void log_Z3_check_assumptions(Z3_context a0, unsigned a1, Z3_ast const * a2, Z3_model* a3, Z3_ast* a4, unsigned* a5, Z3_ast* a6);
|
||||
#define LOG_Z3_check_assumptions(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6) z3_log_ctx _LOG_CTX; Z3_model* Z3ARG3; Z3_ast* Z3ARG4; unsigned Z3ARG1; unsigned * Z3ARG5; Z3_ast* Z3ARG6; if (_LOG_CTX.enabled()) { log_Z3_check_assumptions(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6); Z3ARG3 = _ARG3; Z3ARG4 = _ARG4; Z3ARG1 = _ARG1; Z3ARG5 = _ARG5; Z3ARG6 = _ARG6; }
|
||||
#define RETURN_Z3_check_assumptions if (_LOG_CTX.enabled()) { SetO((Z3ARG3 == 0 ? 0 : *Z3ARG3), 3); SetO((Z3ARG4 == 0 ? 0 : *Z3ARG4), 4); for (unsigned i = 0; Z3ARG5 && i < *Z3ARG5; i++) { SetAO(Z3ARG6[i], 6, i); } } return
|
||||
void log_Z3_get_implied_equalities(Z3_context a0, unsigned a1, Z3_ast const * a2, unsigned* a3);
|
||||
#define LOG_Z3_get_implied_equalities(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_implied_equalities(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_del_model(Z3_context a0, Z3_model a1);
|
||||
#define LOG_Z3_del_model(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_del_model(_ARG0, _ARG1); }
|
||||
void log_Z3_soft_check_cancel(Z3_context a0);
|
||||
#define LOG_Z3_soft_check_cancel(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_soft_check_cancel(_ARG0); }
|
||||
void log_Z3_get_search_failure(Z3_context a0);
|
||||
#define LOG_Z3_get_search_failure(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_search_failure(_ARG0); }
|
||||
void log_Z3_mk_label(Z3_context a0, Z3_symbol a1, Z3_bool a2, Z3_ast a3);
|
||||
#define LOG_Z3_mk_label(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_label(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_get_relevant_labels(Z3_context a0);
|
||||
#define LOG_Z3_get_relevant_labels(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_relevant_labels(_ARG0); }
|
||||
void log_Z3_get_relevant_literals(Z3_context a0);
|
||||
#define LOG_Z3_get_relevant_literals(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_relevant_literals(_ARG0); }
|
||||
void log_Z3_get_guessed_literals(Z3_context a0);
|
||||
#define LOG_Z3_get_guessed_literals(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_guessed_literals(_ARG0); }
|
||||
void log_Z3_del_literals(Z3_context a0, Z3_literals a1);
|
||||
#define LOG_Z3_del_literals(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_del_literals(_ARG0, _ARG1); }
|
||||
void log_Z3_get_num_literals(Z3_context a0, Z3_literals a1);
|
||||
#define LOG_Z3_get_num_literals(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_num_literals(_ARG0, _ARG1); }
|
||||
void log_Z3_get_label_symbol(Z3_context a0, Z3_literals a1, unsigned a2);
|
||||
#define LOG_Z3_get_label_symbol(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_label_symbol(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_literal(Z3_context a0, Z3_literals a1, unsigned a2);
|
||||
#define LOG_Z3_get_literal(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_literal(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_disable_literal(Z3_context a0, Z3_literals a1, unsigned a2);
|
||||
#define LOG_Z3_disable_literal(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_disable_literal(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_block_literals(Z3_context a0, Z3_literals a1);
|
||||
#define LOG_Z3_block_literals(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_block_literals(_ARG0, _ARG1); }
|
||||
void log_Z3_get_model_num_constants(Z3_context a0, Z3_model a1);
|
||||
#define LOG_Z3_get_model_num_constants(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_model_num_constants(_ARG0, _ARG1); }
|
||||
void log_Z3_get_model_constant(Z3_context a0, Z3_model a1, unsigned a2);
|
||||
#define LOG_Z3_get_model_constant(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_model_constant(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_model_num_funcs(Z3_context a0, Z3_model a1);
|
||||
#define LOG_Z3_get_model_num_funcs(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_model_num_funcs(_ARG0, _ARG1); }
|
||||
void log_Z3_get_model_func_decl(Z3_context a0, Z3_model a1, unsigned a2);
|
||||
#define LOG_Z3_get_model_func_decl(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_model_func_decl(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_eval_func_decl(Z3_context a0, Z3_model a1, Z3_func_decl a2, Z3_ast* a3);
|
||||
#define LOG_Z3_eval_func_decl(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; Z3_ast* Z3ARG3; if (_LOG_CTX.enabled()) { log_Z3_eval_func_decl(_ARG0, _ARG1, _ARG2, _ARG3); Z3ARG3 = _ARG3; }
|
||||
#define RETURN_Z3_eval_func_decl if (_LOG_CTX.enabled()) { SetO((Z3ARG3 == 0 ? 0 : *Z3ARG3), 3); } return
|
||||
void log_Z3_is_array_value(Z3_context a0, Z3_model a1, Z3_ast a2, unsigned* a3);
|
||||
#define LOG_Z3_is_array_value(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_is_array_value(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_get_array_value(Z3_context a0, Z3_model a1, Z3_ast a2, unsigned a3, Z3_ast* a4, Z3_ast* a5, Z3_ast* a6);
|
||||
#define LOG_Z3_get_array_value(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6) z3_log_ctx _LOG_CTX; unsigned Z3ARG3; Z3_ast* Z3ARG4; Z3_ast* Z3ARG5; Z3_ast* Z3ARG6; if (_LOG_CTX.enabled()) { log_Z3_get_array_value(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5, _ARG6); Z3ARG3 = _ARG3; Z3ARG4 = _ARG4; Z3ARG5 = _ARG5; Z3ARG6 = _ARG6; }
|
||||
#define RETURN_Z3_get_array_value if (_LOG_CTX.enabled()) { for (unsigned i = 0; i < Z3ARG3; i++) { SetAO(Z3ARG4[i], 4, i); } for (unsigned i = 0; i < Z3ARG3; i++) { SetAO(Z3ARG5[i], 5, i); } SetO((Z3ARG6 == 0 ? 0 : *Z3ARG6), 6); } return
|
||||
void log_Z3_get_model_func_else(Z3_context a0, Z3_model a1, unsigned a2);
|
||||
#define LOG_Z3_get_model_func_else(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_model_func_else(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_model_func_num_entries(Z3_context a0, Z3_model a1, unsigned a2);
|
||||
#define LOG_Z3_get_model_func_num_entries(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_model_func_num_entries(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_get_model_func_entry_num_args(Z3_context a0, Z3_model a1, unsigned a2, unsigned a3);
|
||||
#define LOG_Z3_get_model_func_entry_num_args(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_model_func_entry_num_args(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_get_model_func_entry_arg(Z3_context a0, Z3_model a1, unsigned a2, unsigned a3, unsigned a4);
|
||||
#define LOG_Z3_get_model_func_entry_arg(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_model_func_entry_arg(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4); }
|
||||
void log_Z3_get_model_func_entry_value(Z3_context a0, Z3_model a1, unsigned a2, unsigned a3);
|
||||
#define LOG_Z3_get_model_func_entry_value(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_model_func_entry_value(_ARG0, _ARG1, _ARG2, _ARG3); }
|
||||
void log_Z3_eval(Z3_context a0, Z3_model a1, Z3_ast a2, Z3_ast* a3);
|
||||
#define LOG_Z3_eval(_ARG0, _ARG1, _ARG2, _ARG3) z3_log_ctx _LOG_CTX; Z3_ast* Z3ARG3; if (_LOG_CTX.enabled()) { log_Z3_eval(_ARG0, _ARG1, _ARG2, _ARG3); Z3ARG3 = _ARG3; }
|
||||
#define RETURN_Z3_eval if (_LOG_CTX.enabled()) { SetO((Z3ARG3 == 0 ? 0 : *Z3ARG3), 3); } return
|
||||
void log_Z3_eval_decl(Z3_context a0, Z3_model a1, Z3_func_decl a2, unsigned a3, Z3_ast const * a4, Z3_ast* a5);
|
||||
#define LOG_Z3_eval_decl(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5) z3_log_ctx _LOG_CTX; Z3_ast* Z3ARG5; if (_LOG_CTX.enabled()) { log_Z3_eval_decl(_ARG0, _ARG1, _ARG2, _ARG3, _ARG4, _ARG5); Z3ARG5 = _ARG5; }
|
||||
#define RETURN_Z3_eval_decl if (_LOG_CTX.enabled()) { SetO((Z3ARG5 == 0 ? 0 : *Z3ARG5), 5); } return
|
||||
void log_Z3_context_to_string(Z3_context a0);
|
||||
#define LOG_Z3_context_to_string(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_context_to_string(_ARG0); }
|
||||
void log_Z3_statistics_to_string(Z3_context a0);
|
||||
#define LOG_Z3_statistics_to_string(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_statistics_to_string(_ARG0); }
|
||||
void log_Z3_get_context_assignment(Z3_context a0);
|
||||
#define LOG_Z3_get_context_assignment(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_get_context_assignment(_ARG0); }
|
||||
void log_Z3_mk_polynomial_manager(Z3_context a0);
|
||||
#define LOG_Z3_mk_polynomial_manager(_ARG0) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_polynomial_manager(_ARG0); }
|
||||
void log_Z3_del_polynomial_manager(Z3_context a0, Z3_polynomial_manager a1);
|
||||
#define LOG_Z3_del_polynomial_manager(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_del_polynomial_manager(_ARG0, _ARG1); }
|
||||
void log_Z3_mk_zero_polynomial(Z3_context a0, Z3_polynomial_manager a1);
|
||||
#define LOG_Z3_mk_zero_polynomial(_ARG0, _ARG1) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_mk_zero_polynomial(_ARG0, _ARG1); }
|
||||
void log_Z3_polynomial_inc_ref(Z3_context a0, Z3_polynomial_manager a1, Z3_polynomial a2);
|
||||
#define LOG_Z3_polynomial_inc_ref(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_polynomial_inc_ref(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_polynomial_dec_ref(Z3_context a0, Z3_polynomial_manager a1, Z3_polynomial a2);
|
||||
#define LOG_Z3_polynomial_dec_ref(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_polynomial_dec_ref(_ARG0, _ARG1, _ARG2); }
|
||||
void log_Z3_polynomial_to_string(Z3_context a0, Z3_polynomial_manager a1, Z3_polynomial a2);
|
||||
#define LOG_Z3_polynomial_to_string(_ARG0, _ARG1, _ARG2) z3_log_ctx _LOG_CTX; if (_LOG_CTX.enabled()) { log_Z3_polynomial_to_string(_ARG0, _ARG1, _ARG2); }
|
670
src/api/api_model.cpp
Normal file
670
src/api/api_model.cpp
Normal file
|
@ -0,0 +1,670 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_quant.cpp
|
||||
|
||||
Abstract:
|
||||
API for models
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_model.h"
|
||||
#include"api_ast_vector.h"
|
||||
#include"array_decl_plugin.h"
|
||||
#include"model.h"
|
||||
#include"model_v2_pp.h"
|
||||
#include"model_smt2_pp.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
void Z3_API Z3_model_inc_ref(Z3_context c, Z3_model m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_inc_ref(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
if (m) {
|
||||
to_model(m)->inc_ref();
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_model_dec_ref(Z3_context c, Z3_model m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_dec_ref(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
if (m) {
|
||||
to_model(m)->dec_ref();
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_model_get_const_interp(Z3_context c, Z3_model m, Z3_func_decl a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_get_const_interp(c, m, a);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
expr * r = to_model_ref(m)->get_const_interp(to_func_decl(a));
|
||||
if (!r) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_interp Z3_API Z3_model_get_func_interp(Z3_context c, Z3_model m, Z3_func_decl f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_get_func_interp(c, m, f);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
func_interp * _fi = to_model_ref(m)->get_func_interp(to_func_decl(f));
|
||||
if (!_fi) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_func_interp_ref * fi = alloc(Z3_func_interp_ref, to_model_ref(m));
|
||||
fi->m_func_interp = _fi;
|
||||
mk_c(c)->save_object(fi);
|
||||
RETURN_Z3(of_func_interp(fi));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_model_get_num_consts(Z3_context c, Z3_model m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_get_num_consts(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
return to_model_ref(m)->get_num_constants();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_model_get_const_decl(Z3_context c, Z3_model m, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_get_const_decl(c, m, i);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
model * _m = to_model_ref(m);
|
||||
if (i < _m->get_num_constants()) {
|
||||
RETURN_Z3(of_func_decl(_m->get_constant(i)));
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_model_get_num_funcs(Z3_context c, Z3_model m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_get_num_funcs(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
return to_model_ref(m)->get_num_functions();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl get_model_func_decl_core(Z3_context c, Z3_model m, unsigned i) {
|
||||
CHECK_NON_NULL(m, 0);
|
||||
model * _m = to_model_ref(m);
|
||||
if (i >= _m->get_num_functions()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return 0;
|
||||
}
|
||||
return of_func_decl(_m->get_function(i));
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_model_get_func_decl(Z3_context c, Z3_model m, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_model_func_decl(c, m, i);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_func_decl r = get_model_func_decl_core(c, m, i);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_model_eval(Z3_context c, Z3_model m, Z3_ast t, Z3_bool model_completion, Z3_ast * v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_eval(c, m, t, model_completion, v);
|
||||
if (v) *v = 0;
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, Z3_FALSE);
|
||||
model * _m = to_model_ref(m);
|
||||
expr_ref result(mk_c(c)->m());
|
||||
_m->eval(to_expr(t), result, model_completion == Z3_TRUE);
|
||||
mk_c(c)->save_ast_trail(result.get());
|
||||
*v = of_ast(result.get());
|
||||
RETURN_Z3_model_eval Z3_TRUE;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_model_get_num_sorts(Z3_context c, Z3_model m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_get_num_sorts(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
return to_model_ref(m)->get_num_uninterpreted_sorts();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_model_get_sort(Z3_context c, Z3_model m, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_get_sort(c, m, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (i >= to_model_ref(m)->get_num_uninterpreted_sorts()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
sort * s = to_model_ref(m)->get_uninterpreted_sort(i);
|
||||
RETURN_Z3(of_sort(s));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_model_get_sort_universe(Z3_context c, Z3_model m, Z3_sort s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_get_sort_universe(c, m, s);
|
||||
RESET_ERROR_CODE();
|
||||
if (!to_model_ref(m)->has_uninterpreted_sort(to_sort(s))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ptr_vector<expr> const & universe = to_model_ref(m)->get_universe(to_sort(s));
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
unsigned sz = universe.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
v->m_ast_vector.push_back(universe[i]);
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_as_array(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_is_as_array(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
return is_expr(to_ast(a)) && is_app_of(to_expr(a), mk_c(c)->get_array_fid(), OP_AS_ARRAY);
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_as_array_func_decl(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_as_array_func_decl(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
if (is_expr(to_ast(a)) && is_app_of(to_expr(a), mk_c(c)->get_array_fid(), OP_AS_ARRAY)) {
|
||||
return of_func_decl(to_func_decl(to_app(a)->get_decl()->get_parameter(0).get_ast()));
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_func_interp_inc_ref(Z3_context c, Z3_func_interp f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_interp_inc_ref(c, f);
|
||||
RESET_ERROR_CODE();
|
||||
if (f) {
|
||||
to_func_interp(f)->inc_ref();
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_func_interp_dec_ref(Z3_context c, Z3_func_interp f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_interp_dec_ref(c, f);
|
||||
RESET_ERROR_CODE();
|
||||
if (f) {
|
||||
to_func_interp(f)->dec_ref();
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_func_interp_get_num_entries(Z3_context c, Z3_func_interp f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_interp_get_num_entries(c, f);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(f, 0);
|
||||
return to_func_interp_ref(f)->num_entries();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_entry Z3_API Z3_func_interp_get_entry(Z3_context c, Z3_func_interp f, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_interp_get_entry(c, f, i);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(f, 0);
|
||||
if (i >= to_func_interp_ref(f)->num_entries()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_func_entry_ref * e = alloc(Z3_func_entry_ref, to_func_interp(f)->m_model.get());
|
||||
e->m_func_interp = to_func_interp_ref(f);
|
||||
e->m_func_entry = to_func_interp_ref(f)->get_entry(i);
|
||||
mk_c(c)->save_object(e);
|
||||
RETURN_Z3(of_func_entry(e));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_func_interp_get_else(Z3_context c, Z3_func_interp f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_interp_get_else(c, f);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(f, 0);
|
||||
expr * e = to_func_interp_ref(f)->get_else();
|
||||
RETURN_Z3(of_expr(e));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_func_interp_get_arity(Z3_context c, Z3_func_interp f) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_interp_get_arity(c, f);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(f, 0);
|
||||
return to_func_interp_ref(f)->get_arity();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_func_entry_inc_ref(Z3_context c, Z3_func_entry e) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_entry_inc_ref(c, e);
|
||||
RESET_ERROR_CODE();
|
||||
if (e) {
|
||||
to_func_entry(e)->inc_ref();
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_func_entry_dec_ref(Z3_context c, Z3_func_entry e) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_entry_dec_ref(c, e);
|
||||
RESET_ERROR_CODE();
|
||||
if (e) {
|
||||
to_func_entry(e)->dec_ref();
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_func_entry_get_value(Z3_context c, Z3_func_entry e) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_entry_get_value(c, e);
|
||||
RESET_ERROR_CODE();
|
||||
expr * v = to_func_entry_ref(e)->get_result();
|
||||
RETURN_Z3(of_expr(v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_func_entry_get_num_args(Z3_context c, Z3_func_entry e) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_entry_get_num_args(c, e);
|
||||
RESET_ERROR_CODE();
|
||||
return to_func_entry(e)->m_func_interp->get_arity();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_func_entry_get_arg(Z3_context c, Z3_func_entry e, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_func_entry_get_arg(c, e, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (i >= to_func_entry(e)->m_func_interp->get_arity()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
expr * r = to_func_entry(e)->m_func_entry->get_arg(i);
|
||||
RETURN_Z3(of_expr(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
// ----------------------------
|
||||
//
|
||||
// DEPRECATED API
|
||||
//
|
||||
// ----------------------------
|
||||
|
||||
void Z3_API Z3_del_model(Z3_context c, Z3_model m) {
|
||||
Z3_model_dec_ref(c, m);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_model_num_constants(Z3_context c, Z3_model m) {
|
||||
return Z3_model_get_num_consts(c, m);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_model_constant(Z3_context c, Z3_model m, unsigned i) {
|
||||
return Z3_model_get_const_decl(c, m, i);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_model_num_funcs(Z3_context c, Z3_model m) {
|
||||
return Z3_model_get_num_funcs(c, m);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_model_func_decl(Z3_context c, Z3_model m, unsigned i) {
|
||||
return Z3_model_get_func_decl(c, m, i);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_model_func_else(Z3_context c, Z3_model m, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_model_func_else(c, m, i);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
Z3_func_decl d = get_model_func_decl_core(c, m, i);
|
||||
if (d) {
|
||||
model * _m = to_model_ref(m);
|
||||
func_interp * g = _m->get_func_interp(to_func_decl(d));
|
||||
if (g) {
|
||||
expr * e = g->get_else();
|
||||
mk_c(c)->save_ast_trail(e);
|
||||
RETURN_Z3(of_ast(e));
|
||||
}
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned get_model_func_num_entries_core(Z3_context c, Z3_model m, unsigned i) {
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
Z3_func_decl d = get_model_func_decl_core(c, m, i);
|
||||
if (d) {
|
||||
model * _m = to_model_ref(m);
|
||||
func_interp * g = _m->get_func_interp(to_func_decl(d));
|
||||
if (g) {
|
||||
return g->num_entries();
|
||||
}
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_model_func_num_entries(Z3_context c, Z3_model m, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_model_func_num_entries(c, m, i);
|
||||
return get_model_func_num_entries_core(c, m, i);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned get_model_func_entry_num_args_core(Z3_context c,
|
||||
Z3_model m,
|
||||
unsigned i,
|
||||
unsigned j) {
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
if (j >= get_model_func_num_entries_core(c, m, i)) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return 0;
|
||||
}
|
||||
Z3_func_decl d = get_model_func_decl_core(c, m, i);
|
||||
if (d) {
|
||||
model * _m = to_model_ref(m);
|
||||
func_interp * g = _m->get_func_interp(to_func_decl(d));
|
||||
return g->get_arity();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_model_func_entry_num_args(Z3_context c,
|
||||
Z3_model m,
|
||||
unsigned i,
|
||||
unsigned j) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_model_func_entry_num_args(c, m, i, j);
|
||||
return get_model_func_entry_num_args_core(c, m, i, j);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_model_func_entry_arg(Z3_context c,
|
||||
Z3_model m,
|
||||
unsigned i,
|
||||
unsigned j,
|
||||
unsigned k) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_model_func_entry_arg(c, m, i, j, k);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
if (j >= get_model_func_num_entries_core(c, m, i) || k >= get_model_func_entry_num_args_core(c, m, i, j)) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_func_decl d = get_model_func_decl_core(c, m, i);
|
||||
if (d) {
|
||||
model * _m = to_model_ref(m);
|
||||
func_interp * g = _m->get_func_interp(to_func_decl(d));
|
||||
if (g && j < g->num_entries()) {
|
||||
func_entry const * e = g->get_entry(j);
|
||||
if (k < g->get_arity()) {
|
||||
expr * a = e->get_arg(k);
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
}
|
||||
}
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_model_func_entry_value(Z3_context c,
|
||||
Z3_model m,
|
||||
unsigned i,
|
||||
unsigned j) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_model_func_entry_value(c, m, i, j);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
if (j >= get_model_func_num_entries_core(c, m, i)) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_func_decl d = get_model_func_decl_core(c, m, i);
|
||||
if (d) {
|
||||
model * _m = to_model_ref(m);
|
||||
func_interp * g = _m->get_func_interp(to_func_decl(d));
|
||||
if (g && j < g->num_entries()) {
|
||||
func_entry const* e = g->get_entry(j);
|
||||
expr* a = e->get_result();
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
}
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_eval(Z3_context c,
|
||||
Z3_model m,
|
||||
Z3_ast t,
|
||||
Z3_ast * v) {
|
||||
return Z3_model_eval(c, m, t, mk_c(c)->fparams().m_model_completion, v);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_eval_func_decl(Z3_context c,
|
||||
Z3_model m,
|
||||
Z3_func_decl decl,
|
||||
Z3_ast* v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_eval_func_decl(c, m, decl, v);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, Z3_FALSE);
|
||||
ast_manager & mgr = mk_c(c)->m();
|
||||
model * _m = to_model_ref(m);
|
||||
expr_ref result(mgr);
|
||||
if( _m->eval(to_func_decl(decl), result)) {
|
||||
mk_c(c)->save_ast_trail(result.get());
|
||||
*v = of_ast(result.get());
|
||||
RETURN_Z3_eval_func_decl Z3_TRUE;
|
||||
}
|
||||
else {
|
||||
return Z3_FALSE;
|
||||
}
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
|
||||
Z3_bool Z3_API Z3_is_array_value(Z3_context c, Z3_model _m, Z3_ast _v, unsigned* size) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_is_array_value(c, _m, _v, size);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(_v, Z3_FALSE);
|
||||
CHECK_NON_NULL(_m, Z3_FALSE);
|
||||
model * m = to_model_ref(_m);
|
||||
expr * v = to_expr(_v);
|
||||
ast_manager& mgr = mk_c(c)->m();
|
||||
family_id afid = mk_c(c)->get_array_fid();
|
||||
unsigned sz = 0;
|
||||
array_util pl(mgr);
|
||||
if (pl.is_as_array(v)) {
|
||||
func_decl* f = pl.get_as_array_func_decl(to_app(v));
|
||||
func_interp* g = m->get_func_interp(f);
|
||||
sz = g->num_entries();
|
||||
if (sz > 0 && g->get_arity() != 1) {
|
||||
return Z3_FALSE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (pl.is_store(v)) {
|
||||
if (to_app(v)->get_num_args() != 3) {
|
||||
return Z3_FALSE;
|
||||
}
|
||||
v = to_app(v)->get_arg(0);
|
||||
++sz;
|
||||
}
|
||||
if (!is_app_of(v, afid, OP_CONST_ARRAY)) {
|
||||
return Z3_FALSE;
|
||||
}
|
||||
}
|
||||
if (size) {
|
||||
*size = sz;
|
||||
}
|
||||
return Z3_TRUE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
|
||||
void Z3_API Z3_get_array_value(Z3_context c,
|
||||
Z3_model _m,
|
||||
Z3_ast _v,
|
||||
unsigned num_entries,
|
||||
Z3_ast indices[],
|
||||
Z3_ast values[],
|
||||
Z3_ast* else_value) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_array_value(c, _m, _v, num_entries, indices, values, else_value);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(_m, );
|
||||
model * m = to_model_ref(_m);
|
||||
|
||||
expr* v = to_expr(_v);
|
||||
family_id afid = mk_c(c)->get_array_fid();
|
||||
ast_manager& mgr = mk_c(c)->m();
|
||||
array_util pl(mgr);
|
||||
|
||||
//
|
||||
// note: _v is already reference counted.
|
||||
// saving the trail for the returned values
|
||||
// is redundant.
|
||||
//
|
||||
unsigned sz = 0;
|
||||
if (pl.is_as_array(v)) {
|
||||
func_decl* f = pl.get_as_array_func_decl(to_app(v));
|
||||
func_interp* g = m->get_func_interp(f);
|
||||
sz = g->num_entries();
|
||||
if (g->get_arity() != 1) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
for (unsigned i = 0; i < sz && i < num_entries; ++i) {
|
||||
indices[i] = of_ast(g->get_entry(i)->get_arg(0));
|
||||
values[i] = of_ast(g->get_entry(i)->get_result());
|
||||
}
|
||||
if (else_value) {
|
||||
*else_value = of_ast(g->get_else());
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (sz <= num_entries && is_app_of(v, afid, OP_STORE)) {
|
||||
app* a = to_app(v);
|
||||
if (a->get_num_args() != 3) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
expr* idx = a->get_arg(1);
|
||||
expr* val = a->get_arg(2);
|
||||
indices[sz] = of_ast(idx);
|
||||
values[sz] = of_ast(val);
|
||||
v = to_app(v)->get_arg(0);
|
||||
++sz;
|
||||
}
|
||||
|
||||
if (is_app_of(v, afid, OP_CONST_ARRAY)) {
|
||||
if (else_value) {
|
||||
*else_value = of_ast(to_app(v)->get_arg(0));
|
||||
}
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
}
|
||||
RETURN_Z3_get_array_value;
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_eval_decl(Z3_context c,
|
||||
Z3_model m,
|
||||
Z3_func_decl d,
|
||||
unsigned num_args,
|
||||
Z3_ast const args[],
|
||||
Z3_ast* v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_eval_decl(c, m, d, num_args, args, v);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, Z3_FALSE);
|
||||
ast_manager & mgr = mk_c(c)->m();
|
||||
model * _m = to_model_ref(m);
|
||||
app_ref app(mgr);
|
||||
app = mgr.mk_app(to_func_decl(d), num_args, to_exprs(args));
|
||||
expr_ref result(mgr);
|
||||
_m->eval(app.get(), result);
|
||||
mk_c(c)->save_ast_trail(result.get());
|
||||
*v = of_ast(result.get());
|
||||
RETURN_Z3_eval_decl Z3_TRUE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
char const * Z3_API Z3_model_to_string(Z3_context c, Z3_model m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_model_to_string(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_NON_NULL(m, 0);
|
||||
std::ostringstream buffer;
|
||||
std::string result;
|
||||
if (mk_c(c)->get_print_mode() == Z3_PRINT_SMTLIB2_COMPLIANT) {
|
||||
model_smt2_pp(buffer, mk_c(c)->m(), *(to_model_ref(m)), 0);
|
||||
// Hack for removing the trailing '\n'
|
||||
result = buffer.str();
|
||||
if (result.size() != 0)
|
||||
result.resize(result.size()-1);
|
||||
}
|
||||
else {
|
||||
model_v2_pp(buffer, *(to_model_ref(m)), mk_c(c)->fparams().m_model_partial);
|
||||
result = buffer.str();
|
||||
}
|
||||
return mk_c(c)->mk_external_string(result);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
};
|
58
src/api/api_model.h
Normal file
58
src/api/api_model.h
Normal file
|
@ -0,0 +1,58 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_model.h
|
||||
|
||||
Abstract:
|
||||
API for models
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-08.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_MODEL_H_
|
||||
#define _API_MODEL_H_
|
||||
|
||||
#include"api_util.h"
|
||||
#include"model.h"
|
||||
|
||||
struct Z3_model_ref : public api::object {
|
||||
model_ref m_model;
|
||||
Z3_model_ref() {}
|
||||
virtual ~Z3_model_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_model_ref * to_model(Z3_model s) { return reinterpret_cast<Z3_model_ref *>(s); }
|
||||
inline Z3_model of_model(Z3_model_ref * s) { return reinterpret_cast<Z3_model>(s); }
|
||||
inline model * to_model_ref(Z3_model s) { return to_model(s)->m_model.get(); }
|
||||
|
||||
struct Z3_func_interp_ref : public api::object {
|
||||
model_ref m_model; // must have it to prevent reference to m_func_interp to be killed.
|
||||
func_interp * m_func_interp;
|
||||
Z3_func_interp_ref(model * m):m_model(m), m_func_interp(0) {}
|
||||
virtual ~Z3_func_interp_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_func_interp_ref * to_func_interp(Z3_func_interp s) { return reinterpret_cast<Z3_func_interp_ref *>(s); }
|
||||
inline Z3_func_interp of_func_interp(Z3_func_interp_ref * s) { return reinterpret_cast<Z3_func_interp>(s); }
|
||||
inline func_interp * to_func_interp_ref(Z3_func_interp s) { return to_func_interp(s)->m_func_interp; }
|
||||
|
||||
struct Z3_func_entry_ref : public api::object {
|
||||
model_ref m_model; // must have it to prevent reference to m_func_entry to be killed.
|
||||
func_interp * m_func_interp;
|
||||
func_entry const * m_func_entry;
|
||||
Z3_func_entry_ref(model * m):m_model(m), m_func_interp(0), m_func_entry(0) {}
|
||||
virtual ~Z3_func_entry_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_func_entry_ref * to_func_entry(Z3_func_entry s) { return reinterpret_cast<Z3_func_entry_ref *>(s); }
|
||||
inline Z3_func_entry of_func_entry(Z3_func_entry_ref * s) { return reinterpret_cast<Z3_func_entry>(s); }
|
||||
inline func_entry const * to_func_entry_ref(Z3_func_entry s) { return to_func_entry(s)->m_func_entry; }
|
||||
|
||||
|
||||
#endif
|
340
src/api/api_numeral.cpp
Normal file
340
src/api/api_numeral.cpp
Normal file
|
@ -0,0 +1,340 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_numeral.cpp
|
||||
|
||||
Abstract:
|
||||
API for handling numerals in Z3
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"bv_decl_plugin.h"
|
||||
#include"algebraic_numbers.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
bool is_numeral_sort(Z3_context c, Z3_sort ty) {
|
||||
sort * _ty = to_sort(ty);
|
||||
family_id fid = _ty->get_family_id();
|
||||
if (fid != mk_c(c)->get_arith_fid() &&
|
||||
fid != mk_c(c)->get_bv_fid() &&
|
||||
fid != mk_c(c)->get_datalog_fid()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool check_numeral_sort(Z3_context c, Z3_sort ty) {
|
||||
bool is_num = is_numeral_sort(c, ty);
|
||||
if (!is_num) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
}
|
||||
return is_num;
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_numeral(Z3_context c, const char* n, Z3_sort ty) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_numeral(c, n, ty);
|
||||
RESET_ERROR_CODE();
|
||||
if (!check_numeral_sort(c, ty)) {
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
if (!n) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
std::string fixed_num;
|
||||
char const* m = n;
|
||||
while (*m) {
|
||||
if (!(('0' <= *m && *m <= '9') ||
|
||||
('/' == *m) || ('-' == *m) ||
|
||||
(' ' == *m) || ('\n' == *m) ||
|
||||
('.' == *m) || ('e' == *m) ||
|
||||
('E' == *m))) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
++m;
|
||||
}
|
||||
ast * a = mk_c(c)->mk_numeral_core(rational(n), to_sort(ty));
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_int(Z3_context c, int value, Z3_sort ty) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_int(c, value, ty);
|
||||
RESET_ERROR_CODE();
|
||||
if (!check_numeral_sort(c, ty)) {
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ast * a = mk_c(c)->mk_numeral_core(rational(value), to_sort(ty));
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_unsigned_int(Z3_context c, unsigned value, Z3_sort ty) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_unsigned_int(c, value, ty);
|
||||
RESET_ERROR_CODE();
|
||||
if (!check_numeral_sort(c, ty)) {
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
ast * a = mk_c(c)->mk_numeral_core(rational(value), to_sort(ty));
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_int64(Z3_context c, long long value, Z3_sort ty) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_int64(c, value, ty);
|
||||
RESET_ERROR_CODE();
|
||||
if (!check_numeral_sort(c, ty)) {
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
rational n(value, rational::i64());
|
||||
ast* a = mk_c(c)->mk_numeral_core(n, to_sort(ty));
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_unsigned_int64(Z3_context c, unsigned long long value, Z3_sort ty) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_unsigned_int64(c, value, ty);
|
||||
RESET_ERROR_CODE();
|
||||
if (!check_numeral_sort(c, ty)) {
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
rational n(value, rational::ui64());
|
||||
ast * a = mk_c(c)->mk_numeral_core(n, to_sort(ty));
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_numeral_ast(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_is_numeral_ast(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
expr* e = to_expr(a);
|
||||
return
|
||||
mk_c(c)->autil().is_numeral(e) ||
|
||||
mk_c(c)->bvutil().is_numeral(e);
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_get_numeral_rational(Z3_context c, Z3_ast a, rational& r) {
|
||||
Z3_TRY;
|
||||
// This function is not part of the public API
|
||||
RESET_ERROR_CODE();
|
||||
expr* e = to_expr(a);
|
||||
if (!e) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return Z3_FALSE;
|
||||
}
|
||||
if (mk_c(c)->autil().is_numeral(e, r)) {
|
||||
return Z3_TRUE;
|
||||
}
|
||||
unsigned bv_size;
|
||||
if (mk_c(c)->bvutil().is_numeral(e, r, bv_size)) {
|
||||
return Z3_TRUE;
|
||||
}
|
||||
uint64 v;
|
||||
if (mk_c(c)->datalog_util().is_numeral(e, v)) {
|
||||
r = rational(v, rational::ui64());
|
||||
return Z3_TRUE;
|
||||
}
|
||||
return Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
|
||||
Z3_string Z3_API Z3_get_numeral_string(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
// This function invokes Z3_get_numeral_rational, but it is still ok to add LOG command here because it does not return a Z3 object.
|
||||
LOG_Z3_get_numeral_string(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
rational r;
|
||||
Z3_bool ok = Z3_get_numeral_rational(c, a, r);
|
||||
if (ok == Z3_TRUE) {
|
||||
return mk_c(c)->mk_external_string(r.to_string());
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return "";
|
||||
}
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_get_numeral_decimal_string(Z3_context c, Z3_ast a, unsigned precision) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_numeral_decimal_string(c, a, precision);
|
||||
RESET_ERROR_CODE();
|
||||
expr* e = to_expr(a);
|
||||
if (!e) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return "";
|
||||
}
|
||||
rational r;
|
||||
arith_util & u = mk_c(c)->autil();
|
||||
if (u.is_numeral(e, r) && !r.is_int()) {
|
||||
std::ostringstream buffer;
|
||||
r.display_decimal(buffer, precision);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
}
|
||||
if (u.is_irrational_algebraic_numeral(e)) {
|
||||
algebraic_numbers::anum const & n = u.to_irrational_algebraic_numeral(e);
|
||||
algebraic_numbers::manager & am = u.am();
|
||||
std::ostringstream buffer;
|
||||
am.display_decimal(buffer, n, precision);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
}
|
||||
Z3_bool ok = Z3_get_numeral_rational(c, a, r);
|
||||
if (ok == Z3_TRUE) {
|
||||
return mk_c(c)->mk_external_string(r.to_string());
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return "";
|
||||
}
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_get_numeral_small(Z3_context c, Z3_ast a, long long* num, long long* den) {
|
||||
Z3_TRY;
|
||||
// This function invokes Z3_get_numeral_rational, but it is still ok to add LOG command here because it does not return a Z3 object.
|
||||
LOG_Z3_get_numeral_small(c, a, num, den);
|
||||
RESET_ERROR_CODE();
|
||||
rational r;
|
||||
Z3_bool ok = Z3_get_numeral_rational(c, a, r);
|
||||
if (ok == Z3_TRUE) {
|
||||
rational n = numerator(r);
|
||||
rational d = denominator(r);
|
||||
if (n.is_int64() && d.is_int64()) {
|
||||
*num = n.get_int64();
|
||||
*den = d.get_int64();
|
||||
return Z3_TRUE;
|
||||
}
|
||||
else {
|
||||
return Z3_FALSE;
|
||||
}
|
||||
}
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
|
||||
Z3_bool Z3_API Z3_get_numeral_int(Z3_context c, Z3_ast v, int* i) {
|
||||
Z3_TRY;
|
||||
// This function invokes Z3_get_numeral_int64, but it is still ok to add LOG command here because it does not return a Z3 object.
|
||||
LOG_Z3_get_numeral_int(c, v, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (!i) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return Z3_FALSE;
|
||||
}
|
||||
long long l;
|
||||
if (Z3_get_numeral_int64(c, v, &l) && l >= INT_MIN && l <= INT_MAX) {
|
||||
*i = static_cast<int>(l);
|
||||
return Z3_TRUE;
|
||||
}
|
||||
return Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_get_numeral_uint(Z3_context c, Z3_ast v, unsigned* u) {
|
||||
Z3_TRY;
|
||||
// This function invokes Z3_get_numeral_uint64, but it is still ok to add LOG command here because it does not return a Z3 object.
|
||||
LOG_Z3_get_numeral_uint(c, v, u);
|
||||
RESET_ERROR_CODE();
|
||||
if (!u) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return Z3_FALSE;
|
||||
}
|
||||
unsigned long long l;
|
||||
if (Z3_get_numeral_uint64(c, v, &l) && (l <= 0xFFFFFFFF)) {
|
||||
*u = static_cast<unsigned>(l);
|
||||
return Z3_TRUE;
|
||||
}
|
||||
return Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_get_numeral_uint64(Z3_context c, Z3_ast v, unsigned long long* u) {
|
||||
Z3_TRY;
|
||||
// This function invokes Z3_get_numeral_rational, but it is still ok to add LOG command here because it does not return a Z3 object.
|
||||
LOG_Z3_get_numeral_uint64(c, v, u);
|
||||
RESET_ERROR_CODE();
|
||||
if (!u) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return Z3_FALSE;
|
||||
}
|
||||
rational r;
|
||||
Z3_bool ok = Z3_get_numeral_rational(c, v, r);
|
||||
SASSERT(u);
|
||||
if (ok == Z3_TRUE && r.is_uint64()) {
|
||||
*u = r.get_uint64();
|
||||
return ok;
|
||||
}
|
||||
return Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_get_numeral_int64(Z3_context c, Z3_ast v, long long* i) {
|
||||
Z3_TRY;
|
||||
// This function invokes Z3_get_numeral_rational, but it is still ok to add LOG command here because it does not return a Z3 object.
|
||||
LOG_Z3_get_numeral_int64(c, v, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (!i) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return Z3_FALSE;
|
||||
}
|
||||
rational r;
|
||||
Z3_bool ok = Z3_get_numeral_rational(c, v, r);
|
||||
if (ok == Z3_TRUE && r.is_int64()) {
|
||||
*i = r.get_int64();
|
||||
return ok;
|
||||
}
|
||||
return Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_get_numeral_rational_int64(Z3_context c, Z3_ast v, long long* num, long long* den) {
|
||||
Z3_TRY;
|
||||
// This function invokes Z3_get_numeral_rational, but it is still ok to add LOG command here because it does not return a Z3 object.
|
||||
LOG_Z3_get_numeral_rational_int64(c, v, num, den);
|
||||
RESET_ERROR_CODE();
|
||||
if (!num || !den) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return Z3_FALSE;
|
||||
}
|
||||
rational r;
|
||||
Z3_bool ok = Z3_get_numeral_rational(c, v, r);
|
||||
if (ok != Z3_TRUE) {
|
||||
return ok;
|
||||
}
|
||||
rational n = numerator(r);
|
||||
rational d = denominator(r);
|
||||
if (n.is_int64() && d.is_int64()) {
|
||||
*num = n.get_int64();
|
||||
*den = d.get_int64();
|
||||
return ok;
|
||||
}
|
||||
return Z3_FALSE;
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
};
|
199
src/api/api_params.cpp
Normal file
199
src/api/api_params.cpp
Normal file
|
@ -0,0 +1,199 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_params.cpp
|
||||
|
||||
Abstract:
|
||||
API for creating parameter sets.
|
||||
|
||||
This is essentially a wrapper for params_ref.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-05.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"params.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_params Z3_API Z3_mk_params(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_params(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_params_ref * p = alloc(Z3_params_ref);
|
||||
mk_c(c)->save_object(p);
|
||||
Z3_params r = of_params(p);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Increment the reference counter of the given parameter set.
|
||||
*/
|
||||
void Z3_API Z3_params_inc_ref(Z3_context c, Z3_params p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_params_inc_ref(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
to_params(p)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Decrement the reference counter of the given parameter set.
|
||||
*/
|
||||
void Z3_API Z3_params_dec_ref(Z3_context c, Z3_params p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_params_dec_ref(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
to_params(p)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Add a Boolean parameter \c k with value \c v to the parameter set \c p.
|
||||
*/
|
||||
void Z3_API Z3_params_set_bool(Z3_context c, Z3_params p, Z3_symbol k, Z3_bool v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_params_set_bool(c, p, k, v);
|
||||
RESET_ERROR_CODE();
|
||||
to_params(p)->m_params.set_bool(to_symbol(k), v != 0);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Add a unsigned parameter \c k with value \c v to the parameter set \c p.
|
||||
*/
|
||||
void Z3_API Z3_params_set_uint(Z3_context c, Z3_params p, Z3_symbol k, unsigned v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_params_set_uint(c, p, k, v);
|
||||
RESET_ERROR_CODE();
|
||||
to_params(p)->m_params.set_uint(to_symbol(k), v);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Add a double parameter \c k with value \c v to the parameter set \c p.
|
||||
*/
|
||||
void Z3_API Z3_params_set_double(Z3_context c, Z3_params p, Z3_symbol k, double v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_params_set_double(c, p, k, v);
|
||||
RESET_ERROR_CODE();
|
||||
to_params(p)->m_params.set_double(to_symbol(k), v);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Add a symbol parameter \c k with value \c v to the parameter set \c p.
|
||||
*/
|
||||
void Z3_API Z3_params_set_symbol(Z3_context c, Z3_params p, Z3_symbol k, Z3_symbol v) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_params_set_symbol(c, p, k, v);
|
||||
RESET_ERROR_CODE();
|
||||
to_params(p)->m_params.set_sym(to_symbol(k), to_symbol(v));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Convert a parameter set into a string. This function is mainly used for printing the
|
||||
contents of a parameter set.
|
||||
*/
|
||||
Z3_string Z3_API Z3_params_to_string(Z3_context c, Z3_params p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_params_to_string(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
to_params(p)->m_params.display(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
void Z3_API Z3_params_validate(Z3_context c, Z3_params p, Z3_param_descrs d) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_params_validate(c, p, d);
|
||||
RESET_ERROR_CODE();
|
||||
to_params(p)->m_params.validate(*to_param_descrs_ptr(d));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_param_descrs_inc_ref(Z3_context c, Z3_param_descrs p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_param_descrs_inc_ref(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
to_param_descrs(p)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_param_descrs_dec_ref(Z3_context c, Z3_param_descrs p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_param_descrs_dec_ref(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
to_param_descrs(p)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_param_kind Z3_API Z3_param_descrs_get_kind(Z3_context c, Z3_param_descrs p, Z3_symbol n) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_param_descrs_get_kind(c, p, n);
|
||||
RESET_ERROR_CODE();
|
||||
param_kind k = to_param_descrs_ptr(p)->get_kind(to_symbol(n));
|
||||
switch (k) {
|
||||
case CPK_UINT: return Z3_PK_UINT;
|
||||
case CPK_BOOL: return Z3_PK_BOOL;
|
||||
case CPK_DOUBLE: return Z3_PK_DOUBLE;
|
||||
case CPK_STRING: return Z3_PK_STRING;
|
||||
case CPK_SYMBOL: return Z3_PK_SYMBOL;
|
||||
case CPK_INVALID: return Z3_PK_INVALID;
|
||||
default: return Z3_PK_OTHER;
|
||||
}
|
||||
Z3_CATCH_RETURN(Z3_PK_INVALID);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_param_descrs_size(Z3_context c, Z3_param_descrs p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_param_descrs_size(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
return to_param_descrs_ptr(p)->size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_symbol Z3_API Z3_param_descrs_get_name(Z3_context c, Z3_param_descrs p, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_param_descrs_get_name(c, p, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (i >= to_param_descrs_ptr(p)->size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_symbol result = of_symbol(to_param_descrs_ptr(p)->get_param_name(i));
|
||||
return result;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_param_descrs_to_string(Z3_context c, Z3_param_descrs p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_param_descrs_to_string(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
buffer << "(";
|
||||
unsigned sz = to_param_descrs_ptr(p)->size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (i > 0)
|
||||
buffer << ", ";
|
||||
buffer << to_param_descrs_ptr(p)->get_param_name(i);
|
||||
}
|
||||
buffer << ")";
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
};
|
426
src/api/api_parsers.cpp
Normal file
426
src/api/api_parsers.cpp
Normal file
|
@ -0,0 +1,426 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_parsers.cpp
|
||||
|
||||
Abstract:
|
||||
API for parsing different formats
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"cmd_context.h"
|
||||
#include"smt2parser.h"
|
||||
#include"smtparser.h"
|
||||
#include"z3_solver.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
void init_smtlib_parser(Z3_context c,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol const sort_names[],
|
||||
Z3_sort const types[],
|
||||
unsigned num_decls,
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_func_decl const decls[]) {
|
||||
mk_c(c)->reset_parser();
|
||||
mk_c(c)->m_smtlib_parser = smtlib::parser::create(mk_c(c)->m());
|
||||
mk_c(c)->m_smtlib_parser->initialize_smtlib();
|
||||
smtlib::symtable * table = mk_c(c)->m_smtlib_parser->get_benchmark()->get_symtable();
|
||||
for (unsigned i = 0; i < num_sorts; i++) {
|
||||
table->insert(to_symbol(sort_names[i]), to_sort(types[i]));
|
||||
}
|
||||
for (unsigned i = 0; i < num_decls; i++) {
|
||||
table->insert(to_symbol(decl_names[i]), to_func_decl(decls[i]));
|
||||
}
|
||||
}
|
||||
|
||||
void Z3_API Z3_parse_smtlib_string(Z3_context c,
|
||||
const char * str,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol const sort_names[],
|
||||
Z3_sort const sorts[],
|
||||
unsigned num_decls,
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_func_decl const decls[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parse_smtlib_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
std::ostringstream outs;
|
||||
bool ok = false;
|
||||
|
||||
RESET_ERROR_CODE();
|
||||
init_smtlib_parser(c, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
mk_c(c)->m_smtlib_parser->set_error_stream(outs);
|
||||
try {
|
||||
ok = mk_c(c)->m_smtlib_parser->parse_string(str);
|
||||
}
|
||||
catch (...) {
|
||||
ok = false;
|
||||
}
|
||||
mk_c(c)->m_smtlib_error_buffer = outs.str();
|
||||
if (!ok) {
|
||||
mk_c(c)->reset_parser();
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_parse_smtlib_file(Z3_context c,
|
||||
const char * file_name,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol const sort_names[],
|
||||
Z3_sort const types[],
|
||||
unsigned num_decls,
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_func_decl const decls[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parse_smtlib_file(c, file_name, num_sorts, sort_names, types, num_decls, decl_names, decls);
|
||||
bool ok = false;
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream outs;
|
||||
init_smtlib_parser(c, num_sorts, sort_names, types, num_decls, decl_names, decls);
|
||||
mk_c(c)->m_smtlib_parser->set_error_stream(outs);
|
||||
try {
|
||||
ok = mk_c(c)->m_smtlib_parser->parse_file(file_name);
|
||||
}
|
||||
catch(...) {
|
||||
ok = false;
|
||||
}
|
||||
mk_c(c)->m_smtlib_error_buffer = outs.str();
|
||||
if (!ok) {
|
||||
mk_c(c)->reset_parser();
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_smtlib_num_formulas(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_smtlib_num_formulas(c);
|
||||
RESET_ERROR_CODE();
|
||||
if (mk_c(c)->m_smtlib_parser) {
|
||||
return mk_c(c)->m_smtlib_parser->get_benchmark()->get_num_formulas();
|
||||
}
|
||||
SET_ERROR_CODE(Z3_NO_PARSER);
|
||||
return 0;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_smtlib_formula(Z3_context c, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_smtlib_formula(c, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (mk_c(c)->m_smtlib_parser) {
|
||||
if (i < mk_c(c)->m_smtlib_parser->get_benchmark()->get_num_formulas()) {
|
||||
ast * f = mk_c(c)->m_smtlib_parser->get_benchmark()->begin_formulas()[i];
|
||||
mk_c(c)->save_ast_trail(f);
|
||||
RETURN_Z3(of_ast(f));
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_NO_PARSER);
|
||||
}
|
||||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_smtlib_num_assumptions(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_smtlib_num_assumptions(c);
|
||||
RESET_ERROR_CODE();
|
||||
if (mk_c(c)->m_smtlib_parser) {
|
||||
return mk_c(c)->m_smtlib_parser->get_benchmark()->get_num_axioms();
|
||||
}
|
||||
SET_ERROR_CODE(Z3_NO_PARSER);
|
||||
return 0;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_smtlib_assumption(Z3_context c, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_smtlib_assumption(c, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (mk_c(c)->m_smtlib_parser) {
|
||||
if (i < mk_c(c)->m_smtlib_parser->get_benchmark()->get_num_axioms()) {
|
||||
ast * a = mk_c(c)->m_smtlib_parser->get_benchmark()->begin_axioms()[i];
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_NO_PARSER);
|
||||
}
|
||||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_smtlib_num_decls(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_smtlib_num_decls(c);
|
||||
RESET_ERROR_CODE();
|
||||
if (mk_c(c)->m_smtlib_parser) {
|
||||
mk_c(c)->extract_smtlib_parser_decls();
|
||||
return mk_c(c)->m_smtlib_parser_decls.size();
|
||||
}
|
||||
SET_ERROR_CODE(Z3_NO_PARSER);
|
||||
return 0;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_get_smtlib_decl(Z3_context c, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_smtlib_decl(c, i);
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->extract_smtlib_parser_decls();
|
||||
if (mk_c(c)->m_smtlib_parser) {
|
||||
if (i < mk_c(c)->m_smtlib_parser_decls.size()) {
|
||||
func_decl * d = mk_c(c)->m_smtlib_parser_decls[i];
|
||||
mk_c(c)->save_ast_trail(d);
|
||||
RETURN_Z3(of_func_decl(d));
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_NO_PARSER);
|
||||
}
|
||||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_smtlib_num_sorts(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_smtlib_num_sorts(c);
|
||||
RESET_ERROR_CODE();
|
||||
if (mk_c(c)->m_smtlib_parser) {
|
||||
mk_c(c)->extract_smtlib_parser_decls();
|
||||
return mk_c(c)->m_smtlib_parser_sorts.size();
|
||||
}
|
||||
SET_ERROR_CODE(Z3_NO_PARSER);
|
||||
return 0;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_get_smtlib_sort(Z3_context c, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_smtlib_sort(c, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (mk_c(c)->m_smtlib_parser) {
|
||||
mk_c(c)->extract_smtlib_parser_decls();
|
||||
if (i < mk_c(c)->m_smtlib_parser_sorts.size()) {
|
||||
sort* s = mk_c(c)->m_smtlib_parser_sorts[i];
|
||||
mk_c(c)->save_ast_trail(s);
|
||||
RETURN_Z3(of_sort(s));
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_NO_PARSER);
|
||||
}
|
||||
RETURN_Z3(0);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_get_smtlib_error(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_smtlib_error(c);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->m_smtlib_error_buffer.c_str();
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_ast parse_z3_stream(Z3_context c, std::istream& is) {
|
||||
z3_solver parser(c, is, verbose_stream(), mk_c(c)->fparams(), false);
|
||||
if (!parser.parse()) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return of_ast(mk_c(c)->m().mk_true());
|
||||
}
|
||||
expr_ref_vector assumptions(mk_c(c)->m());
|
||||
parser.get_assumptions(assumptions);
|
||||
return of_ast(mk_c(c)->mk_and(assumptions.size(), assumptions.c_ptr()));
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_parse_z3_string(Z3_context c, Z3_string str) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parse_z3_string(c, str);
|
||||
std::string s(str);
|
||||
std::istringstream is(s);
|
||||
Z3_ast r = parse_z3_stream(c, is);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_parse_z3_file(Z3_context c, Z3_string file_name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parse_z3_file(c, file_name);
|
||||
std::ifstream is(file_name);
|
||||
if (!is) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
Z3_ast r = parse_z3_stream(c, is);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
// ---------------
|
||||
// Support for SMTLIB2
|
||||
|
||||
class z3_context_solver : public solver {
|
||||
api::context & m_ctx;
|
||||
smt::solver & ctx() const { return m_ctx.get_solver(); }
|
||||
public:
|
||||
virtual ~z3_context_solver() {}
|
||||
z3_context_solver(api::context& c) : m_ctx(c) {}
|
||||
virtual void init(ast_manager & m, symbol const & logic) {}
|
||||
virtual void collect_statistics(statistics & st) const {}
|
||||
virtual void reset() { ctx().reset(); }
|
||||
virtual void assert_expr(expr * t) { ctx().assert_expr(t); }
|
||||
virtual void push() { ctx().push(); }
|
||||
virtual void pop(unsigned n) { ctx().pop(n); }
|
||||
virtual unsigned get_scope_level() const { return ctx().get_scope_level(); }
|
||||
virtual lbool check_sat(unsigned num_assumptions, expr * const * assumptions) {
|
||||
return ctx().check(num_assumptions, assumptions);
|
||||
}
|
||||
virtual void get_unsat_core(ptr_vector<expr> & r) {
|
||||
unsigned sz = ctx().get_unsat_core_size();
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
r.push_back(ctx().get_unsat_core_expr(i));
|
||||
}
|
||||
virtual void get_model(model_ref & m) { ctx().get_model(m); }
|
||||
virtual proof * get_proof() { return ctx().get_proof(); }
|
||||
virtual std::string reason_unknown() const { return ctx().last_failure_as_string(); }
|
||||
virtual void get_labels(svector<symbol> & r) {
|
||||
buffer<symbol> tmp;
|
||||
ctx().get_relevant_labels(0, tmp);
|
||||
r.append(tmp.size(), tmp.c_ptr());
|
||||
}
|
||||
|
||||
// These are controlled by the main API
|
||||
virtual void set_cancel(bool f) { }
|
||||
void cancel() { set_cancel(true); }
|
||||
void reset_cancel() { set_cancel(false); }
|
||||
virtual void set_progress_callback(progress_callback * callback) {}
|
||||
};
|
||||
|
||||
Z3_ast parse_smtlib2_stream(bool exec, Z3_context c, std::istream& is,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol const sort_names[],
|
||||
Z3_sort const sorts[],
|
||||
unsigned num_decls,
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_func_decl const decls[]) {
|
||||
Z3_TRY;
|
||||
cmd_context ctx(mk_c(c)->fparams(), false, &(mk_c(c)->m()));
|
||||
ctx.set_ignore_check(true);
|
||||
if (exec) {
|
||||
ctx.set_solver(alloc(z3_context_solver, *mk_c(c)));
|
||||
}
|
||||
for (unsigned i = 0; i < num_decls; ++i) {
|
||||
ctx.insert(to_symbol(decl_names[i]), to_func_decl(decls[i]));
|
||||
}
|
||||
for (unsigned i = 0; i < num_sorts; ++i) {
|
||||
psort* ps = ctx.pm().mk_psort_cnst(to_sort(sorts[i]));
|
||||
ctx.insert(ctx.pm().mk_psort_user_decl(0, to_symbol(sort_names[i]), ps));
|
||||
}
|
||||
if (!parse_smt2_commands(ctx, is)) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return of_ast(mk_c(c)->m().mk_true());
|
||||
}
|
||||
ptr_vector<expr>::const_iterator it = ctx.begin_assertions();
|
||||
ptr_vector<expr>::const_iterator end = ctx.end_assertions();
|
||||
unsigned size = static_cast<unsigned>(end - it);
|
||||
return of_ast(mk_c(c)->mk_and(size, it));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_parse_smtlib2_string(Z3_context c, Z3_string str,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol const sort_names[],
|
||||
Z3_sort const sorts[],
|
||||
unsigned num_decls,
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_func_decl const decls[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parse_smtlib2_string(c, str, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
std::string s(str);
|
||||
std::istringstream is(s);
|
||||
Z3_ast r = parse_smtlib2_stream(false, c, is, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_parse_smtlib2_file(Z3_context c, Z3_string file_name,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol const sort_names[],
|
||||
Z3_sort const sorts[],
|
||||
unsigned num_decls,
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_func_decl const decls[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_parse_smtlib2_string(c, file_name, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
std::ifstream is(file_name);
|
||||
if (!is) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
Z3_ast r = parse_smtlib2_stream(false, c, is, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_exec_smtlib2_string(Z3_context c, Z3_string str,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol sort_names[],
|
||||
Z3_sort sorts[],
|
||||
unsigned num_decls,
|
||||
Z3_symbol decl_names[],
|
||||
Z3_func_decl decls[]) {
|
||||
Z3_TRY;
|
||||
cmd_context ctx(mk_c(c)->fparams(), false, &(mk_c(c)->m()));
|
||||
std::string s(str);
|
||||
std::istringstream is(s);
|
||||
// No logging for this one, since it private.
|
||||
return parse_smtlib2_stream(true, c, is, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_exec_smtlib2_file(Z3_context c, Z3_string file_name,
|
||||
unsigned num_sorts,
|
||||
Z3_symbol sort_names[],
|
||||
Z3_sort sorts[],
|
||||
unsigned num_decls,
|
||||
Z3_symbol decl_names[],
|
||||
Z3_func_decl decls[]) {
|
||||
Z3_TRY;
|
||||
std::ifstream is(file_name);
|
||||
if (!is) {
|
||||
SET_ERROR_CODE(Z3_PARSER_ERROR);
|
||||
return 0;
|
||||
}
|
||||
// No logging for this one, since it private.
|
||||
return parse_smtlib2_stream(true, c, is, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
};
|
78
src/api/api_poly.cpp
Normal file
78
src/api/api_poly.cpp
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_poly.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
External API for polynomial package
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-10-18.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"z3.h"
|
||||
#include"z3_internal.h"
|
||||
#include"api_context.h"
|
||||
#include"api_poly.h"
|
||||
#include"api_util.h"
|
||||
#include"api_log_macros.h"
|
||||
|
||||
Z3_polynomial_manager Z3_mk_polynomial_manager(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_polynomial_manager(c);
|
||||
RESET_ERROR_CODE();
|
||||
_Z3_polynomial_manager * m = alloc(_Z3_polynomial_manager);
|
||||
RETURN_Z3(of_poly_manager(m));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_del_polynomial_manager(Z3_context c, Z3_polynomial_manager m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_del_polynomial_manager(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
dealloc(to_poly_manager(m));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_polynomial Z3_mk_zero_polynomial(Z3_context c, Z3_polynomial_manager m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_zero_polynomial(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
polynomial::polynomial * r = to_poly_manager(m)->m_manager.mk_zero();
|
||||
to_poly_manager(m)->m_result = r;
|
||||
RETURN_Z3(of_poly(r));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_polynomial_inc_ref(Z3_context c, Z3_polynomial_manager m, Z3_polynomial p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_polynomial_inc_ref(c, m, p);
|
||||
RESET_ERROR_CODE();
|
||||
to_poly_manager(m)->m_manager.inc_ref(to_poly(p));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_polynomial_dec_ref(Z3_context c, Z3_polynomial_manager m, Z3_polynomial p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_polynomial_inc_ref(c, m, p);
|
||||
RESET_ERROR_CODE();
|
||||
to_poly_manager(m)->m_manager.dec_ref(to_poly(p));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_string Z3_polynomial_to_string(Z3_context c, Z3_polynomial_manager m, Z3_polynomial p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_polynomial_to_string(c, m, p);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
to_poly_manager(m)->m_manager.display(buffer, to_poly(p));
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
40
src/api/api_poly.h
Normal file
40
src/api/api_poly.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_poly.h
|
||||
|
||||
Abstract:
|
||||
External API for polynomial package
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-10-18.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_POLY_H_
|
||||
#define _API_POLY_H_
|
||||
|
||||
#include"polynomial.h"
|
||||
|
||||
struct _Z3_polynomial_manager {
|
||||
unsynch_mpz_manager m_num_manager;
|
||||
polynomial::manager m_manager;
|
||||
polynomial_ref m_result;
|
||||
|
||||
_Z3_polynomial_manager():
|
||||
m_manager(m_num_manager),
|
||||
m_result(m_manager) {
|
||||
}
|
||||
};
|
||||
|
||||
inline _Z3_polynomial_manager * to_poly_manager(Z3_polynomial_manager m) { return reinterpret_cast<_Z3_polynomial_manager*>(m); }
|
||||
inline Z3_polynomial_manager of_poly_manager(_Z3_polynomial_manager * m) { return reinterpret_cast<Z3_polynomial_manager>(m); }
|
||||
|
||||
inline polynomial::polynomial * to_poly(Z3_polynomial p) { return reinterpret_cast<polynomial::polynomial*>(p); }
|
||||
inline Z3_polynomial of_poly(polynomial::polynomial * p) { return reinterpret_cast<Z3_polynomial>(p); }
|
||||
|
||||
#endif
|
511
src/api/api_quant.cpp
Normal file
511
src/api/api_quant.cpp
Normal file
|
@ -0,0 +1,511 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_quant.cpp
|
||||
|
||||
Abstract:
|
||||
API for quantifiers
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"pattern_validation.h"
|
||||
#include"expr_abstract.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier(
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body)
|
||||
{
|
||||
return Z3_mk_quantifier_ex(
|
||||
c,
|
||||
is_forall,
|
||||
weight,
|
||||
0,
|
||||
0,
|
||||
num_patterns, patterns,
|
||||
0, 0,
|
||||
num_decls, sorts,
|
||||
decl_names,
|
||||
body
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
Z3_ast mk_quantifier_ex_core(
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_symbol quantifier_id,
|
||||
Z3_symbol skolem_id,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
if (!mk_c(c)->m().is_bool(to_expr(body))) {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
}
|
||||
if (num_patterns > 0 && num_no_patterns > 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
}
|
||||
expr * const* ps = reinterpret_cast<expr * const*>(patterns);
|
||||
expr * const* no_ps = reinterpret_cast<expr * const*>(no_patterns);
|
||||
pattern_validator v(mk_c(c)->m());
|
||||
for (unsigned i = 0; i < num_patterns; i++) {
|
||||
if (!v(num_decls, ps[i])) {
|
||||
SET_ERROR_CODE(Z3_INVALID_PATTERN);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
sort* const* ts = reinterpret_cast<sort * const*>(sorts);
|
||||
svector<symbol> names;
|
||||
for (unsigned i = 0; i < num_decls; ++i) {
|
||||
names.push_back(to_symbol(decl_names[i]));
|
||||
}
|
||||
expr_ref result(mk_c(c)->m());
|
||||
if (num_decls > 0) {
|
||||
result = mk_c(c)->m().mk_quantifier(
|
||||
(0 != is_forall),
|
||||
names.size(), ts, names.c_ptr(), to_expr(body),
|
||||
weight,
|
||||
to_symbol(quantifier_id),
|
||||
to_symbol(skolem_id),
|
||||
num_patterns, ps,
|
||||
num_no_patterns, no_ps
|
||||
);
|
||||
}
|
||||
else {
|
||||
result = to_expr(body);
|
||||
}
|
||||
mk_c(c)->save_ast_trail(result.get());
|
||||
return of_ast(result.get());
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier_ex(
|
||||
Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_symbol quantifier_id,
|
||||
Z3_symbol skolem_id,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns, Z3_ast const no_patterns[],
|
||||
unsigned num_decls, Z3_sort const sorts[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body)
|
||||
{
|
||||
LOG_Z3_mk_quantifier_ex(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
num_no_patterns, no_patterns, num_decls, sorts, decl_names, body);
|
||||
Z3_ast r = mk_quantifier_ex_core(c, is_forall, weight, quantifier_id, skolem_id, num_patterns, patterns,
|
||||
num_no_patterns, no_patterns, num_decls, sorts, decl_names, body);
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_forall(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier(c, 1, weight, num_patterns, patterns, num_decls, types, decl_names, body);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_exists(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_patterns, Z3_pattern const patterns[],
|
||||
unsigned num_decls, Z3_sort const types[],
|
||||
Z3_symbol const decl_names[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier(c, 0, weight, num_patterns, patterns, num_decls, types, decl_names, body);
|
||||
}
|
||||
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const_ex(Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
Z3_symbol quantifier_id,
|
||||
Z3_symbol skolem_id,
|
||||
unsigned num_bound,
|
||||
Z3_app const bound[],
|
||||
unsigned num_patterns,
|
||||
Z3_pattern const patterns[],
|
||||
unsigned num_no_patterns,
|
||||
Z3_ast const no_patterns[],
|
||||
Z3_ast body) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_quantifier_const_ex(c, is_forall, weight, quantifier_id, skolem_id, num_bound, bound, num_patterns, patterns,
|
||||
num_no_patterns, no_patterns, body);
|
||||
RESET_ERROR_CODE();
|
||||
svector<Z3_symbol> names;
|
||||
svector<Z3_sort> types;
|
||||
ptr_vector<expr> bound_asts;
|
||||
if (num_patterns > 0 && num_no_patterns > 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
}
|
||||
for (unsigned i = 0; i < num_bound; ++i) {
|
||||
app* a = to_app(bound[i]);
|
||||
SASSERT(a->get_kind() == AST_APP);
|
||||
symbol s(to_app(a)->get_decl()->get_name());
|
||||
names.push_back(of_symbol(s));
|
||||
types.push_back(of_sort(mk_c(c)->m().get_sort(a)));
|
||||
bound_asts.push_back(a);
|
||||
if (a->get_family_id() != null_family_id || a->get_num_args() != 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
}
|
||||
// Abstract patterns
|
||||
svector<Z3_pattern> _patterns;
|
||||
expr_ref_vector pinned(mk_c(c)->m());
|
||||
for (unsigned i = 0; i < num_patterns; ++i) {
|
||||
expr_ref result(mk_c(c)->m());
|
||||
app* pat = to_pattern(patterns[i]);
|
||||
SASSERT(mk_c(c)->m().is_pattern(pat));
|
||||
expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
pinned.push_back(result.get());
|
||||
SASSERT(mk_c(c)->m().is_pattern(result.get()));
|
||||
_patterns.push_back(of_pattern(result.get()));
|
||||
}
|
||||
svector<Z3_ast> _no_patterns;
|
||||
for (unsigned i = 0; i < num_no_patterns; ++i) {
|
||||
expr_ref result(mk_c(c)->m());
|
||||
if (!is_app(to_expr(no_patterns[i]))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
app* pat = to_app(to_expr(no_patterns[i]));
|
||||
expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), pat, result);
|
||||
SASSERT(result.get()->get_kind() == AST_APP);
|
||||
pinned.push_back(result.get());
|
||||
_no_patterns.push_back(of_ast(result.get()));
|
||||
}
|
||||
expr_ref abs_body(mk_c(c)->m());
|
||||
expr_abstract(mk_c(c)->m(), 0, num_bound, bound_asts.c_ptr(), to_expr(body), abs_body);
|
||||
|
||||
Z3_ast result = mk_quantifier_ex_core(c, is_forall, weight,
|
||||
quantifier_id,
|
||||
skolem_id,
|
||||
num_patterns, _patterns.c_ptr(),
|
||||
num_no_patterns, _no_patterns.c_ptr(),
|
||||
names.size(), types.c_ptr(), names.c_ptr(),
|
||||
of_ast(abs_body.get()));
|
||||
RETURN_Z3(result);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_quantifier_const(Z3_context c,
|
||||
Z3_bool is_forall,
|
||||
unsigned weight,
|
||||
unsigned num_bound,
|
||||
Z3_app const bound[],
|
||||
unsigned num_patterns,
|
||||
Z3_pattern const patterns[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier_const_ex(c, is_forall, weight, 0, 0,
|
||||
num_bound, bound,
|
||||
num_patterns, patterns,
|
||||
0, 0,
|
||||
body);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_forall_const(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_bound,
|
||||
Z3_app const bound[],
|
||||
unsigned num_patterns,
|
||||
Z3_pattern const patterns[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier_const(c, true, weight, num_bound, bound, num_patterns, patterns, body);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_exists_const(Z3_context c,
|
||||
unsigned weight,
|
||||
unsigned num_bound,
|
||||
Z3_app const bound[],
|
||||
unsigned num_patterns,
|
||||
Z3_pattern const patterns[],
|
||||
Z3_ast body) {
|
||||
return Z3_mk_quantifier_const(c, false, weight, num_bound, bound, num_patterns, patterns, body);
|
||||
}
|
||||
|
||||
Z3_pattern Z3_API Z3_mk_pattern(Z3_context c, unsigned num_patterns, Z3_ast const terms[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_pattern(c, num_patterns, terms);
|
||||
RESET_ERROR_CODE();
|
||||
for (unsigned i = 0; i < num_patterns; ++i) {
|
||||
if (!is_app(to_expr(terms[i]))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
}
|
||||
app* a = mk_c(c)->m().mk_pattern(num_patterns, reinterpret_cast<app*const*>(to_exprs(terms)));
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_pattern(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_mk_bound(Z3_context c, unsigned index, Z3_sort ty) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_bound(c, index, ty);
|
||||
RESET_ERROR_CODE();
|
||||
ast* a = mk_c(c)->m().mk_var(index, to_sort(ty));
|
||||
mk_c(c)->save_ast_trail(a);
|
||||
RETURN_Z3(of_ast(a));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_is_quantifier_forall(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_is_quantifier_forall(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
return to_quantifier(_a)->is_forall();
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return Z3_FALSE;
|
||||
}
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_quantifier_weight(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_quantifier_weight(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
return to_quantifier(_a)->get_weight();
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_quantifier_num_patterns(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_quantifier_num_patterns(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
return to_quantifier(_a)->get_num_patterns();
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_pattern Z3_API Z3_get_quantifier_pattern_ast(Z3_context c, Z3_ast a, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_quantifier_pattern_ast(c, a, i);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
Z3_pattern r = of_pattern(to_quantifier(_a)->get_patterns()[i]);
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
unsigned Z3_API Z3_get_quantifier_num_no_patterns(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_quantifier_num_no_patterns(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
return to_quantifier(_a)->get_num_no_patterns();
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_quantifier_no_pattern_ast(Z3_context c, Z3_ast a, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_quantifier_no_pattern_ast(c, a, i);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
Z3_ast r = of_ast(to_quantifier(_a)->get_no_pattern(i));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_symbol Z3_API Z3_get_quantifier_bound_name(Z3_context c, Z3_ast a, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_quantifier_bound_name(c, a, i);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
return of_symbol(to_quantifier(_a)->get_decl_names()[i]);
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_API Z3_get_quantifier_bound_sort(Z3_context c, Z3_ast a, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_quantifier_bound_sort(c, a, i);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
Z3_sort r = of_sort(to_quantifier(_a)->get_decl_sort(i));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_quantifier_body(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_quantifier_body(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
Z3_ast r = of_ast(to_quantifier(_a)->get_expr());
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_quantifier_num_bound(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_quantifier_num_bound(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
ast * _a = to_ast(a);
|
||||
if (_a->get_kind() == AST_QUANTIFIER) {
|
||||
|
||||
return to_quantifier(_a)->get_num_decls();
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_pattern_num_terms(Z3_context c, Z3_pattern p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_pattern_num_terms(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
app* _p = to_pattern(p);
|
||||
if (mk_c(c)->m().is_pattern(_p)) {
|
||||
return _p->get_num_args();
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
return 0;
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_pattern(Z3_context c, Z3_pattern p, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_pattern(c, p, idx);
|
||||
RESET_ERROR_CODE();
|
||||
app* _p = to_pattern(p);
|
||||
if (mk_c(c)->m().is_pattern(_p)) {
|
||||
Z3_ast r = of_ast(_p->get_arg(idx));
|
||||
RETURN_Z3(r);
|
||||
}
|
||||
else {
|
||||
SET_ERROR_CODE(Z3_SORT_ERROR);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_API Z3_mk_injective_function(Z3_context c,
|
||||
Z3_symbol s,
|
||||
unsigned domain_size,
|
||||
Z3_sort const domain[],
|
||||
Z3_sort range) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_injective_function(c, s, domain_size, domain, range);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager & m = mk_c(c)->m();
|
||||
mk_c(c)->reset_last_result();
|
||||
sort* range_ = to_sort(range);
|
||||
func_decl* d = m.mk_func_decl(to_symbol(s), domain_size, to_sorts(domain), range_);
|
||||
expr_ref_vector args(m);
|
||||
expr_ref fn(m), body(m);
|
||||
vector<symbol> names;
|
||||
for (unsigned i = 0; i < domain_size; ++i) {
|
||||
unsigned idx = domain_size-i-1;
|
||||
args.push_back(m.mk_var(idx, to_sort(domain[i])));
|
||||
names.push_back(symbol(idx));
|
||||
}
|
||||
fn = m.mk_app(d, args.size(), args.c_ptr());
|
||||
|
||||
for (unsigned i = 0; i < domain_size; ++i) {
|
||||
expr* arg = args[i].get();
|
||||
sort* dom = m.get_sort(arg);
|
||||
func_decl* inv = m.mk_fresh_func_decl(symbol("inv"), to_symbol(s), 1, &range_, dom);
|
||||
body = m.mk_eq(m.mk_app(inv, fn.get()), arg);
|
||||
body = m.mk_forall(args.size(), to_sorts(domain), names.c_ptr(), body.get());
|
||||
mk_c(c)->save_multiple_ast_trail(body.get());
|
||||
mk_c(c)->assert_cnstr(body.get());
|
||||
}
|
||||
mk_c(c)->save_multiple_ast_trail(d);
|
||||
RETURN_Z3(of_func_decl(d));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_pattern_to_ast(Z3_context c, Z3_pattern p) {
|
||||
RESET_ERROR_CODE();
|
||||
return (Z3_ast)(p);
|
||||
}
|
||||
|
||||
char const * Z3_API Z3_pattern_to_string(Z3_context c, Z3_pattern p) {
|
||||
return Z3_ast_to_string(c, reinterpret_cast<Z3_ast>(p));
|
||||
}
|
||||
|
||||
};
|
323
src/api/api_solver.cpp
Normal file
323
src/api/api_solver.cpp
Normal file
|
@ -0,0 +1,323 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_solver.cpp
|
||||
|
||||
Abstract:
|
||||
New solver API
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-07.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_tactic.h"
|
||||
#include"api_solver.h"
|
||||
#include"api_model.h"
|
||||
#include"api_stats.h"
|
||||
#include"api_ast_vector.h"
|
||||
#include"tactic2solver.h"
|
||||
#include"scoped_ctrl_c.h"
|
||||
#include"cancel_eh.h"
|
||||
#include"scoped_timer.h"
|
||||
#include"smt_strategic_solver.h"
|
||||
#include"default_solver.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_solver Z3_API Z3_mk_simple_solver(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_simple_solver(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref);
|
||||
s->m_solver = mk_default_solver();
|
||||
s->m_solver->set_front_end_params(mk_c(c)->fparams());
|
||||
s->m_solver->init(mk_c(c)->m(), symbol::null);
|
||||
mk_c(c)->save_object(s);
|
||||
Z3_solver r = of_solver(s);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_solver Z3_API Z3_mk_solver(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_solver(c);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref);
|
||||
s->m_solver = mk_smt_strategic_solver();
|
||||
s->m_solver->set_front_end_params(mk_c(c)->fparams());
|
||||
s->m_solver->init(mk_c(c)->m(), symbol::null);
|
||||
mk_c(c)->save_object(s);
|
||||
Z3_solver r = of_solver(s);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_solver Z3_API Z3_mk_solver_for_logic(Z3_context c, Z3_symbol logic) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_solver_for_logic(c, logic);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref);
|
||||
s->m_solver = mk_smt_strategic_solver(true /* force solver to use tactics even when auto_config is disabled */);
|
||||
s->m_solver->set_front_end_params(mk_c(c)->fparams());
|
||||
s->m_solver->init(mk_c(c)->m(), to_symbol(logic));
|
||||
mk_c(c)->save_object(s);
|
||||
Z3_solver r = of_solver(s);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_solver Z3_API Z3_mk_solver_from_tactic(Z3_context c, Z3_tactic t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_solver_from_tactic(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_solver_ref * s = alloc(Z3_solver_ref);
|
||||
s->m_solver = alloc(tactic2solver_api, to_tactic_ref(t));
|
||||
s->m_solver->set_front_end_params(mk_c(c)->fparams());
|
||||
s->m_solver->init(mk_c(c)->m(), symbol::null);
|
||||
mk_c(c)->save_object(s);
|
||||
Z3_solver r = of_solver(s);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_solver_get_help(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_help(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
param_descrs descrs;
|
||||
to_solver_ref(s)->collect_param_descrs(descrs);
|
||||
descrs.display(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_param_descrs Z3_API Z3_solver_get_param_descrs(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_param_descrs(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
|
||||
mk_c(c)->save_object(d);
|
||||
to_solver_ref(s)->collect_param_descrs(d->m_descrs);
|
||||
Z3_param_descrs r = of_param_descrs(d);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_solver_set_params(Z3_context c, Z3_solver s, Z3_params p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_set_params(c, s, p);
|
||||
RESET_ERROR_CODE();
|
||||
to_solver_ref(s)->updt_params(to_param_ref(p));
|
||||
to_solver(s)->m_params = to_param_ref(p);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_solver_inc_ref(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_inc_ref(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
to_solver(s)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_solver_dec_ref(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_dec_ref(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
to_solver(s)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_solver_push(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_push(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
to_solver_ref(s)->push();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_solver_pop(Z3_context c, Z3_solver s, unsigned n) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_pop(c, s, n);
|
||||
RESET_ERROR_CODE();
|
||||
if (n > to_solver_ref(s)->get_scope_level()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return;
|
||||
}
|
||||
if (n > 0)
|
||||
to_solver_ref(s)->pop(n);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_solver_reset(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_reset(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
to_solver_ref(s)->reset();
|
||||
to_solver_ref(s)->init(mk_c(c)->m(), symbol::null);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_solver_get_num_scopes(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_num_scopes(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
return to_solver_ref(s)->get_scope_level();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_solver_assert(Z3_context c, Z3_solver s, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_assert(c, s, a);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_FORMULA(a,);
|
||||
to_solver_ref(s)->assert_expr(to_expr(a));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_solver_get_assertions(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_assertions(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
unsigned sz = to_solver_ref(s)->get_num_assertions();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
v->m_ast_vector.push_back(to_solver_ref(s)->get_assertion(i));
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
static Z3_lbool _solver_check(Z3_context c, Z3_solver s, unsigned num_assumptions, Z3_ast const assumptions[]) {
|
||||
for (unsigned i = 0; i < num_assumptions; i++) {
|
||||
if (!is_expr(to_ast(assumptions[i]))) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return Z3_L_UNDEF;
|
||||
}
|
||||
}
|
||||
expr * const * _assumptions = to_exprs(assumptions);
|
||||
to_solver_ref(s)->set_produce_models(to_solver(s)->m_params.get_bool(":model", true));
|
||||
to_solver_ref(s)->set_produce_proofs(mk_c(c)->m().proofs_enabled());
|
||||
to_solver_ref(s)->set_produce_unsat_cores(num_assumptions > 0);
|
||||
unsigned timeout = to_solver(s)->m_params.get_uint(":timeout", UINT_MAX);
|
||||
bool use_ctrl_c = to_solver(s)->m_params.get_bool(":ctrl-c", false);
|
||||
cancel_eh<solver> eh(*to_solver_ref(s));
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
lbool result;
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh, false, use_ctrl_c);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
try {
|
||||
result = to_solver_ref(s)->check_sat(num_assumptions, _assumptions);
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
return Z3_L_UNDEF;
|
||||
}
|
||||
}
|
||||
return static_cast<Z3_lbool>(result);
|
||||
}
|
||||
|
||||
Z3_lbool Z3_API Z3_solver_check(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_check(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
return _solver_check(c, s, 0, 0);
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_lbool Z3_API Z3_solver_check_assumptions(Z3_context c, Z3_solver s, unsigned num_assumptions, Z3_ast const assumptions[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_check_assumptions(c, s, num_assumptions, assumptions);
|
||||
RESET_ERROR_CODE();
|
||||
return _solver_check(c, s, num_assumptions, assumptions);
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_model Z3_API Z3_solver_get_model(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_model(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
model_ref _m;
|
||||
to_solver_ref(s)->get_model(_m);
|
||||
if (!_m) {
|
||||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref);
|
||||
m_ref->m_model = _m;
|
||||
mk_c(c)->save_object(m_ref);
|
||||
RETURN_Z3(of_model(m_ref));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_solver_get_proof(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_proof(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
proof * p = to_solver_ref(s)->get_proof();
|
||||
if (!p) {
|
||||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
mk_c(c)->save_ast_trail(p);
|
||||
RETURN_Z3(of_ast(p));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast_vector Z3_API Z3_solver_get_unsat_core(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_unsat_core(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
ptr_vector<expr> core;
|
||||
to_solver_ref(s)->get_unsat_core(core);
|
||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(v);
|
||||
for (unsigned i = 0; i < core.size(); i++) {
|
||||
v->m_ast_vector.push_back(core[i]);
|
||||
}
|
||||
RETURN_Z3(of_ast_vector(v));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_solver_get_reason_unknown(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_reason_unknown(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->mk_external_string(to_solver_ref(s)->reason_unknown());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_stats Z3_API Z3_solver_get_statistics(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_get_statistics(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_stats_ref * st = alloc(Z3_stats_ref);
|
||||
to_solver_ref(s)->collect_statistics(st->m_stats);
|
||||
mk_c(c)->save_object(st);
|
||||
Z3_stats r = of_stats(st);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_solver_to_string(Z3_context c, Z3_solver s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_solver_to_string(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
to_solver_ref(s)->display(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
};
|
35
src/api/api_solver.h
Normal file
35
src/api/api_solver.h
Normal file
|
@ -0,0 +1,35 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_solver.h
|
||||
|
||||
Abstract:
|
||||
New solver API
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-07.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_SOLVER_H_
|
||||
#define _API_SOLVER_H_
|
||||
|
||||
#include"api_util.h"
|
||||
#include"solver.h"
|
||||
|
||||
struct Z3_solver_ref : public api::object {
|
||||
solver * m_solver;
|
||||
params_ref m_params;
|
||||
Z3_solver_ref():m_solver(0) {}
|
||||
virtual ~Z3_solver_ref() { dealloc(m_solver); }
|
||||
};
|
||||
|
||||
inline Z3_solver_ref * to_solver(Z3_solver s) { return reinterpret_cast<Z3_solver_ref *>(s); }
|
||||
inline Z3_solver of_solver(Z3_solver_ref * s) { return reinterpret_cast<Z3_solver>(s); }
|
||||
inline solver * to_solver_ref(Z3_solver s) { return to_solver(s)->m_solver; }
|
||||
|
||||
#endif
|
365
src/api/api_solver_old.cpp
Normal file
365
src/api/api_solver_old.cpp
Normal file
|
@ -0,0 +1,365 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_solver_old.cpp
|
||||
|
||||
Abstract:
|
||||
OLD API for using solvers.
|
||||
|
||||
This has been deprecated
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_model.h"
|
||||
#include"smt_implied_equalities.h"
|
||||
#include"cancel_eh.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
void Z3_API Z3_push(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_push(c);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
mk_c(c)->push();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_pop(Z3_context c, unsigned num_scopes) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_pop(c, num_scopes);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
if (num_scopes > mk_c(c)->get_solver().get_scope_level()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return;
|
||||
}
|
||||
if (num_scopes > 0) {
|
||||
mk_c(c)->pop(num_scopes);
|
||||
}
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_num_scopes(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_num_scopes(c);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->get_num_scopes();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_assert_cnstr(Z3_context c, Z3_ast a) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_assert_cnstr(c, a);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_FORMULA(a,);
|
||||
mk_c(c)->assert_cnstr(to_expr(a));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_lbool Z3_API Z3_check_and_get_model(Z3_context c, Z3_model * m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_check_and_get_model(c, m);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
cancel_eh<smt::solver> eh(mk_c(c)->get_solver());
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
flet<bool> _model(mk_c(c)->fparams().m_model, true);
|
||||
lbool result;
|
||||
try {
|
||||
model_ref _m;
|
||||
result = mk_c(c)->check(_m);
|
||||
if (m) {
|
||||
if (_m) {
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref);
|
||||
m_ref->m_model = _m;
|
||||
// Must bump reference counter for backward compatibility reasons.
|
||||
// Don't need to invoke save_object, since the counter was bumped
|
||||
m_ref->inc_ref();
|
||||
*m = of_model(m_ref);
|
||||
}
|
||||
else {
|
||||
*m = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
RETURN_Z3_check_and_get_model static_cast<Z3_lbool>(l_undef);
|
||||
}
|
||||
RETURN_Z3_check_and_get_model static_cast<Z3_lbool>(result);
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_lbool Z3_API Z3_check(Z3_context c) {
|
||||
Z3_TRY;
|
||||
// This is just syntax sugar...
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
Z3_lbool r = Z3_check_and_get_model(c, 0);
|
||||
return r;
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_lbool Z3_API Z3_get_implied_equalities(Z3_context c,
|
||||
unsigned num_terms,
|
||||
Z3_ast const terms[],
|
||||
unsigned class_ids[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_implied_equalities(c, num_terms, terms, class_ids);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
lbool result = smt::implied_equalities(mk_c(c)->get_solver(), num_terms, to_exprs(terms), class_ids);
|
||||
return static_cast<Z3_lbool>(result);
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
|
||||
Z3_lbool Z3_API Z3_check_assumptions(Z3_context c,
|
||||
unsigned num_assumptions, Z3_ast const assumptions[],
|
||||
Z3_model * m, Z3_ast* proof,
|
||||
unsigned* core_size, Z3_ast core[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_check_assumptions(c, num_assumptions, assumptions, m, proof, core_size, core);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
expr * const* _assumptions = to_exprs(assumptions);
|
||||
flet<bool> _model(mk_c(c)->fparams().m_model, true);
|
||||
cancel_eh<smt::solver> eh(mk_c(c)->get_solver());
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
lbool result;
|
||||
result = mk_c(c)->get_solver().check(num_assumptions, _assumptions);
|
||||
if (result != l_false && m) {
|
||||
model_ref _m;
|
||||
mk_c(c)->get_solver().get_model(_m);
|
||||
if (_m) {
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref);
|
||||
m_ref->m_model = _m;
|
||||
// Must bump reference counter for backward compatibility reasons.
|
||||
// Don't need to invoke save_object, since the counter was bumped
|
||||
m_ref->inc_ref();
|
||||
*m = of_model(m_ref);
|
||||
}
|
||||
else {
|
||||
*m = 0;
|
||||
}
|
||||
}
|
||||
if (result == l_false && core_size) {
|
||||
*core_size = mk_c(c)->get_solver().get_unsat_core_size();
|
||||
if (*core_size > num_assumptions) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
}
|
||||
for (unsigned i = 0; i < *core_size; ++i) {
|
||||
core[i] = of_ast(mk_c(c)->get_solver().get_unsat_core_expr(i));
|
||||
}
|
||||
}
|
||||
else if (core_size) {
|
||||
*core_size = 0;
|
||||
}
|
||||
if (result == l_false && proof) {
|
||||
*proof = of_ast(mk_c(c)->get_solver().get_proof());
|
||||
}
|
||||
else if (proof) {
|
||||
*proof = 0; // breaks abstraction.
|
||||
}
|
||||
RETURN_Z3_check_assumptions static_cast<Z3_lbool>(result);
|
||||
Z3_CATCH_RETURN(Z3_L_UNDEF);
|
||||
}
|
||||
|
||||
Z3_search_failure Z3_API Z3_get_search_failure(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_search_failure(c);
|
||||
RESET_ERROR_CODE();
|
||||
CHECK_SEARCHING(c);
|
||||
smt::failure f = mk_c(c)->get_solver().last_failure();
|
||||
return api::mk_Z3_search_failure(f);
|
||||
Z3_CATCH_RETURN(Z3_UNKNOWN);
|
||||
}
|
||||
|
||||
class labeled_literal {
|
||||
expr_ref m_literal;
|
||||
symbol m_label;
|
||||
bool m_enabled;
|
||||
public:
|
||||
labeled_literal(ast_manager& m, expr* l, symbol const& n) : m_literal(l,m), m_label(n), m_enabled(true) {}
|
||||
labeled_literal(ast_manager& m, expr* l) : m_literal(l,m), m_label(), m_enabled(true) {}
|
||||
bool is_enabled() const { return m_enabled; }
|
||||
void disable() { m_enabled = false; }
|
||||
symbol const& get_label() const { return m_label; }
|
||||
expr* get_literal() { return m_literal.get(); }
|
||||
};
|
||||
|
||||
typedef vector<labeled_literal> labels;
|
||||
|
||||
Z3_literals Z3_API Z3_get_relevant_labels(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_relevant_labels(c);
|
||||
RESET_ERROR_CODE();
|
||||
buffer<symbol> labl_syms;
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
expr_ref_vector lits(m);
|
||||
mk_c(c)->get_solver().get_relevant_labels(0, labl_syms);
|
||||
mk_c(c)->get_solver().get_relevant_labeled_literals(mk_c(c)->fparams().m_at_labels_cex, lits);
|
||||
labels* lbls = alloc(labels);
|
||||
SASSERT(labl_syms.size() == lits.size());
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
lbls->push_back(labeled_literal(m,lits[i].get(), labl_syms[i]));
|
||||
}
|
||||
RETURN_Z3(reinterpret_cast<Z3_literals>(lbls));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_literals Z3_API Z3_get_relevant_literals(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_relevant_literals(c);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
expr_ref_vector lits(m);
|
||||
mk_c(c)->get_solver().get_relevant_literals(lits);
|
||||
labels* lbls = alloc(labels);
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
lbls->push_back(labeled_literal(m,lits[i].get()));
|
||||
}
|
||||
RETURN_Z3(reinterpret_cast<Z3_literals>(lbls));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_literals Z3_API Z3_get_guessed_literals(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_guessed_literals(c);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
expr_ref_vector lits(m);
|
||||
mk_c(c)->get_solver().get_guessed_literals(lits);
|
||||
labels* lbls = alloc(labels);
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
lbls->push_back(labeled_literal(m,lits[i].get()));
|
||||
}
|
||||
RETURN_Z3(reinterpret_cast<Z3_literals>(lbls));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_del_literals(Z3_context c, Z3_literals lbls) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_del_literals(c, lbls);
|
||||
RESET_ERROR_CODE();
|
||||
dealloc(reinterpret_cast<labels*>(lbls));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_num_literals(Z3_context c,Z3_literals lbls) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_num_literals(c, lbls);
|
||||
RESET_ERROR_CODE();
|
||||
return reinterpret_cast<labels*>(lbls)->size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_symbol Z3_API Z3_get_label_symbol(Z3_context c,Z3_literals lbls, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_label_symbol(c, lbls, idx);
|
||||
RESET_ERROR_CODE();
|
||||
return of_symbol((*reinterpret_cast<labels*>(lbls))[idx].get_label());
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_literal(Z3_context c,Z3_literals lbls, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_literal(c, lbls, idx);
|
||||
RESET_ERROR_CODE();
|
||||
expr* e = (*reinterpret_cast<labels*>(lbls))[idx].get_literal();
|
||||
mk_c(c)->save_ast_trail(e);
|
||||
RETURN_Z3(of_ast(e));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_disable_literal(Z3_context c, Z3_literals lbls, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_disable_literal(c, lbls, idx);
|
||||
RESET_ERROR_CODE();
|
||||
(*reinterpret_cast<labels*>(lbls))[idx].disable();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_block_literals(Z3_context c, Z3_literals lbls) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_block_literals(c, lbls);
|
||||
RESET_ERROR_CODE();
|
||||
labels* _lbls = reinterpret_cast<labels*>(lbls);
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
expr_ref_vector lits(m);
|
||||
for (unsigned i = 0; i < _lbls->size(); ++i) {
|
||||
if ((*_lbls)[i].is_enabled()) {
|
||||
lits.push_back(m.mk_not((*_lbls)[i].get_literal()));
|
||||
}
|
||||
}
|
||||
expr_ref clause(m);
|
||||
clause = m.mk_or(lits.size(), lits.c_ptr());
|
||||
mk_c(c)->save_ast_trail(clause.get());
|
||||
mk_c(c)->assert_cnstr(clause.get());
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
char const * Z3_API Z3_context_to_string(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_context_to_string(c);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
mk_c(c)->get_solver().display(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_API Z3_get_context_assignment(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_context_assignment(c);
|
||||
RESET_ERROR_CODE();
|
||||
ast_manager& m = mk_c(c)->m();
|
||||
expr_ref result(m);
|
||||
expr_ref_vector assignment(m);
|
||||
mk_c(c)->get_solver().get_assignments(assignment);
|
||||
result = mk_c(c)->mk_and(assignment.size(), assignment.c_ptr());
|
||||
RETURN_Z3(of_ast(result.get()));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_statistics_to_string(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_statistics_to_string(c);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
mk_c(c)->get_solver().display_statistics(buffer);
|
||||
memory::display_max_usage(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_soft_check_cancel(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_soft_check_cancel(c);
|
||||
RESET_ERROR_CODE();
|
||||
mk_c(c)->interrupt();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
void Z3_display_statistics(Z3_context c, std::ostream& s) {
|
||||
mk_c(c)->get_solver().display_statistics(s);
|
||||
}
|
||||
|
||||
void Z3_display_istatistics(Z3_context c, std::ostream& s) {
|
||||
mk_c(c)->get_solver().display_istatistics(s);
|
||||
}
|
||||
|
133
src/api/api_stats.cpp
Normal file
133
src/api/api_stats.cpp
Normal file
|
@ -0,0 +1,133 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_stats.cpp
|
||||
|
||||
Abstract:
|
||||
API for browsing statistics
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-07.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_stats.h"
|
||||
|
||||
extern "C" {
|
||||
|
||||
Z3_string Z3_API Z3_stats_to_string(Z3_context c, Z3_stats s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_stats_to_string(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
to_stats_ref(s).display_smt2(buffer);
|
||||
std::string result = buffer.str();
|
||||
// Hack for removing the trailing '\n'
|
||||
result = buffer.str();
|
||||
SASSERT(result.size() > 0);
|
||||
result.resize(result.size()-1);
|
||||
return mk_c(c)->mk_external_string(result);
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
void Z3_API Z3_stats_inc_ref(Z3_context c, Z3_stats s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_stats_inc_ref(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
to_stats(s)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_stats_dec_ref(Z3_context c, Z3_stats s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_stats_dec_ref(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
to_stats(s)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_stats_size(Z3_context c, Z3_stats s) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_stats_size(c, s);
|
||||
RESET_ERROR_CODE();
|
||||
return to_stats_ref(s).size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_stats_get_key(Z3_context c, Z3_stats s, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_stats_get_key(c, s, idx);
|
||||
RESET_ERROR_CODE();
|
||||
if (idx >= to_stats_ref(s).size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return "";
|
||||
}
|
||||
return to_stats_ref(s).get_key(idx);
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_stats_is_uint(Z3_context c, Z3_stats s, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_stats_is_uint(c, s, idx);
|
||||
RESET_ERROR_CODE();
|
||||
if (idx >= to_stats_ref(s).size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return Z3_FALSE;
|
||||
}
|
||||
return to_stats_ref(s).is_uint(idx);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_API Z3_stats_is_double(Z3_context c, Z3_stats s, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_stats_is_double(c, s, idx);
|
||||
RESET_ERROR_CODE();
|
||||
if (idx >= to_stats_ref(s).size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return Z3_FALSE;
|
||||
}
|
||||
return !to_stats_ref(s).is_uint(idx);
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_stats_get_uint_value(Z3_context c, Z3_stats s, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_stats_get_uint_value(c, s, idx);
|
||||
RESET_ERROR_CODE();
|
||||
if (idx >= to_stats_ref(s).size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return 0;
|
||||
}
|
||||
if (!to_stats_ref(s).is_uint(idx)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0;
|
||||
}
|
||||
return to_stats_ref(s).get_uint_value(idx);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
double Z3_API Z3_stats_get_double_value(Z3_context c, Z3_stats s, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_stats_get_double_value(c, s, idx);
|
||||
RESET_ERROR_CODE();
|
||||
if (idx >= to_stats_ref(s).size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return 0.0;
|
||||
}
|
||||
if (to_stats_ref(s).is_uint(idx)) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return 0.0;
|
||||
}
|
||||
return to_stats_ref(s).get_double_value(idx);
|
||||
Z3_CATCH_RETURN(0.0);
|
||||
}
|
||||
|
||||
};
|
33
src/api/api_stats.h
Normal file
33
src/api/api_stats.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_stats.h
|
||||
|
||||
Abstract:
|
||||
API for Z3 statistics
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-07.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_STATS_H_
|
||||
#define _API_STATS_H_
|
||||
|
||||
#include"api_util.h"
|
||||
#include"statistics.h"
|
||||
|
||||
struct Z3_stats_ref : public api::object {
|
||||
statistics m_stats;
|
||||
virtual ~Z3_stats_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_stats_ref * to_stats(Z3_stats s) { return reinterpret_cast<Z3_stats_ref *>(s); }
|
||||
inline Z3_stats of_stats(Z3_stats_ref * s) { return reinterpret_cast<Z3_stats>(s); }
|
||||
inline statistics & to_stats_ref(Z3_stats s) { return to_stats(s)->m_stats; }
|
||||
|
||||
#endif
|
528
src/api/api_tactic.cpp
Normal file
528
src/api/api_tactic.cpp
Normal file
|
@ -0,0 +1,528 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_tactic.cpp
|
||||
|
||||
Abstract:
|
||||
API for creating tactics and probes
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-06.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_tactic.h"
|
||||
#include"api_model.h"
|
||||
#include"scoped_ctrl_c.h"
|
||||
#include"cancel_eh.h"
|
||||
#include"scoped_timer.h"
|
||||
|
||||
Z3_apply_result_ref::Z3_apply_result_ref(ast_manager & m):m_core(m) {
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
#define RETURN_TACTIC(_t_) { \
|
||||
Z3_tactic_ref * _ref_ = alloc(Z3_tactic_ref); \
|
||||
_ref_->m_tactic = _t_; \
|
||||
mk_c(c)->save_object(_ref_); \
|
||||
Z3_tactic _result_ = of_tactic(_ref_); \
|
||||
RETURN_Z3(_result_); \
|
||||
}
|
||||
|
||||
#define RETURN_PROBE(_t_) { \
|
||||
Z3_probe_ref * _ref_ = alloc(Z3_probe_ref); \
|
||||
_ref_->m_probe = _t_; \
|
||||
mk_c(c)->save_object(_ref_); \
|
||||
Z3_probe _result_ = of_probe(_ref_); \
|
||||
RETURN_Z3(_result_); \
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_mk_tactic(Z3_context c, Z3_string name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_tactic(c, name);
|
||||
RESET_ERROR_CODE();
|
||||
tactic_cmd * t = mk_c(c)->find_tactic_cmd(symbol(name));
|
||||
if (t == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
tactic * new_t = t->mk(mk_c(c)->m());
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_tactic_inc_ref(Z3_context c, Z3_tactic t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_inc_ref(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
to_tactic(t)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_tactic_dec_ref(Z3_context c, Z3_tactic t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_dec_ref(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
to_tactic(t)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_mk_probe(Z3_context c, Z3_string name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_mk_probe(c, name);
|
||||
RESET_ERROR_CODE();
|
||||
probe_info * p = mk_c(c)->find_probe(symbol(name));
|
||||
if (p == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
probe * new_p = p->get();
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_probe_inc_ref(Z3_context c, Z3_probe p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_inc_ref(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
to_probe(p)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_probe_dec_ref(Z3_context c, Z3_probe p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_dec_ref(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
to_probe(p)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_and_then(Z3_context c, Z3_tactic t1, Z3_tactic t2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_and_then(c, t1, t2);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = and_then(to_tactic_ref(t1), to_tactic_ref(t2));
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_or_else(Z3_context c, Z3_tactic t1, Z3_tactic t2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_or_else(c, t1, t2);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = or_else(to_tactic_ref(t1), to_tactic_ref(t2));
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_par_or(Z3_context c, unsigned num, Z3_tactic const ts[]) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_par_or(c, num, ts);
|
||||
RESET_ERROR_CODE();
|
||||
ptr_buffer<tactic> _ts;
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
_ts.push_back(to_tactic_ref(ts[i]));
|
||||
}
|
||||
tactic * new_t = par(num, _ts.c_ptr());
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_par_and_then(Z3_context c, Z3_tactic t1, Z3_tactic t2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_par_and_then(c, t1, t2);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = par_and_then(to_tactic_ref(t1), to_tactic_ref(t2));
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_try_for(Z3_context c, Z3_tactic t, unsigned ms) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_try_for(c, t, ms);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = try_for(to_tactic_ref(t), ms);
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_when(Z3_context c, Z3_probe p, Z3_tactic t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_when(c, p, t);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = when(to_probe_ref(p), to_tactic_ref(t));
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_cond(Z3_context c, Z3_probe p, Z3_tactic t1, Z3_tactic t2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_cond(c, p, t1, t2);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = cond(to_probe_ref(p), to_tactic_ref(t1), to_tactic_ref(t2));
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_repeat(Z3_context c, Z3_tactic t, unsigned max) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_repeat(c, t, max);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = repeat(to_tactic_ref(t), max);
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_skip(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_skip(c);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = mk_skip_tactic();
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_fail(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_fail(c);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = mk_fail_tactic();
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_fail_if(Z3_context c, Z3_probe p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_fail_if(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = fail_if(to_probe_ref(p));
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_fail_if_not_decided(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_fail_if_not_decided(c);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = mk_fail_if_undecided_tactic();
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_tactic Z3_API Z3_tactic_using_params(Z3_context c, Z3_tactic t, Z3_params p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_using_params(c, t, p);
|
||||
RESET_ERROR_CODE();
|
||||
tactic * new_t = using_params(to_tactic_ref(t), to_param_ref(p));
|
||||
RETURN_TACTIC(new_t);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_probe_const(Z3_context c, double val) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_const(c, val);
|
||||
RESET_ERROR_CODE();
|
||||
probe * new_p = mk_const_probe(val);
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_probe_lt(Z3_context c, Z3_probe p1, Z3_probe p2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_lt(c, p1, p2);
|
||||
RESET_ERROR_CODE();
|
||||
probe * new_p = mk_lt(to_probe_ref(p1), to_probe_ref(p2));
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_probe_gt(Z3_context c, Z3_probe p1, Z3_probe p2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_gt(c, p1, p2);
|
||||
RESET_ERROR_CODE();
|
||||
probe * new_p = mk_gt(to_probe_ref(p1), to_probe_ref(p2));
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_probe_le(Z3_context c, Z3_probe p1, Z3_probe p2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_le(c, p1, p2);
|
||||
RESET_ERROR_CODE();
|
||||
probe * new_p = mk_le(to_probe_ref(p1), to_probe_ref(p2));
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_probe_ge(Z3_context c, Z3_probe p1, Z3_probe p2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_ge(c, p1, p2);
|
||||
RESET_ERROR_CODE();
|
||||
probe * new_p = mk_ge(to_probe_ref(p1), to_probe_ref(p2));
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_probe_eq(Z3_context c, Z3_probe p1, Z3_probe p2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_eq(c, p1, p2);
|
||||
RESET_ERROR_CODE();
|
||||
probe * new_p = mk_eq(to_probe_ref(p1), to_probe_ref(p2));
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_probe_and(Z3_context c, Z3_probe p1, Z3_probe p2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_and(c, p1, p2);
|
||||
RESET_ERROR_CODE();
|
||||
probe * new_p = mk_and(to_probe_ref(p1), to_probe_ref(p2));
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_probe_or(Z3_context c, Z3_probe p1, Z3_probe p2) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_or(c, p1, p2);
|
||||
RESET_ERROR_CODE();
|
||||
probe * new_p = mk_or(to_probe_ref(p1), to_probe_ref(p2));
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_probe Z3_API Z3_probe_not(Z3_context c, Z3_probe p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_not(c, p);
|
||||
RESET_ERROR_CODE();
|
||||
probe * new_p = mk_not(to_probe_ref(p));
|
||||
RETURN_PROBE(new_p);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_num_tactics(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_num_tactics(c);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->num_tactics();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_get_tactic_name(Z3_context c, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_tactic_name(c, idx);
|
||||
RESET_ERROR_CODE();
|
||||
if (idx >= mk_c(c)->num_tactics()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return "";
|
||||
}
|
||||
return mk_c(c)->get_tactic(idx)->get_name().bare_str();
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_get_num_probes(Z3_context c) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_num_probes(c);
|
||||
RESET_ERROR_CODE();
|
||||
return mk_c(c)->num_probes();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_get_probe_name(Z3_context c, unsigned idx) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_get_probe_name(c, idx);
|
||||
RESET_ERROR_CODE();
|
||||
if (idx >= mk_c(c)->num_probes()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
return "";
|
||||
}
|
||||
return mk_c(c)->get_probe(idx)->get_name().bare_str();
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_tactic_get_help(Z3_context c, Z3_tactic t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_get_help(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
param_descrs descrs;
|
||||
to_tactic_ref(t)->collect_param_descrs(descrs);
|
||||
descrs.display(buffer);
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_param_descrs Z3_API Z3_tactic_get_param_descrs(Z3_context c, Z3_tactic t) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_get_param_descrs(c, t);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_param_descrs_ref * d = alloc(Z3_param_descrs_ref);
|
||||
mk_c(c)->save_object(d);
|
||||
to_tactic_ref(t)->collect_param_descrs(d->m_descrs);
|
||||
Z3_param_descrs r = of_param_descrs(d);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_tactic_get_descr(Z3_context c, Z3_string name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_get_descr(c, name);
|
||||
RESET_ERROR_CODE();
|
||||
tactic_cmd * t = mk_c(c)->find_tactic_cmd(symbol(name));
|
||||
if (t == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return "";
|
||||
}
|
||||
return t->get_descr();
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_probe_get_descr(Z3_context c, Z3_string name) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_get_descr(c, name);
|
||||
RESET_ERROR_CODE();
|
||||
probe_info * p = mk_c(c)->find_probe(symbol(name));
|
||||
if (p == 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_ARG);
|
||||
return "";
|
||||
}
|
||||
return p->get_descr();
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
static Z3_apply_result _tactic_apply(Z3_context c, Z3_tactic t, Z3_goal g, params_ref p) {
|
||||
goal_ref new_goal;
|
||||
new_goal = alloc(goal, *to_goal_ref(g));
|
||||
Z3_apply_result_ref * ref = alloc(Z3_apply_result_ref, mk_c(c)->m());
|
||||
mk_c(c)->save_object(ref);
|
||||
|
||||
unsigned timeout = p.get_uint(":timeout", UINT_MAX);
|
||||
bool use_ctrl_c = p.get_bool(":ctrl-c", false);
|
||||
cancel_eh<tactic> eh(*to_tactic_ref(t));
|
||||
|
||||
to_tactic_ref(t)->updt_params(p);
|
||||
|
||||
api::context::set_interruptable(*(mk_c(c)), eh);
|
||||
{
|
||||
scoped_ctrl_c ctrlc(eh, false, use_ctrl_c);
|
||||
scoped_timer timer(timeout, &eh);
|
||||
try {
|
||||
exec(*to_tactic_ref(t), new_goal, ref->m_subgoals, ref->m_mc, ref->m_pc, ref->m_core);
|
||||
return of_apply_result(ref);
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
mk_c(c)->handle_exception(ex);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double Z3_API Z3_probe_apply(Z3_context c, Z3_probe p, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_probe_apply(c, p, g);
|
||||
RESET_ERROR_CODE();
|
||||
return to_probe_ref(p)->operator()(*to_goal_ref(g)).get_value();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_apply_result Z3_API Z3_tactic_apply(Z3_context c, Z3_tactic t, Z3_goal g) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_apply(c, t, g);
|
||||
RESET_ERROR_CODE();
|
||||
params_ref p;
|
||||
Z3_apply_result r = _tactic_apply(c, t, g, p);
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_apply_result Z3_API Z3_tactic_apply_ex(Z3_context c, Z3_tactic t, Z3_goal g, Z3_params p) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_tactic_apply_ex(c, t, g, p);
|
||||
RESET_ERROR_CODE();
|
||||
Z3_apply_result r = _tactic_apply(c, t, g, to_param_ref(p));
|
||||
RETURN_Z3(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void Z3_API Z3_apply_result_inc_ref(Z3_context c, Z3_apply_result r) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_apply_result_inc_ref(c, r);
|
||||
RESET_ERROR_CODE();
|
||||
to_apply_result(r)->inc_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_API Z3_apply_result_dec_ref(Z3_context c, Z3_apply_result r) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_apply_result_dec_ref(c, r);
|
||||
RESET_ERROR_CODE();
|
||||
to_apply_result(r)->dec_ref();
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_string Z3_API Z3_apply_result_to_string(Z3_context c, Z3_apply_result r) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_apply_result_to_string(c, r);
|
||||
RESET_ERROR_CODE();
|
||||
std::ostringstream buffer;
|
||||
buffer << "(goals\n";
|
||||
unsigned sz = to_apply_result(r)->m_subgoals.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
to_apply_result(r)->m_subgoals[i]->display(buffer);
|
||||
}
|
||||
buffer << ")";
|
||||
return mk_c(c)->mk_external_string(buffer.str());
|
||||
Z3_CATCH_RETURN("");
|
||||
}
|
||||
|
||||
unsigned Z3_API Z3_apply_result_get_num_subgoals(Z3_context c, Z3_apply_result r) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_apply_result_get_num_subgoals(c, r);
|
||||
RESET_ERROR_CODE();
|
||||
return to_apply_result(r)->m_subgoals.size();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_goal Z3_API Z3_apply_result_get_subgoal(Z3_context c, Z3_apply_result r, unsigned i) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_apply_result_get_subgoal(c, r, i);
|
||||
RESET_ERROR_CODE();
|
||||
if (i > to_apply_result(r)->m_subgoals.size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
Z3_goal_ref * g = alloc(Z3_goal_ref);
|
||||
g->m_goal = to_apply_result(r)->m_subgoals[i];
|
||||
mk_c(c)->save_object(g);
|
||||
Z3_goal result = of_goal(g);
|
||||
RETURN_Z3(result);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_model Z3_API Z3_apply_result_convert_model(Z3_context c, Z3_apply_result r, unsigned i, Z3_model m) {
|
||||
Z3_TRY;
|
||||
LOG_Z3_apply_result_convert_model(c, r, i, m);
|
||||
RESET_ERROR_CODE();
|
||||
if (i > to_apply_result(r)->m_subgoals.size()) {
|
||||
SET_ERROR_CODE(Z3_IOB);
|
||||
RETURN_Z3(0);
|
||||
}
|
||||
model_ref new_m = to_model_ref(m)->copy();
|
||||
if (to_apply_result(r)->m_mc)
|
||||
to_apply_result(r)->m_mc->operator()(new_m, i);
|
||||
Z3_model_ref * m_ref = alloc(Z3_model_ref);
|
||||
m_ref->m_model = new_m;
|
||||
mk_c(c)->save_object(m_ref);
|
||||
RETURN_Z3(of_model(m_ref));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
};
|
54
src/api/api_tactic.h
Normal file
54
src/api/api_tactic.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_tactic.h
|
||||
|
||||
Abstract:
|
||||
API for creating tactics and goals.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-03-06.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_TACTIC_H_
|
||||
#define _API_TACTIC_H_
|
||||
|
||||
#include"api_goal.h"
|
||||
#include"tactical.h"
|
||||
|
||||
struct Z3_tactic_ref : public api::object {
|
||||
tactic_ref m_tactic;
|
||||
virtual ~Z3_tactic_ref() {}
|
||||
};
|
||||
|
||||
struct Z3_probe_ref : public api::object {
|
||||
probe_ref m_probe;
|
||||
virtual ~Z3_probe_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_tactic_ref * to_tactic(Z3_tactic g) { return reinterpret_cast<Z3_tactic_ref *>(g); }
|
||||
inline Z3_tactic of_tactic(Z3_tactic_ref * g) { return reinterpret_cast<Z3_tactic>(g); }
|
||||
inline tactic * to_tactic_ref(Z3_tactic g) { return g == 0 ? 0 : to_tactic(g)->m_tactic.get(); }
|
||||
|
||||
inline Z3_probe_ref * to_probe(Z3_probe g) { return reinterpret_cast<Z3_probe_ref *>(g); }
|
||||
inline Z3_probe of_probe(Z3_probe_ref * g) { return reinterpret_cast<Z3_probe>(g); }
|
||||
inline probe * to_probe_ref(Z3_probe g) { return g == 0 ? 0 : to_probe(g)->m_probe.get(); }
|
||||
|
||||
struct Z3_apply_result_ref : public api::object {
|
||||
goal_ref_buffer m_subgoals;
|
||||
model_converter_ref m_mc;
|
||||
proof_converter_ref m_pc;
|
||||
expr_dependency_ref m_core;
|
||||
Z3_apply_result_ref(ast_manager & m);
|
||||
virtual ~Z3_apply_result_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_apply_result_ref * to_apply_result(Z3_apply_result g) { return reinterpret_cast<Z3_apply_result_ref *>(g); }
|
||||
inline Z3_apply_result of_apply_result(Z3_apply_result_ref * g) { return reinterpret_cast<Z3_apply_result>(g); }
|
||||
|
||||
#endif
|
333
src/api/api_user_theory.cpp
Normal file
333
src/api/api_user_theory.cpp
Normal file
|
@ -0,0 +1,333 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_user_theory.cpp
|
||||
|
||||
Abstract:
|
||||
API for external theories
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"api_log_macros.h"
|
||||
#include"api_context.h"
|
||||
#include"api_util.h"
|
||||
#include"user_smt_theory.h"
|
||||
|
||||
smt::user_theory * mk_t(Z3_theory t) {
|
||||
return reinterpret_cast<smt::user_theory*>(t);
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
///////////////////////////////
|
||||
// Theory plugin
|
||||
// No support for logging
|
||||
|
||||
Z3_theory Z3_mk_theory(Z3_context c, Z3_string th_name, void * ext_data) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
if (mk_c(c)->get_solver().get_scope_level() > 0) {
|
||||
SET_ERROR_CODE(Z3_INVALID_USAGE);
|
||||
return 0;
|
||||
}
|
||||
return reinterpret_cast<Z3_theory>(mk_user_theory(mk_c(c)->get_solver(), c, ext_data, th_name));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
void * Z3_theory_get_ext_data(Z3_theory t) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
void * r = mk_t(t)->get_ext_data();
|
||||
return r;
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_sort Z3_theory_mk_sort(Z3_context c, Z3_theory t, Z3_symbol s) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
sort * r = mk_t(t)->mk_sort(to_symbol(s));
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
return of_sort(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_theory_mk_value(Z3_context c, Z3_theory t, Z3_symbol n, Z3_sort s) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
func_decl * d = mk_t(t)->mk_value_decl(to_symbol(n), to_sort(s));
|
||||
app * r = mk_c(c)->m().mk_const(d);
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
return of_ast(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_theory_mk_constant(Z3_context c, Z3_theory t, Z3_symbol n, Z3_sort s) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
Z3_func_decl d = Z3_theory_mk_func_decl(c, t, n, 0, 0, s);
|
||||
app * r = mk_c(c)->m().mk_const(to_func_decl(d));
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
return of_ast(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_func_decl Z3_theory_mk_func_decl(Z3_context c, Z3_theory t, Z3_symbol n,
|
||||
unsigned domain_size, Z3_sort const domain[],
|
||||
Z3_sort range) {
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
func_decl * r = mk_t(t)->mk_func_decl(to_symbol(n), domain_size, to_sorts(domain), to_sort(range));
|
||||
mk_c(c)->save_ast_trail(r);
|
||||
return of_func_decl(r);
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_context Z3_theory_get_context(Z3_theory t) {
|
||||
Z3_context c = reinterpret_cast<Z3_context>(mk_t(t)->get_ext_context());
|
||||
RESET_ERROR_CODE();
|
||||
return c;
|
||||
}
|
||||
|
||||
void Z3_set_delete_callback(Z3_theory t, Z3_theory_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_delete_fptr(reinterpret_cast<smt::theory_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_reduce_app_callback(Z3_theory t, Z3_reduce_app_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_reduce_app_fptr(reinterpret_cast<reduce_app_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_reduce_eq_callback(Z3_theory t, Z3_reduce_eq_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_reduce_eq_fptr(reinterpret_cast<reduce_eq_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_reduce_distinct_callback(Z3_theory t, Z3_reduce_distinct_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_reduce_distinct_fptr(reinterpret_cast<reduce_distinct_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_new_app_callback(Z3_theory t, Z3_theory_ast_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_new_app_fptr(reinterpret_cast<smt::theory_app_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_new_elem_callback(Z3_theory t, Z3_theory_ast_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_new_elem_fptr(reinterpret_cast<smt::theory_app_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_init_search_callback(Z3_theory t, Z3_theory_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_init_search_fptr(reinterpret_cast<smt::theory_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_push_callback(Z3_theory t, Z3_theory_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_push_fptr(reinterpret_cast<smt::theory_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_pop_callback(Z3_theory t, Z3_theory_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_pop_fptr(reinterpret_cast<smt::theory_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_restart_callback(Z3_theory t, Z3_theory_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_restart_fptr(reinterpret_cast<smt::theory_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_reset_callback(Z3_theory t, Z3_theory_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_reset_fptr(reinterpret_cast<smt::theory_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_final_check_callback(Z3_theory t, Z3_theory_final_check_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_final_check_fptr(reinterpret_cast<smt::theory_final_check_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_new_eq_callback(Z3_theory t, Z3_theory_ast_ast_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_new_eq_fptr(reinterpret_cast<smt::theory_app_app_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_new_diseq_callback(Z3_theory t, Z3_theory_ast_ast_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_new_diseq_fptr(reinterpret_cast<smt::theory_app_app_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_new_assignment_callback(Z3_theory t, Z3_theory_ast_bool_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_new_assignment_fptr(reinterpret_cast<smt::theory_app_bool_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_set_new_relevant_callback(Z3_theory t, Z3_theory_ast_callback_fptr f) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->set_new_relevant_fptr(reinterpret_cast<smt::theory_app_callback_fptr>(f));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_theory_assert_axiom(Z3_theory t, Z3_ast ax) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->assert_axiom(to_ast(ax));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_theory_assume_eq(Z3_theory t, Z3_ast lhs, Z3_ast rhs) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->assume_eq(to_ast(lhs), to_ast(rhs));
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
void Z3_theory_enable_axiom_simplification(Z3_theory t, Z3_bool flag) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
mk_t(t)->enable_axiom_simplification(flag == Z3_TRUE);
|
||||
Z3_CATCH;
|
||||
}
|
||||
|
||||
Z3_ast Z3_theory_get_eqc_root(Z3_theory t, Z3_ast n) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return of_ast(mk_t(t)->get_root(to_ast(n)));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_theory_get_eqc_next(Z3_theory t, Z3_ast n) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return of_ast(mk_t(t)->get_next(to_ast(n)));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_theory_get_num_parents(Z3_theory t, Z3_ast n) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return mk_t(t)->get_num_parents(to_ast(n));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_theory_get_parent(Z3_theory t, Z3_ast n, unsigned i) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return of_ast(mk_t(t)->get_parent(to_ast(n), i));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_theory_get_num_elems(Z3_theory t) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return mk_t(t)->get_num_asts();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_theory_get_elem(Z3_theory t, unsigned i) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return of_ast(mk_t(t)->get_ast(i));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
unsigned Z3_theory_get_num_apps(Z3_theory t) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return mk_t(t)->get_num_parents();
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_ast Z3_theory_get_app(Z3_theory t, unsigned i) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return of_ast(mk_t(t)->get_parent(i));
|
||||
Z3_CATCH_RETURN(0);
|
||||
}
|
||||
|
||||
Z3_bool Z3_theory_is_value(Z3_theory t, Z3_ast n) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return is_app(to_ast(n)) && mk_t(t)->get_family_id() == to_app(to_ast(n))->get_family_id();
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
Z3_bool Z3_theory_is_decl(Z3_theory t, Z3_func_decl d) {
|
||||
Z3_context c = Z3_theory_get_context(t);
|
||||
Z3_TRY;
|
||||
RESET_ERROR_CODE();
|
||||
return mk_t(t)->get_family_id() == to_func_decl(d)->get_family_id();
|
||||
Z3_CATCH_RETURN(Z3_FALSE);
|
||||
}
|
||||
|
||||
};
|
150
src/api/api_util.h
Normal file
150
src/api/api_util.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
api_util.h
|
||||
|
||||
Abstract:
|
||||
Goodies used to build the Z3 external API.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-02-29.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _API_UTIL_H_
|
||||
#define _API_UTIL_H_
|
||||
|
||||
#include"params.h"
|
||||
#include"lbool.h"
|
||||
#include"ast.h"
|
||||
|
||||
#define Z3_TRY try {
|
||||
#define Z3_CATCH_CORE(CODE) } catch (z3_exception & ex) { mk_c(c)->handle_exception(ex); CODE }
|
||||
#define Z3_CATCH Z3_CATCH_CORE(return;)
|
||||
#define Z3_CATCH_RETURN(VAL) Z3_CATCH_CORE(return VAL;)
|
||||
|
||||
#define CHECK_REF_COUNT(a) (reinterpret_cast<ast const*>(a)->get_ref_count() > 0)
|
||||
#define VALIDATE(a) SASSERT(!a || CHECK_REF_COUNT(a))
|
||||
|
||||
namespace api {
|
||||
// Generic wrapper for ref-count objects exposed by the API
|
||||
class object {
|
||||
unsigned m_ref_count;
|
||||
public:
|
||||
object():m_ref_count(0) {}
|
||||
virtual ~object() {}
|
||||
void inc_ref() { m_ref_count++; }
|
||||
void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); }
|
||||
};
|
||||
};
|
||||
|
||||
inline ast * to_ast(Z3_ast a) { VALIDATE(a); return reinterpret_cast<ast *>(a); }
|
||||
inline Z3_ast of_ast(ast* a) { return reinterpret_cast<Z3_ast>(a); }
|
||||
|
||||
inline expr * to_expr(Z3_ast a) { VALIDATE(a); return reinterpret_cast<expr*>(a); }
|
||||
inline Z3_ast of_expr(expr* e) { return reinterpret_cast<Z3_ast>(e); }
|
||||
|
||||
inline expr * const * to_exprs(Z3_ast const* a) { return reinterpret_cast<expr* const*>(a); }
|
||||
inline Z3_ast * const * of_exprs(expr* const* e) { return reinterpret_cast<Z3_ast* const*>(e); }
|
||||
|
||||
inline app * to_app(Z3_app a) { VALIDATE(a); return reinterpret_cast<app*>(a); }
|
||||
inline app * to_app(Z3_ast a) { VALIDATE(a); return reinterpret_cast<app*>(a); }
|
||||
inline Z3_app of_app(app* a) { return reinterpret_cast<Z3_app>(a); }
|
||||
|
||||
inline app * const* to_apps(Z3_ast const* a) { VALIDATE(a); return reinterpret_cast<app * const*>(a); }
|
||||
|
||||
inline ast * const * to_asts(Z3_ast const* a) { return reinterpret_cast<ast* const*>(a); }
|
||||
|
||||
inline sort * to_sort(Z3_sort a) { VALIDATE(a); return reinterpret_cast<sort*>(a); }
|
||||
inline Z3_sort of_sort(sort* s) { return reinterpret_cast<Z3_sort>(s); }
|
||||
|
||||
inline sort * const * to_sorts(Z3_sort const* a) { return reinterpret_cast<sort* const*>(a); }
|
||||
inline Z3_sort const * of_sorts(sort* const* s) { return reinterpret_cast<Z3_sort const*>(s); }
|
||||
|
||||
inline func_decl * to_func_decl(Z3_func_decl a) { VALIDATE(a); return reinterpret_cast<func_decl*>(a); }
|
||||
inline Z3_func_decl of_func_decl(func_decl* f) { return reinterpret_cast<Z3_func_decl>(f); }
|
||||
|
||||
inline func_decl * const * to_func_decls(Z3_func_decl const* f) { return reinterpret_cast<func_decl*const*>(f); }
|
||||
|
||||
inline symbol to_symbol(Z3_symbol s) { return symbol::mk_symbol_from_c_ptr(reinterpret_cast<void*>(s)); }
|
||||
inline Z3_symbol of_symbol(symbol s) { return reinterpret_cast<Z3_symbol>(const_cast<void*>(s.c_ptr())); }
|
||||
|
||||
inline Z3_pattern of_pattern(ast* a) { VALIDATE(a); return reinterpret_cast<Z3_pattern>(a); }
|
||||
inline app* to_pattern(Z3_pattern p) { return reinterpret_cast<app*>(p); }
|
||||
|
||||
inline Z3_lbool of_lbool(lbool b) { return static_cast<Z3_lbool>(b); }
|
||||
inline lbool to_lbool(Z3_lbool b) { return static_cast<lbool>(b); }
|
||||
|
||||
struct Z3_params_ref : public api::object {
|
||||
params_ref m_params;
|
||||
virtual ~Z3_params_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_params_ref * to_params(Z3_params p) { return reinterpret_cast<Z3_params_ref *>(p); }
|
||||
inline Z3_params of_params(Z3_params_ref * p) { return reinterpret_cast<Z3_params>(p); }
|
||||
inline params_ref to_param_ref(Z3_params p) { return p == 0 ? params_ref() : to_params(p)->m_params; }
|
||||
|
||||
struct Z3_param_descrs_ref : public api::object {
|
||||
param_descrs m_descrs;
|
||||
virtual ~Z3_param_descrs_ref() {}
|
||||
};
|
||||
|
||||
inline Z3_param_descrs_ref * to_param_descrs(Z3_param_descrs p) { return reinterpret_cast<Z3_param_descrs_ref *>(p); }
|
||||
inline Z3_param_descrs of_param_descrs(Z3_param_descrs_ref * p) { return reinterpret_cast<Z3_param_descrs>(p); }
|
||||
inline param_descrs * to_param_descrs_ptr(Z3_param_descrs p) { return p == 0 ? 0 : &(to_param_descrs(p)->m_descrs); }
|
||||
|
||||
|
||||
#define SKIP ((void) 0)
|
||||
|
||||
#define MK_UNARY_BODY(NAME, FID, OP, EXTRA_CODE) \
|
||||
Z3_TRY; \
|
||||
RESET_ERROR_CODE(); \
|
||||
EXTRA_CODE; \
|
||||
expr * _n = to_expr(n); \
|
||||
ast* a = mk_c(c)->m().mk_app(FID, OP, 0, 0, 1, &_n); \
|
||||
mk_c(c)->save_ast_trail(a); \
|
||||
check_sorts(c, a); \
|
||||
RETURN_Z3(of_ast(a)); \
|
||||
Z3_CATCH_RETURN(0);
|
||||
|
||||
#define MK_UNARY(NAME, FID, OP, EXTRA_CODE) \
|
||||
Z3_ast Z3_API NAME(Z3_context c, Z3_ast n) { \
|
||||
LOG_ ## NAME(c, n); \
|
||||
MK_UNARY_BODY(NAME, FID, OP, EXTRA_CODE); \
|
||||
}
|
||||
|
||||
#define MK_BINARY_BODY(NAME, FID, OP, EXTRA_CODE) \
|
||||
Z3_TRY; \
|
||||
RESET_ERROR_CODE(); \
|
||||
EXTRA_CODE; \
|
||||
expr * args[2] = { to_expr(n1), to_expr(n2) }; \
|
||||
ast* a = mk_c(c)->m().mk_app(FID, OP, 0, 0, 2, args); \
|
||||
mk_c(c)->save_ast_trail(a); \
|
||||
check_sorts(c, a); \
|
||||
RETURN_Z3(of_ast(a)); \
|
||||
Z3_CATCH_RETURN(0);
|
||||
|
||||
#define MK_BINARY(NAME, FID, OP, EXTRA_CODE) \
|
||||
Z3_ast Z3_API NAME(Z3_context c, Z3_ast n1, Z3_ast n2) { \
|
||||
LOG_ ## NAME(c, n1, n2); \
|
||||
MK_BINARY_BODY(NAME, FID, OP, EXTRA_CODE); \
|
||||
}
|
||||
|
||||
#define MK_NARY(NAME, FID, OP, EXTRA_CODE) \
|
||||
Z3_ast Z3_API NAME(Z3_context c, unsigned num_args, Z3_ast const* args) { \
|
||||
Z3_TRY; \
|
||||
LOG_ ## NAME(c, num_args, args); \
|
||||
RESET_ERROR_CODE(); \
|
||||
EXTRA_CODE; \
|
||||
ast* a = mk_c(c)->m().mk_app(FID, OP, 0, 0, num_args, to_exprs(args)); \
|
||||
mk_c(c)->save_ast_trail(a); \
|
||||
check_sorts(c, a); \
|
||||
RETURN_Z3(of_ast(a)); \
|
||||
Z3_CATCH_RETURN(0); \
|
||||
}
|
||||
|
||||
#endif
|
494
src/api/expr_pattern_match.cpp
Normal file
494
src/api/expr_pattern_match.cpp
Normal file
|
@ -0,0 +1,494 @@
|
|||
/*++
|
||||
Copyright (c) 2007 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
ast_pattern_match.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Search for opportune pattern matching utilities.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2007-04-10
|
||||
Leonardo (leonardo)
|
||||
|
||||
Notes:
|
||||
|
||||
instead of the brute force enumeration of permutations
|
||||
we can add an instruction 'gate' which copies the ast
|
||||
into a register and creates another register with the same
|
||||
term. Matching against a 'gate' is a noop, apart from clearing
|
||||
the ast in the register. Then on backtracking we know how many
|
||||
terms were matched from the permutation. It does not make sense
|
||||
to enumerate all combinations of terms that were not considered, so
|
||||
skip these.
|
||||
|
||||
Also, compilation should re-order terms to fail fast.
|
||||
|
||||
--*/
|
||||
|
||||
#include"ast.h"
|
||||
#include"expr_pattern_match.h"
|
||||
#include"smtparser.h"
|
||||
#include"for_each_ast.h"
|
||||
#include"ast_ll_pp.h"
|
||||
#include"ast_pp.h"
|
||||
|
||||
expr_pattern_match::expr_pattern_match(ast_manager & manager):
|
||||
m_manager(manager), m_precompiled(manager) {
|
||||
}
|
||||
|
||||
expr_pattern_match::~expr_pattern_match() {
|
||||
}
|
||||
|
||||
bool
|
||||
expr_pattern_match::match_quantifier(quantifier* qf, app_ref_vector& patterns, unsigned& weight) {
|
||||
if (m_regs.empty()) {
|
||||
// HACK: the code crashes if database is empty.
|
||||
return false;
|
||||
}
|
||||
m_regs[0] = qf->get_expr();
|
||||
for (unsigned i = 0; i < m_precompiled.size(); ++i) {
|
||||
quantifier* qf2 = m_precompiled[i].get();
|
||||
if (qf2->is_forall() != qf->is_forall()) {
|
||||
continue;
|
||||
}
|
||||
if (qf2->get_num_decls() != qf->get_num_decls()) {
|
||||
continue;
|
||||
}
|
||||
subst s;
|
||||
if (match(qf->get_expr(), m_first_instrs[i], s)) {
|
||||
for (unsigned j = 0; j < qf2->get_num_patterns(); ++j) {
|
||||
app* p = static_cast<app*>(qf2->get_pattern(j));
|
||||
expr_ref p_result(m_manager);
|
||||
instantiate(p, qf->get_num_decls(), s, p_result);
|
||||
patterns.push_back(to_app(p_result.get()));
|
||||
}
|
||||
weight = qf2->get_weight();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
expr_pattern_match::instantiate(expr* a, unsigned num_bound, subst& s, expr_ref& result) {
|
||||
bound b;
|
||||
for (unsigned i = 0; i < num_bound; ++i) {
|
||||
b.insert(m_bound_dom[i], m_bound_rng[i]);
|
||||
}
|
||||
|
||||
inst_proc proc(m_manager, s, b, m_regs);
|
||||
for_each_ast(proc, a);
|
||||
expr* v = 0;
|
||||
proc.m_memoize.find(a, v);
|
||||
SASSERT(v);
|
||||
result = v;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
expr_pattern_match::compile(expr* q)
|
||||
{
|
||||
SASSERT(q->get_kind() == AST_QUANTIFIER);
|
||||
quantifier* qf = to_quantifier(q);
|
||||
unsigned ip = m_instrs.size();
|
||||
m_first_instrs.push_back(ip);
|
||||
m_precompiled.push_back(qf);
|
||||
|
||||
instr instr(BACKTRACK);
|
||||
unsigned_vector regs;
|
||||
ptr_vector<expr> pats;
|
||||
unsigned max_reg = 1;
|
||||
subst s;
|
||||
pats.push_back(qf->get_expr());
|
||||
regs.push_back(0);
|
||||
unsigned num_bound = 0;
|
||||
obj_map<var, unsigned> bound;
|
||||
|
||||
while (!pats.empty()) {
|
||||
|
||||
unsigned reg = regs.back();
|
||||
expr* pat = pats.back();
|
||||
regs.pop_back();
|
||||
pats.pop_back();
|
||||
|
||||
instr.m_pat = pat;
|
||||
instr.m_next = m_instrs.size()+1;
|
||||
instr.m_reg = reg;
|
||||
instr.m_offset = max_reg;
|
||||
|
||||
switch(pat->get_kind()) {
|
||||
case AST_VAR: {
|
||||
var* b = to_var(pat);
|
||||
if (bound.find(b, instr.m_num_bound)) {
|
||||
instr.m_kind = CHECK_BOUND;
|
||||
}
|
||||
else {
|
||||
instr.m_kind = SET_BOUND;
|
||||
instr.m_num_bound = num_bound;
|
||||
bound.insert(b, num_bound);
|
||||
++num_bound;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AST_APP: {
|
||||
unsigned r = 0;
|
||||
app* app = to_app(pat);
|
||||
func_decl* d = app->get_decl();
|
||||
|
||||
for (unsigned i = 0; i < app->get_num_args(); ++i) {
|
||||
regs.push_back(max_reg);
|
||||
pats.push_back(app->get_arg(i));
|
||||
++max_reg;
|
||||
}
|
||||
|
||||
if (is_var(d)) {
|
||||
if (s.find(d, r)) {
|
||||
instr.m_kind = CHECK_VAR;
|
||||
instr.m_other_reg = r;
|
||||
}
|
||||
else {
|
||||
instr.m_kind = SET_VAR;
|
||||
s.insert(d, reg);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (d->is_associative() && d->is_commutative()) {
|
||||
instr.m_kind = BIND_AC;
|
||||
}
|
||||
else if (d->is_commutative()) {
|
||||
SASSERT(app->get_num_args() == 2);
|
||||
instr.m_kind = BIND_C;
|
||||
}
|
||||
else {
|
||||
instr.m_kind = BIND;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
instr.m_kind = CHECK_TERM;
|
||||
break;
|
||||
}
|
||||
m_instrs.push_back(instr);
|
||||
}
|
||||
|
||||
if (m_regs.size() <= max_reg) {
|
||||
m_regs.resize(max_reg+1, 0);
|
||||
}
|
||||
if (m_bound_dom.size() <= num_bound) {
|
||||
m_bound_dom.resize(num_bound+1, 0);
|
||||
m_bound_rng.resize(num_bound+1, 0);
|
||||
}
|
||||
|
||||
instr.m_kind = YIELD;
|
||||
m_instrs.push_back(instr);
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
expr_pattern_match::match(expr* a, unsigned init, subst& s)
|
||||
{
|
||||
svector<instr> bstack;
|
||||
instr pc = m_instrs[init];
|
||||
|
||||
while (true) {
|
||||
bool ok = false;
|
||||
switch(pc.m_kind) {
|
||||
case YIELD:
|
||||
// substitution s contains registers with matching declarations.
|
||||
return true;
|
||||
case CHECK_TERM:
|
||||
TRACE("expr_pattern_match", display(tout, pc);
|
||||
ast_pp(tout, m_regs[pc.m_reg], m_manager) << "\n";);
|
||||
ok = (pc.m_pat == m_regs[pc.m_reg]);
|
||||
break;
|
||||
case SET_VAR:
|
||||
case CHECK_VAR: {
|
||||
TRACE("expr_pattern_match", display(tout, pc);
|
||||
ast_pp(tout, m_regs[pc.m_reg], m_manager) << "\n";);
|
||||
app* app1 = to_app(pc.m_pat);
|
||||
a = m_regs[pc.m_reg];
|
||||
if (a->get_kind() != AST_APP) {
|
||||
break;
|
||||
}
|
||||
app* app2 = to_app(a);
|
||||
if (app1->get_num_args() != app2->get_num_args()) {
|
||||
break;
|
||||
}
|
||||
if (pc.m_kind == CHECK_VAR &&
|
||||
to_app(m_regs[pc.m_reg])->get_decl() !=
|
||||
to_app(m_regs[pc.m_other_reg])->get_decl()) {
|
||||
break;
|
||||
}
|
||||
for (unsigned i = 0; i < app2->get_num_args(); ++i) {
|
||||
m_regs[pc.m_offset + i] = app2->get_arg(i);
|
||||
}
|
||||
if (pc.m_kind == SET_VAR) {
|
||||
s.insert(app1->get_decl(), pc.m_reg);
|
||||
}
|
||||
ok = true;
|
||||
break;
|
||||
}
|
||||
case SET_BOUND: {
|
||||
TRACE("expr_pattern_match", display(tout, pc);
|
||||
ast_pp(tout, m_regs[pc.m_reg], m_manager) << "\n";);
|
||||
a = m_regs[pc.m_reg];
|
||||
if (a->get_kind() != AST_VAR) {
|
||||
break;
|
||||
}
|
||||
ok = true;
|
||||
var* var_a = to_var(a);
|
||||
var* var_p = to_var(pc.m_pat);
|
||||
// check that the mapping of bound variables remains a bijection.
|
||||
for (unsigned i = 0; ok && i < pc.m_num_bound; ++i) {
|
||||
ok = (a != m_bound_rng[i]);
|
||||
}
|
||||
if (!ok) {
|
||||
break;
|
||||
}
|
||||
m_bound_dom[pc.m_num_bound] = var_p;
|
||||
m_bound_rng[pc.m_num_bound] = var_a;
|
||||
break;
|
||||
}
|
||||
case CHECK_BOUND:
|
||||
TRACE("expr_pattern_match",
|
||||
tout
|
||||
<< "check bound "
|
||||
<< pc.m_num_bound << " " << pc.m_reg;
|
||||
);
|
||||
ok = m_bound_rng[pc.m_num_bound] == m_regs[pc.m_reg];
|
||||
break;
|
||||
case BIND:
|
||||
case BIND_AC:
|
||||
case BIND_C: {
|
||||
TRACE("expr_pattern_match", display(tout, pc);
|
||||
tout << mk_pp(m_regs[pc.m_reg],m_manager) << "\n";);
|
||||
app* app1 = to_app(pc.m_pat);
|
||||
a = m_regs[pc.m_reg];
|
||||
if (a->get_kind() != AST_APP) {
|
||||
break;
|
||||
}
|
||||
app* app2 = to_app(a);
|
||||
if (app1->get_num_args() != app2->get_num_args()) {
|
||||
break;
|
||||
}
|
||||
if (!match_decl(app1->get_decl(), app2->get_decl())) {
|
||||
break;
|
||||
}
|
||||
switch(pc.m_kind) {
|
||||
case BIND:
|
||||
for (unsigned i = 0; i < app2->get_num_args(); ++i) {
|
||||
m_regs[pc.m_offset + i] = app2->get_arg(i);
|
||||
}
|
||||
ok = true;
|
||||
break; // process the next instruction.
|
||||
case BIND_AC:
|
||||
// push CHOOSE_AC on the backtracking stack.
|
||||
bstack.push_back(instr(CHOOSE_AC, pc.m_offset, pc.m_next, app2, 1));
|
||||
break;
|
||||
case BIND_C:
|
||||
// push CHOOSE_C on the backtracking stack.
|
||||
ok = true;
|
||||
m_regs[pc.m_offset] = app2->get_arg(0);
|
||||
m_regs[pc.m_offset+1] = app2->get_arg(1);
|
||||
bstack.push_back(instr(CHOOSE_C, pc.m_offset, pc.m_next, app2, 2));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CHOOSE_C:
|
||||
ok = true;
|
||||
SASSERT (pc.m_count == 2);
|
||||
m_regs[pc.m_offset+1] = pc.m_app->get_arg(0);
|
||||
m_regs[pc.m_offset] = pc.m_app->get_arg(1);
|
||||
break;
|
||||
case CHOOSE_AC: {
|
||||
ok = true;
|
||||
app* app2 = pc.m_app;
|
||||
for (unsigned i = 0; i < app2->get_num_args(); ++i) {
|
||||
m_regs[pc.m_offset + i] = app2->get_arg(i);
|
||||
}
|
||||
// generate the k'th permutation.
|
||||
unsigned k = pc.m_count;
|
||||
unsigned fac = 1;
|
||||
unsigned num_args = pc.m_app->get_num_args();
|
||||
for (unsigned j = 2; j <= num_args; ++j) {
|
||||
fac *= (j-1);
|
||||
SASSERT(((k /fac) % j) + 1 <= j);
|
||||
std::swap(m_regs[pc.m_offset + j - 1], m_regs[pc.m_offset + j - ((k / fac) % j) - 1]);
|
||||
}
|
||||
if (k < fac*num_args) {
|
||||
bstack.push_back(instr(CHOOSE_AC, pc.m_offset, pc.m_next, app2, k+1));
|
||||
}
|
||||
TRACE("expr_pattern_match",
|
||||
{
|
||||
tout << "fac: " << fac << " num_args:" << num_args << " k:" << k << "\n";
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
ast_pp(tout, m_regs[pc.m_offset + i], m_manager);
|
||||
tout << " ";
|
||||
}
|
||||
tout << "\n";
|
||||
});
|
||||
break;
|
||||
}
|
||||
case BACKTRACK:
|
||||
if (bstack.empty()) {
|
||||
return false;
|
||||
}
|
||||
pc = bstack.back();
|
||||
bstack.pop_back();
|
||||
continue; // with the loop.
|
||||
}
|
||||
|
||||
if (ok) {
|
||||
pc = m_instrs[pc.m_next];
|
||||
}
|
||||
else {
|
||||
TRACE("expr_pattern_match", tout << "backtrack\n";);
|
||||
pc = m_instrs[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
expr_pattern_match::match_decl(func_decl const * pat, func_decl const * d) const {
|
||||
if (pat == d) {
|
||||
return true;
|
||||
}
|
||||
if (pat->get_arity() != d->get_arity()) {
|
||||
return false;
|
||||
}
|
||||
// match families
|
||||
if (pat->get_family_id() == null_family_id) {
|
||||
return false;
|
||||
}
|
||||
if (d->get_family_id() != pat->get_family_id()) {
|
||||
return false;
|
||||
}
|
||||
if (d->get_decl_kind() != pat->get_decl_kind()) {
|
||||
return false;
|
||||
}
|
||||
if (d->get_num_parameters() != pat->get_num_parameters()) {
|
||||
return false;
|
||||
}
|
||||
for (unsigned i = 0; i < d->get_num_parameters(); ++i) {
|
||||
if (!(d->get_parameter(i) == pat->get_parameter(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
expr_pattern_match::is_var(func_decl* d) {
|
||||
const char* s = d->get_name().bare_str();
|
||||
return s && *s == '?';
|
||||
}
|
||||
|
||||
void
|
||||
expr_pattern_match::initialize(char const * spec_string) {
|
||||
if (!m_instrs.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_instrs.push_back(instr(BACKTRACK));
|
||||
|
||||
smtlib::parser* parser = smtlib::parser::create(m_manager);
|
||||
parser->initialize_smtlib();
|
||||
if (!parser->parse_string(spec_string)) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
smtlib::benchmark* bench = parser->get_benchmark();
|
||||
smtlib::theory::expr_iterator it = bench->begin_formulas();
|
||||
smtlib::theory::expr_iterator end = bench->end_formulas();
|
||||
for (; it != end; ++it) {
|
||||
compile(*it);
|
||||
}
|
||||
dealloc(parser);
|
||||
TRACE("expr_pattern_match", display(tout); );
|
||||
}
|
||||
|
||||
void
|
||||
expr_pattern_match::display(std::ostream& out) const {
|
||||
for (unsigned i = 0; i < m_instrs.size(); ++i) {
|
||||
display(out, m_instrs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
expr_pattern_match::display(std::ostream& out, instr const& pc) const {
|
||||
switch(pc.m_kind) {
|
||||
case BACKTRACK:
|
||||
out << "backtrack\n";
|
||||
break;
|
||||
case BIND:
|
||||
out << "bind ";
|
||||
ast_pp(out, to_app(pc.m_pat)->get_decl(), m_manager) << " ";
|
||||
ast_pp(out, pc.m_pat, m_manager) << "\n";
|
||||
out << "next: " << pc.m_next << "\n";
|
||||
out << "offset: " << pc.m_offset << "\n";
|
||||
out << "reg: " << pc.m_reg << "\n";
|
||||
break;
|
||||
case BIND_AC:
|
||||
out << "bind_ac ";
|
||||
ast_pp(out, to_app(pc.m_pat)->get_decl(), m_manager) << " ";
|
||||
ast_pp(out, pc.m_pat, m_manager) << "\n";
|
||||
out << "next: " << pc.m_next << "\n";
|
||||
out << "offset: " << pc.m_offset << "\n";
|
||||
out << "reg: " << pc.m_reg << "\n";
|
||||
break;
|
||||
case BIND_C:
|
||||
out << "bind_c ";
|
||||
ast_pp(out, to_app(pc.m_pat)->get_decl(), m_manager) << " ";
|
||||
ast_pp(out, pc.m_pat, m_manager) << "\n";
|
||||
out << "next: " << pc.m_next << "\n";
|
||||
out << "offset: " << pc.m_offset << "\n";
|
||||
out << "reg: " << pc.m_reg << "\n";
|
||||
break;
|
||||
case CHOOSE_AC:
|
||||
out << "choose_ac\n";
|
||||
out << "next: " << pc.m_next << "\n";
|
||||
out << "count: " << pc.m_count << "\n";
|
||||
break;
|
||||
case CHOOSE_C:
|
||||
out << "choose_c\n";
|
||||
out << "next: " << pc.m_next << "\n";
|
||||
//out << "reg: " << pc.m_reg << "\n";
|
||||
break;
|
||||
case CHECK_VAR:
|
||||
out << "check_var ";
|
||||
ast_pp(out, pc.m_pat, m_manager) << "\n";
|
||||
out << "next: " << pc.m_next << "\n";
|
||||
out << "reg: " << pc.m_reg << "\n";
|
||||
out << "other_reg: " << pc.m_other_reg << "\n";
|
||||
break;
|
||||
case CHECK_TERM:
|
||||
out << "check ";
|
||||
ast_pp(out, pc.m_pat, m_manager) << "\n";
|
||||
out << "next: " << pc.m_next << "\n";
|
||||
out << "reg: " << pc.m_reg << "\n";
|
||||
break;
|
||||
case YIELD:
|
||||
out << "yield\n";
|
||||
break;
|
||||
case SET_VAR:
|
||||
out << "set_var ";
|
||||
ast_pp(out, pc.m_pat, m_manager) << "\n";
|
||||
out << "next: " << pc.m_next << "\n";
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
} }
|
||||
|
||||
|
||||
// TBD: fix type overloading.
|
||||
// TBD: bound number of permutations.
|
||||
// TBD: forward pruning checks.
|
149
src/api/expr_pattern_match.h
Normal file
149
src/api/expr_pattern_match.h
Normal file
|
@ -0,0 +1,149 @@
|
|||
/*++
|
||||
Copyright (c) 2007 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
expr_pattern_match.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Search for opportune pattern matching utilities.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2007-04-10
|
||||
Leonardo (leonardo)
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _EXPR_PATTERN_MATCH_H_
|
||||
#define _EXPR_PATTERN_MATCH_H_
|
||||
|
||||
#include"ast.h"
|
||||
#include"map.h"
|
||||
#include"front_end_params.h"
|
||||
#include"pattern_inference.h"
|
||||
|
||||
class expr_pattern_match : public pattern_database {
|
||||
|
||||
enum instr_kind {
|
||||
BACKTRACK,
|
||||
BIND,
|
||||
BIND_AC,
|
||||
BIND_C,
|
||||
CHOOSE_AC,
|
||||
CHOOSE_C,
|
||||
SET_VAR,
|
||||
CHECK_VAR,
|
||||
CHECK_TERM,
|
||||
SET_BOUND,
|
||||
CHECK_BOUND,
|
||||
YIELD,
|
||||
};
|
||||
|
||||
struct instr {
|
||||
instr(instr_kind k) : m_kind(k) {}
|
||||
instr(instr_kind k, unsigned o, unsigned next, app* app, unsigned count):
|
||||
m_kind(k), m_offset(o), m_next(next), m_app(app), m_count(count) {}
|
||||
|
||||
instr_kind m_kind;
|
||||
unsigned m_offset;
|
||||
unsigned m_next;
|
||||
app* m_app;
|
||||
expr* m_pat;
|
||||
unsigned m_reg;
|
||||
unsigned m_other_reg;
|
||||
unsigned m_count;
|
||||
unsigned m_num_bound;
|
||||
};
|
||||
|
||||
typedef obj_map<func_decl, unsigned> subst;
|
||||
typedef obj_map<var, var*> bound;
|
||||
|
||||
struct inst_proc {
|
||||
ast_manager& m_manager;
|
||||
expr_ref_vector m_pinned;
|
||||
subst& m_subst;
|
||||
bound& m_bound;
|
||||
obj_map<expr, expr*> m_memoize;
|
||||
ptr_vector<expr>& m_regs;
|
||||
|
||||
|
||||
inst_proc(ast_manager& m, subst& s, bound& b, ptr_vector<expr>& regs) :
|
||||
m_manager(m), m_pinned(m), m_subst(s), m_bound(b), m_regs(regs) {}
|
||||
|
||||
|
||||
void operator()(ast* a) {
|
||||
}
|
||||
|
||||
void operator()(expr* a) {
|
||||
m_memoize.insert(a, a);
|
||||
}
|
||||
|
||||
void operator()(var* v) {
|
||||
var* b = 0;
|
||||
if (m_bound.find(v, b)) {
|
||||
m_memoize.insert(v, b);
|
||||
}
|
||||
else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(app * n) {
|
||||
unsigned r;
|
||||
ptr_vector<expr> args;
|
||||
unsigned num_args = n->get_num_args();
|
||||
func_decl * decl = n->get_decl();
|
||||
expr* result;
|
||||
if (m_subst.find(decl, r)) {
|
||||
decl = to_app(m_regs[r])->get_decl();
|
||||
}
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
expr* arg = 0;
|
||||
if (m_memoize.find(n->get_arg(i), arg)) {
|
||||
SASSERT(arg);
|
||||
args.push_back(arg);
|
||||
}
|
||||
else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
if (m_manager.is_pattern(n)) {
|
||||
result = m_manager.mk_pattern(num_args, reinterpret_cast<app**>(args.c_ptr()));
|
||||
}
|
||||
else {
|
||||
result = m_manager.mk_app(decl, num_args, args.c_ptr());
|
||||
}
|
||||
m_pinned.push_back(result);
|
||||
m_memoize.insert(n, result);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
ast_manager & m_manager;
|
||||
quantifier_ref_vector m_precompiled;
|
||||
unsigned_vector m_first_instrs;
|
||||
svector<instr> m_instrs;
|
||||
ptr_vector<expr> m_regs;
|
||||
ptr_vector<var> m_bound_dom;
|
||||
ptr_vector<var> m_bound_rng;
|
||||
|
||||
public:
|
||||
expr_pattern_match(ast_manager & manager);
|
||||
~expr_pattern_match();
|
||||
virtual bool match_quantifier(quantifier * qf, app_ref_vector & patterns, unsigned & weight);
|
||||
virtual void initialize(char const * database);
|
||||
void display(std::ostream& out) const;
|
||||
|
||||
private:
|
||||
void instantiate(expr* a, unsigned num_bound, subst& s, expr_ref& result);
|
||||
void compile(expr* q);
|
||||
bool match(expr* a, unsigned init, subst& s);
|
||||
bool match_decl(func_decl const * pat, func_decl const * d) const;
|
||||
bool is_var(func_decl* d);
|
||||
void display(std::ostream& out, instr const& pc) const;
|
||||
};
|
||||
|
||||
#endif
|
252
src/api/smtlib.cpp
Normal file
252
src/api/smtlib.cpp
Normal file
|
@ -0,0 +1,252 @@
|
|||
|
||||
#include"smtlib.h"
|
||||
#include"ast_pp.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#ifdef ARRAYSIZE
|
||||
#undef ARRAYSIZE
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#include <strsafe.h>
|
||||
#endif
|
||||
|
||||
#include <iostream>
|
||||
|
||||
|
||||
using namespace smtlib;
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// symtable
|
||||
|
||||
symtable::~symtable() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void symtable::reset() {
|
||||
svector<ptr_vector<func_decl>*> range;
|
||||
m_ids.get_range(range);
|
||||
for (unsigned i = 0; i < range.size(); ++i) {
|
||||
ptr_vector<func_decl> const & v = *range[i];
|
||||
for (unsigned j = 0; j < v.size(); ++j) {
|
||||
m_manager.dec_ref(v[j]);
|
||||
}
|
||||
dealloc(range[i]);
|
||||
}
|
||||
m_ids.reset();
|
||||
ptr_vector<sort> sorts;
|
||||
m_sorts1.get_range(sorts);
|
||||
for (unsigned i = 0; i < sorts.size(); ++i) {
|
||||
m_manager.dec_ref(sorts[i]);
|
||||
}
|
||||
m_sorts1.reset();
|
||||
ptr_vector<sort_builder> sort_builders;
|
||||
m_sorts.get_range(sort_builders);
|
||||
for (unsigned i = 0; i < sort_builders.size(); ++i) {
|
||||
dealloc(sort_builders[i]);
|
||||
}
|
||||
m_sorts.reset();
|
||||
}
|
||||
|
||||
|
||||
void symtable::insert(symbol s, func_decl * d) {
|
||||
ptr_vector<func_decl>* decls = 0;
|
||||
m_manager.inc_ref(d);
|
||||
if (!m_ids.find(s, decls)) {
|
||||
SASSERT(!decls);
|
||||
decls = alloc(ptr_vector<func_decl>);
|
||||
decls->push_back(d);
|
||||
m_ids.insert(s, decls);
|
||||
}
|
||||
else {
|
||||
SASSERT(decls);
|
||||
if ((*decls)[0] != d) {
|
||||
decls->push_back(d);
|
||||
}
|
||||
else {
|
||||
m_manager.dec_ref(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool symtable::find1(symbol s, func_decl*& d) {
|
||||
ptr_vector<func_decl>* decls = 0;
|
||||
|
||||
if (!m_ids.find(s, decls)) {
|
||||
SASSERT(!decls);
|
||||
return false;
|
||||
}
|
||||
SASSERT(decls && !decls->empty());
|
||||
d = (*decls)[0];
|
||||
return true;
|
||||
}
|
||||
|
||||
bool symtable::find_overload(symbol s, ptr_vector<sort> const & dom, func_decl * & d) {
|
||||
ptr_vector<func_decl>* decls = 0;
|
||||
d = 0;
|
||||
if (!m_ids.find(s, decls)) {
|
||||
SASSERT(!decls);
|
||||
return false;
|
||||
}
|
||||
SASSERT(decls);
|
||||
for (unsigned i = 0; i < decls->size(); ++i) {
|
||||
func_decl* decl = (*decls)[i];
|
||||
if (decl->is_associative() && decl->get_arity() > 0) {
|
||||
for (unsigned j = 0; j < dom.size(); ++j) {
|
||||
if (dom[j] != decl->get_domain(0)) {
|
||||
goto try_next;
|
||||
}
|
||||
}
|
||||
d = decl;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (decl->get_arity() != dom.size()) {
|
||||
goto try_next;
|
||||
}
|
||||
for (unsigned j = 0; j < decl->get_arity(); ++j) {
|
||||
if (decl->get_domain(j) != dom[j]) {
|
||||
goto try_next;
|
||||
}
|
||||
}
|
||||
d = decl;
|
||||
return true;
|
||||
|
||||
try_next:
|
||||
if (decl->get_family_id() == m_manager.get_basic_family_id() && decl->get_decl_kind() == OP_DISTINCT) {
|
||||
// we skip type checking for 'distinct'
|
||||
d = decl;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Store in result the func_decl that are not attached to any family id.
|
||||
// That is, the uninterpreted constants and function declarations.
|
||||
void symtable::get_func_decls(ptr_vector<func_decl> & result) const {
|
||||
svector<ptr_vector<func_decl>*> tmp;
|
||||
m_ids.get_range(tmp);
|
||||
svector<ptr_vector<func_decl>*>::const_iterator it = tmp.begin();
|
||||
svector<ptr_vector<func_decl>*>::const_iterator end = tmp.end();
|
||||
for (; it != end; ++it) {
|
||||
ptr_vector<func_decl> * curr = *it;
|
||||
if (curr) {
|
||||
ptr_vector<func_decl>::const_iterator it2 = curr->begin();
|
||||
ptr_vector<func_decl>::const_iterator end2 = curr->end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
func_decl * d = *it2;
|
||||
if (d && d->get_family_id() == null_family_id) {
|
||||
result.push_back(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void symtable::insert(symbol s, sort_builder* sb) {
|
||||
m_sorts.insert(s, sb);
|
||||
}
|
||||
|
||||
bool symtable::lookup(symbol s, sort_builder*& sb) {
|
||||
return m_sorts.find(s, sb);
|
||||
}
|
||||
|
||||
void symtable::push_sort(symbol name, sort* srt) {
|
||||
m_sorts.begin_scope();
|
||||
sort_builder* sb = alloc(basic_sort_builder,srt);
|
||||
m_sorts.insert(name, sb);
|
||||
m_sorts_trail.push_back(sb);
|
||||
}
|
||||
|
||||
void symtable::pop_sorts(unsigned num_sorts) {
|
||||
while (num_sorts > 0) {
|
||||
dealloc(m_sorts_trail.back());
|
||||
m_sorts_trail.pop_back();
|
||||
m_sorts.end_scope();
|
||||
}
|
||||
}
|
||||
|
||||
void symtable::get_sorts(ptr_vector<sort>& result) const {
|
||||
vector<sort*,false> tmp;
|
||||
m_sorts1.get_range(tmp);
|
||||
for (unsigned i = 0; i < tmp.size(); ++i) {
|
||||
if (tmp[i]->get_family_id() == null_family_id) {
|
||||
result.push_back(tmp[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------
|
||||
// theory
|
||||
|
||||
func_decl * theory::declare_func(symbol const & id, sort_ref_buffer & domain, sort * range,
|
||||
bool is_assoc, bool is_comm, bool is_inj) {
|
||||
func_decl * decl = m_ast_manager.mk_func_decl(id, domain.size(), domain.c_ptr(), range,
|
||||
is_assoc, is_comm, is_inj);
|
||||
|
||||
m_symtable.insert(id, decl);
|
||||
m_asts.push_back(decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
||||
sort * theory::declare_sort(symbol const & id) {
|
||||
sort * decl = m_ast_manager.mk_sort(id);
|
||||
m_symtable.insert(id, decl);
|
||||
m_asts.push_back(decl);
|
||||
return decl;
|
||||
}
|
||||
|
||||
|
||||
bool theory::get_func_decl(symbol id, func_decl * & decl) {
|
||||
return m_symtable.find1(id, decl);
|
||||
}
|
||||
|
||||
bool theory::get_sort(symbol id, sort* & s) {
|
||||
return m_symtable.find(id, s);
|
||||
}
|
||||
|
||||
bool theory::get_const(symbol id, expr * & term) {
|
||||
func_decl* decl = 0;
|
||||
if (!get_func_decl(id,decl)) {
|
||||
return false;
|
||||
}
|
||||
if (decl->get_arity() != 0) {
|
||||
return false;
|
||||
}
|
||||
term = m_ast_manager.mk_const(decl);
|
||||
m_asts.push_back(term);
|
||||
return true;
|
||||
}
|
||||
|
||||
void benchmark::display_as_smt2(std::ostream & out) const {
|
||||
if (m_logic != symbol::null)
|
||||
out << "(set-logic " << m_logic << ")\n";
|
||||
out << "(set-info :smt-lib-version 2.0)\n";
|
||||
out << "(set-info :status ";
|
||||
switch (m_status) {
|
||||
case SAT: out << "sat"; break;
|
||||
case UNSAT: out << "unsat"; break;
|
||||
default: out << "unknown"; break;
|
||||
}
|
||||
out << ")\n";
|
||||
#if 0
|
||||
ast_manager & m = m_ast_manager;
|
||||
ptr_vector<func_decl> decls;
|
||||
m_symtable.get_func_decls(decls);
|
||||
ptr_vector<func_decl>::const_iterator it = decls.begin();
|
||||
ptr_vector<func_decl>::const_iterator end = decls.end();
|
||||
for (; it != end; ++it) {
|
||||
func_decl * f = *it;
|
||||
out << "(declare-fun " << f->get_name() << " (";
|
||||
for (unsigned i = 0; i < f->get_arity(); i++) {
|
||||
if (i > 0) out << " ";
|
||||
out << mk_ismt2_pp(f->get_domain(i), m);
|
||||
}
|
||||
out << ") " << mk_ismt2_pp(f->get_range(), m);
|
||||
out << ")\n";
|
||||
}
|
||||
#endif
|
||||
}
|
232
src/api/smtlib.h
Normal file
232
src/api/smtlib.h
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smtlib.h
|
||||
|
||||
Abstract:
|
||||
|
||||
SMT library utilities
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2006-09-29
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _SMTLIB_H_
|
||||
#define _SMTLIB_H_
|
||||
|
||||
#include "ast.h"
|
||||
#include "symbol_table.h"
|
||||
#include "map.h"
|
||||
#include "arith_decl_plugin.h"
|
||||
|
||||
namespace smtlib {
|
||||
|
||||
class sort_builder {
|
||||
public:
|
||||
virtual ~sort_builder() {}
|
||||
virtual bool apply(unsigned num_params, parameter const* params, sort_ref& result) = 0;
|
||||
virtual char const* error_message() { return ""; }
|
||||
};
|
||||
|
||||
class basic_sort_builder : public sort_builder {
|
||||
sort* m_sort;
|
||||
public:
|
||||
basic_sort_builder(sort* s) : m_sort(s) {}
|
||||
|
||||
virtual bool apply(unsigned np, parameter const*, sort_ref& result) {
|
||||
result = m_sort;
|
||||
return m_sort && np != 0;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class symtable {
|
||||
ast_manager& m_manager;
|
||||
symbol_table<sort*> m_sorts1;
|
||||
symbol_table<sort_builder*> m_sorts;
|
||||
ptr_vector<sort_builder> m_sorts_trail;
|
||||
symbol_table<ptr_vector<func_decl>* > m_ids;
|
||||
|
||||
public:
|
||||
|
||||
symtable(ast_manager& m): m_manager(m) {}
|
||||
|
||||
~symtable();
|
||||
|
||||
void reset();
|
||||
|
||||
void insert(symbol s, func_decl * d);
|
||||
|
||||
bool find(symbol s, ptr_vector<func_decl> * & decls) {
|
||||
return m_ids.find(s, decls);
|
||||
}
|
||||
|
||||
bool find1(symbol s, func_decl * & d);
|
||||
|
||||
bool find_overload(symbol s, ptr_vector<sort> const & dom, func_decl * & d);
|
||||
|
||||
void insert(symbol s, sort * d) {
|
||||
sort * d2;
|
||||
if (m_sorts1.find(s, d2)) {
|
||||
m_manager.dec_ref(d2);
|
||||
}
|
||||
m_manager.inc_ref(d);
|
||||
m_sorts1.insert(s, d);
|
||||
}
|
||||
|
||||
bool find(symbol s, sort * & d) {
|
||||
return m_sorts1.find(s, d);
|
||||
}
|
||||
|
||||
void insert(symbol s, sort_builder* sb);
|
||||
|
||||
bool lookup(symbol s, sort_builder*& sb);
|
||||
|
||||
void push_sort(symbol s, sort*);
|
||||
|
||||
void pop_sorts(unsigned num_sorts);
|
||||
|
||||
void get_func_decls(ptr_vector<func_decl> & result) const;
|
||||
|
||||
void get_sorts(ptr_vector<sort>& result) const;
|
||||
};
|
||||
|
||||
class theory {
|
||||
public:
|
||||
typedef ptr_vector<expr>::const_iterator expr_iterator;
|
||||
|
||||
theory(ast_manager & ast_manager, symbol const& name):
|
||||
m_name(name),
|
||||
m_ast_manager(ast_manager),
|
||||
m_symtable(ast_manager),
|
||||
m_asts(ast_manager)
|
||||
{}
|
||||
|
||||
virtual ~theory() {}
|
||||
|
||||
symtable * get_symtable() { return &m_symtable; }
|
||||
|
||||
void insert(sort * s) { m_symtable.insert(s->get_name(), s); }
|
||||
|
||||
void insert(func_decl * c) { m_symtable.insert(c->get_name(), c); }
|
||||
|
||||
func_decl * declare_func(symbol const & id, sort_ref_buffer & domain, sort * range,
|
||||
bool is_assoc, bool is_comm, bool is_inj);
|
||||
|
||||
sort * declare_sort(symbol const & id);
|
||||
|
||||
void add_axiom(expr * axiom) {
|
||||
m_asts.push_back(axiom);
|
||||
m_axioms.push_back(axiom);
|
||||
}
|
||||
|
||||
expr_iterator begin_axioms() const {
|
||||
return m_axioms.begin();
|
||||
}
|
||||
|
||||
unsigned get_num_axioms() const {
|
||||
return m_axioms.size();
|
||||
}
|
||||
|
||||
expr * const * get_axioms() const {
|
||||
return m_axioms.c_ptr();
|
||||
}
|
||||
|
||||
expr_iterator end_axioms() const {
|
||||
return m_axioms.end();
|
||||
}
|
||||
|
||||
void add_assumption(expr * axiom) {
|
||||
m_asts.push_back(axiom);
|
||||
m_assumptions.push_back(axiom);
|
||||
}
|
||||
|
||||
unsigned get_num_assumptions() const {
|
||||
return m_assumptions.size();
|
||||
}
|
||||
|
||||
expr * const * get_assumptions() const {
|
||||
return m_assumptions.c_ptr();
|
||||
}
|
||||
|
||||
bool get_func_decl(symbol, func_decl*&);
|
||||
|
||||
bool get_sort(symbol, sort*&);
|
||||
|
||||
bool get_const(symbol, expr*&);
|
||||
|
||||
void set_name(symbol const& name) { m_name = name; }
|
||||
|
||||
symbol const get_name() const { return m_name; }
|
||||
protected:
|
||||
symbol m_name;
|
||||
ast_manager& m_ast_manager;
|
||||
ptr_vector<expr> m_axioms;
|
||||
ptr_vector<expr> m_assumptions;
|
||||
symtable m_symtable;
|
||||
ast_ref_vector m_asts;
|
||||
|
||||
private:
|
||||
theory& operator=(theory const&);
|
||||
|
||||
theory(theory const&);
|
||||
};
|
||||
|
||||
class benchmark : public theory {
|
||||
public:
|
||||
enum status {
|
||||
UNKNOWN,
|
||||
SAT,
|
||||
UNSAT
|
||||
};
|
||||
|
||||
benchmark(ast_manager & ast_manager, symbol const & name) :
|
||||
theory(ast_manager, name),
|
||||
m_status(UNKNOWN) {}
|
||||
|
||||
virtual ~benchmark() {}
|
||||
|
||||
status get_status() const { return m_status; }
|
||||
void set_status(status status) { m_status = status; }
|
||||
|
||||
symbol get_logic() const {
|
||||
if (m_logic == symbol::null) {
|
||||
return symbol("ALL");
|
||||
}
|
||||
return m_logic;
|
||||
}
|
||||
|
||||
void set_logic(symbol const & s) { m_logic = s; }
|
||||
|
||||
unsigned get_num_formulas() const {
|
||||
return m_formulas.size();
|
||||
}
|
||||
|
||||
expr_iterator begin_formulas() const {
|
||||
return m_formulas.begin();
|
||||
}
|
||||
|
||||
expr_iterator end_formulas() const {
|
||||
return m_formulas.end();
|
||||
}
|
||||
|
||||
void add_formula(expr * formula) {
|
||||
m_asts.push_back(formula);
|
||||
m_formulas.push_back(formula);
|
||||
}
|
||||
|
||||
void display_as_smt2(std::ostream & out) const;
|
||||
|
||||
private:
|
||||
status m_status;
|
||||
symbol m_logic;
|
||||
ptr_vector<expr> m_formulas;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
116
src/api/smtlib_solver.cpp
Normal file
116
src/api/smtlib_solver.cpp
Normal file
|
@ -0,0 +1,116 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smtlib_solver.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
SMT based solver.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2006-11-3.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"smtparser.h"
|
||||
#include"smtlib_solver.h"
|
||||
#include"warning.h"
|
||||
#include"ast_pp.h"
|
||||
#include"ast_ll_pp.h"
|
||||
#include"well_sorted.h"
|
||||
#include"spc_prover.h"
|
||||
#include"model.h"
|
||||
#include"model_v2_pp.h"
|
||||
#include"solver.h"
|
||||
#include"smt_strategic_solver.h"
|
||||
#include"cmd_context.h"
|
||||
|
||||
namespace smtlib {
|
||||
|
||||
solver::solver(front_end_params & params):
|
||||
m_ast_manager(params.m_proof_mode, params.m_trace_stream),
|
||||
m_params(params),
|
||||
m_ctx(0),
|
||||
m_parser(parser::create(m_ast_manager, params.m_ignore_user_patterns)),
|
||||
m_error_code(0) {
|
||||
m_parser->initialize_smtlib();
|
||||
}
|
||||
|
||||
solver::~solver() {
|
||||
if (m_ctx)
|
||||
dealloc(m_ctx);
|
||||
}
|
||||
|
||||
bool solver::solve_smt(char const * benchmark_file) {
|
||||
IF_VERBOSE(100, verbose_stream() << "parsing...\n";);
|
||||
if (!m_parser->parse_file(benchmark_file)) {
|
||||
if (benchmark_file) {
|
||||
warning_msg("could not parse file '%s'.", benchmark_file);
|
||||
}
|
||||
else {
|
||||
warning_msg("could not parse input stream.");
|
||||
}
|
||||
m_error_code = ERR_PARSER;
|
||||
return false;
|
||||
}
|
||||
benchmark * benchmark = m_parser->get_benchmark();
|
||||
solve_benchmark(*benchmark);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool solver::solve_smt_string(char const * benchmark_string) {
|
||||
if (!m_parser->parse_string(benchmark_string)) {
|
||||
warning_msg("could not parse string '%s'.", benchmark_string);
|
||||
return false;
|
||||
}
|
||||
benchmark * benchmark = m_parser->get_benchmark();
|
||||
solve_benchmark(*benchmark);
|
||||
return true;
|
||||
}
|
||||
|
||||
void solver::display_statistics() {
|
||||
if (m_ctx)
|
||||
m_ctx->display_statistics();
|
||||
}
|
||||
|
||||
void solver::solve_benchmark(benchmark & benchmark) {
|
||||
if (benchmark.get_num_formulas() == 0) {
|
||||
// Hack: it seems SMT-LIB allow benchmarks without any :formula
|
||||
benchmark.add_formula(m_ast_manager.mk_true());
|
||||
}
|
||||
m_ctx = alloc(cmd_context, m_params, true, &m_ast_manager, benchmark.get_logic());
|
||||
m_ctx->set_solver(mk_smt_strategic_solver(*m_ctx));
|
||||
theory::expr_iterator fit = benchmark.begin_formulas();
|
||||
theory::expr_iterator fend = benchmark.end_formulas();
|
||||
for (; fit != fend; ++fit)
|
||||
solve_formula(benchmark, *fit);
|
||||
}
|
||||
|
||||
void solver::solve_formula(benchmark const & benchmark, expr * f) {
|
||||
IF_VERBOSE(100, verbose_stream() << "starting...\n";);
|
||||
m_ctx->reset();
|
||||
for (unsigned i = 0; i < benchmark.get_num_axioms(); i++)
|
||||
m_ctx->assert_expr(benchmark.get_axioms()[i]);
|
||||
m_ctx->assert_expr(f);
|
||||
m_ctx->check_sat(benchmark.get_num_assumptions(), benchmark.get_assumptions());
|
||||
check_sat_result * r = m_ctx->get_check_sat_result();
|
||||
if (r != 0) {
|
||||
proof * pr = r->get_proof();
|
||||
if (pr != 0 && m_params.m_display_proof)
|
||||
std::cout << mk_ll_pp(pr, m_ast_manager, false, false);
|
||||
model_ref md;
|
||||
if (r->status() != l_false) r->get_model(md);
|
||||
if (md.get() != 0 && m_params.m_model) {
|
||||
model_v2_pp(std::cout, *(md.get()), m_params.m_model_partial);
|
||||
}
|
||||
}
|
||||
else {
|
||||
m_error_code = ERR_UNKNOWN_RESULT;
|
||||
}
|
||||
}
|
||||
};
|
48
src/api/smtlib_solver.h
Normal file
48
src/api/smtlib_solver.h
Normal file
|
@ -0,0 +1,48 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smtlib_solver.h
|
||||
|
||||
Abstract:
|
||||
|
||||
SMT based solver.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2006-11-3.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _SMTLIB_SOLVER_H_
|
||||
#define _SMTLIB_SOLVER_H_
|
||||
|
||||
#include"smtparser.h"
|
||||
#include"front_end_params.h"
|
||||
#include"lbool.h"
|
||||
|
||||
class cmd_context;
|
||||
|
||||
namespace smtlib {
|
||||
class solver {
|
||||
ast_manager m_ast_manager;
|
||||
front_end_params & m_params;
|
||||
cmd_context * m_ctx;
|
||||
scoped_ptr<parser> m_parser;
|
||||
unsigned m_error_code;
|
||||
public:
|
||||
solver(front_end_params & params);
|
||||
~solver();
|
||||
bool solve_smt(char const * benchmark_file);
|
||||
bool solve_smt_string(char const * benchmark_string);
|
||||
void display_statistics();
|
||||
unsigned get_error_code() const { return m_error_code; }
|
||||
private:
|
||||
void solve_benchmark(benchmark & benchmark);
|
||||
void solve_formula(benchmark const & benchmark, expr * f);
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
5317
src/api/smtparser.cpp
Normal file
5317
src/api/smtparser.cpp
Normal file
File diff suppressed because it is too large
Load diff
51
src/api/smtparser.h
Normal file
51
src/api/smtparser.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
smtparser.h
|
||||
|
||||
Abstract:
|
||||
|
||||
SMT parsing utilities
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2006-09-25
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _SMT_PARSER_H_
|
||||
#define _SMT_PARSER_H_
|
||||
|
||||
#include "ast.h"
|
||||
#include "vector.h"
|
||||
#include "smtlib.h"
|
||||
#include "z3.h"
|
||||
#include <iostream>
|
||||
|
||||
namespace smtlib {
|
||||
class parser {
|
||||
public:
|
||||
static parser * create(ast_manager & ast_manager, bool ignore_user_patterns = false);
|
||||
|
||||
virtual ~parser() {}
|
||||
|
||||
virtual void add_builtin_op(char const *, family_id fid, decl_kind kind) = 0;
|
||||
virtual void add_builtin_type(char const *, family_id fid, decl_kind kind) = 0;
|
||||
|
||||
virtual void initialize_smtlib() = 0;
|
||||
|
||||
virtual void set_error_stream(std::ostream& strm) = 0;
|
||||
|
||||
virtual bool parse_file(char const * path) = 0;
|
||||
virtual bool parse_string(char const * string) = 0;
|
||||
|
||||
virtual bool parse_commands(Z3_context ctx, std::istream& is, std::ostream& os) = 0;
|
||||
|
||||
virtual benchmark * get_benchmark() = 0;
|
||||
};
|
||||
};
|
||||
|
||||
#endif
|
40
src/api/z3.h
Normal file
40
src/api/z3.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*++
|
||||
Copyright (c) 2007 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Z3 API.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner)
|
||||
Leonardo de Moura (leonardo) 2007-06-8
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
|
||||
#ifndef _Z3__H_
|
||||
#define _Z3__H_
|
||||
|
||||
#include<stdio.h>
|
||||
#include"z3_macros.h"
|
||||
#include"z3_api.h"
|
||||
#include"z3_internal_types.h"
|
||||
|
||||
#undef __in
|
||||
#undef __out
|
||||
#undef __inout
|
||||
#undef __in_z
|
||||
#undef __out_z
|
||||
#undef __ecount
|
||||
#undef __in_ecount
|
||||
#undef __out_ecount
|
||||
#undef __inout_ecount
|
||||
|
||||
#endif
|
||||
|
7563
src/api/z3_api.h
Normal file
7563
src/api/z3_api.h
Normal file
File diff suppressed because it is too large
Load diff
40
src/api/z3_internal.h
Normal file
40
src/api/z3_internal.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_internal.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Z3 internal API for C and Python.
|
||||
It provides access to internal Z3 components.
|
||||
It should only be used by advanced users.
|
||||
We used it to build regression tests in Python.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-10-18
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _Z3_INTERNAL_H_
|
||||
#define _Z3_INTERNAL_H_
|
||||
|
||||
#include"z3_macros.h"
|
||||
#include"z3_api.h"
|
||||
#include"z3_internal_types.h"
|
||||
#include"z3_poly.h"
|
||||
|
||||
#undef __in
|
||||
#undef __out
|
||||
#undef __inout
|
||||
#undef __in_z
|
||||
#undef __out_z
|
||||
#undef __ecount
|
||||
#undef __in_ecount
|
||||
#undef __out_ecount
|
||||
#undef __inout_ecount
|
||||
|
||||
#endif
|
34
src/api/z3_internal_types.h
Normal file
34
src/api/z3_internal_types.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_internal_types.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Z3 internal API type declarations.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-10-18
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _Z3_INTERNAL_TYPES_H_
|
||||
#define _Z3_INTERNAL_TYPES_H_
|
||||
|
||||
DEFINE_TYPE(Z3_polynomial_manager);
|
||||
DEFINE_TYPE(Z3_polynomial);
|
||||
DEFINE_TYPE(Z3_monomial);
|
||||
|
||||
/*
|
||||
Definitions for update_api.py
|
||||
|
||||
def_Type('POLYNOMIAL_MANAGER', 'Z3_polynomial_manager', 'PolynomialManagerObj')
|
||||
def_Type('POLYNOMIAL', 'Z3_polynomial', 'PolynomialObj')
|
||||
def_Type('MONOMIAL', 'Z3_monomial', 'MonomialObj')
|
||||
*/
|
||||
|
||||
#endif
|
70
src/api/z3_logger.h
Normal file
70
src/api/z3_logger.h
Normal file
|
@ -0,0 +1,70 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_logger.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Goodies for log generation
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-09-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include<iostream>
|
||||
#include"symbol.h"
|
||||
struct ll_escaped { char const * m_str; ll_escaped(char const * str):m_str(str) {} };
|
||||
static std::ostream & operator<<(std::ostream & out, ll_escaped const & d) {
|
||||
char const * s = d.m_str;
|
||||
while (*s) {
|
||||
char c = *s;
|
||||
if (('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z') ||
|
||||
c == '~' || c == '!' || c == '@' || c == '#' || c == '$' || c == '%' || c == '^' || c == '&' ||
|
||||
c == '*' || c == '-' || c == '_' || c == '+' || c == '.' || c == '?' || c == '/' || c == ' ' ||
|
||||
c == '<' || c == '>') {
|
||||
out << c;
|
||||
}
|
||||
else {
|
||||
char str[4] = {'0', '0', '0', 0};
|
||||
str[2] = '0' + (c % 10);
|
||||
c /= 10;
|
||||
str[1] = '0' + (c % 10);
|
||||
c /= 10;
|
||||
str[0] = '0' + c;
|
||||
out << '\\' << str;
|
||||
}
|
||||
s++;
|
||||
}
|
||||
return out;
|
||||
}
|
||||
|
||||
static void R() { *g_z3_log << "R\n"; g_z3_log->flush(); }
|
||||
static void P(void * obj) { *g_z3_log << "P " << obj << "\n"; g_z3_log->flush(); }
|
||||
static void I(__int64 i) { *g_z3_log << "I " << i << "\n"; g_z3_log->flush(); }
|
||||
static void U(__uint64 u) { *g_z3_log << "U " << u << "\n"; g_z3_log->flush(); }
|
||||
static void D(double d) { *g_z3_log << "D " << d << "\n"; g_z3_log->flush(); }
|
||||
static void S(Z3_string str) { *g_z3_log << "S \"" << ll_escaped(str) << "\"\n"; g_z3_log->flush(); }
|
||||
static void Sy(Z3_symbol sym) {
|
||||
symbol s = symbol::mk_symbol_from_c_ptr(reinterpret_cast<void *>(sym));
|
||||
if (s == symbol::null) {
|
||||
*g_z3_log << "N\n";
|
||||
}
|
||||
else if (s.is_numerical()) {
|
||||
*g_z3_log << "# " << s.get_num() << "\n";
|
||||
}
|
||||
else {
|
||||
*g_z3_log << "$ |" << ll_escaped(s.bare_str()) << "|\n";
|
||||
}
|
||||
g_z3_log->flush();
|
||||
}
|
||||
static void Ap(unsigned sz) { *g_z3_log << "p " << sz << "\n"; g_z3_log->flush(); }
|
||||
static void Au(unsigned sz) { *g_z3_log << "u " << sz << "\n"; g_z3_log->flush(); }
|
||||
static void Asy(unsigned sz) { *g_z3_log << "s " << sz << "\n"; g_z3_log->flush(); }
|
||||
static void C(unsigned id) { *g_z3_log << "C " << id << "\n"; g_z3_log->flush(); }
|
||||
void _Z3_append_log(char const * msg) { *g_z3_log << "M \"" << ll_escaped(msg) << "\"\n"; g_z3_log->flush(); }
|
||||
|
54
src/api/z3_macros.h
Normal file
54
src/api/z3_macros.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
#ifndef __in
|
||||
#define __in
|
||||
#endif
|
||||
|
||||
#ifndef __out
|
||||
#define __out
|
||||
#endif
|
||||
|
||||
#ifndef __out_opt
|
||||
#define __out_opt __out
|
||||
#endif
|
||||
|
||||
#ifndef __ecount
|
||||
#define __ecount(num_args)
|
||||
#endif
|
||||
|
||||
#ifndef __in_ecount
|
||||
#define __in_ecount(num_args) __in __ecount(num_args)
|
||||
#endif
|
||||
|
||||
#ifndef __out_ecount
|
||||
#define __out_ecount(num_args) __out __ecount(num_args)
|
||||
#endif
|
||||
|
||||
#ifndef __inout_ecount
|
||||
#define __inout_ecount(num_args) __in __out __ecount(num_args)
|
||||
#endif
|
||||
|
||||
#ifndef __inout
|
||||
#define __inout __in __out
|
||||
#endif
|
||||
|
||||
#ifndef Z3_bool_opt
|
||||
#define Z3_bool_opt Z3_bool
|
||||
#endif
|
||||
|
||||
#ifndef Z3_API
|
||||
#define Z3_API
|
||||
#endif
|
||||
|
||||
#ifndef DEFINE_TYPE
|
||||
#define DEFINE_TYPE(T) typedef struct _ ## T *T
|
||||
#endif
|
||||
|
||||
#ifndef DEFINE_VOID
|
||||
#define DEFINE_VOID(T) typedef void* T
|
||||
#endif
|
||||
|
||||
#ifndef BEGIN_MLAPI_EXCLUDE
|
||||
#define BEGIN_MLAPI_EXCLUDE
|
||||
#endif
|
||||
#ifndef END_MLAPI_EXCLUDE
|
||||
#define END_MLAPI_EXCLUDE
|
||||
#endif
|
72
src/api/z3_poly.h
Normal file
72
src/api/z3_poly.h
Normal file
|
@ -0,0 +1,72 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_poly.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Z3 multivariate polynomial API.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-10-18
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _Z3_POLY_H_
|
||||
#define _Z3_POLY_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
|
||||
/**
|
||||
\brief Create a new polynomial manager.
|
||||
|
||||
def_API('Z3_mk_polynomial_manager', POLYNOMIAL_MANAGER, (_in(CONTEXT),))
|
||||
*/
|
||||
Z3_polynomial_manager Z3_API Z3_mk_polynomial_manager(__in Z3_context c);
|
||||
|
||||
/**
|
||||
\brief Delete the given polynomial manager.
|
||||
|
||||
def_API('Z3_del_polynomial_manager', VOID, (_in(CONTEXT), _in(POLYNOMIAL_MANAGER)))
|
||||
*/
|
||||
void Z3_API Z3_del_polynomial_manager(__in Z3_context c, __in Z3_polynomial_manager m);
|
||||
|
||||
/**
|
||||
\brief Return the zero polynomial.
|
||||
|
||||
def_API('Z3_mk_zero_polynomial', POLYNOMIAL, (_in(CONTEXT), _in(POLYNOMIAL_MANAGER)))
|
||||
*/
|
||||
Z3_polynomial Z3_API Z3_mk_zero_polynomial(__in Z3_context c, __in Z3_polynomial_manager m);
|
||||
|
||||
/**
|
||||
\brief Increment p's reference counter
|
||||
|
||||
def_API('Z3_polynomial_inc_ref', VOID, (_in(CONTEXT), _in(POLYNOMIAL_MANAGER), _in(POLYNOMIAL)))
|
||||
*/
|
||||
void Z3_API Z3_polynomial_inc_ref(__in Z3_context c, __in Z3_polynomial_manager m, __in Z3_polynomial p);
|
||||
|
||||
/**
|
||||
\brief Decrement p's reference counter.
|
||||
|
||||
def_API('Z3_polynomial_dec_ref', VOID, (_in(CONTEXT), _in(POLYNOMIAL_MANAGER), _in(POLYNOMIAL)))
|
||||
*/
|
||||
void Z3_API Z3_polynomial_dec_ref(__in Z3_context c, __in Z3_polynomial_manager m, __in Z3_polynomial p);
|
||||
|
||||
/**
|
||||
\brief Convert the given polynomial into a string.
|
||||
|
||||
def_API('Z3_polynomial_to_string', STRING, (_in(CONTEXT), _in(POLYNOMIAL_MANAGER), _in(POLYNOMIAL)))
|
||||
*/
|
||||
Z3_string Z3_API Z3_polynomial_to_string(__in Z3_context c, __in Z3_polynomial_manager m, __in Z3_polynomial p);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
80
src/api/z3_private.h
Normal file
80
src/api/z3_private.h
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*++
|
||||
Copyright (c) 2007 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_private.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Z3 API.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner)
|
||||
Leonardo de Moura (leonardo) 2007-06-8
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
|
||||
#include<iostream>
|
||||
#include"rational.h"
|
||||
#include"z3_macros.h"
|
||||
|
||||
#ifndef _Z3_PRIVATE__H_
|
||||
#define _Z3_PRIVATE__H_
|
||||
|
||||
|
||||
#ifndef CAMLIDL
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // __cplusplus
|
||||
#else
|
||||
[pointer_default(ref)] interface Z3 {
|
||||
#endif // CAMLIDL
|
||||
|
||||
Z3_bool Z3_API Z3_get_numeral_rational(__in Z3_context c, __in Z3_ast a, rational& r);
|
||||
|
||||
/**
|
||||
\brief \mlh exec_smtlib2_string c str \endmlh
|
||||
Parse the given string using the SMT-LIB2 parser and execute its commands.
|
||||
|
||||
It returns a formula comprising of the conjunction of assertions in the scope
|
||||
(up to push/pop) at the end of the string.
|
||||
The returned formula is also asserted to the logical context on return.
|
||||
*/
|
||||
Z3_ast Z3_API Z3_exec_smtlib2_string(__in Z3_context c,
|
||||
__in Z3_string str,
|
||||
__in unsigned num_sorts,
|
||||
__in_ecount(num_sorts) Z3_symbol sort_names[],
|
||||
__in_ecount(num_sorts) Z3_sort sorts[],
|
||||
__in unsigned num_decls,
|
||||
__in_ecount(num_decls) Z3_symbol decl_names[],
|
||||
__in_ecount(num_decls) Z3_func_decl decls[]
|
||||
);
|
||||
|
||||
/**
|
||||
\brief Similar to #Z3_exec_smtlib2_string, but reads the commands from a file.
|
||||
*/
|
||||
Z3_ast Z3_API Z3_exec_smtlib2_file(__in Z3_context c,
|
||||
__in Z3_string file_name,
|
||||
__in unsigned num_sorts,
|
||||
__in_ecount(num_sorts) Z3_symbol sort_names[],
|
||||
__in_ecount(num_sorts) Z3_sort sorts[],
|
||||
__in unsigned num_decls,
|
||||
__in_ecount(num_decls) Z3_symbol decl_names[],
|
||||
__in_ecount(num_decls) Z3_func_decl decls[]
|
||||
);
|
||||
|
||||
|
||||
#ifndef CAMLIDL
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif // __cplusplus
|
||||
#else
|
||||
}
|
||||
#endif // CAMLIDL
|
||||
|
||||
#endif
|
||||
|
711
src/api/z3_replayer.cpp
Normal file
711
src/api/z3_replayer.cpp
Normal file
|
@ -0,0 +1,711 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_replayer.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Interpreter for Z3 logs
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-09-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"vector.h"
|
||||
#include"map.h"
|
||||
#include"z3_replayer.h"
|
||||
#include"stream_buffer.h"
|
||||
#include"symbol.h"
|
||||
#include"trace.h"
|
||||
|
||||
void register_z3_replayer_cmds(z3_replayer & in);
|
||||
|
||||
void throw_invalid_reference() {
|
||||
throw z3_replayer_exception("invalid argument reference");
|
||||
}
|
||||
|
||||
struct z3_replayer::imp {
|
||||
z3_replayer & m_owner;
|
||||
std::istream & m_stream;
|
||||
char m_curr; // current char;
|
||||
int m_line; // line
|
||||
svector<char> m_string;
|
||||
symbol m_id;
|
||||
__int64 m_int64;
|
||||
__uint64 m_uint64;
|
||||
double m_double;
|
||||
size_t m_ptr;
|
||||
size_t_map<void *> m_heap;
|
||||
svector<z3_replayer_cmd> m_cmds;
|
||||
|
||||
enum value_kind { INT64, UINT64, DOUBLE, STRING, SYMBOL, OBJECT, UINT_ARRAY, SYMBOL_ARRAY, OBJECT_ARRAY };
|
||||
|
||||
struct value {
|
||||
value_kind m_kind;
|
||||
union {
|
||||
__int64 m_int;
|
||||
__uint64 m_uint;
|
||||
double m_double;
|
||||
char const * m_str;
|
||||
void * m_obj;
|
||||
};
|
||||
value():m_kind(OBJECT), m_int(0) {}
|
||||
value(void * obj):m_kind(OBJECT), m_obj(obj) {}
|
||||
value(value_kind k, char const * str):m_kind(k), m_str(str) {}
|
||||
value(value_kind k, __uint64 u):m_kind(k), m_uint(u) {}
|
||||
value(value_kind k, __int64 i):m_kind(k), m_int(i) {}
|
||||
value(value_kind k, double d):m_kind(k), m_double(d) {}
|
||||
};
|
||||
|
||||
svector<value> m_args;
|
||||
void * m_result;
|
||||
vector<ptr_vector<void> > m_obj_arrays;
|
||||
vector<svector<Z3_symbol> > m_sym_arrays;
|
||||
vector<unsigned_vector> m_unsigned_arrays;
|
||||
|
||||
imp(z3_replayer & o, std::istream & in):
|
||||
m_owner(o),
|
||||
m_stream(in),
|
||||
m_curr(0),
|
||||
m_line(1) {
|
||||
next();
|
||||
}
|
||||
|
||||
void display_arg(std::ostream & out, value const & v) const {
|
||||
switch (v.m_kind) {
|
||||
case INT64:
|
||||
out << v.m_int;
|
||||
break;
|
||||
case UINT64:
|
||||
out << v.m_uint;
|
||||
break;
|
||||
case DOUBLE:
|
||||
out << v.m_double;
|
||||
break;
|
||||
case STRING:
|
||||
out << v.m_str;
|
||||
break;
|
||||
case SYMBOL:
|
||||
out << symbol::mk_symbol_from_c_ptr(v.m_str);
|
||||
break;
|
||||
case OBJECT:
|
||||
out << v.m_obj;
|
||||
break;
|
||||
case UINT_ARRAY:
|
||||
case OBJECT_ARRAY:
|
||||
case SYMBOL_ARRAY:
|
||||
out << "<array>";
|
||||
break;
|
||||
default:
|
||||
out << "<unknown>";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void display_args(std::ostream & out) const {
|
||||
for (unsigned i = 0; i < m_args.size(); i++) {
|
||||
if (i > 0) out << " ";
|
||||
display_arg(out, m_args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
char curr() const { return m_curr; }
|
||||
void new_line() { m_line++; }
|
||||
void next() { m_curr = m_stream.get(); }
|
||||
|
||||
void read_string_core(char delimiter) {
|
||||
if (curr() != delimiter)
|
||||
throw z3_replayer_exception("invalid string/symbol");
|
||||
m_string.reset();
|
||||
next();
|
||||
while (true) {
|
||||
char c = curr();
|
||||
if (c == EOF) {
|
||||
throw z3_replayer_exception("unexpected end of file");
|
||||
}
|
||||
else if (c == '\n') {
|
||||
throw z3_replayer_exception("unexpected end of line");
|
||||
}
|
||||
else if (c == '\\') {
|
||||
next();
|
||||
unsigned val = 0;
|
||||
unsigned sz = 0;
|
||||
while (sz < 3) {
|
||||
c = curr();
|
||||
if ('0' <= c && c <= '9') {
|
||||
val *= 10;
|
||||
val += c - '0';
|
||||
sz++;
|
||||
}
|
||||
else {
|
||||
throw z3_replayer_exception("invalid scaped character");
|
||||
}
|
||||
if (val > 255)
|
||||
throw z3_replayer_exception("invalid scaped character");
|
||||
next();
|
||||
}
|
||||
TRACE("z3_replayer_escape", tout << "val: " << val << "\n";);
|
||||
m_string.push_back(static_cast<char>(val));
|
||||
}
|
||||
else if (c == delimiter) {
|
||||
next();
|
||||
m_string.push_back(0);
|
||||
return;
|
||||
}
|
||||
else {
|
||||
m_string.push_back(c);
|
||||
next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void read_string() {
|
||||
read_string_core('"');
|
||||
}
|
||||
|
||||
void read_quoted_symbol() {
|
||||
read_string_core('|');
|
||||
m_id = m_string.begin();
|
||||
}
|
||||
|
||||
void read_int64() {
|
||||
if (!(curr() == '-' || ('0' <= curr() && curr() <= '9')))
|
||||
throw z3_replayer_exception("invalid integer");
|
||||
bool sign = false;
|
||||
if (curr() == '-') {
|
||||
sign = true;
|
||||
next();
|
||||
if (!('0' <= curr() && curr() <= '9'))
|
||||
throw z3_replayer_exception("invalid integer");
|
||||
}
|
||||
m_int64 = 0;
|
||||
while (true) {
|
||||
char c = curr();
|
||||
if ('0' <= c && c <= '9') {
|
||||
m_int64 = 10*m_int64 + (c - '0');
|
||||
next();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (sign)
|
||||
m_int64 = -m_int64;
|
||||
}
|
||||
|
||||
void read_uint64() {
|
||||
if (!('0' <= curr() && curr() <= '9'))
|
||||
throw z3_replayer_exception("invalid unsigned");
|
||||
m_uint64 = 0;
|
||||
while (true) {
|
||||
char c = curr();
|
||||
if ('0' <= c && c <= '9') {
|
||||
m_uint64 = 10*m_uint64 + (c - '0');
|
||||
next();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool is_double_char() const {
|
||||
return curr() == '-' || curr() == '.' || ('0' <= curr() && curr() <= '9') || curr() == 'e' || curr() == 'E';
|
||||
}
|
||||
|
||||
void read_double() {
|
||||
m_string.reset();
|
||||
while (is_double_char()) {
|
||||
m_string.push_back(curr());
|
||||
next();
|
||||
}
|
||||
if (m_string.empty())
|
||||
throw z3_replayer_exception("invalid double");
|
||||
m_string.push_back(0);
|
||||
char * ptr;
|
||||
m_double = strtod(m_string.begin(), &ptr);
|
||||
}
|
||||
|
||||
void read_ptr() {
|
||||
if (!(('0' <= curr() && curr() <= '9') || ('A' <= curr() && curr() <= 'F') || ('a' <= curr() && curr() <= 'f')))
|
||||
throw z3_replayer_exception("invalid ptr");
|
||||
m_ptr = 0;
|
||||
while (true) {
|
||||
char c = curr();
|
||||
if ('0' <= c && c <= '9') {
|
||||
m_ptr = m_ptr * 16 + (c - '0');
|
||||
}
|
||||
else if ('a' <= c && c <= 'f') {
|
||||
m_ptr = m_ptr * 16 + 10 + (c - 'a');
|
||||
}
|
||||
else if ('A' <= c && c <= 'F') {
|
||||
m_ptr = m_ptr * 16 + 10 + (c - 'A');
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
next();
|
||||
}
|
||||
}
|
||||
|
||||
void skip_blank() {
|
||||
while (true) {
|
||||
char c = curr();
|
||||
if (c == '\n') {
|
||||
new_line();
|
||||
next();
|
||||
}
|
||||
else if (c == ' ' || c == '\t') {
|
||||
next();
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void push_array(unsigned sz, value_kind k) {
|
||||
unsigned asz = m_args.size();
|
||||
if (sz > asz)
|
||||
throw z3_replayer_exception("invalid array size");
|
||||
__uint64 aidx;
|
||||
value_kind nk;
|
||||
for (unsigned i = asz - sz; i < asz; i++) {
|
||||
if (m_args[i].m_kind != k)
|
||||
throw z3_replayer_exception("invalid array: mixed value types");
|
||||
}
|
||||
if (k == UINT64) {
|
||||
aidx = m_unsigned_arrays.size();
|
||||
nk = UINT_ARRAY;
|
||||
m_unsigned_arrays.push_back(unsigned_vector());
|
||||
unsigned_vector & v = m_unsigned_arrays.back();
|
||||
for (unsigned i = asz - sz; i < asz; i++) {
|
||||
v.push_back(static_cast<unsigned>(m_args[i].m_uint));
|
||||
}
|
||||
}
|
||||
else if (k == SYMBOL) {
|
||||
aidx = m_sym_arrays.size();
|
||||
nk = SYMBOL_ARRAY;
|
||||
m_sym_arrays.push_back(svector<Z3_symbol>());
|
||||
svector<Z3_symbol> & v = m_sym_arrays.back();
|
||||
for (unsigned i = asz - sz; i < asz; i++) {
|
||||
v.push_back(reinterpret_cast<Z3_symbol>(const_cast<char*>(m_args[i].m_str)));
|
||||
}
|
||||
}
|
||||
else if (k == OBJECT) {
|
||||
TRACE("z3_replayer_bug",
|
||||
tout << "args: "; display_args(tout); tout << "\n";
|
||||
tout << "push_back, sz: " << sz << ", m_obj_arrays.size(): " << m_obj_arrays.size() << "\n";
|
||||
for (unsigned i = asz - sz; i < asz; i++) {
|
||||
tout << "pushing: " << m_args[i].m_obj << "\n";
|
||||
});
|
||||
aidx = m_obj_arrays.size();
|
||||
nk = OBJECT_ARRAY;
|
||||
m_obj_arrays.push_back(ptr_vector<void>());
|
||||
ptr_vector<void> & v = m_obj_arrays.back();
|
||||
for (unsigned i = asz - sz; i < asz; i++) {
|
||||
v.push_back(m_args[i].m_obj);
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw z3_replayer_exception("unsupported array type");
|
||||
}
|
||||
m_args.shrink(asz - sz);
|
||||
m_args.push_back(value(nk, aidx));
|
||||
}
|
||||
|
||||
#define TICK_FREQUENCY 100000
|
||||
|
||||
void parse() {
|
||||
unsigned long long counter = 0;
|
||||
unsigned tick = 0;
|
||||
while (true) {
|
||||
IF_VERBOSE(1, {
|
||||
counter++; tick++;
|
||||
if (tick >= TICK_FREQUENCY) {
|
||||
std::cout << "[replayer] " << counter << " operations executed" << std::endl;
|
||||
tick = 0;
|
||||
}
|
||||
});
|
||||
skip_blank();
|
||||
char c = curr();
|
||||
if (c == EOF)
|
||||
return;
|
||||
switch (c) {
|
||||
case 'R':
|
||||
// reset
|
||||
next();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "R\n";);
|
||||
reset();
|
||||
break;
|
||||
case 'P': {
|
||||
// push pointer
|
||||
next(); skip_blank(); read_ptr();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "P " << m_ptr << "\n";);
|
||||
if (m_ptr == 0) {
|
||||
m_args.push_back(0);
|
||||
}
|
||||
else {
|
||||
void * obj = 0;
|
||||
if (!m_heap.find(m_ptr, obj))
|
||||
throw z3_replayer_exception("invalid pointer");
|
||||
m_args.push_back(value(obj));
|
||||
TRACE("z3_replayer_bug", tout << "args after 'P':\n"; display_args(tout); tout << "\n";);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'S': {
|
||||
// push string
|
||||
next(); skip_blank(); read_string();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "S " << m_string.begin() << "\n";);
|
||||
symbol sym(m_string.begin()); // save string
|
||||
m_args.push_back(value(STRING, sym.bare_str()));
|
||||
break;
|
||||
}
|
||||
case 'N':
|
||||
// push null symbol
|
||||
next();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "N\n";);
|
||||
m_args.push_back(value(SYMBOL, static_cast<char const *>(0)));
|
||||
break;
|
||||
case '$': {
|
||||
// push symbol
|
||||
next(); skip_blank(); read_quoted_symbol();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "$ " << m_id << "\n";);
|
||||
m_args.push_back(value(SYMBOL, m_id.bare_str()));
|
||||
break;
|
||||
}
|
||||
case '#': {
|
||||
// push numeral symbol
|
||||
next(); skip_blank(); read_uint64();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "# " << m_uint64 << "\n";);
|
||||
symbol sym(static_cast<unsigned>(m_uint64));
|
||||
m_args.push_back(value(SYMBOL, static_cast<char const *>(sym.c_ptr())));
|
||||
break;
|
||||
}
|
||||
case 'I':
|
||||
// push integer;
|
||||
next(); skip_blank(); read_int64();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "I " << m_int64 << "\n";);
|
||||
m_args.push_back(value(INT64, m_int64));
|
||||
break;
|
||||
case 'U':
|
||||
// push unsigned;
|
||||
next(); skip_blank(); read_uint64();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "U " << m_uint64 << "\n";);
|
||||
m_args.push_back(value(UINT64, m_uint64));
|
||||
break;
|
||||
case 'D':
|
||||
// push double
|
||||
next(); skip_blank(); read_double();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "D " << m_double << "\n";);
|
||||
m_args.push_back(value(DOUBLE, m_double));
|
||||
break;
|
||||
case 'p':
|
||||
case 's':
|
||||
case 'u':
|
||||
// push array
|
||||
next(); skip_blank(); read_uint64();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "A " << m_uint64 << "\n";);
|
||||
if (c == 'p')
|
||||
push_array(static_cast<unsigned>(m_uint64), OBJECT);
|
||||
else if (c == 's')
|
||||
push_array(static_cast<unsigned>(m_uint64), SYMBOL);
|
||||
else
|
||||
push_array(static_cast<unsigned>(m_uint64), UINT64);
|
||||
break;
|
||||
case 'C': {
|
||||
// call procedure
|
||||
next(); skip_blank(); read_uint64();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "C " << m_uint64 << "\n";);
|
||||
unsigned idx = static_cast<unsigned>(m_uint64);
|
||||
if (idx >= m_cmds.size())
|
||||
throw z3_replayer_exception("invalid command");
|
||||
try {
|
||||
m_cmds[idx](m_owner);
|
||||
}
|
||||
catch (z3_error & ex) {
|
||||
throw ex;
|
||||
}
|
||||
catch (z3_exception & ex) {
|
||||
std::cout << "[z3 exception]: " << ex.msg() << std::endl;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case '=':
|
||||
// save result
|
||||
// = obj_id
|
||||
next(); skip_blank(); read_ptr();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "= " << m_ptr << "\n";);
|
||||
m_heap.insert(m_ptr, m_result);
|
||||
break;
|
||||
case '*': {
|
||||
// save out
|
||||
// @ obj_id pos
|
||||
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
|
||||
unsigned pos = static_cast<unsigned>(m_uint64);
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "* " << m_ptr << " " << pos << "\n";);
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
|
||||
throw_invalid_reference();
|
||||
m_heap.insert(m_ptr, m_args[pos].m_obj);
|
||||
break;
|
||||
}
|
||||
case '@': {
|
||||
// save array out
|
||||
// @ obj_id array_pos idx
|
||||
next(); skip_blank(); read_ptr(); skip_blank(); read_uint64();
|
||||
unsigned pos = static_cast<unsigned>(m_uint64);
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
|
||||
throw_invalid_reference();
|
||||
unsigned aidx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||
ptr_vector<void> & v = m_obj_arrays[aidx];
|
||||
skip_blank(); read_uint64();
|
||||
unsigned idx = static_cast<unsigned>(m_uint64);
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "@ " << m_ptr << " " << pos << " " << idx << "\n";);
|
||||
TRACE("z3_replayer_bug", tout << "v[idx]: " << v[idx] << "\n";);
|
||||
m_heap.insert(m_ptr, v[idx]);
|
||||
break;
|
||||
}
|
||||
case 'M':
|
||||
// user message
|
||||
next(); skip_blank(); read_string();
|
||||
TRACE("z3_replayer", tout << "[" << m_line << "] " << "M " << m_string.begin() << "\n";);
|
||||
std::cout << m_string.begin() << "\n"; std::cout.flush();
|
||||
break;
|
||||
default:
|
||||
TRACE("z3_replayer", tout << "unknown command " << c << "\n";);
|
||||
throw z3_replayer_exception("unknown log command");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int get_int(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
||||
throw_invalid_reference();
|
||||
return static_cast<int>(m_args[pos].m_int);
|
||||
}
|
||||
|
||||
__int64 get_int64(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
||||
throw_invalid_reference();
|
||||
return m_args[pos].m_int;
|
||||
}
|
||||
|
||||
unsigned get_uint(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
||||
throw_invalid_reference();
|
||||
return static_cast<unsigned>(m_args[pos].m_uint);
|
||||
}
|
||||
|
||||
__uint64 get_uint64(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
||||
throw_invalid_reference();
|
||||
return m_args[pos].m_uint;
|
||||
}
|
||||
|
||||
double get_double(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != DOUBLE)
|
||||
throw_invalid_reference();
|
||||
return m_args[pos].m_double;
|
||||
}
|
||||
|
||||
Z3_string get_str(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
|
||||
throw_invalid_reference();
|
||||
return m_args[pos].m_str;
|
||||
}
|
||||
|
||||
Z3_symbol get_symbol(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL)
|
||||
throw_invalid_reference();
|
||||
return reinterpret_cast<Z3_symbol>(const_cast<char*>(m_args[pos].m_str));
|
||||
}
|
||||
|
||||
void * get_obj(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
|
||||
throw_invalid_reference();
|
||||
return m_args[pos].m_obj;
|
||||
}
|
||||
|
||||
unsigned * get_uint_array(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT_ARRAY)
|
||||
throw_invalid_reference();
|
||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||
return m_unsigned_arrays[idx].c_ptr();
|
||||
}
|
||||
|
||||
Z3_symbol * get_symbol_array(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != SYMBOL_ARRAY)
|
||||
throw_invalid_reference();
|
||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||
return m_sym_arrays[idx].c_ptr();
|
||||
}
|
||||
|
||||
void ** get_obj_array(unsigned pos) const {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT_ARRAY)
|
||||
throw_invalid_reference();
|
||||
unsigned idx = static_cast<unsigned>(m_args[pos].m_uint);
|
||||
ptr_vector<void> const & v = m_obj_arrays[idx];
|
||||
TRACE("z3_replayer_bug", tout << "pos: " << pos << ", idx: " << idx << " size(): " << v.size() << "\n";
|
||||
for (unsigned i = 0; i < v.size(); i++) tout << v[i] << " "; tout << "\n";);
|
||||
return v.c_ptr();
|
||||
}
|
||||
|
||||
int * get_int_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
||||
throw_invalid_reference();
|
||||
return reinterpret_cast<int*>(&(m_args[pos].m_int));
|
||||
}
|
||||
|
||||
__int64 * get_int64_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != INT64)
|
||||
throw_invalid_reference();
|
||||
return &(m_args[pos].m_int);
|
||||
}
|
||||
|
||||
unsigned * get_uint_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
||||
throw_invalid_reference();
|
||||
return reinterpret_cast<unsigned*>(&(m_args[pos].m_uint));
|
||||
}
|
||||
|
||||
__uint64 * get_uint64_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != UINT64)
|
||||
throw_invalid_reference();
|
||||
return &(m_args[pos].m_uint);
|
||||
}
|
||||
|
||||
Z3_string * get_str_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != STRING)
|
||||
throw_invalid_reference();
|
||||
return &(m_args[pos].m_str);
|
||||
}
|
||||
|
||||
void ** get_obj_addr(unsigned pos) {
|
||||
if (pos >= m_args.size() || m_args[pos].m_kind != OBJECT)
|
||||
throw_invalid_reference();
|
||||
return &(m_args[pos].m_obj);
|
||||
}
|
||||
|
||||
void store_result(void * obj) {
|
||||
m_result = obj;
|
||||
}
|
||||
|
||||
void register_cmd(unsigned id, z3_replayer_cmd cmd) {
|
||||
m_cmds.reserve(id+1, 0);
|
||||
m_cmds[id] = cmd;
|
||||
}
|
||||
|
||||
void reset() {
|
||||
m_result = 0;
|
||||
m_args.reset();
|
||||
m_obj_arrays.reset();
|
||||
m_sym_arrays.reset();
|
||||
m_unsigned_arrays.reset();
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
z3_replayer::z3_replayer(std::istream & in) {
|
||||
m_imp = alloc(imp, *this, in);
|
||||
register_z3_replayer_cmds(*this);
|
||||
}
|
||||
|
||||
z3_replayer::~z3_replayer() {
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
unsigned z3_replayer::get_line() const {
|
||||
return m_imp->m_line;
|
||||
}
|
||||
|
||||
bool z3_replayer::get_bool(unsigned pos) const {
|
||||
return get_int(pos) != 0;
|
||||
}
|
||||
|
||||
int z3_replayer::get_int(unsigned pos) const {
|
||||
return m_imp->get_int(pos);
|
||||
}
|
||||
|
||||
unsigned z3_replayer::get_uint(unsigned pos) const {
|
||||
return m_imp->get_uint(pos);
|
||||
}
|
||||
|
||||
__int64 z3_replayer::get_int64(unsigned pos) const {
|
||||
return m_imp->get_int64(pos);
|
||||
}
|
||||
|
||||
__uint64 z3_replayer::get_uint64(unsigned pos) const {
|
||||
return m_imp->get_uint64(pos);
|
||||
}
|
||||
|
||||
double z3_replayer::get_double(unsigned pos) const {
|
||||
return m_imp->get_double(pos);
|
||||
}
|
||||
|
||||
Z3_string z3_replayer::get_str(unsigned pos) const {
|
||||
return m_imp->get_str(pos);
|
||||
}
|
||||
|
||||
Z3_symbol z3_replayer::get_symbol(unsigned pos) const {
|
||||
return m_imp->get_symbol(pos);
|
||||
}
|
||||
|
||||
void * z3_replayer::get_obj(unsigned pos) const {
|
||||
return m_imp->get_obj(pos);
|
||||
}
|
||||
|
||||
unsigned * z3_replayer::get_uint_array(unsigned pos) const {
|
||||
return m_imp->get_uint_array(pos);
|
||||
}
|
||||
|
||||
Z3_symbol * z3_replayer::get_symbol_array(unsigned pos) const {
|
||||
return m_imp->get_symbol_array(pos);
|
||||
}
|
||||
|
||||
void ** z3_replayer::get_obj_array(unsigned pos) const {
|
||||
return m_imp->get_obj_array(pos);
|
||||
}
|
||||
|
||||
int * z3_replayer::get_int_addr(unsigned pos) {
|
||||
return m_imp->get_int_addr(pos);
|
||||
}
|
||||
|
||||
__int64 * z3_replayer::get_int64_addr(unsigned pos) {
|
||||
return m_imp->get_int64_addr(pos);
|
||||
}
|
||||
|
||||
unsigned * z3_replayer::get_uint_addr(unsigned pos) {
|
||||
return m_imp->get_uint_addr(pos);
|
||||
}
|
||||
|
||||
__uint64 * z3_replayer::get_uint64_addr(unsigned pos) {
|
||||
return m_imp->get_uint64_addr(pos);
|
||||
}
|
||||
|
||||
Z3_string * z3_replayer::get_str_addr(unsigned pos) {
|
||||
return m_imp->get_str_addr(pos);
|
||||
}
|
||||
|
||||
void ** z3_replayer::get_obj_addr(unsigned pos) {
|
||||
return m_imp->get_obj_addr(pos);
|
||||
}
|
||||
|
||||
void z3_replayer::store_result(void * obj) {
|
||||
return m_imp->store_result(obj);
|
||||
}
|
||||
|
||||
void z3_replayer::register_cmd(unsigned id, z3_replayer_cmd cmd) {
|
||||
return m_imp->register_cmd(id, cmd);
|
||||
}
|
||||
|
||||
void z3_replayer::parse() {
|
||||
return m_imp->parse();
|
||||
}
|
66
src/api/z3_replayer.h
Normal file
66
src/api/z3_replayer.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_replayer.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Interpreter for Z3 logs
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-09-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _Z3_REPLAYER_H_
|
||||
#define _Z3_REPLAYER_H_
|
||||
|
||||
#include<iostream>
|
||||
#include"z3.h"
|
||||
#include"z3_exception.h"
|
||||
|
||||
class z3_replayer;
|
||||
|
||||
typedef void (*z3_replayer_cmd)(z3_replayer &);
|
||||
|
||||
typedef default_exception z3_replayer_exception;
|
||||
|
||||
class z3_replayer {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
public:
|
||||
z3_replayer(std::istream & in);
|
||||
~z3_replayer();
|
||||
void parse();
|
||||
unsigned get_line() const;
|
||||
|
||||
int get_int(unsigned pos) const;
|
||||
unsigned get_uint(unsigned pos) const;
|
||||
__int64 get_int64(unsigned pos) const;
|
||||
__uint64 get_uint64(unsigned pos) const;
|
||||
double get_double(unsigned pos) const;
|
||||
bool get_bool(unsigned pos) const;
|
||||
Z3_string get_str(unsigned pos) const;
|
||||
Z3_symbol get_symbol(unsigned pos) const;
|
||||
void * get_obj(unsigned pos) const;
|
||||
|
||||
unsigned * get_uint_array(unsigned pos) const;
|
||||
Z3_symbol * get_symbol_array(unsigned pos) const;
|
||||
void ** get_obj_array(unsigned pos) const;
|
||||
|
||||
int * get_int_addr(unsigned pos);
|
||||
__int64 * get_int64_addr(unsigned pos);
|
||||
unsigned * get_uint_addr(unsigned pos);
|
||||
__uint64 * get_uint64_addr(unsigned pos);
|
||||
Z3_string * get_str_addr(unsigned pos);
|
||||
void ** get_obj_addr(unsigned pos);
|
||||
|
||||
void store_result(void * obj);
|
||||
void register_cmd(unsigned id, z3_replayer_cmd cmd);
|
||||
};
|
||||
|
||||
#endif
|
1304
src/api/z3_solver.cpp
Normal file
1304
src/api/z3_solver.cpp
Normal file
File diff suppressed because it is too large
Load diff
1007
src/api/z3_solver.h
Normal file
1007
src/api/z3_solver.h
Normal file
File diff suppressed because it is too large
Load diff
64
src/api/z3_v1.h
Normal file
64
src/api/z3_v1.h
Normal file
|
@ -0,0 +1,64 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
z3_v1.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Z3 1.x backwards compatibility macros.
|
||||
These macros are used to simulate the Z3 API using in the 1.x versions.
|
||||
This file should only be used by users still using the Z3 1.x API.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-09-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _Z3_V1_H_
|
||||
#define _Z3_V1_H_
|
||||
|
||||
#include"z3.h"
|
||||
|
||||
// Backwards compatibility
|
||||
#define Z3_type_ast Z3_sort
|
||||
#define Z3_const_decl_ast Z3_func_decl
|
||||
#define Z3_const Z3_app
|
||||
#define Z3_pattern_ast Z3_pattern
|
||||
#define Z3_UNINTERPRETED_TYPE Z3_UNINTERPRETED_SORT
|
||||
#define Z3_BOOL_TYPE Z3_BOOL_SORT
|
||||
#define Z3_INT_TYPE Z3_INT_SORT
|
||||
#define Z3_REAL_TYPE Z3_REAL_SORT
|
||||
#define Z3_BV_TYPE Z3_BV_SORT
|
||||
#define Z3_ARRAY_TYPE Z3_ARRAY_SORT
|
||||
#define Z3_TUPLE_TYPE Z3_DATATYPE_SORT
|
||||
#define Z3_UNKNOWN_TYPE Z3_UNKNOWN_SORT
|
||||
#define Z3_CONST_DECL_AST Z3_FUNC_DECL_AST
|
||||
#define Z3_TYPE_AST Z3_SORT_AST
|
||||
#define Z3_SORT_ERROR Z3_TYPE_ERROR
|
||||
#define Z3_mk_uninterpreted_type Z3_mk_uninterpreted_sort
|
||||
#define Z3_mk_bool_type Z3_mk_bool_sort
|
||||
#define Z3_mk_int_type Z3_mk_int_sort
|
||||
#define Z3_mk_real_type Z3_mk_real_sort
|
||||
#define Z3_mk_bv_type Z3_mk_bv_sort
|
||||
#define Z3_mk_array_type Z3_mk_array_sort
|
||||
#define Z3_mk_tuple_type Z3_mk_tuple_sort
|
||||
#define Z3_get_type Z3_get_sort
|
||||
#define Z3_get_pattern_ast Z3_get_pattern
|
||||
#define Z3_get_type_kind Z3_get_sort_kind
|
||||
#define Z3_get_type_name Z3_get_sort_name
|
||||
#define Z3_get_bv_type_size Z3_get_bv_sort_size
|
||||
#define Z3_get_array_type_domain Z3_get_array_sort_domain
|
||||
#define Z3_get_array_type_range Z3_get_array_sort_range
|
||||
#define Z3_get_tuple_type_num_fields Z3_get_tuple_sort_num_fields
|
||||
#define Z3_get_tuple_type_field_decl Z3_get_tuple_sort_field_decl
|
||||
#define Z3_get_tuple_type_mk_decl Z3_get_tuple_sort_mk_decl
|
||||
#define Z3_to_const_ast Z3_to_app
|
||||
#define Z3_get_numeral_value_string Z3_get_numeral_string
|
||||
#define Z3_get_const_ast_decl Z3_get_app_decl
|
||||
#define Z3_get_value Z3_eval_func_decl
|
||||
|
||||
#endif
|
1
src/assertion_set/README
Normal file
1
src/assertion_set/README
Normal file
|
@ -0,0 +1 @@
|
|||
This module is obsolete. It is subsumed by the tactic module.
|
430
src/assertion_set/assertion_set.cpp
Normal file
430
src/assertion_set/assertion_set.cpp
Normal file
|
@ -0,0 +1,430 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
assertion_set.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Assertion set.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-04-20
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"assertion_set.h"
|
||||
#include"cmd_context.h"
|
||||
#include"ast_ll_pp.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"for_each_expr.h"
|
||||
|
||||
void assertion_set::copy(assertion_set & target) const {
|
||||
if (this == &target)
|
||||
return;
|
||||
m().copy(m_forms, target.m_forms);
|
||||
m().copy(m_proofs, target.m_proofs);
|
||||
target.m_inconsistent = m_inconsistent;
|
||||
}
|
||||
|
||||
void assertion_set::push_back(expr * f, proof * pr) {
|
||||
if (m().is_true(f))
|
||||
return;
|
||||
if (m().is_false(f)) {
|
||||
m().del(m_forms);
|
||||
m().del(m_proofs);
|
||||
m_inconsistent = true;
|
||||
}
|
||||
else {
|
||||
SASSERT(!m_inconsistent);
|
||||
}
|
||||
m().push_back(m_forms, f);
|
||||
if (m().proofs_enabled())
|
||||
m().push_back(m_proofs, pr);
|
||||
}
|
||||
|
||||
void assertion_set::quick_process(bool save_first, expr * & f) {
|
||||
if (!m().is_and(f) && !(m().is_not(f) && m().is_or(to_app(f)->get_arg(0)))) {
|
||||
if (!save_first) {
|
||||
push_back(f, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
typedef std::pair<expr *, bool> expr_pol;
|
||||
sbuffer<expr_pol, 64> todo;
|
||||
todo.push_back(expr_pol(f, true));
|
||||
while (!todo.empty()) {
|
||||
if (m_inconsistent)
|
||||
return;
|
||||
expr_pol p = todo.back();
|
||||
expr * curr = p.first;
|
||||
bool pol = p.second;
|
||||
todo.pop_back();
|
||||
if (pol && m().is_and(curr)) {
|
||||
app * t = to_app(curr);
|
||||
unsigned i = t->get_num_args();
|
||||
while (i > 0) {
|
||||
--i;
|
||||
todo.push_back(expr_pol(t->get_arg(i), true));
|
||||
}
|
||||
}
|
||||
else if (!pol && m().is_or(curr)) {
|
||||
app * t = to_app(curr);
|
||||
unsigned i = t->get_num_args();
|
||||
while (i > 0) {
|
||||
--i;
|
||||
todo.push_back(expr_pol(t->get_arg(i), false));
|
||||
}
|
||||
}
|
||||
else if (m().is_not(curr)) {
|
||||
todo.push_back(expr_pol(to_app(curr)->get_arg(0), !pol));
|
||||
}
|
||||
else {
|
||||
if (!pol)
|
||||
curr = m().mk_not(curr);
|
||||
if (save_first) {
|
||||
f = curr;
|
||||
save_first = false;
|
||||
}
|
||||
else {
|
||||
push_back(curr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assertion_set::process_and(bool save_first, app * f, proof * pr, expr_ref & out_f, proof_ref & out_pr) {
|
||||
unsigned num = f->get_num_args();
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
if (m_inconsistent)
|
||||
return;
|
||||
slow_process(save_first && i == 0, f->get_arg(i), m().mk_and_elim(pr, i), out_f, out_pr);
|
||||
}
|
||||
}
|
||||
|
||||
void assertion_set::process_not_or(bool save_first, app * f, proof * pr, expr_ref & out_f, proof_ref & out_pr) {
|
||||
unsigned num = f->get_num_args();
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
if (m_inconsistent)
|
||||
return;
|
||||
expr * child = f->get_arg(i);
|
||||
if (m().is_not(child)) {
|
||||
expr * not_child = to_app(child)->get_arg(0);
|
||||
slow_process(save_first && i == 0, not_child, m().mk_not_or_elim(pr, i), out_f, out_pr);
|
||||
}
|
||||
else {
|
||||
expr_ref not_child(m());
|
||||
not_child = m().mk_not(child);
|
||||
slow_process(save_first && i == 0, not_child, m().mk_not_or_elim(pr, i), out_f, out_pr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assertion_set::slow_process(bool save_first, expr * f, proof * pr, expr_ref & out_f, proof_ref & out_pr) {
|
||||
if (m().is_and(f))
|
||||
process_and(save_first, to_app(f), pr, out_f, out_pr);
|
||||
else if (m().is_not(f) && m().is_or(to_app(f)->get_arg(0)))
|
||||
process_not_or(save_first, to_app(to_app(f)->get_arg(0)), pr, out_f, out_pr);
|
||||
else if (save_first) {
|
||||
out_f = f;
|
||||
out_pr = pr;
|
||||
}
|
||||
else {
|
||||
push_back(f, pr);
|
||||
}
|
||||
}
|
||||
|
||||
void assertion_set::slow_process(expr * f, proof * pr) {
|
||||
expr_ref out_f(m());
|
||||
proof_ref out_pr(m());
|
||||
slow_process(false, f, pr, out_f, out_pr);
|
||||
}
|
||||
|
||||
void assertion_set::assert_expr(expr * f, proof * pr) {
|
||||
SASSERT(m().proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
|
||||
if (m_inconsistent)
|
||||
return;
|
||||
if (m().proofs_enabled())
|
||||
slow_process(f, pr);
|
||||
else
|
||||
quick_process(false, f);
|
||||
}
|
||||
|
||||
void assertion_set::update(unsigned i, expr * f, proof * pr) {
|
||||
SASSERT(m().proofs_enabled() == (pr != 0 && !m().is_undef_proof(pr)));
|
||||
if (m_inconsistent)
|
||||
return;
|
||||
if (m().proofs_enabled()) {
|
||||
expr_ref out_f(m());
|
||||
proof_ref out_pr(m());
|
||||
slow_process(true, f, pr, out_f, out_pr);
|
||||
if (!m_inconsistent) {
|
||||
if (m().is_false(out_f)) {
|
||||
push_back(out_f, out_pr);
|
||||
}
|
||||
else {
|
||||
m().set(m_forms, i, out_f);
|
||||
m().set(m_proofs, i, out_pr);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
quick_process(true, f);
|
||||
if (!m_inconsistent) {
|
||||
if (m().is_false(f))
|
||||
push_back(f, 0);
|
||||
else
|
||||
m().set(m_forms, i, f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void assertion_set::reset() {
|
||||
m().del(m_forms);
|
||||
m().del(m_proofs);
|
||||
m_inconsistent = false;
|
||||
}
|
||||
|
||||
void assertion_set::display(cmd_context & ctx, std::ostream & out) const {
|
||||
out << "(assertion-set";
|
||||
unsigned sz = size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
out << "\n ";
|
||||
ctx.display(out, form(i), 2);
|
||||
}
|
||||
out << ")" << std::endl;
|
||||
}
|
||||
|
||||
void assertion_set::display(cmd_context & ctx) const {
|
||||
display(ctx, ctx.regular_stream());
|
||||
}
|
||||
|
||||
void assertion_set::display(std::ostream & out) const {
|
||||
out << "(assertion-set";
|
||||
unsigned sz = size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
out << "\n ";
|
||||
out << mk_ismt2_pp(form(i), m(), 2);
|
||||
}
|
||||
out << ")" << std::endl;
|
||||
}
|
||||
|
||||
void assertion_set::display_as_and(std::ostream & out) const {
|
||||
ptr_buffer<expr> args;
|
||||
unsigned sz = size();
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
args.push_back(form(i));
|
||||
expr_ref tmp(m());
|
||||
tmp = m().mk_and(args.size(), args.c_ptr());
|
||||
out << mk_ismt2_pp(tmp, m()) << "\n";
|
||||
}
|
||||
|
||||
void assertion_set::display_ll(std::ostream & out) const {
|
||||
unsigned sz = size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
out << mk_ll_pp(form(i), m()) << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Assumes that the formula is already in CNF.
|
||||
*/
|
||||
void assertion_set::display_dimacs(std::ostream & out) const {
|
||||
obj_map<expr, unsigned> expr2var;
|
||||
unsigned num_vars = 0;
|
||||
unsigned num_cls = size();
|
||||
for (unsigned i = 0; i < num_cls; i++) {
|
||||
expr * f = form(i);
|
||||
unsigned num_lits;
|
||||
expr * const * lits;
|
||||
if (m().is_or(f)) {
|
||||
num_lits = to_app(f)->get_num_args();
|
||||
lits = to_app(f)->get_args();
|
||||
}
|
||||
else {
|
||||
num_lits = 1;
|
||||
lits = &f;
|
||||
}
|
||||
for (unsigned j = 0; j < num_lits; j++) {
|
||||
expr * l = lits[j];
|
||||
if (m().is_not(l))
|
||||
l = to_app(l)->get_arg(0);
|
||||
if (expr2var.contains(l))
|
||||
continue;
|
||||
num_vars++;
|
||||
expr2var.insert(l, num_vars);
|
||||
}
|
||||
}
|
||||
out << "p cnf " << num_vars << " " << num_cls << "\n";
|
||||
for (unsigned i = 0; i < num_cls; i++) {
|
||||
expr * f = form(i);
|
||||
unsigned num_lits;
|
||||
expr * const * lits;
|
||||
if (m().is_or(f)) {
|
||||
num_lits = to_app(f)->get_num_args();
|
||||
lits = to_app(f)->get_args();
|
||||
}
|
||||
else {
|
||||
num_lits = 1;
|
||||
lits = &f;
|
||||
}
|
||||
for (unsigned j = 0; j < num_lits; j++) {
|
||||
expr * l = lits[j];
|
||||
if (m().is_not(l)) {
|
||||
out << "-";
|
||||
l = to_app(l)->get_arg(0);
|
||||
}
|
||||
unsigned id = UINT_MAX;
|
||||
expr2var.find(l, id);
|
||||
SASSERT(id != UINT_MAX);
|
||||
out << id << " ";
|
||||
}
|
||||
out << "0\n";
|
||||
}
|
||||
}
|
||||
|
||||
unsigned assertion_set::num_exprs() const {
|
||||
expr_fast_mark1 visited;
|
||||
unsigned sz = size();
|
||||
unsigned r = 0;
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
r += get_num_exprs(form(i), visited);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Eliminate true formulas.
|
||||
*/
|
||||
void assertion_set::elim_true() {
|
||||
unsigned sz = size();
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * f = form(i);
|
||||
if (m().is_true(f))
|
||||
continue;
|
||||
if (i == j) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
m().set(m_forms, j, f);
|
||||
if (m().proofs_enabled())
|
||||
m().set(m_proofs, j, m().get(m_proofs, i));
|
||||
j++;
|
||||
}
|
||||
for (; j < sz; j++) {
|
||||
m().pop_back(m_forms);
|
||||
if (m().proofs_enabled())
|
||||
m().pop_back(m_proofs);
|
||||
}
|
||||
}
|
||||
|
||||
void assertion_set::elim_redundancies() {
|
||||
if (inconsistent())
|
||||
return;
|
||||
expr_ref_fast_mark1 neg_lits(m());
|
||||
expr_ref_fast_mark2 pos_lits(m());
|
||||
unsigned sz = size();
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * f = form(i);
|
||||
if (m().is_true(f))
|
||||
continue;
|
||||
if (m().is_not(f)) {
|
||||
expr * atom = to_app(f)->get_arg(0);
|
||||
if (neg_lits.is_marked(atom))
|
||||
continue;
|
||||
if (pos_lits.is_marked(atom)) {
|
||||
proof * p = 0;
|
||||
if (m().proofs_enabled()) {
|
||||
proof * pr1 = 0;
|
||||
proof * pr2 = pr(i);
|
||||
for (unsigned j = 0; j < i; j++) {
|
||||
if (form(j) == atom) {
|
||||
pr1 = pr(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SASSERT(pr1);
|
||||
proof * prs[2] = { pr1, pr2 };
|
||||
p = m().mk_unit_resolution(2, prs);
|
||||
}
|
||||
push_back(m().mk_false(), p);
|
||||
return;
|
||||
}
|
||||
neg_lits.mark(atom);
|
||||
}
|
||||
else {
|
||||
if (pos_lits.is_marked(f))
|
||||
continue;
|
||||
if (neg_lits.is_marked(f)) {
|
||||
proof * p = 0;
|
||||
if (m().proofs_enabled()) {
|
||||
proof * pr1 = 0;
|
||||
proof * pr2 = pr(i);
|
||||
for (unsigned j = 0; j < i; j++) {
|
||||
expr * curr = form(j);
|
||||
expr * atom;
|
||||
if (m().is_not(curr, atom) && atom == f) {
|
||||
pr1 = pr(j);
|
||||
break;
|
||||
}
|
||||
}
|
||||
SASSERT(pr1);
|
||||
proof * prs[2] = { pr1, pr2 };
|
||||
p = m().mk_unit_resolution(2, prs);
|
||||
}
|
||||
push_back(m().mk_false(), p);
|
||||
return;
|
||||
}
|
||||
pos_lits.mark(f);
|
||||
}
|
||||
if (i == j) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
m().set(m_forms, j, f);
|
||||
if (m().proofs_enabled())
|
||||
m().set(m_proofs, j, pr(i));
|
||||
j++;
|
||||
}
|
||||
|
||||
for (; j < sz; j++) {
|
||||
m().pop_back(m_forms);
|
||||
if (m().proofs_enabled())
|
||||
m().pop_back(m_proofs);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Assert expressions from ctx into t.
|
||||
*/
|
||||
void assert_exprs_from(cmd_context const & ctx, assertion_set & t) {
|
||||
ptr_vector<expr>::const_iterator it = ctx.begin_assertions();
|
||||
ptr_vector<expr>::const_iterator end = ctx.end_assertions();
|
||||
for (; it != end; ++it) {
|
||||
t.assert_expr(*it);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Translate the assertion set to a new one that uses a different ast_manager.
|
||||
*/
|
||||
assertion_set * assertion_set::translate(ast_translation & translator) const {
|
||||
ast_manager & m_to = translator.to();
|
||||
assertion_set * res = alloc(assertion_set, m_to);
|
||||
|
||||
unsigned sz = m().size(m_forms);
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
res->m().push_back(res->m_forms, translator(m().get(m_forms, i)));
|
||||
if (m_to.proofs_enabled())
|
||||
res->m().push_back(res->m_proofs, translator(m().get(m_proofs, i)));
|
||||
}
|
||||
|
||||
res->m_inconsistent = m_inconsistent;
|
||||
|
||||
return res;
|
||||
}
|
98
src/assertion_set/assertion_set.h
Normal file
98
src/assertion_set/assertion_set.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
assertion_set.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Assertion set.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-04-20
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ASSERTION_SET_H_
|
||||
#define _ASSERTION_SET_H_
|
||||
|
||||
#include"ast.h"
|
||||
#include"ast_translation.h"
|
||||
#include"for_each_expr.h"
|
||||
|
||||
class cmd_context;
|
||||
|
||||
class assertion_set {
|
||||
ast_manager & m_manager;
|
||||
bool m_inconsistent;
|
||||
expr_array m_forms;
|
||||
expr_array m_proofs;
|
||||
|
||||
void push_back(expr * f, proof * pr);
|
||||
void quick_process(bool save_first, expr * & f);
|
||||
void process_and(bool save_first, app * f, proof * pr, expr_ref & out_f, proof_ref & out_pr);
|
||||
void process_not_or(bool save_first, app * f, proof * pr, expr_ref & out_f, proof_ref & out_pr);
|
||||
void slow_process(bool save_first, expr * f, proof * pr, expr_ref & out_f, proof_ref & out_pr);
|
||||
void slow_process(expr * f, proof * pr);
|
||||
|
||||
public:
|
||||
assertion_set(ast_manager & m):m_manager(m), m_inconsistent(false) {}
|
||||
~assertion_set() { reset(); }
|
||||
|
||||
ast_manager & m() const { return m_manager; }
|
||||
|
||||
bool inconsistent() const { return m_inconsistent; }
|
||||
|
||||
void reset();
|
||||
|
||||
void copy(assertion_set & target) const;
|
||||
|
||||
void assert_expr(expr * f, proof * pr);
|
||||
|
||||
void assert_expr(expr * f) {
|
||||
assert_expr(f, m().mk_asserted(f));
|
||||
}
|
||||
|
||||
unsigned size() const { return m().size(m_forms); }
|
||||
|
||||
unsigned num_exprs() const;
|
||||
|
||||
expr * form(unsigned i) const { return m().get(m_forms, i); }
|
||||
|
||||
proof * pr(unsigned i) const { return m().proofs_enabled() ? static_cast<proof*>(m().get(m_proofs, i)) : 0; }
|
||||
|
||||
void update(unsigned i, expr * f, proof * pr = 0);
|
||||
|
||||
void elim_true();
|
||||
|
||||
void elim_redundancies();
|
||||
|
||||
void display(cmd_context & ctx, std::ostream & out) const;
|
||||
|
||||
void display(cmd_context & ctx) const;
|
||||
|
||||
void display(std::ostream & out) const;
|
||||
|
||||
void display_ll(std::ostream & out) const;
|
||||
|
||||
void display_as_and(std::ostream & out) const;
|
||||
|
||||
void display_dimacs(std::ostream & out) const;
|
||||
|
||||
assertion_set * translate(ast_translation & translator) const;
|
||||
};
|
||||
|
||||
void assert_exprs_from(cmd_context const & ctx, assertion_set & t);
|
||||
|
||||
template<typename ForEachProc>
|
||||
void for_each_expr_as(ForEachProc& proc, assertion_set const& s) {
|
||||
expr_mark visited;
|
||||
for (unsigned i = 0; i < s.size(); ++i) {
|
||||
for_each_expr(proc, visited, s.form(i));
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
122
src/assertion_set/assertion_set_rewriter.cpp
Normal file
122
src/assertion_set/assertion_set_rewriter.cpp
Normal file
|
@ -0,0 +1,122 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
assertion_set_rewriter.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Apply rewriting rules in an assertion set.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-27
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"assertion_set_rewriter.h"
|
||||
#include"th_rewriter.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"assertion_set_util.h"
|
||||
|
||||
struct assertion_set_rewriter::imp {
|
||||
ast_manager & m_manager;
|
||||
th_rewriter m_r;
|
||||
unsigned m_num_steps;
|
||||
|
||||
imp(ast_manager & m, params_ref const & p):
|
||||
m_manager(m),
|
||||
m_r(m, p),
|
||||
m_num_steps(0) {
|
||||
}
|
||||
|
||||
ast_manager & m() const { return m_manager; }
|
||||
|
||||
void set_cancel(bool f) {
|
||||
m_r.set_cancel(f);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
m_r.reset();
|
||||
m_num_steps = 0;
|
||||
}
|
||||
|
||||
void operator()(assertion_set & s) {
|
||||
SASSERT(is_well_sorted(s));
|
||||
as_st_report report("simplifier", s);
|
||||
TRACE("before_simplifier", s.display(tout););
|
||||
m_num_steps = 0;
|
||||
if (s.inconsistent())
|
||||
return;
|
||||
expr_ref new_curr(m());
|
||||
proof_ref new_pr(m());
|
||||
unsigned size = s.size();
|
||||
for (unsigned idx = 0; idx < size; idx++) {
|
||||
if (s.inconsistent())
|
||||
break;
|
||||
expr * curr = s.form(idx);
|
||||
m_r(curr, new_curr, new_pr);
|
||||
m_num_steps += m_r.get_num_steps();
|
||||
if (m().proofs_enabled()) {
|
||||
proof * pr = s.pr(idx);
|
||||
new_pr = m().mk_modus_ponens(pr, new_pr);
|
||||
}
|
||||
s.update(idx, new_curr, new_pr);
|
||||
}
|
||||
TRACE("after_simplifier_bug", s.display(tout););
|
||||
s.elim_redundancies();
|
||||
TRACE("after_simplifier", s.display(tout););
|
||||
SASSERT(is_well_sorted(s));
|
||||
}
|
||||
|
||||
unsigned get_num_steps() const { return m_num_steps; }
|
||||
};
|
||||
|
||||
assertion_set_rewriter::assertion_set_rewriter(ast_manager & m, params_ref const & p):
|
||||
m_params(p) {
|
||||
m_imp = alloc(imp, m, p);
|
||||
}
|
||||
|
||||
assertion_set_rewriter::~assertion_set_rewriter() {
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
void assertion_set_rewriter::updt_params(params_ref const & p) {
|
||||
m_params = p;
|
||||
m_imp->m_r.updt_params(p);
|
||||
}
|
||||
|
||||
void assertion_set_rewriter::get_param_descrs(param_descrs & r) {
|
||||
th_rewriter::get_param_descrs(r);
|
||||
}
|
||||
|
||||
void assertion_set_rewriter::operator()(assertion_set & s) {
|
||||
m_imp->operator()(s);
|
||||
}
|
||||
|
||||
void assertion_set_rewriter::set_cancel(bool f) {
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
|
||||
void assertion_set_rewriter::cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned assertion_set_rewriter::get_num_steps() const {
|
||||
return m_imp->get_num_steps();
|
||||
}
|
||||
|
56
src/assertion_set/assertion_set_rewriter.h
Normal file
56
src/assertion_set/assertion_set_rewriter.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
assertion_set_rewriter.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Apply rewriting rules in an assertion set.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _ASSERTION_SET_REWRITER_H_
|
||||
#define _ASSERTION_SET_REWRITER_H_
|
||||
|
||||
#include"assertion_set_strategy.h"
|
||||
|
||||
class assertion_set_rewriter : public assertion_set_strategy {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
params_ref m_params;
|
||||
public:
|
||||
assertion_set_rewriter(ast_manager & m, params_ref const & ref = params_ref());
|
||||
virtual ~assertion_set_rewriter();
|
||||
|
||||
virtual void updt_params(params_ref const & p);
|
||||
static void get_param_descrs(param_descrs & r);
|
||||
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
|
||||
|
||||
/**
|
||||
\brief Apply rewriting/simplification rules on the assertion set \c s.
|
||||
*/
|
||||
void operator()(assertion_set & s);
|
||||
|
||||
virtual void operator()(assertion_set & s, model_converter_ref & mc) {
|
||||
operator()(s);
|
||||
mc = 0;
|
||||
}
|
||||
|
||||
virtual void cleanup();
|
||||
|
||||
unsigned get_num_steps() const;
|
||||
virtual void set_cancel(bool f);
|
||||
};
|
||||
|
||||
inline as_st * mk_simplifier(ast_manager & m, params_ref const & p = params_ref()) {
|
||||
return clean(alloc(assertion_set_rewriter, m, p));
|
||||
}
|
||||
|
||||
#endif
|
1255
src/assertion_set/assertion_set_strategy.cpp
Normal file
1255
src/assertion_set/assertion_set_strategy.cpp
Normal file
File diff suppressed because it is too large
Load diff
223
src/assertion_set/assertion_set_strategy.h
Normal file
223
src/assertion_set/assertion_set_strategy.h
Normal file
|
@ -0,0 +1,223 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
assertion_set_strategy.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Abstract strategy for assertion sets, and simple combinators.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-05-17
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _AS_STRATEGY_H_
|
||||
#define _AS_STRATEGY_H_
|
||||
|
||||
#include"params.h"
|
||||
#include"assertion_set.h"
|
||||
#include"model_converter.h"
|
||||
#include"statistics.h"
|
||||
#include"strategy_exception.h"
|
||||
#include"lbool.h"
|
||||
#include"assertion_set_util.h"
|
||||
|
||||
struct front_end_params;
|
||||
|
||||
class progress_callback;
|
||||
|
||||
// minimum verbosity level for strategies
|
||||
#define ST_VERBOSITY_LVL 10
|
||||
|
||||
class as_st_report {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
public:
|
||||
as_st_report(char const * id, assertion_set & s);
|
||||
~as_st_report();
|
||||
};
|
||||
|
||||
void report_st_progress(char const * id, unsigned val);
|
||||
|
||||
/**
|
||||
\brief Abstract assertion-set strategy.
|
||||
*/
|
||||
class assertion_set_strategy {
|
||||
unsigned m_ref_count;
|
||||
public:
|
||||
assertion_set_strategy():m_ref_count(0) {}
|
||||
virtual ~assertion_set_strategy() {}
|
||||
void inc_ref() { m_ref_count++; }
|
||||
void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); }
|
||||
virtual void updt_params(params_ref const & p) {}
|
||||
virtual void collect_param_descrs(param_descrs & r) {}
|
||||
void cancel();
|
||||
void reset_cancel();
|
||||
virtual void set_cancel(bool f) {}
|
||||
virtual void operator()(assertion_set & s, model_converter_ref & mc) = 0;
|
||||
virtual void collect_statistics(statistics & st) const {}
|
||||
virtual void reset_statistics() {}
|
||||
virtual void cleanup() = 0;
|
||||
virtual void reset() { cleanup(); }
|
||||
// for backward compatibility
|
||||
virtual void set_front_end_params(front_end_params & p) {}
|
||||
virtual void set_logic(symbol const & l) {}
|
||||
virtual void set_progress_callback(progress_callback * callback) {}
|
||||
};
|
||||
|
||||
bool is_equal(assertion_set const & s1, assertion_set const & s2);
|
||||
|
||||
// dummy for using ref_vector
|
||||
struct assertion_set_strategy_context {
|
||||
static void inc_ref(assertion_set_strategy * st) { st->inc_ref(); }
|
||||
static void dec_ref(assertion_set_strategy * st) { st->dec_ref(); }
|
||||
};
|
||||
|
||||
typedef assertion_set_strategy as_st;
|
||||
typedef assertion_set_strategy_context as_st_ctx;
|
||||
|
||||
typedef ref<as_st> as_st_ref;
|
||||
typedef ref_vector<as_st, as_st_ctx> as_st_ref_vector;
|
||||
typedef ref_buffer<as_st, as_st_ctx> as_st_ref_buffer;
|
||||
|
||||
as_st * and_then(unsigned num, as_st * const * sts);
|
||||
as_st * and_then(as_st * st1, as_st * st2);
|
||||
as_st * and_then(as_st * st1, as_st * st2, as_st * st3);
|
||||
as_st * and_then(as_st * st1, as_st * st2, as_st * st3, as_st * st4);
|
||||
as_st * and_then(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5);
|
||||
as_st * and_then(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6);
|
||||
as_st * and_then(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6, as_st * st7);
|
||||
as_st * and_then(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6, as_st * st7, as_st * st8);
|
||||
as_st * and_then(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6, as_st * st7, as_st * st8, as_st * st9);
|
||||
as_st * and_then(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6, as_st * st7, as_st * st8, as_st * st9, as_st * st10);
|
||||
|
||||
as_st * or_else(unsigned num, as_st * const * sts);
|
||||
as_st * or_else(as_st * st1, as_st * st2);
|
||||
as_st * or_else(as_st * st1, as_st * st2, as_st * st3);
|
||||
as_st * or_else(as_st * st1, as_st * st2, as_st * st3, as_st * st4);
|
||||
as_st * or_else(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5);
|
||||
as_st * or_else(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6);
|
||||
as_st * or_else(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6, as_st * st7);
|
||||
as_st * or_else(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6, as_st * st7, as_st * st8);
|
||||
as_st * or_else(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6, as_st * st7, as_st * st8, as_st * st9);
|
||||
as_st * or_else(as_st * st1, as_st * st2, as_st * st3, as_st * st4, as_st * st5, as_st * st6, as_st * st7, as_st * st8, as_st * st9, as_st * st10);
|
||||
|
||||
as_st * par(unsigned num, as_st * const * sts);
|
||||
as_st * par(as_st * st1, as_st * st2);
|
||||
as_st * par(as_st * st1, as_st * st2, as_st * st3);
|
||||
as_st * par(as_st * st1, as_st * st2, as_st * st3, as_st * st4);
|
||||
|
||||
as_st * round_robin(unsigned num, as_st * const * sts, unsigned start, unsigned end, unsigned delta);
|
||||
as_st * round_robin(as_st * st1, as_st * st2, unsigned start, unsigned end, unsigned delta);
|
||||
as_st * round_robin(as_st * st1, as_st * st2, as_st * st3, unsigned start, unsigned end, unsigned delta);
|
||||
as_st * round_robin(as_st * st1, as_st * st2, as_st * st3, as_st * st4, unsigned start, unsigned end, unsigned delta);
|
||||
|
||||
as_st * try_for(as_st * st, unsigned msecs);
|
||||
as_st * clean(as_st * st);
|
||||
as_st * using_params(as_st * st, params_ref const & p);
|
||||
as_st * noop();
|
||||
as_st * trace_mc(as_st * st);
|
||||
|
||||
as_st * filter_is_sat(as_st* st, bool const& unless_condition);
|
||||
as_st * filter_is_unsat(as_st* st, bool const& unless_condition);
|
||||
|
||||
as_st * mk_report_verbose_st(char const* msg, unsigned lvl);
|
||||
|
||||
as_st * repeat(as_st * st, unsigned max = UINT_MAX);
|
||||
|
||||
class wrapper_as_st : public as_st {
|
||||
protected:
|
||||
as_st * m_st;
|
||||
public:
|
||||
wrapper_as_st(as_st * s): m_st(s) { SASSERT(s); s->inc_ref(); }
|
||||
virtual ~wrapper_as_st();
|
||||
|
||||
virtual void operator()(assertion_set& s, model_converter_ref& mc) { (*m_st)(s, mc); }
|
||||
virtual void cleanup(void) { m_st->cleanup(); }
|
||||
virtual void collect_statistics(statistics & st) const { m_st->collect_statistics(st); }
|
||||
virtual void reset_statistics() { m_st->reset_statistics(); }
|
||||
virtual void set_front_end_params(front_end_params & p) { m_st->set_front_end_params(p); }
|
||||
virtual void updt_params(params_ref const & p) { m_st->updt_params(p); }
|
||||
virtual void collect_param_descrs(param_descrs & r) { m_st->collect_param_descrs(r); }
|
||||
virtual void reset() { m_st->reset(); }
|
||||
virtual void set_logic(symbol const& l) { m_st->set_logic(l); }
|
||||
virtual void set_progress_callback(progress_callback * callback) { m_st->set_progress_callback(callback); }
|
||||
|
||||
protected:
|
||||
virtual void set_cancel(bool f) { if (m_st) m_st->set_cancel(f); }
|
||||
};
|
||||
|
||||
|
||||
class as_test {
|
||||
unsigned m_ref_count;
|
||||
public:
|
||||
as_test():m_ref_count(0) {}
|
||||
void inc_ref() { m_ref_count++; }
|
||||
void dec_ref() { SASSERT(m_ref_count > 0); m_ref_count--; if (m_ref_count == 0) dealloc(this); }
|
||||
virtual bool operator()(assertion_set const & s) const = 0;
|
||||
};
|
||||
|
||||
as_test * check_mem(unsigned l);
|
||||
as_test * check_as_size(unsigned l);
|
||||
as_test * check_decided();
|
||||
as_st * cond(as_test * c, as_st * t, as_st * e);
|
||||
|
||||
void exec(as_st * st, assertion_set & s, model_converter_ref & mc);
|
||||
lbool check_sat(as_st * st, assertion_set & s, model_ref & md, proof_ref & pr, std::string & reason_unknown);
|
||||
|
||||
class assertion_set_strategy_factory {
|
||||
public:
|
||||
virtual ~assertion_set_strategy_factory() {}
|
||||
virtual as_st * operator()(ast_manager & m, params_ref const & p) = 0;
|
||||
};
|
||||
|
||||
typedef assertion_set_strategy_factory as_st_f;
|
||||
|
||||
as_st * fail();
|
||||
as_st * fail_if_not_decided(as_st * st);
|
||||
as_st * fail_if_sat();
|
||||
as_st * fail_if_unsat();
|
||||
as_st * fail_if_not_small(unsigned sz);
|
||||
as_st * fail_if_not_small_set(unsigned sz);
|
||||
|
||||
#define MK_FAIL_IF(NAME, TEST, MSG) \
|
||||
class NAME ## _st : public assertion_set_strategy { \
|
||||
public: \
|
||||
virtual void operator()(assertion_set & s, model_converter_ref & mc) { if (TEST) throw strategy_exception(MSG); } \
|
||||
virtual void cleanup() {} \
|
||||
}; \
|
||||
inline as_st * NAME() { return alloc(NAME ## _st); }
|
||||
|
||||
as_st * par_or(ast_manager & m, unsigned num, as_st_f * const * stfs);
|
||||
|
||||
#define MK_ST_FACTORY(NAME, CODE) \
|
||||
class NAME : public assertion_set_strategy_factory { \
|
||||
public: \
|
||||
virtual ~NAME() {} \
|
||||
virtual as_st * operator()(ast_manager & m, params_ref const & p) { CODE } \
|
||||
};
|
||||
|
||||
#define MK_SIMPLE_ST_FACTORY(NAME, ST) MK_ST_FACTORY(NAME, return ST;)
|
||||
|
||||
struct is_qfbv_test : public as_test {
|
||||
virtual bool operator()(assertion_set const & s) const { return is_qfbv(s); }
|
||||
};
|
||||
|
||||
struct is_qflia_test : public as_test {
|
||||
virtual bool operator()(assertion_set const & s) const { return is_qflia(s); }
|
||||
};
|
||||
|
||||
struct is_qflra_test : public as_test {
|
||||
virtual bool operator()(assertion_set const & s) const { return is_qflra(s); }
|
||||
};
|
||||
|
||||
inline as_test * is_qfbv() { return alloc(is_qfbv_test); }
|
||||
inline as_test * is_qflia() { return alloc(is_qflia_test); }
|
||||
inline as_test * is_qflra() { return alloc(is_qflra_test); }
|
||||
|
||||
#endif
|
220
src/assertion_set/assertion_set_util.cpp
Normal file
220
src/assertion_set/assertion_set_util.cpp
Normal file
|
@ -0,0 +1,220 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
assertion_set_util.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Assertion set goodies
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-04-28
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"assertion_set_util.h"
|
||||
#include"well_sorted.h"
|
||||
#include"for_each_expr.h"
|
||||
#include"bv_decl_plugin.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
|
||||
void as_shared_occs::operator()(assertion_set const & s) {
|
||||
m_occs.reset();
|
||||
shared_occs_mark visited;
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * t = s.form(i);
|
||||
m_occs(t, visited);
|
||||
}
|
||||
}
|
||||
|
||||
bool is_well_sorted(assertion_set const & s) {
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * t = s.form(i);
|
||||
if (!is_well_sorted(s.m(), t))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
struct is_non_propositional {
|
||||
struct found {};
|
||||
ast_manager & m;
|
||||
|
||||
is_non_propositional(ast_manager & _m):m(_m) {}
|
||||
void operator()(var *) { throw found(); }
|
||||
void operator()(quantifier *) { throw found(); }
|
||||
void operator()(app * n) {
|
||||
if (!m.is_bool(n))
|
||||
throw found();
|
||||
|
||||
family_id fid = n->get_family_id();
|
||||
if (fid == m.get_basic_family_id())
|
||||
return;
|
||||
|
||||
if (is_uninterp_const(n))
|
||||
return;
|
||||
|
||||
throw found();
|
||||
}
|
||||
};
|
||||
|
||||
struct is_non_qfbv {
|
||||
struct found {};
|
||||
ast_manager & m;
|
||||
bv_util u;
|
||||
|
||||
is_non_qfbv(ast_manager & _m):m(_m), u(m) {}
|
||||
|
||||
void operator()(var *) { throw found(); }
|
||||
|
||||
void operator()(quantifier *) { throw found(); }
|
||||
|
||||
void operator()(app * n) {
|
||||
if (!m.is_bool(n) && !u.is_bv(n))
|
||||
throw found();
|
||||
family_id fid = n->get_family_id();
|
||||
if (fid == m.get_basic_family_id())
|
||||
return;
|
||||
if (fid == u.get_family_id())
|
||||
return;
|
||||
if (is_uninterp_const(n))
|
||||
return;
|
||||
|
||||
throw found();
|
||||
}
|
||||
};
|
||||
|
||||
bool is_propositional(assertion_set const & s) {
|
||||
return !test<is_non_propositional>(s);
|
||||
}
|
||||
|
||||
bool is_qfbv(assertion_set const & s) {
|
||||
return !test<is_non_qfbv>(s);
|
||||
}
|
||||
|
||||
struct is_non_qflira {
|
||||
struct found {};
|
||||
ast_manager & m;
|
||||
arith_util u;
|
||||
bool m_int;
|
||||
bool m_real;
|
||||
|
||||
is_non_qflira(ast_manager & _m, bool _int, bool _real):m(_m), u(m), m_int(_int), m_real(_real) {}
|
||||
|
||||
void operator()(var *) { throw found(); }
|
||||
|
||||
void operator()(quantifier *) { throw found(); }
|
||||
|
||||
bool compatible_sort(app * n) const {
|
||||
if (m.is_bool(n))
|
||||
return true;
|
||||
if (m_int && u.is_int(n))
|
||||
return true;
|
||||
if (m_real && u.is_real(n))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
void operator()(app * n) {
|
||||
if (!compatible_sort(n))
|
||||
throw found();
|
||||
family_id fid = n->get_family_id();
|
||||
if (fid == m.get_basic_family_id())
|
||||
return;
|
||||
if (fid == u.get_family_id()) {
|
||||
switch (n->get_decl_kind()) {
|
||||
case OP_LE: case OP_GE: case OP_LT: case OP_GT:
|
||||
case OP_ADD: case OP_NUM:
|
||||
return;
|
||||
case OP_MUL:
|
||||
if (n->get_num_args() != 2)
|
||||
throw found();
|
||||
if (!u.is_numeral(n->get_arg(0)))
|
||||
throw found();
|
||||
return;
|
||||
case OP_TO_REAL:
|
||||
if (!m_real)
|
||||
throw found();
|
||||
break;
|
||||
default:
|
||||
throw found();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (is_uninterp_const(n))
|
||||
return;
|
||||
throw found();
|
||||
}
|
||||
};
|
||||
|
||||
bool is_qflia(assertion_set const & s) {
|
||||
is_non_qflira proc(s.m(), true, false);
|
||||
return !test(s, proc);
|
||||
}
|
||||
|
||||
bool is_qflra(assertion_set const & s) {
|
||||
is_non_qflira proc(s.m(), false, true);
|
||||
return !test(s, proc);
|
||||
}
|
||||
|
||||
bool is_qflira(assertion_set const & s) {
|
||||
is_non_qflira proc(s.m(), true, true);
|
||||
return !test(s, proc);
|
||||
}
|
||||
|
||||
bool is_lp(assertion_set const & s) {
|
||||
ast_manager & m = s.m();
|
||||
arith_util u(m);
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * f = s.form(i);
|
||||
bool sign = false;
|
||||
while (m.is_not(f, f))
|
||||
sign = !sign;
|
||||
if (m.is_eq(f) && !sign) {
|
||||
if (m.get_sort(to_app(f)->get_arg(0))->get_family_id() != u.get_family_id())
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
if (u.is_le(f) || u.is_ge(f) || u.is_lt(f) || u.is_gt(f))
|
||||
continue;
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool is_ilp(assertion_set const & s) {
|
||||
if (!is_qflia(s))
|
||||
return false;
|
||||
if (has_term_ite(s))
|
||||
return false;
|
||||
return is_lp(s);
|
||||
}
|
||||
|
||||
bool is_mip(assertion_set const & s) {
|
||||
if (!is_qflira(s))
|
||||
return false;
|
||||
if (has_term_ite(s))
|
||||
return false;
|
||||
return is_lp(s);
|
||||
}
|
||||
|
||||
struct has_term_ite_proc {
|
||||
struct found {};
|
||||
ast_manager & m;
|
||||
has_term_ite_proc(ast_manager & _m):m(_m) {}
|
||||
void operator()(var *) {}
|
||||
void operator()(quantifier *) {}
|
||||
void operator()(app * n) { if (m.is_term_ite(n)) throw found(); }
|
||||
};
|
||||
|
||||
bool has_term_ite(assertion_set const & s) {
|
||||
return test<has_term_ite_proc>(s);
|
||||
}
|
||||
|
91
src/assertion_set/assertion_set_util.h
Normal file
91
src/assertion_set/assertion_set_util.h
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
assertion_set_util.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Assertion set goodies
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-04-28
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ASSERTION_SET_UTIL_H_
|
||||
#define _ASSERTION_SET_UTIL_H_
|
||||
|
||||
#include"assertion_set.h"
|
||||
#include"shared_occs.h"
|
||||
|
||||
/**
|
||||
\brief Functor for computing the set of shared occurrences in an assertion set.
|
||||
|
||||
It is essentially a wrapper for shared_occs functor.
|
||||
*/
|
||||
class as_shared_occs {
|
||||
shared_occs m_occs;
|
||||
public:
|
||||
as_shared_occs(ast_manager & m, bool track_atomic = false, bool visit_quantifiers = true, bool visit_patterns = false):
|
||||
m_occs(m, track_atomic, visit_quantifiers, visit_patterns) {
|
||||
}
|
||||
void operator()(assertion_set const & s);
|
||||
bool is_shared(expr * t) { return m_occs.is_shared(t); }
|
||||
unsigned num_shared() const { return m_occs.num_shared(); }
|
||||
void reset() { return m_occs.reset(); }
|
||||
void cleanup() { return m_occs.cleanup(); }
|
||||
void display(std::ostream & out, ast_manager & m) const { m_occs.display(out, m); }
|
||||
};
|
||||
|
||||
bool is_well_sorted(assertion_set const & s);
|
||||
|
||||
// Return true if the assertion set is propositional logic
|
||||
bool is_propositional(assertion_set const & s);
|
||||
|
||||
// Return true if the assertion set is in QF_BV
|
||||
bool is_qfbv(assertion_set const & s);
|
||||
|
||||
// Return true if the assertion set is in QF_LIA
|
||||
bool is_qflia(assertion_set const & s);
|
||||
|
||||
// Return true if the assertion set is in QF_LRA
|
||||
bool is_qflra(assertion_set const & s);
|
||||
|
||||
// Return true if the assertion set is in QF_LIRA
|
||||
bool is_qflira(assertion_set const & s);
|
||||
|
||||
// Return true if the assertion set is in ILP problem (that is QF_LIA without boolean structure)
|
||||
bool is_ilp(assertion_set const & s);
|
||||
|
||||
// Return true if the assertion set is in MIP problem (that is QF_LIRA without boolean structure)
|
||||
bool is_mip(assertion_set const & s);
|
||||
|
||||
bool has_term_ite(assertion_set const & s);
|
||||
|
||||
inline bool is_decided(assertion_set const & s) { return s.size() == 0 || s.inconsistent(); }
|
||||
|
||||
template<typename Predicate>
|
||||
bool test(assertion_set const & s, Predicate & proc) {
|
||||
expr_fast_mark1 visited;
|
||||
try {
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
quick_for_each_expr(proc, visited, s.form(i));
|
||||
}
|
||||
catch (typename Predicate::found) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
template<typename Predicate>
|
||||
bool test(assertion_set const & s) {
|
||||
Predicate proc(s.m());
|
||||
return test(s, proc);
|
||||
}
|
||||
|
||||
#endif
|
94
src/assertion_set/der_strategy.cpp
Normal file
94
src/assertion_set/der_strategy.cpp
Normal file
|
@ -0,0 +1,94 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
der_strategy.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
DER strategy
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-10-20
|
||||
|
||||
--*/
|
||||
#include"der_strategy.h"
|
||||
|
||||
struct der_strategy::imp {
|
||||
ast_manager & m_manager;
|
||||
der_rewriter m_r;
|
||||
|
||||
imp(ast_manager & m):
|
||||
m_manager(m),
|
||||
m_r(m) {
|
||||
}
|
||||
|
||||
ast_manager & m() const { return m_manager; }
|
||||
|
||||
void set_cancel(bool f) {
|
||||
m_r.set_cancel(f);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
m_r.reset();
|
||||
}
|
||||
|
||||
void operator()(assertion_set & s) {
|
||||
SASSERT(is_well_sorted(s));
|
||||
as_st_report report("der", s);
|
||||
TRACE("before_der", s.display(tout););
|
||||
if (s.inconsistent())
|
||||
return;
|
||||
expr_ref new_curr(m());
|
||||
proof_ref new_pr(m());
|
||||
unsigned size = s.size();
|
||||
for (unsigned idx = 0; idx < size; idx++) {
|
||||
if (s.inconsistent())
|
||||
break;
|
||||
expr * curr = s.form(idx);
|
||||
m_r(curr, new_curr, new_pr);
|
||||
if (m().proofs_enabled()) {
|
||||
proof * pr = s.pr(idx);
|
||||
new_pr = m().mk_modus_ponens(pr, new_pr);
|
||||
}
|
||||
s.update(idx, new_curr, new_pr);
|
||||
}
|
||||
s.elim_redundancies();
|
||||
TRACE("after_der", s.display(tout););
|
||||
SASSERT(is_well_sorted(s));
|
||||
}
|
||||
};
|
||||
|
||||
der_strategy::der_strategy(ast_manager & m) {
|
||||
m_imp = alloc(imp, m);
|
||||
}
|
||||
|
||||
der_strategy::~der_strategy() {
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
void der_strategy::operator()(assertion_set & s) {
|
||||
m_imp->operator()(s);
|
||||
}
|
||||
|
||||
void der_strategy::set_cancel(bool f) {
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
|
||||
void der_strategy::cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m);
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
47
src/assertion_set/der_strategy.h
Normal file
47
src/assertion_set/der_strategy.h
Normal file
|
@ -0,0 +1,47 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
der_strategy.h
|
||||
|
||||
Abstract:
|
||||
|
||||
DER strategy
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-10-20
|
||||
|
||||
--*/
|
||||
#ifndef _DER_STRATEGY_H_
|
||||
#define _DER_STRATEGY_H_
|
||||
|
||||
#include"der.h"
|
||||
#include"assertion_set_strategy.h"
|
||||
|
||||
// TODO: delete obsolete class
|
||||
class der_strategy : public assertion_set_strategy {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
public:
|
||||
der_strategy(ast_manager & m);
|
||||
virtual ~der_strategy();
|
||||
|
||||
void operator()(assertion_set & s);
|
||||
|
||||
virtual void operator()(assertion_set & s, model_converter_ref & mc) {
|
||||
operator()(s);
|
||||
mc = 0;
|
||||
}
|
||||
|
||||
virtual void cleanup();
|
||||
virtual void set_cancel(bool f);
|
||||
};
|
||||
|
||||
inline as_st * mk_der(ast_manager & m) {
|
||||
return alloc(der_strategy, m);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
232
src/assertion_set/elim_distinct.cpp
Normal file
232
src/assertion_set/elim_distinct.cpp
Normal file
|
@ -0,0 +1,232 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
elim_distinct.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Replace one distinct(t0, ..., tn) with (t0 = 0 and ... and tn = n)
|
||||
when the sort of t0...tn is uninterpreted.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-04-28
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"elim_distinct.h"
|
||||
#include"assertion_set.h"
|
||||
#include"model_converter.h"
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"rewriter_def.h"
|
||||
#include"critical_flet.h"
|
||||
|
||||
struct elim_distinct::imp {
|
||||
struct mc : public model_converter {
|
||||
ast_ref_vector m_asts;
|
||||
sort * m_usort;
|
||||
obj_map<func_decl, func_decl *> m_inv_map;
|
||||
public:
|
||||
mc(ast_manager & m):m_asts(m) {
|
||||
}
|
||||
};
|
||||
|
||||
struct u2i_cfg : public default_rewriter_cfg {
|
||||
arith_util m_autil;
|
||||
ast_ref_vector m_asts;
|
||||
sort * m_usort;
|
||||
sort * m_int_sort;
|
||||
obj_map<func_decl, func_decl *> m_f2f;
|
||||
|
||||
ast_manager & m() const { return m_asts.get_manager(); }
|
||||
|
||||
bool must_remap(func_decl * f) const {
|
||||
if (f->get_range() == m_usort)
|
||||
return true;
|
||||
for (unsigned i = 0; i < f->get_arity(); i++) {
|
||||
if (f->get_domain(i) == m_usort)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
sort * remap(sort * s) {
|
||||
return (s == m_usort) ? m_int_sort : s;
|
||||
}
|
||||
|
||||
func_decl * remap(func_decl * f) {
|
||||
ptr_buffer<sort> new_domain;
|
||||
sort * new_range = remap(f->get_range());
|
||||
for (unsigned i = 0; i < f->get_arity(); i++)
|
||||
new_domain.push_back(remap(f->get_domain(i)));
|
||||
func_decl * new_f = m().mk_func_decl(f->get_name(), new_domain.size(), new_domain.c_ptr(), new_range);
|
||||
m_asts.push_back(new_f);
|
||||
m_asts.push_back(f);
|
||||
m_f2f.insert(f, new_f);
|
||||
return new_f;
|
||||
}
|
||||
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
|
||||
result_pr = 0;
|
||||
func_decl * new_f;
|
||||
if (m_f2f.find(f, new_f)) {
|
||||
result = m().mk_app(new_f, num, args);
|
||||
return BR_DONE;
|
||||
}
|
||||
|
||||
if (!must_remap(f))
|
||||
return BR_FAILED;
|
||||
|
||||
if (m().is_eq(f)) {
|
||||
result = m().mk_eq(args[0], args[1]);
|
||||
return BR_DONE;
|
||||
}
|
||||
|
||||
if (m().is_ite(f)) {
|
||||
result = m().mk_ite(args[0], args[1], args[2]);
|
||||
return BR_DONE;
|
||||
}
|
||||
|
||||
if (f->get_family_id() != null_family_id || f->get_info() != 0) {
|
||||
throw elim_distinct_exception("uninterpreted sort is used in interpreted function symbol");
|
||||
}
|
||||
|
||||
new_f = remap(f);
|
||||
result = m().mk_app(new_f, num, args);
|
||||
return BR_DONE;
|
||||
}
|
||||
|
||||
bool reduce_quantifier(quantifier * old_q,
|
||||
expr * new_body,
|
||||
expr * const * new_patterns,
|
||||
expr * const * new_no_patterns,
|
||||
expr_ref & result,
|
||||
proof_ref & result_pr) {
|
||||
throw elim_distinct_exception("elim-distinct tactic does not support quantifiers");
|
||||
}
|
||||
|
||||
u2i_cfg(ast_manager & m, sort * u):
|
||||
m_autil(m),
|
||||
m_asts(m),
|
||||
m_usort(u) {
|
||||
m_asts.push_back(u);
|
||||
m_int_sort = m_autil.mk_int();
|
||||
m_asts.push_back(m_int_sort);
|
||||
}
|
||||
};
|
||||
|
||||
class u2i : public rewriter_tpl<u2i_cfg> {
|
||||
u2i_cfg m_cfg;
|
||||
public:
|
||||
u2i(ast_manager & m, sort * u):
|
||||
rewriter_tpl<u2i_cfg>(m, false, m_cfg),
|
||||
m_cfg(m, u) {
|
||||
if (m.proofs_enabled())
|
||||
throw elim_distinct_exception("elim-distinct tactic does not support proof generation");
|
||||
}
|
||||
arith_util & autil() { return cfg().m_autil; }
|
||||
};
|
||||
|
||||
ast_manager & m_manager;
|
||||
u2i * m_u2i;
|
||||
|
||||
imp(ast_manager & m):m_manager(m), m_u2i(0) {}
|
||||
ast_manager & m() const { return m_manager; }
|
||||
|
||||
bool is_distinct(expr * t) {
|
||||
if (!m().is_distinct(t))
|
||||
return false;
|
||||
if (to_app(t)->get_num_args() == 0)
|
||||
return false;
|
||||
return m().is_uninterp(m().get_sort(to_app(t)->get_arg(0)));
|
||||
}
|
||||
|
||||
model_converter * operator()(assertion_set & s, app * d) {
|
||||
if (d && !is_distinct(d))
|
||||
d = 0;
|
||||
app * r = 0;
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * curr = s.form(i);
|
||||
if (curr == d)
|
||||
break;
|
||||
if (is_distinct(curr)) {
|
||||
if (!r || to_app(curr)->get_num_args() > r->get_num_args())
|
||||
r = to_app(curr);
|
||||
}
|
||||
}
|
||||
if (d != 0)
|
||||
r = d;
|
||||
if (r == 0)
|
||||
return 0;
|
||||
sort * u = m().get_sort(to_app(r)->get_arg(0));
|
||||
u2i conv(m(), u);
|
||||
{
|
||||
critical_flet<u2i*> l1(m_u2i, &conv);
|
||||
expr_ref new_curr(m());
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
expr * curr = s.form(i);
|
||||
if (curr == r) {
|
||||
unsigned num = r->get_num_args();
|
||||
for (unsigned j = 0; j < num; j++) {
|
||||
expr * arg = r->get_arg(j);
|
||||
conv(arg, new_curr);
|
||||
expr * eq = m().mk_eq(new_curr, conv.autil().mk_numeral(rational(j), true));
|
||||
s.assert_expr(eq);
|
||||
}
|
||||
new_curr = m().mk_true();
|
||||
}
|
||||
else {
|
||||
conv(curr, new_curr);
|
||||
}
|
||||
|
||||
s.update(i, new_curr);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: create model converter
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
// Remark: m_u2i is protected by the omp global critical section.
|
||||
// If this is a performance problem, then replace critical_flet by a custom flet that uses a different
|
||||
// section name
|
||||
#pragma omp critical (critical_flet)
|
||||
{
|
||||
if (m_u2i)
|
||||
m_u2i->cancel();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template class rewriter_tpl<elim_distinct::imp::u2i_cfg>;
|
||||
|
||||
elim_distinct::elim_distinct(ast_manager & m) {
|
||||
m_imp = alloc(imp, m);
|
||||
}
|
||||
|
||||
elim_distinct::~elim_distinct() {
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
model_converter * elim_distinct::operator()(assertion_set & s, app * d) {
|
||||
return m_imp->operator()(s, d);
|
||||
}
|
||||
|
||||
void elim_distinct::cancel() {
|
||||
m_imp->cancel();
|
||||
}
|
||||
|
||||
void elim_distinct::reset() {
|
||||
cleanup();
|
||||
}
|
||||
|
||||
void elim_distinct::cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
dealloc(m_imp);
|
||||
m_imp = alloc(imp, m);
|
||||
}
|
54
src/assertion_set/elim_distinct.h
Normal file
54
src/assertion_set/elim_distinct.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
elim_distinct.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Replace one distinct(t0, ..., tn) with (t0 = 0 and ... and tn = n)
|
||||
when the sort of t0...tn is uninterpreted.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-04-28
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ELIM_DISTINCT_H_
|
||||
#define _ELIM_DISTINCT_H_
|
||||
|
||||
#include"assertion_set.h"
|
||||
|
||||
class model_converter;
|
||||
class ast_manager;
|
||||
class assertion_set;
|
||||
|
||||
class elim_distinct_exception : public default_exception {
|
||||
public:
|
||||
elim_distinct_exception(char const * msg):default_exception(msg) {}
|
||||
};
|
||||
|
||||
class elim_distinct {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
public:
|
||||
elim_distinct(ast_manager & m);
|
||||
~elim_distinct();
|
||||
|
||||
/**
|
||||
\brief It throws an elim_distinct_exception if the strategy failed.
|
||||
If d == 0, then search for the biggest distinct(t0, ..., tn) in the assertion set.
|
||||
if d != 0, then succeed only if d is in the assertion set.
|
||||
*/
|
||||
model_converter * operator()(assertion_set & s, app * d);
|
||||
|
||||
void cancel();
|
||||
|
||||
void reset();
|
||||
void cleanup();
|
||||
};
|
||||
|
||||
#endif
|
120
src/assertion_set/elim_var_model_converter.cpp
Normal file
120
src/assertion_set/elim_var_model_converter.cpp
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
elim_var_model_converter.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Model converter that introduces eliminated variables in a model.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-05-05
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"elim_var_model_converter.h"
|
||||
#include"model_evaluator.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"model_v2_pp.h"
|
||||
#include"ast_pp.h"
|
||||
|
||||
elim_var_model_converter::~elim_var_model_converter() {
|
||||
}
|
||||
|
||||
struct elim_var_model_converter::set_eval {
|
||||
elim_var_model_converter * m_owner;
|
||||
model_evaluator * m_old;
|
||||
set_eval(elim_var_model_converter * owner, model_evaluator * ev) {
|
||||
m_owner = owner;
|
||||
m_old = owner->m_eval;
|
||||
#pragma omp critical (elim_var_model_converter)
|
||||
{
|
||||
owner->m_eval = ev;
|
||||
}
|
||||
}
|
||||
~set_eval() {
|
||||
#pragma omp critical (elim_var_model_converter)
|
||||
{
|
||||
m_owner->m_eval = m_old;
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
static void display_decls_info(std::ostream & out, model_ref & md) {
|
||||
ast_manager & m = md->get_manager();
|
||||
unsigned sz = md->get_num_decls();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
func_decl * d = md->get_decl(i);
|
||||
out << d->get_name();
|
||||
out << " (";
|
||||
for (unsigned j = 0; j < d->get_arity(); j++)
|
||||
out << mk_pp(d->get_domain(j), m);
|
||||
out << mk_pp(d->get_range(), m);
|
||||
out << ") ";
|
||||
if (d->get_info())
|
||||
out << *(d->get_info());
|
||||
out << " :id " << d->get_id() << "\n";
|
||||
}
|
||||
}
|
||||
|
||||
void elim_var_model_converter::operator()(model_ref & md) {
|
||||
TRACE("elim_var_mc", model_v2_pp(tout, *md); display_decls_info(tout, md););
|
||||
model_evaluator ev(*(md.get()));
|
||||
ev.set_model_completion(true);
|
||||
expr_ref val(m());
|
||||
{
|
||||
set_eval setter(this, &ev);
|
||||
unsigned i = m_vars.size();
|
||||
while (i > 0) {
|
||||
--i;
|
||||
expr * def = m_defs.get(i);
|
||||
ev(def, val);
|
||||
TRACE("elim_var_mc", tout << m_vars.get(i)->get_name() << " ->\n" << mk_ismt2_pp(def, m()) << "\n==>\n" << mk_ismt2_pp(val, m()) << "\n";);
|
||||
func_decl * f = m_vars.get(i);
|
||||
unsigned arity = f->get_arity();
|
||||
if (arity == 0) {
|
||||
md->register_decl(f, val);
|
||||
}
|
||||
else {
|
||||
func_interp * new_fi = alloc(func_interp, m(), arity);
|
||||
new_fi->set_else(val);
|
||||
md->register_decl(f, new_fi);
|
||||
}
|
||||
}
|
||||
}
|
||||
TRACE("elim_var_mc", model_v2_pp(tout, *md); display_decls_info(tout, md););
|
||||
}
|
||||
|
||||
void elim_var_model_converter::cancel() {
|
||||
#pragma omp critical (elim_var_model_converter)
|
||||
{
|
||||
if (m_eval)
|
||||
m_eval->cancel();
|
||||
}
|
||||
}
|
||||
|
||||
void elim_var_model_converter::display(std::ostream & out) {
|
||||
ast_manager & m = m_vars.get_manager();
|
||||
out << "(elim-var-model-converter";
|
||||
for (unsigned i = 0; i < m_vars.size(); i++) {
|
||||
out << "\n (" << m_vars.get(i)->get_name() << " ";
|
||||
unsigned indent = m_vars.get(i)->get_name().size() + 4;
|
||||
out << mk_ismt2_pp(m_defs.get(i), m, indent) << ")";
|
||||
}
|
||||
out << ")" << std::endl;
|
||||
}
|
||||
|
||||
model_converter * elim_var_model_converter::translate(ast_translation & translator) {
|
||||
elim_var_model_converter * res = alloc(elim_var_model_converter, translator.to());
|
||||
for (unsigned i = 0; i < m_vars.size(); i++)
|
||||
res->m_vars.push_back(translator(m_vars[i].get()));
|
||||
for (unsigned i = 0; i < m_defs.size(); i++)
|
||||
res->m_defs.push_back(translator(m_defs[i].get()));
|
||||
// m_eval is a transient object. So, it doesn't need to be translated.
|
||||
return res;
|
||||
}
|
56
src/assertion_set/elim_var_model_converter.h
Normal file
56
src/assertion_set/elim_var_model_converter.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
elim_var_model_converter.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Model converter that introduces eliminated variables in a model.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-05-05
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _ELIM_VAR_MODEL_CONVERTER_H_
|
||||
#define _ELIM_VAR_MODEL_CONVERTER_H_
|
||||
|
||||
#include"ast.h"
|
||||
#include"model_converter.h"
|
||||
|
||||
class model_evaluator;
|
||||
|
||||
class elim_var_model_converter : public model_converter {
|
||||
func_decl_ref_vector m_vars;
|
||||
expr_ref_vector m_defs;
|
||||
model_evaluator * m_eval;
|
||||
struct set_eval;
|
||||
public:
|
||||
elim_var_model_converter(ast_manager & m):m_vars(m), m_defs(m), m_eval(0) {
|
||||
}
|
||||
|
||||
virtual ~elim_var_model_converter();
|
||||
|
||||
ast_manager & m() const { return m_vars.get_manager(); }
|
||||
|
||||
virtual void operator()(model_ref & md);
|
||||
|
||||
virtual void cancel();
|
||||
|
||||
virtual void display(std::ostream & out);
|
||||
|
||||
// register a variable that was eliminated
|
||||
void insert(func_decl * v, expr * def) {
|
||||
m_vars.push_back(v);
|
||||
m_defs.push_back(def);
|
||||
}
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
775
src/assertion_set/gaussian_elim.cpp
Normal file
775
src/assertion_set/gaussian_elim.cpp
Normal file
|
@ -0,0 +1,775 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
gaussian_elim.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
(extended) Gaussian elimination for assertion sets.
|
||||
It also supports other theories besides arithmetic.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-29
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"gaussian_elim.h"
|
||||
#include"ast.h"
|
||||
#include"expr_replacer.h"
|
||||
#include"model_converter.h"
|
||||
#include"assertion_set.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"elim_var_model_converter.h"
|
||||
#include"occurs.h"
|
||||
#include"cooperate.h"
|
||||
#include"assertion_set_util.h"
|
||||
|
||||
struct gaussian_elim::imp {
|
||||
ast_manager & m_manager;
|
||||
expr_replacer * m_r;
|
||||
bool m_r_owner;
|
||||
arith_util m_a_util;
|
||||
obj_map<expr, unsigned> m_num_occs;
|
||||
unsigned m_num_steps;
|
||||
unsigned m_num_eliminated_vars;
|
||||
bool m_produce_models;
|
||||
bool m_theory_solver;
|
||||
bool m_ite_solver;
|
||||
unsigned m_max_occs;
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
m_produce_models = p.get_bool(":produce-models", false);
|
||||
m_ite_solver = p.get_bool(":ite-solver", true);
|
||||
m_theory_solver = p.get_bool(":theory-solver", true);
|
||||
m_max_occs = p.get_uint(":gaussian-max-occs", UINT_MAX);
|
||||
}
|
||||
|
||||
typedef elim_var_model_converter gmc;
|
||||
|
||||
expr_substitution m_subst;
|
||||
expr_substitution m_norm_subst;
|
||||
expr_sparse_mark m_candidate_vars;
|
||||
expr_sparse_mark m_candidate_set;
|
||||
ptr_vector<expr> m_candidates;
|
||||
ptr_vector<app> m_vars;
|
||||
ptr_vector<app> m_ordered_vars;
|
||||
volatile bool m_cancel;
|
||||
|
||||
imp(ast_manager & m, params_ref const & p, expr_replacer * r, bool owner):
|
||||
m_manager(m),
|
||||
m_r(r),
|
||||
m_r_owner(r == 0 || owner),
|
||||
m_a_util(m),
|
||||
m_num_steps(0),
|
||||
m_num_eliminated_vars(0),
|
||||
m_subst(m),
|
||||
m_norm_subst(m),
|
||||
m_cancel(false) {
|
||||
updt_params(p);
|
||||
if (m_r == 0)
|
||||
m_r = mk_default_expr_replacer(m);
|
||||
}
|
||||
|
||||
~imp() {
|
||||
if (m_r_owner)
|
||||
dealloc(m_r);
|
||||
}
|
||||
|
||||
ast_manager & m() const { return m_manager; }
|
||||
|
||||
bool check_occs(expr * t) const {
|
||||
if (m_max_occs == UINT_MAX)
|
||||
return true;
|
||||
unsigned num = 0;
|
||||
m_num_occs.find(t, num);
|
||||
TRACE("gaussian_check_occs", tout << mk_ismt2_pp(t, m_manager) << " num_occs: " << num << " max: " << m_max_occs << "\n";);
|
||||
return num <= m_max_occs;
|
||||
}
|
||||
|
||||
// Use: (= x def) and (= def x)
|
||||
bool trivial_solve(expr * lhs, expr * rhs, app_ref & var, expr_ref & def, proof_ref & pr) {
|
||||
if (is_uninterp_const(lhs) && !m_candidate_vars.is_marked(lhs) && !occurs(lhs, rhs) && check_occs(lhs)) {
|
||||
var = to_app(lhs);
|
||||
def = rhs;
|
||||
pr = 0;
|
||||
return true;
|
||||
}
|
||||
else if (is_uninterp_const(rhs) && !m_candidate_vars.is_marked(rhs) && !occurs(rhs, lhs) && check_occs(rhs)) {
|
||||
var = to_app(rhs);
|
||||
def = lhs;
|
||||
if (m_manager.proofs_enabled())
|
||||
pr = m().mk_commutativity(m().mk_eq(lhs, rhs));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// (ite c (= x t1) (= x t2)) --> (= x (ite c t1 t2))
|
||||
bool solve_ite_core(app * ite, expr * lhs1, expr * rhs1, expr * lhs2, expr * rhs2, app_ref & var, expr_ref & def, proof_ref & pr) {
|
||||
if (lhs1 != lhs2)
|
||||
return false;
|
||||
if (!is_uninterp_const(lhs1) || m_candidate_vars.is_marked(lhs1))
|
||||
return false;
|
||||
if (occurs(lhs1, ite->get_arg(0)) || occurs(lhs1, rhs1) || occurs(lhs1, rhs2))
|
||||
return false;
|
||||
if (!check_occs(lhs1))
|
||||
return false;
|
||||
var = to_app(lhs1);
|
||||
def = m().mk_ite(ite->get_arg(0), rhs1, rhs2);
|
||||
|
||||
if (m().proofs_enabled())
|
||||
pr = m().mk_rewrite(ite, m().mk_eq(var, def));
|
||||
return true;
|
||||
}
|
||||
|
||||
// (ite c (= x t1) (= x t2)) --> (= x (ite c t1 t2))
|
||||
bool solve_ite(app * ite, app_ref & var, expr_ref & def, proof_ref & pr) {
|
||||
expr * t = ite->get_arg(1);
|
||||
expr * e = ite->get_arg(2);
|
||||
|
||||
if (!m().is_eq(t) || !m().is_eq(e))
|
||||
return false;
|
||||
|
||||
expr * lhs1 = to_app(t)->get_arg(0);
|
||||
expr * rhs1 = to_app(t)->get_arg(1);
|
||||
expr * lhs2 = to_app(e)->get_arg(0);
|
||||
expr * rhs2 = to_app(e)->get_arg(1);
|
||||
|
||||
return
|
||||
solve_ite_core(ite, lhs1, rhs1, lhs2, rhs2, var, def, pr) ||
|
||||
solve_ite_core(ite, rhs1, lhs1, lhs2, rhs2, var, def, pr) ||
|
||||
solve_ite_core(ite, lhs1, rhs1, rhs2, lhs2, var, def, pr) ||
|
||||
solve_ite_core(ite, rhs1, lhs1, rhs2, lhs2, var, def, pr);
|
||||
}
|
||||
|
||||
bool is_pos_literal(expr * n) {
|
||||
return is_app(n) && to_app(n)->get_num_args() == 0 && to_app(n)->get_family_id() == null_family_id;
|
||||
}
|
||||
|
||||
bool is_neg_literal(expr * n) {
|
||||
if (m_manager.is_not(n))
|
||||
return is_pos_literal(to_app(n)->get_arg(0));
|
||||
return false;
|
||||
}
|
||||
|
||||
#if 0
|
||||
bool not_bool_eq(expr * f, app_ref & var, expr_ref & def, proof_ref & pr) {
|
||||
if (!m().is_not(f))
|
||||
return false;
|
||||
expr * eq = to_app(f)->get_arg(0);
|
||||
if (!m().is_eq(f))
|
||||
return false;
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
\brief Given t of the form (f s_0 ... s_n),
|
||||
return true if x occurs in some s_j for j != i
|
||||
*/
|
||||
bool occurs_except(expr * x, app * t, unsigned i) {
|
||||
unsigned num = t->get_num_args();
|
||||
for (unsigned j = 0; j < num; j++) {
|
||||
if (i != j && occurs(x, t->get_arg(j)))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool solve_arith_core(app * lhs, expr * rhs, expr * eq, app_ref & var, expr_ref & def, proof_ref & pr) {
|
||||
SASSERT(m_a_util.is_add(lhs));
|
||||
bool is_int = m_a_util.is_int(lhs);
|
||||
expr * a;
|
||||
expr * v;
|
||||
rational a_val;
|
||||
unsigned num = lhs->get_num_args();
|
||||
unsigned i;
|
||||
for (i = 0; i < num; i++) {
|
||||
expr * arg = lhs->get_arg(i);
|
||||
if (is_uninterp_const(arg) && !m_candidate_vars.is_marked(arg) && check_occs(arg) && !occurs(arg, rhs) && !occurs_except(arg, lhs, i)) {
|
||||
a_val = rational(1);
|
||||
v = arg;
|
||||
break;
|
||||
}
|
||||
else if (m_a_util.is_mul(arg, a, v) &&
|
||||
is_uninterp_const(v) && !m_candidate_vars.is_marked(v) &&
|
||||
m_a_util.is_numeral(a, a_val) &&
|
||||
!a_val.is_zero() &&
|
||||
(!is_int || a_val.is_minus_one()) &&
|
||||
check_occs(v) &&
|
||||
!occurs(v, rhs) &&
|
||||
!occurs_except(v, lhs, i)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == num)
|
||||
return false;
|
||||
var = to_app(v);
|
||||
expr_ref inv_a(m());
|
||||
if (!a_val.is_one()) {
|
||||
inv_a = m_a_util.mk_numeral(rational(1)/a_val, is_int);
|
||||
rhs = m_a_util.mk_mul(inv_a, rhs);
|
||||
}
|
||||
|
||||
ptr_buffer<expr> other_args;
|
||||
for (unsigned j = 0; j < num; j++) {
|
||||
if (i != j) {
|
||||
if (inv_a)
|
||||
other_args.push_back(m_a_util.mk_mul(inv_a, lhs->get_arg(j)));
|
||||
else
|
||||
other_args.push_back(lhs->get_arg(j));
|
||||
}
|
||||
}
|
||||
switch (other_args.size()) {
|
||||
case 0:
|
||||
def = rhs;
|
||||
break;
|
||||
case 1:
|
||||
def = m_a_util.mk_sub(rhs, other_args[0]);
|
||||
break;
|
||||
default:
|
||||
def = m_a_util.mk_sub(rhs, m_a_util.mk_add(other_args.size(), other_args.c_ptr()));
|
||||
break;
|
||||
}
|
||||
if (m().proofs_enabled()) {
|
||||
pr = m().mk_rewrite(eq, m().mk_eq(var, def));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool solve_arith(expr * lhs, expr * rhs, expr * eq, app_ref & var, expr_ref & def, proof_ref & pr) {
|
||||
return
|
||||
(m_a_util.is_add(lhs) && solve_arith_core(to_app(lhs), rhs, eq, var, def, pr)) ||
|
||||
(m_a_util.is_add(rhs) && solve_arith_core(to_app(rhs), lhs, eq, var, def, pr));
|
||||
}
|
||||
|
||||
bool solve(expr * f, app_ref & var, expr_ref & def, proof_ref & pr) {
|
||||
if (m().is_eq(f)) {
|
||||
if (trivial_solve(to_app(f)->get_arg(0), to_app(f)->get_arg(1), var, def, pr))
|
||||
return true;
|
||||
if (m_theory_solver) {
|
||||
expr * lhs = to_app(f)->get_arg(0);
|
||||
expr * rhs = to_app(f)->get_arg(1);
|
||||
if (solve_arith(lhs, rhs, f, var, def, pr))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m().is_iff(f))
|
||||
return trivial_solve(to_app(f)->get_arg(0), to_app(f)->get_arg(1), var, def, pr);
|
||||
|
||||
#if 0
|
||||
if (not_bool_eq(f, var, def, pr))
|
||||
return true;
|
||||
#endif
|
||||
|
||||
if (m_ite_solver && m().is_ite(f))
|
||||
return solve_ite(to_app(f), var, def, pr);
|
||||
|
||||
if (is_pos_literal(f)) {
|
||||
if (m_candidate_vars.is_marked(f))
|
||||
return false;
|
||||
var = to_app(f);
|
||||
def = m().mk_true();
|
||||
if (m().proofs_enabled()) {
|
||||
// [rewrite]: (iff (iff l true) l)
|
||||
// [symmetry T1]: (iff l (iff l true))
|
||||
pr = m().mk_rewrite(m().mk_eq(var, def), var);
|
||||
pr = m().mk_symmetry(pr);
|
||||
}
|
||||
TRACE("gaussian_elim_bug2", tout << "eliminating: " << mk_ismt2_pp(f, m()) << "\n";);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (is_neg_literal(f)) {
|
||||
var = to_app(to_app(f)->get_arg(0));
|
||||
if (m_candidate_vars.is_marked(var))
|
||||
return false;
|
||||
def = m().mk_false();
|
||||
if (m().proofs_enabled()) {
|
||||
// [rewrite]: (iff (iff l false) ~l)
|
||||
// [symmetry T1]: (iff ~l (iff l false))
|
||||
pr = m().mk_rewrite(m().mk_eq(var, def), f);
|
||||
pr = m().mk_symmetry(pr);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void checkpoint() {
|
||||
if (m_cancel)
|
||||
throw gaussian_elim_exception(STE_CANCELED_MSG);
|
||||
cooperate("gaussian elimination");
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Start collecting candidates
|
||||
*/
|
||||
void collect(assertion_set & set) {
|
||||
m_subst.reset();
|
||||
m_norm_subst.reset();
|
||||
m_r->set_substitution(0);
|
||||
m_candidate_vars.reset();
|
||||
m_candidate_set.reset();
|
||||
m_candidates.reset();
|
||||
m_vars.reset();
|
||||
|
||||
app_ref var(m());
|
||||
expr_ref def(m());
|
||||
proof_ref pr(m());
|
||||
unsigned size = set.size();
|
||||
for (unsigned idx = 0; idx < size; idx++) {
|
||||
checkpoint();
|
||||
expr * f = set.form(idx);
|
||||
if (solve(f, var, def, pr)) {
|
||||
m_vars.push_back(var);
|
||||
m_candidates.push_back(f);
|
||||
m_candidate_set.mark(f);
|
||||
m_candidate_vars.mark(var);
|
||||
if (m().proofs_enabled()) {
|
||||
if (pr == 0)
|
||||
pr = set.pr(idx);
|
||||
else
|
||||
pr = m().mk_modus_ponens(set.pr(idx), pr);
|
||||
}
|
||||
m_subst.insert(var, def, pr);
|
||||
}
|
||||
m_num_steps++;
|
||||
}
|
||||
|
||||
TRACE("gaussian_elim",
|
||||
tout << "candidate vars:\n";
|
||||
ptr_vector<app>::iterator it = m_vars.begin();
|
||||
ptr_vector<app>::iterator end = m_vars.end();
|
||||
for (; it != end; ++it) {
|
||||
tout << mk_ismt2_pp(*it, m()) << " ";
|
||||
}
|
||||
tout << "\n";);
|
||||
}
|
||||
|
||||
|
||||
void sort_vars() {
|
||||
SASSERT(m_candidates.size() == m_vars.size());
|
||||
TRACE("gaussian_elim_bug", tout << "sorting vars...\n";);
|
||||
m_ordered_vars.reset();
|
||||
|
||||
|
||||
// The variables (and its definitions) in m_subst must remain alive until the end of this procedure.
|
||||
// Reason: they are scheduled for unmarking in visiting/done.
|
||||
// They should remain alive while they are on the stack.
|
||||
// To make sure this is the case, whenever a variable (and its definition) is removed from m_subst,
|
||||
// I add them to the saved vector.
|
||||
|
||||
expr_ref_vector saved(m());
|
||||
|
||||
expr_fast_mark1 visiting;
|
||||
expr_fast_mark2 done;
|
||||
|
||||
typedef std::pair<expr *, unsigned> frame;
|
||||
svector<frame> todo;
|
||||
ptr_vector<app>::const_iterator it = m_vars.begin();
|
||||
ptr_vector<app>::const_iterator end = m_vars.end();
|
||||
unsigned num;
|
||||
for (; it != end; ++it) {
|
||||
checkpoint();
|
||||
app * v = *it;
|
||||
if (!m_candidate_vars.is_marked(v))
|
||||
continue;
|
||||
todo.push_back(frame(v, 0));
|
||||
while (!todo.empty()) {
|
||||
start:
|
||||
frame & fr = todo.back();
|
||||
expr * t = fr.first;
|
||||
m_num_steps++;
|
||||
TRACE("gaussian_elim_bug", tout << "processing:\n" << mk_ismt2_pp(t, m()) << "\n";);
|
||||
if (t->get_ref_count() > 1 && done.is_marked(t)) {
|
||||
todo.pop_back();
|
||||
continue;
|
||||
}
|
||||
switch (t->get_kind()) {
|
||||
case AST_VAR:
|
||||
todo.pop_back();
|
||||
break;
|
||||
case AST_QUANTIFIER:
|
||||
num = to_quantifier(t)->get_num_children();
|
||||
while (fr.second < num) {
|
||||
expr * c = to_quantifier(t)->get_child(fr.second);
|
||||
fr.second++;
|
||||
if (c->get_ref_count() > 1 && done.is_marked(c))
|
||||
continue;
|
||||
todo.push_back(frame(c, 0));
|
||||
goto start;
|
||||
}
|
||||
if (t->get_ref_count() > 1)
|
||||
done.mark(t);
|
||||
todo.pop_back();
|
||||
break;
|
||||
case AST_APP:
|
||||
num = to_app(t)->get_num_args();
|
||||
if (num == 0) {
|
||||
if (fr.second == 0) {
|
||||
if (m_candidate_vars.is_marked(t)) {
|
||||
if (visiting.is_marked(t)) {
|
||||
// cycle detected: remove t
|
||||
visiting.reset_mark(t);
|
||||
m_candidate_vars.mark(t, false);
|
||||
SASSERT(!m_candidate_vars.is_marked(t));
|
||||
|
||||
// Must save t and its definition.
|
||||
// See comment in the beginning of the function
|
||||
expr * def = 0;
|
||||
proof * pr;
|
||||
m_subst.find(to_app(t), def, pr);
|
||||
SASSERT(def != 0);
|
||||
saved.push_back(t);
|
||||
saved.push_back(def);
|
||||
//
|
||||
|
||||
m_subst.erase(t);
|
||||
}
|
||||
else {
|
||||
visiting.mark(t);
|
||||
fr.second = 1;
|
||||
expr * def = 0;
|
||||
proof * pr;
|
||||
m_subst.find(to_app(t), def, pr);
|
||||
SASSERT(def != 0);
|
||||
todo.push_back(frame(def, 0));
|
||||
goto start;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
SASSERT(fr.second == 1);
|
||||
if (m_candidate_vars.is_marked(t)) {
|
||||
visiting.reset_mark(t);
|
||||
m_ordered_vars.push_back(to_app(t));
|
||||
}
|
||||
else {
|
||||
// var was removed from the list of candidate vars to elim cycle
|
||||
// do nothing
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
while (fr.second < num) {
|
||||
expr * arg = to_app(t)->get_arg(fr.second);
|
||||
fr.second++;
|
||||
if (arg->get_ref_count() > 1 && done.is_marked(arg))
|
||||
continue;
|
||||
todo.push_back(frame(arg, 0));
|
||||
goto start;
|
||||
}
|
||||
}
|
||||
if (t->get_ref_count() > 1)
|
||||
done.mark(t);
|
||||
todo.pop_back();
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
todo.pop_back();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleanup
|
||||
it = m_vars.begin();
|
||||
for (unsigned idx = 0; it != end; ++it, ++idx) {
|
||||
if (!m_candidate_vars.is_marked(*it)) {
|
||||
m_candidate_set.mark(m_candidates[idx], false);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("gaussian_elim",
|
||||
tout << "ordered vars:\n";
|
||||
ptr_vector<app>::iterator it = m_ordered_vars.begin();
|
||||
ptr_vector<app>::iterator end = m_ordered_vars.end();
|
||||
for (; it != end; ++it) {
|
||||
SASSERT(m_candidate_vars.is_marked(*it));
|
||||
tout << mk_ismt2_pp(*it, m()) << " ";
|
||||
}
|
||||
tout << "\n";);
|
||||
m_candidate_vars.reset();
|
||||
}
|
||||
|
||||
void normalize() {
|
||||
m_norm_subst.reset();
|
||||
m_r->set_substitution(&m_norm_subst);
|
||||
|
||||
expr_ref new_def(m());
|
||||
proof_ref new_pr(m());
|
||||
unsigned size = m_ordered_vars.size();
|
||||
for (unsigned idx = 0; idx < size; idx++) {
|
||||
checkpoint();
|
||||
expr * v = m_ordered_vars[idx];
|
||||
expr * def = 0;
|
||||
proof * pr = 0;
|
||||
m_subst.find(v, def, pr);
|
||||
SASSERT(def != 0);
|
||||
m_r->operator()(def, new_def, new_pr);
|
||||
m_num_steps += m_r->get_num_steps() + 1;
|
||||
if (m().proofs_enabled())
|
||||
new_pr = m().mk_transitivity(pr, new_pr);
|
||||
m_norm_subst.insert(v, new_def, new_pr);
|
||||
// we updated the substituting, but we don't need to reset m_r
|
||||
// because all cached values there do not depend on v.
|
||||
}
|
||||
m_subst.reset();
|
||||
TRACE("gaussian_elim",
|
||||
tout << "after normalizing variables\n";
|
||||
for (unsigned i = 0; i < m_ordered_vars.size(); i++) {
|
||||
expr * v = m_ordered_vars[i];
|
||||
expr * def = 0;
|
||||
proof * pr = 0;
|
||||
m_norm_subst.find(v, def, pr);
|
||||
tout << mk_ismt2_pp(v, m()) << "\n----->\n" << mk_ismt2_pp(def, m()) << "\n\n";
|
||||
});
|
||||
#if 0
|
||||
DEBUG_CODE({
|
||||
for (unsigned i = 0; i < m_ordered_vars.size(); i++) {
|
||||
expr * v = m_ordered_vars[i];
|
||||
expr * def = 0;
|
||||
proof * pr = 0;
|
||||
m_norm_subst.find(v, def, pr);
|
||||
SASSERT(def != 0);
|
||||
CASSERT("gaussian_elim_bug", !occurs(v, def));
|
||||
}
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void substitute(assertion_set & set) {
|
||||
// force the cache of m_r to be reset.
|
||||
m_r->set_substitution(&m_norm_subst);
|
||||
|
||||
expr_ref new_f(m());
|
||||
proof_ref new_pr(m());
|
||||
unsigned size = set.size();
|
||||
for (unsigned idx = 0; idx < size; idx++) {
|
||||
checkpoint();
|
||||
expr * f = set.form(idx);
|
||||
TRACE("gaussian_leak", tout << "processing:\n" << mk_ismt2_pp(f, m()) << "\n";);
|
||||
if (m_candidate_set.is_marked(f)) {
|
||||
// f may be deleted after the following update.
|
||||
// so, we must remove remove the mark before doing the update
|
||||
m_candidate_set.mark(f, false);
|
||||
SASSERT(!m_candidate_set.is_marked(f));
|
||||
set.update(idx, m().mk_true(), m().mk_true_proof());
|
||||
m_num_steps ++;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
m_r->operator()(f, new_f, new_pr);
|
||||
}
|
||||
TRACE("gaussian_elim_subst", tout << mk_ismt2_pp(f, m()) << "\n--->\n" << mk_ismt2_pp(new_f, m()) << "\n";);
|
||||
m_num_steps += m_r->get_num_steps() + 1;
|
||||
if (m().proofs_enabled()) {
|
||||
new_pr = m().mk_modus_ponens(set.pr(idx), new_pr);
|
||||
}
|
||||
set.update(idx, new_f, new_pr);
|
||||
if (set.inconsistent())
|
||||
return;
|
||||
}
|
||||
set.elim_true();
|
||||
TRACE("gaussian_elim",
|
||||
tout << "after applying substitution\n";
|
||||
set.display(tout););
|
||||
#if 0
|
||||
DEBUG_CODE({
|
||||
for (unsigned i = 0; i < m_ordered_vars.size(); i++) {
|
||||
expr * v = m_ordered_vars[i];
|
||||
for (unsigned j = 0; j < set.size(); j++) {
|
||||
CASSERT("gaussian_elim_bug", !occurs(v, set.form(j)));
|
||||
}
|
||||
}});
|
||||
#endif
|
||||
}
|
||||
|
||||
void save_elim_vars(model_converter_ref & mc) {
|
||||
IF_VERBOSE(100, if (!m_ordered_vars.empty()) verbose_stream() << "num. eliminated vars: " << m_ordered_vars.size() << "\n";);
|
||||
m_num_eliminated_vars += m_ordered_vars.size();
|
||||
if (m_produce_models) {
|
||||
if (mc.get() == 0)
|
||||
mc = alloc(gmc, m());
|
||||
ptr_vector<app>::iterator it = m_ordered_vars.begin();
|
||||
ptr_vector<app>::iterator end = m_ordered_vars.end();
|
||||
for (; it != end; ++it) {
|
||||
app * v = *it;
|
||||
expr * def = 0;
|
||||
proof * pr;
|
||||
m_norm_subst.find(v, def, pr);
|
||||
SASSERT(def != 0);
|
||||
static_cast<gmc*>(mc.get())->insert(v->get_decl(), def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void collect_num_occs(expr * t, expr_fast_mark1 & visited) {
|
||||
ptr_buffer<expr, 128> stack;
|
||||
|
||||
#define VISIT(ARG) { \
|
||||
if (is_uninterp_const(ARG)) { \
|
||||
obj_map<expr, unsigned>::obj_map_entry * entry = m_num_occs.insert_if_not_there2(ARG, 0); \
|
||||
entry->get_data().m_value++; \
|
||||
} \
|
||||
if (!visited.is_marked(ARG)) { \
|
||||
visited.mark(ARG, true); \
|
||||
stack.push_back(ARG); \
|
||||
} \
|
||||
}
|
||||
|
||||
VISIT(t);
|
||||
|
||||
while (!stack.empty()) {
|
||||
expr * t = stack.back();
|
||||
stack.pop_back();
|
||||
if (!is_app(t))
|
||||
continue;
|
||||
unsigned j = to_app(t)->get_num_args();
|
||||
while (j > 0) {
|
||||
--j;
|
||||
expr * arg = to_app(t)->get_arg(j);
|
||||
VISIT(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void collect_num_occs(assertion_set & s) {
|
||||
if (m_max_occs == UINT_MAX)
|
||||
return; // no need to compute num occs
|
||||
m_num_occs.reset();
|
||||
expr_fast_mark1 visited;
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
collect_num_occs(s.form(i), visited);
|
||||
}
|
||||
|
||||
void operator()(assertion_set & s, model_converter_ref & mc) {
|
||||
SASSERT(is_well_sorted(s));
|
||||
as_st_report report("gaussian-elimination", s);
|
||||
TRACE("gaussian_elim", tout << "starting guassian elimination\n"; s.display(tout); tout << "\n";);
|
||||
m_num_steps = 0;
|
||||
mc = 0;
|
||||
if (s.inconsistent())
|
||||
return;
|
||||
|
||||
while (true) {
|
||||
collect_num_occs(s);
|
||||
collect(s);
|
||||
if (m_subst.empty())
|
||||
break;
|
||||
sort_vars();
|
||||
if (m_ordered_vars.empty())
|
||||
break;
|
||||
normalize();
|
||||
substitute(s);
|
||||
if (s.inconsistent()) {
|
||||
mc = 0;
|
||||
break;
|
||||
}
|
||||
save_elim_vars(mc);
|
||||
TRACE("gaussian_elim_round", s.display(tout); if (mc) mc->display(tout););
|
||||
}
|
||||
TRACE("gaussian_elim", s.display(tout););
|
||||
SASSERT(is_well_sorted(s));
|
||||
}
|
||||
|
||||
void set_cancel(bool f) {
|
||||
m_cancel = f;
|
||||
m_r->set_cancel(f);
|
||||
}
|
||||
|
||||
unsigned get_num_steps() const {
|
||||
return m_num_steps;
|
||||
}
|
||||
|
||||
unsigned get_num_eliminated_vars() const {
|
||||
return m_num_eliminated_vars;
|
||||
}
|
||||
};
|
||||
|
||||
gaussian_elim::gaussian_elim(ast_manager & m, params_ref const & p, expr_replacer * r, bool owner):
|
||||
m_params(p) {
|
||||
m_imp = alloc(imp, m, p, r, owner);
|
||||
}
|
||||
|
||||
gaussian_elim::~gaussian_elim() {
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
ast_manager & gaussian_elim::m() const {
|
||||
return m_imp->m();
|
||||
}
|
||||
|
||||
void gaussian_elim::updt_params(params_ref const & p) {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
}
|
||||
|
||||
void gaussian_elim::get_param_descrs(param_descrs & r) {
|
||||
insert_produce_models(r);
|
||||
r.insert(":gaussian-max-occs", CPK_UINT, "(default: infty) maximum number of occurrences for considering a variable for gaussian eliminations.");
|
||||
r.insert(":theory-solver", CPK_BOOL, "(default: true) use theory solvers.");
|
||||
r.insert(":ite-solver", CPK_BOOL, "(default: true) use if-then-else solver.");
|
||||
}
|
||||
|
||||
void gaussian_elim::operator()(assertion_set & s, model_converter_ref & mc) {
|
||||
m_imp->operator()(s, mc);
|
||||
report_st_progress(":num-elim-vars", get_num_eliminated_vars());
|
||||
}
|
||||
|
||||
void gaussian_elim::set_cancel(bool f) {
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
|
||||
void gaussian_elim::cleanup() {
|
||||
unsigned num_elim_vars = m_imp->m_num_eliminated_vars;
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
expr_replacer * r = m_imp->m_r_owner ? m_imp->m_r : 0;
|
||||
if (r)
|
||||
r->set_substitution(0);
|
||||
bool owner = m_imp->m_r_owner;
|
||||
m_imp->m_r_owner = false; // stole replacer
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params, r, owner);
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
m_imp->m_num_eliminated_vars = num_elim_vars;
|
||||
}
|
||||
|
||||
unsigned gaussian_elim::get_num_steps() const {
|
||||
return m_imp->get_num_steps();
|
||||
}
|
||||
|
||||
unsigned gaussian_elim::get_num_eliminated_vars() const {
|
||||
return m_imp->get_num_eliminated_vars();
|
||||
}
|
||||
|
||||
void gaussian_elim::collect_statistics(statistics & st) const {
|
||||
st.update("eliminated vars", get_num_eliminated_vars());
|
||||
}
|
||||
|
||||
void gaussian_elim::reset_statistics() {
|
||||
m_imp->m_num_eliminated_vars = 0;
|
||||
}
|
||||
|
||||
as_st * mk_gaussian(ast_manager & m, params_ref const & p) {
|
||||
return clean(alloc(gaussian_elim, m, p, mk_expr_simp_replacer(m, p), true));
|
||||
}
|
66
src/assertion_set/gaussian_elim.h
Normal file
66
src/assertion_set/gaussian_elim.h
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
gaussian_elim.h
|
||||
|
||||
Abstract:
|
||||
|
||||
(extended) Gaussian elimination for assertion sets.
|
||||
It also supports other theories besides arithmetic.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-21
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _GAUSSIAN_ELIM_H_
|
||||
#define _GAUSSIAN_ELIM_H_
|
||||
|
||||
#include"assertion_set_strategy.h"
|
||||
|
||||
class expr_replacer;
|
||||
|
||||
MK_ST_EXCEPTION(gaussian_elim_exception);
|
||||
|
||||
class gaussian_elim : public assertion_set_strategy {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
params_ref m_params;
|
||||
public:
|
||||
gaussian_elim(ast_manager & m, params_ref const & p = params_ref(), expr_replacer * r = 0, bool owner = false);
|
||||
virtual ~gaussian_elim();
|
||||
|
||||
ast_manager & m () const;
|
||||
|
||||
virtual void updt_params(params_ref const & p);
|
||||
static void get_param_descrs(param_descrs & r);
|
||||
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
|
||||
|
||||
/**
|
||||
\brief Apply gaussian elimination on the assertion set \c s.
|
||||
Return a model_converter that converts any model for the updated set into a model for the old set.
|
||||
*/
|
||||
virtual void operator()(assertion_set & s, model_converter_ref & mc);
|
||||
|
||||
virtual void cleanup();
|
||||
|
||||
unsigned get_num_steps() const;
|
||||
unsigned get_num_eliminated_vars() const;
|
||||
|
||||
virtual void collect_statistics(statistics & st) const;
|
||||
virtual void reset_statistics();
|
||||
protected:
|
||||
virtual void set_cancel(bool f);
|
||||
};
|
||||
|
||||
as_st * mk_gaussian(ast_manager & m, params_ref const & p = params_ref());
|
||||
|
||||
inline as_st * mk_eq_solver(ast_manager & m, params_ref const & p = params_ref()) {
|
||||
return mk_gaussian(m, p);
|
||||
}
|
||||
|
||||
#endif
|
29
src/assertion_set/num_occurs_assertion_set.cpp
Normal file
29
src/assertion_set/num_occurs_assertion_set.cpp
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
num_occurs_assertion_set.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
TODO: delete
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-10-20.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"num_occurs_assertion_set.h"
|
||||
#include"assertion_set.h"
|
||||
|
||||
// TODO delete
|
||||
void num_occurs_as::operator()(assertion_set const & s) {
|
||||
expr_fast_mark1 visited;
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
process(s.form(i), visited);
|
||||
}
|
||||
}
|
38
src/assertion_set/num_occurs_assertion_set.h
Normal file
38
src/assertion_set/num_occurs_assertion_set.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
num_occurs_assertion_set.h
|
||||
|
||||
Abstract:
|
||||
|
||||
TODO: delete
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2012-10-20.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _NUM_OCCURS_AS_H_
|
||||
#define _NUM_OCCURS_AS_H_
|
||||
|
||||
#include"num_occurs.h"
|
||||
|
||||
class assertion_set;
|
||||
|
||||
/**
|
||||
\brief Functor for computing the number of occurrences of each sub-expression in a expression F.
|
||||
*/
|
||||
class num_occurs_as : public num_occurs {
|
||||
public:
|
||||
num_occurs_as(bool ignore_ref_count1 = false, bool ignore_quantifiers = false):
|
||||
num_occurs(ignore_ref_count1, ignore_quantifiers) {
|
||||
}
|
||||
|
||||
void operator()(assertion_set const & s); // TODO delete
|
||||
};
|
||||
|
||||
#endif
|
521
src/assertion_set/reduce_args.cpp
Normal file
521
src/assertion_set/reduce_args.cpp
Normal file
|
@ -0,0 +1,521 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
reduce_args.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2010-04-06.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"reduce_args.h"
|
||||
#include"cooperate.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"map.h"
|
||||
#include"rewriter_def.h"
|
||||
#include"elim_var_model_converter.h"
|
||||
#include"filter_model_converter.h"
|
||||
|
||||
struct reduce_args::imp {
|
||||
ast_manager & m_manager;
|
||||
bool m_produce_models;
|
||||
volatile bool m_cancel;
|
||||
|
||||
ast_manager & m() const { return m_manager; }
|
||||
|
||||
imp(ast_manager & m, params_ref const & p):
|
||||
m_manager(m) {
|
||||
updt_params(p);
|
||||
m_cancel = false;
|
||||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
m_produce_models = p.get_bool(":produce-models", false);
|
||||
}
|
||||
|
||||
void set_cancel(bool f) {
|
||||
m_cancel = f;
|
||||
}
|
||||
|
||||
void checkpoint() {
|
||||
if (m_cancel)
|
||||
throw reduce_args_exception(STE_CANCELED_MSG);
|
||||
cooperate("reduce-args");
|
||||
}
|
||||
|
||||
struct find_non_candidates_proc {
|
||||
ast_manager & m_manager;
|
||||
obj_hashtable<func_decl> & m_non_cadidates;
|
||||
|
||||
find_non_candidates_proc(ast_manager & m, obj_hashtable<func_decl> & non_cadidates):
|
||||
m_manager(m),
|
||||
m_non_cadidates(non_cadidates) {
|
||||
}
|
||||
|
||||
void operator()(var * n) {}
|
||||
|
||||
void operator()(quantifier * n) {}
|
||||
|
||||
void operator()(app * n) {
|
||||
if (n->get_num_args() == 0)
|
||||
return; // ignore constants
|
||||
func_decl * d = n->get_decl();
|
||||
if (d->get_family_id() != null_family_id)
|
||||
return; // ignore interpreted symbols
|
||||
if (m_non_cadidates.contains(d))
|
||||
return; // it is already in the set.
|
||||
unsigned j = n->get_num_args();
|
||||
while (j > 0) {
|
||||
--j;
|
||||
if (m_manager.is_value(n->get_arg(j)))
|
||||
return;
|
||||
}
|
||||
m_non_cadidates.insert(d);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Populate the table non_cadidates with function declarations \c f
|
||||
such that there is a function application (f t1 ... tn) where t1 ... tn are not values.
|
||||
*/
|
||||
void find_non_candidates(assertion_set const & s, obj_hashtable<func_decl> & non_candidates) {
|
||||
non_candidates.reset();
|
||||
find_non_candidates_proc proc(m_manager, non_candidates);
|
||||
expr_fast_mark1 visited;
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
checkpoint();
|
||||
quick_for_each_expr(proc, visited, s.form(i));
|
||||
}
|
||||
|
||||
TRACE("reduce_args", tout << "non_candidates:\n";
|
||||
obj_hashtable<func_decl>::iterator it = non_candidates.begin();
|
||||
obj_hashtable<func_decl>::iterator end = non_candidates.end();
|
||||
for (; it != end; ++it) {
|
||||
func_decl * d = *it;
|
||||
tout << d->get_name() << "\n";
|
||||
});
|
||||
}
|
||||
|
||||
struct populate_decl2args_proc {
|
||||
ast_manager & m_manager;
|
||||
obj_hashtable<func_decl> & m_non_cadidates;
|
||||
obj_map<func_decl, bit_vector> & m_decl2args;
|
||||
|
||||
populate_decl2args_proc(ast_manager & m, obj_hashtable<func_decl> & nc, obj_map<func_decl, bit_vector> & d):
|
||||
m_manager(m), m_non_cadidates(nc), m_decl2args(d) {}
|
||||
|
||||
void operator()(var * n) {}
|
||||
void operator()(quantifier * n) {}
|
||||
void operator()(app * n) {
|
||||
if (n->get_num_args() == 0)
|
||||
return; // ignore constants
|
||||
func_decl * d = n->get_decl();
|
||||
if (d->get_family_id() != null_family_id)
|
||||
return; // ignore interpreted symbols
|
||||
if (m_non_cadidates.contains(d))
|
||||
return; // declaration is not a candidate
|
||||
unsigned j = n->get_num_args();
|
||||
obj_map<func_decl, bit_vector>::iterator it = m_decl2args.find_iterator(d);
|
||||
if (it == m_decl2args.end()) {
|
||||
m_decl2args.insert(d, bit_vector());
|
||||
it = m_decl2args.find_iterator(d);
|
||||
SASSERT(it != m_decl2args.end());
|
||||
it->m_value.reserve(j);
|
||||
while (j > 0) {
|
||||
--j;
|
||||
it->m_value.set(j, m_manager.is_value(n->get_arg(j)));
|
||||
}
|
||||
} else {
|
||||
SASSERT(j == it->m_value.size());
|
||||
while (j > 0) {
|
||||
--j;
|
||||
it->m_value.set(j, it->m_value.get(j) && m_manager.is_value(n->get_arg(j)));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void populate_decl2args(assertion_set const & s,
|
||||
obj_hashtable<func_decl> & non_candidates,
|
||||
obj_map<func_decl, bit_vector> & decl2args) {
|
||||
expr_fast_mark1 visited;
|
||||
decl2args.reset();
|
||||
populate_decl2args_proc proc(m_manager, non_candidates, decl2args);
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
checkpoint();
|
||||
quick_for_each_expr(proc, visited, s.form(i));
|
||||
}
|
||||
|
||||
// Remove all cases where the simplification is not applicable.
|
||||
ptr_buffer<func_decl> bad_decls;
|
||||
obj_map<func_decl, bit_vector>::iterator it = decl2args.begin();
|
||||
obj_map<func_decl, bit_vector>::iterator end = decl2args.end();
|
||||
for (; it != end; it++) {
|
||||
bool is_zero = true;
|
||||
for (unsigned i = 0; i < it->m_value.size() && is_zero ; i++) {
|
||||
if (it->m_value.get(i))
|
||||
is_zero = false;
|
||||
}
|
||||
if (is_zero)
|
||||
bad_decls.push_back(it->m_key);
|
||||
}
|
||||
|
||||
ptr_buffer<func_decl>::iterator it2 = bad_decls.begin();
|
||||
ptr_buffer<func_decl>::iterator end2 = bad_decls.end();
|
||||
for (; it2 != end2; ++it2)
|
||||
decl2args.erase(*it2);
|
||||
|
||||
TRACE("reduce_args", tout << "decl2args:" << std::endl;
|
||||
for (obj_map<func_decl, bit_vector>::iterator it = decl2args.begin() ; it != decl2args.end() ; it++) {
|
||||
tout << it->m_key->get_name() << ": ";
|
||||
for (unsigned i = 0 ; i < it->m_value.size() ; i++)
|
||||
tout << (it->m_value.get(i) ? "1" : "0");
|
||||
tout << std::endl;
|
||||
});
|
||||
}
|
||||
|
||||
struct arg2func_hash_proc {
|
||||
bit_vector const & m_bv;
|
||||
|
||||
arg2func_hash_proc(bit_vector const & bv):m_bv(bv) {}
|
||||
unsigned operator()(app const * n) const {
|
||||
// compute the hash-code using only the arguments where m_bv is true.
|
||||
unsigned a = 0x9e3779b9;
|
||||
unsigned num_args = n->get_num_args();
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
if (!m_bv.get(i))
|
||||
continue; // ignore argument
|
||||
a = hash_u_u(a, n->get_arg(i)->get_id());
|
||||
}
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
struct arg2func_eq_proc {
|
||||
bit_vector const & m_bv;
|
||||
|
||||
arg2func_eq_proc(bit_vector const & bv):m_bv(bv) {}
|
||||
bool operator()(app const * n1, app const * n2) const {
|
||||
// compare only the arguments where m_bv is true
|
||||
SASSERT(n1->get_num_args() == n2->get_num_args());
|
||||
unsigned num_args = n1->get_num_args();
|
||||
for (unsigned i = 0; i < num_args; i++) {
|
||||
if (!m_bv.get(i))
|
||||
continue; // ignore argument
|
||||
if (n1->get_arg(i) != n2->get_arg(i))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
typedef map<app *, func_decl *, arg2func_hash_proc, arg2func_eq_proc> arg2func;
|
||||
typedef obj_map<func_decl, arg2func *> decl2arg2func_map;
|
||||
|
||||
struct reduce_args_ctx {
|
||||
ast_manager & m_manager;
|
||||
decl2arg2func_map m_decl2arg2funcs;
|
||||
|
||||
reduce_args_ctx(ast_manager & m): m_manager(m) {
|
||||
}
|
||||
|
||||
~reduce_args_ctx() {
|
||||
obj_map<func_decl, arg2func *>::iterator it = m_decl2arg2funcs.begin();
|
||||
obj_map<func_decl, arg2func *>::iterator end = m_decl2arg2funcs.end();
|
||||
for (; it != end; ++it) {
|
||||
arg2func * map = it->m_value;
|
||||
arg2func::iterator it2 = map->begin();
|
||||
arg2func::iterator end2 = map->end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
m_manager.dec_ref(it2->m_key);
|
||||
m_manager.dec_ref(it2->m_value);
|
||||
}
|
||||
dealloc(map);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct populate_decl2arg_set_proc {
|
||||
ast_manager & m_manager;
|
||||
obj_map<func_decl, bit_vector> & m_decl2args;
|
||||
decl2arg2func_map & m_decl2arg2funcs;
|
||||
|
||||
populate_decl2arg_set_proc(ast_manager & m,
|
||||
obj_map<func_decl, bit_vector> & d,
|
||||
decl2arg2func_map & ds):
|
||||
m_manager(m), m_decl2args(d), m_decl2arg2funcs(ds) {}
|
||||
|
||||
void operator()(var * n) {}
|
||||
void operator()(quantifier * n) {}
|
||||
|
||||
void operator()(app * n) {
|
||||
if (n->get_num_args() == 0)
|
||||
return; // ignore constants
|
||||
func_decl * d = n->get_decl();
|
||||
if (d->get_family_id() != null_family_id)
|
||||
return; // ignore interpreted symbols
|
||||
obj_map<func_decl, bit_vector>::iterator it = m_decl2args.find_iterator(d);
|
||||
if (it == m_decl2args.end())
|
||||
return; // not reducing the arguments of this declaration
|
||||
bit_vector & bv = it->m_value;
|
||||
arg2func * map = 0;
|
||||
decl2arg2func_map::iterator it2 = m_decl2arg2funcs.find_iterator(d);
|
||||
if (it2 == m_decl2arg2funcs.end()) {
|
||||
map = alloc(arg2func, arg2func_hash_proc(bv), arg2func_eq_proc(bv));
|
||||
m_decl2arg2funcs.insert(d, map);
|
||||
}
|
||||
else {
|
||||
map = it2->m_value;
|
||||
}
|
||||
if (!map->contains(n)) {
|
||||
// create fresh symbol...
|
||||
ptr_buffer<sort> domain;
|
||||
unsigned arity = d->get_arity();
|
||||
for (unsigned i = 0; i < arity; i++) {
|
||||
if (!bv.get(i))
|
||||
domain.push_back(d->get_domain(i));
|
||||
}
|
||||
func_decl * new_d = m_manager.mk_fresh_func_decl(d->get_name(), symbol::null, domain.size(), domain.c_ptr(), d->get_range());
|
||||
map->insert(n, new_d);
|
||||
m_manager.inc_ref(n);
|
||||
m_manager.inc_ref(new_d);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void populate_decl2arg_set(assertion_set const & s,
|
||||
obj_map<func_decl, bit_vector> & decl2args,
|
||||
decl2arg2func_map & decl2arg2funcs) {
|
||||
expr_fast_mark1 visited;
|
||||
|
||||
populate_decl2arg_set_proc proc(m_manager, decl2args, decl2arg2funcs);
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
checkpoint();
|
||||
quick_for_each_expr(proc, visited, s.form(i));
|
||||
}
|
||||
}
|
||||
|
||||
struct reduce_args_rw_cfg : public default_rewriter_cfg {
|
||||
ast_manager & m;
|
||||
imp & m_owner;
|
||||
obj_map<func_decl, bit_vector> & m_decl2args;
|
||||
decl2arg2func_map & m_decl2arg2funcs;
|
||||
|
||||
reduce_args_rw_cfg(imp & owner, obj_map<func_decl, bit_vector> & decl2args, decl2arg2func_map & decl2arg2funcs):
|
||||
m(owner.m_manager),
|
||||
m_owner(owner),
|
||||
m_decl2args(decl2args),
|
||||
m_decl2arg2funcs(decl2arg2funcs) {
|
||||
}
|
||||
|
||||
bool max_steps_exceeded(unsigned num_steps) const {
|
||||
m_owner.checkpoint();
|
||||
return false;
|
||||
}
|
||||
|
||||
br_status reduce_app(func_decl * f, unsigned num, expr * const * args, expr_ref & result, proof_ref & result_pr) {
|
||||
result_pr = 0;
|
||||
if (f->get_arity() == 0)
|
||||
return BR_FAILED; // ignore constants
|
||||
if (f->get_family_id() != null_family_id)
|
||||
return BR_FAILED; // ignore interpreted symbols
|
||||
decl2arg2func_map::iterator it = m_decl2arg2funcs.find_iterator(f);
|
||||
if (it == m_decl2arg2funcs.end())
|
||||
return BR_FAILED;
|
||||
SASSERT(m_decl2args.contains(f));
|
||||
bit_vector & bv = m_decl2args.find(f);
|
||||
arg2func * map = it->m_value;
|
||||
app_ref tmp(m);
|
||||
tmp = m.mk_app(f, num, args);
|
||||
CTRACE("reduce_args", !map->contains(tmp),
|
||||
tout << "map does not contain tmp f: " << f->get_name() << "\n";
|
||||
tout << mk_ismt2_pp(tmp, m) << "\n";
|
||||
arg2func::iterator it = map->begin();
|
||||
arg2func::iterator end = map->end();
|
||||
for (; it != end; ++it) {
|
||||
tout << mk_ismt2_pp(it->m_key, m) << "\n---> " << it->m_value->get_name() << "\n";
|
||||
});
|
||||
SASSERT(map->contains(tmp));
|
||||
func_decl * new_f = map->find(tmp);
|
||||
ptr_buffer<expr> new_args;
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
if (!bv.get(i))
|
||||
new_args.push_back(args[i]);
|
||||
}
|
||||
result = m.mk_app(new_f, new_args.size(), new_args.c_ptr());
|
||||
return BR_DONE;
|
||||
}
|
||||
};
|
||||
|
||||
struct reduce_args_rw : rewriter_tpl<reduce_args_rw_cfg> {
|
||||
reduce_args_rw_cfg m_cfg;
|
||||
public:
|
||||
reduce_args_rw(imp & owner, obj_map<func_decl, bit_vector> & decl2args, decl2arg2func_map & decl2arg2funcs):
|
||||
rewriter_tpl<reduce_args_rw_cfg>(owner.m_manager, false, m_cfg),
|
||||
m_cfg(owner, decl2args, decl2arg2funcs) {
|
||||
}
|
||||
};
|
||||
|
||||
model_converter * mk_mc(obj_map<func_decl, bit_vector> & decl2args, decl2arg2func_map & decl2arg2funcs) {
|
||||
ptr_buffer<expr> new_args;
|
||||
var_ref_vector new_vars(m_manager);
|
||||
ptr_buffer<expr> new_eqs;
|
||||
elim_var_model_converter * e_mc = alloc(elim_var_model_converter, m_manager);
|
||||
filter_model_converter * f_mc = alloc(filter_model_converter, m_manager);
|
||||
decl2arg2func_map::iterator it = decl2arg2funcs.begin();
|
||||
decl2arg2func_map::iterator end = decl2arg2funcs.end();
|
||||
for (; it != end; ++it) {
|
||||
func_decl * f = it->m_key;
|
||||
arg2func * map = it->m_value;
|
||||
expr * def = 0;
|
||||
SASSERT(decl2args.contains(f));
|
||||
bit_vector & bv = decl2args.find(f);
|
||||
new_vars.reset();
|
||||
new_args.reset();
|
||||
for (unsigned i = 0; i < f->get_arity(); i++) {
|
||||
new_vars.push_back(m_manager.mk_var(i, f->get_domain(i)));
|
||||
if (!bv.get(i))
|
||||
new_args.push_back(new_vars.back());
|
||||
}
|
||||
arg2func::iterator it2 = map->begin();
|
||||
arg2func::iterator end2 = map->end();
|
||||
for (; it2 != end2; ++it2) {
|
||||
app * t = it2->m_key;
|
||||
func_decl * new_def = it2->m_value;
|
||||
f_mc->insert(new_def);
|
||||
SASSERT(new_def->get_arity() == new_args.size());
|
||||
app * new_t = m_manager.mk_app(new_def, new_args.size(), new_args.c_ptr());
|
||||
if (def == 0) {
|
||||
def = new_t;
|
||||
}
|
||||
else {
|
||||
new_eqs.reset();
|
||||
for (unsigned i = 0; i < f->get_arity(); i++) {
|
||||
if (bv.get(i))
|
||||
new_eqs.push_back(m_manager.mk_eq(new_vars.get(i), t->get_arg(i)));
|
||||
}
|
||||
SASSERT(new_eqs.size() > 0);
|
||||
expr * cond;
|
||||
if (new_eqs.size() == 1)
|
||||
cond = new_eqs[0];
|
||||
else
|
||||
cond = m_manager.mk_and(new_eqs.size(), new_eqs.c_ptr());
|
||||
def = m_manager.mk_ite(cond, new_t, def);
|
||||
}
|
||||
}
|
||||
SASSERT(def);
|
||||
e_mc->insert(f, def);
|
||||
}
|
||||
return concat(f_mc, e_mc);
|
||||
}
|
||||
|
||||
void operator()(assertion_set & s, model_converter_ref & mc) {
|
||||
mc = 0;
|
||||
if (s.inconsistent())
|
||||
return;
|
||||
if (m().proofs_enabled())
|
||||
throw reduce_args_exception("reduce-args does not support proofs");
|
||||
as_st_report report("reduce-args", s);
|
||||
TRACE("reduce_args", s.display(tout););
|
||||
|
||||
obj_hashtable<func_decl> non_candidates;
|
||||
obj_map<func_decl, bit_vector> decl2args;
|
||||
find_non_candidates(s, non_candidates);
|
||||
populate_decl2args(s, non_candidates, decl2args);
|
||||
|
||||
if (decl2args.empty())
|
||||
return;
|
||||
|
||||
ptr_vector<arg2func> arg2funcs;
|
||||
reduce_args_ctx ctx(m_manager);
|
||||
populate_decl2arg_set(s, decl2args, ctx.m_decl2arg2funcs);
|
||||
|
||||
reduce_args_rw rw(*this, decl2args, ctx.m_decl2arg2funcs);
|
||||
|
||||
unsigned sz = s.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (s.inconsistent())
|
||||
break;
|
||||
expr * f = s.form(i);
|
||||
expr_ref new_f(m_manager);
|
||||
rw(f, new_f);
|
||||
s.update(i, new_f);
|
||||
}
|
||||
|
||||
report_st_progress(":reduced-funcs", decl2args.size());
|
||||
|
||||
if (m_produce_models)
|
||||
mc = mk_mc(decl2args, ctx.m_decl2arg2funcs);
|
||||
|
||||
TRACE("reduce_args", s.display(tout); if (mc) mc->display(tout););
|
||||
}
|
||||
};
|
||||
|
||||
reduce_args::reduce_args(ast_manager & m, params_ref const & p):
|
||||
m_params(p) {
|
||||
m_imp = alloc(imp, m, p);
|
||||
}
|
||||
|
||||
reduce_args::~reduce_args() {
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
ast_manager & reduce_args::m() const {
|
||||
return m_imp->m();
|
||||
}
|
||||
|
||||
void reduce_args::updt_params(params_ref const & p) {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
}
|
||||
|
||||
void reduce_args::get_param_descrs(param_descrs & r) {
|
||||
insert_produce_models(r);
|
||||
}
|
||||
|
||||
void reduce_args::operator()(assertion_set & s, model_converter_ref & mc) {
|
||||
m_imp->operator()(s, mc);
|
||||
}
|
||||
|
||||
void reduce_args::set_cancel(bool f) {
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
|
||||
void reduce_args::cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
void reduce_args::collect_statistics(statistics & st) const {
|
||||
}
|
||||
|
||||
void reduce_args::reset_statistics() {
|
||||
}
|
||||
|
||||
as_st * mk_reduce_args(ast_manager & m, params_ref const & p) {
|
||||
return clean(alloc(reduce_args, m, p));
|
||||
}
|
||||
|
||||
|
92
src/assertion_set/reduce_args.h
Normal file
92
src/assertion_set/reduce_args.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
reduce_args.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2010-04-05.
|
||||
|
||||
Revision History:
|
||||
|
||||
Make it a strategy 2011-07-26.
|
||||
|
||||
--*/
|
||||
#ifndef _REDUCE_ARGS_H_
|
||||
#define _REDUCE_ARGS_H_
|
||||
|
||||
#include"assertion_set_strategy.h"
|
||||
|
||||
MK_ST_EXCEPTION(reduce_args_exception);
|
||||
|
||||
/**
|
||||
\brief Reduce the number of arguments in function applications.
|
||||
|
||||
Example, suppose we have a function f with 2 arguments.
|
||||
There are 1000 applications of this function, but the first argument is always "a", "b" or "c".
|
||||
Thus, we replace the f(t1, t2)
|
||||
with
|
||||
f_a(t2) if t1 = a
|
||||
f_b(t2) if t2 = b
|
||||
f_c(t2) if t2 = c
|
||||
|
||||
Since f_a, f_b, f_c are new symbols, satisfiability is preserved.
|
||||
|
||||
This transformation is very similar in spirit to the Ackermman's reduction.
|
||||
|
||||
This transformation should work in the following way:
|
||||
|
||||
1- Create a mapping decl2arg_map from declarations to tuples of booleans, an entry [f -> (true, false, true)]
|
||||
means that f is a declaration with 3 arguments where the first and third arguments are always values.
|
||||
2- Traverse the formula and populate the mapping.
|
||||
For each function application f(t1, ..., tn) do
|
||||
a) Create a boolean tuple (is_value(t1), ..., is_value(tn)) and do
|
||||
the logical-and with the tuple that is already in the mapping. If there is no such tuple
|
||||
in the mapping, we just add a new entry.
|
||||
|
||||
If all entries are false-tuples, then there is nothing to be done. The transformation is not applicable.
|
||||
|
||||
Now, we create a mapping decl2new_decl from (decl, val_1, ..., val_n) to decls. Note that, n may be different for each entry,
|
||||
but it is the same for the same declaration.
|
||||
For example, suppose we have [f -> (true, false, true)] in decl2arg_map, and applications f(1, a, 2), f(1, b, 2), f(1, b, 3), f(2, b, 3), f(2, c, 3) in the formula.
|
||||
Then, decl2arg_map would contain
|
||||
(f, 1, 2) -> f_1_2
|
||||
(f, 1, 3) -> f_1_3
|
||||
(f, 2, 3) -> f_2_3
|
||||
where f_1_2, f_1_3 and f_2_3 are new function symbols.
|
||||
Using the new map, we can replace the occurrences of f.
|
||||
*/
|
||||
class reduce_args : public assertion_set_strategy {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
params_ref m_params;
|
||||
public:
|
||||
reduce_args(ast_manager & m, params_ref const & p = params_ref());
|
||||
virtual ~reduce_args();
|
||||
|
||||
ast_manager & m () const;
|
||||
|
||||
virtual void updt_params(params_ref const & p);
|
||||
static void get_param_descrs(param_descrs & r);
|
||||
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
|
||||
|
||||
virtual void operator()(assertion_set & s, model_converter_ref & mc);
|
||||
|
||||
virtual void cleanup();
|
||||
|
||||
virtual void collect_statistics(statistics & st) const;
|
||||
virtual void reset_statistics();
|
||||
protected:
|
||||
virtual void set_cancel(bool f);
|
||||
};
|
||||
|
||||
as_st * mk_reduce_args(ast_manager & m, params_ref const & p = params_ref());
|
||||
|
||||
#endif /* _REDUCE_ARGS_H_ */
|
||||
|
791
src/assertion_set/sat_strategy/assertion_set2sat.cpp
Normal file
791
src/assertion_set/sat_strategy/assertion_set2sat.cpp
Normal file
|
@ -0,0 +1,791 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
assertion_set2sat.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
"Compile" an assertion set into the SAT engine.
|
||||
Atoms are "abstracted" into boolean variables.
|
||||
The mapping between boolean variables and atoms
|
||||
can be used to convert back the state of the
|
||||
SAT engine into an assertion set.
|
||||
|
||||
The idea is to support scenarios such as:
|
||||
1) simplify, blast, convert into SAT, and solve
|
||||
2) convert into SAT, apply SAT for a while, learn new units, and translate back into an assertion set.
|
||||
3) convert into SAT, apply SAT preprocessor (failed literal propagation, resolution, etc) and translate back into an assertion set.
|
||||
4) Convert boolean structure into SAT, convert atoms into another engine, combine engines using lazy combination, solve.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-05-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"assertion_set2sat.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"ref_util.h"
|
||||
#include"cooperate.h"
|
||||
#include"filter_model_converter.h"
|
||||
#include"model_evaluator.h"
|
||||
#include"for_each_expr.h"
|
||||
#include"model_v2_pp.h"
|
||||
#include"assertion_set_util.h"
|
||||
|
||||
struct assertion_set2sat::imp {
|
||||
struct frame {
|
||||
app * m_t;
|
||||
unsigned m_root:1;
|
||||
unsigned m_sign:1;
|
||||
unsigned m_idx;
|
||||
frame(app * t, bool r, bool s, unsigned idx):
|
||||
m_t(t), m_root(r), m_sign(s), m_idx(idx) {}
|
||||
};
|
||||
ast_manager & m;
|
||||
svector<frame> m_frame_stack;
|
||||
svector<sat::literal> m_result_stack;
|
||||
obj_map<app, sat::literal> m_cache;
|
||||
obj_hashtable<expr> m_interface_vars;
|
||||
sat::solver & m_solver;
|
||||
atom2bool_var & m_map;
|
||||
sat::bool_var m_true;
|
||||
bool m_ite_extra;
|
||||
unsigned long long m_max_memory;
|
||||
volatile bool m_cancel;
|
||||
|
||||
imp(ast_manager & _m, params_ref const & p, sat::solver & s, atom2bool_var & map):
|
||||
m(_m),
|
||||
m_solver(s),
|
||||
m_map(map) {
|
||||
updt_params(p);
|
||||
m_cancel = false;
|
||||
m_true = sat::null_bool_var;
|
||||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
m_ite_extra = p.get_bool(":ite-extra", true);
|
||||
m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
|
||||
}
|
||||
|
||||
void throw_op_not_handled() {
|
||||
throw assertion_set2sat_exception("operator not supported, apply simplifier before invoking translator");
|
||||
}
|
||||
|
||||
void mk_clause(sat::literal l) {
|
||||
TRACE("assertion_set2sat", tout << "mk_clause: " << l << "\n";);
|
||||
m_solver.mk_clause(1, &l);
|
||||
}
|
||||
|
||||
void mk_clause(sat::literal l1, sat::literal l2) {
|
||||
TRACE("assertion_set2sat", tout << "mk_clause: " << l1 << " " << l2 << "\n";);
|
||||
m_solver.mk_clause(l1, l2);
|
||||
}
|
||||
|
||||
void mk_clause(sat::literal l1, sat::literal l2, sat::literal l3) {
|
||||
TRACE("assertion_set2sat", tout << "mk_clause: " << l1 << " " << l2 << " " << l3 << "\n";);
|
||||
m_solver.mk_clause(l1, l2, l3);
|
||||
}
|
||||
|
||||
void mk_clause(unsigned num, sat::literal * lits) {
|
||||
TRACE("assertion_set2sat", tout << "mk_clause: "; for (unsigned i = 0; i < num; i++) tout << lits[i] << " "; tout << "\n";);
|
||||
m_solver.mk_clause(num, lits);
|
||||
}
|
||||
|
||||
sat::bool_var mk_true() {
|
||||
// create fake variable to represent true;
|
||||
if (m_true == sat::null_bool_var) {
|
||||
m_true = m_solver.mk_var();
|
||||
mk_clause(sat::literal(m_true, false)); // v is true
|
||||
}
|
||||
return m_true;
|
||||
}
|
||||
|
||||
void convert_atom(expr * t, bool root, bool sign) {
|
||||
SASSERT(m.is_bool(t));
|
||||
sat::literal l;
|
||||
sat::bool_var v = m_map.to_bool_var(t);
|
||||
if (v == sat::null_bool_var) {
|
||||
if (m.is_true(t)) {
|
||||
l = sat::literal(mk_true(), sign);
|
||||
}
|
||||
else if (m.is_false(t)) {
|
||||
l = sat::literal(mk_true(), !sign);
|
||||
}
|
||||
else {
|
||||
bool ext = !is_uninterp_const(t) || m_interface_vars.contains(t);
|
||||
sat::bool_var v = m_solver.mk_var(ext);
|
||||
m_map.insert(t, v);
|
||||
l = sat::literal(v, sign);
|
||||
TRACE("assertion_set2sat", tout << "new_var: " << v << "\n" << mk_ismt2_pp(t, m) << "\n";);
|
||||
}
|
||||
}
|
||||
else {
|
||||
SASSERT(v != sat::null_bool_var);
|
||||
l = sat::literal(v, sign);
|
||||
}
|
||||
SASSERT(l != sat::null_literal);
|
||||
if (root)
|
||||
mk_clause(l);
|
||||
else
|
||||
m_result_stack.push_back(l);
|
||||
}
|
||||
|
||||
bool process_cached(app * t, bool root, bool sign) {
|
||||
sat::literal l;
|
||||
if (m_cache.find(t, l)) {
|
||||
if (sign)
|
||||
l.neg();
|
||||
if (root)
|
||||
mk_clause(l);
|
||||
else
|
||||
m_result_stack.push_back(l);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool visit(expr * t, bool root, bool sign) {
|
||||
if (!is_app(t)) {
|
||||
convert_atom(t, root, sign);
|
||||
return true;
|
||||
}
|
||||
if (process_cached(to_app(t), root, sign))
|
||||
return true;
|
||||
if (to_app(t)->get_family_id() != m.get_basic_family_id()) {
|
||||
convert_atom(t, root, sign);
|
||||
return true;
|
||||
}
|
||||
switch (to_app(t)->get_decl_kind()) {
|
||||
case OP_NOT:
|
||||
case OP_OR:
|
||||
case OP_IFF:
|
||||
m_frame_stack.push_back(frame(to_app(t), root, sign, 0));
|
||||
return false;
|
||||
case OP_ITE:
|
||||
case OP_EQ:
|
||||
if (m.is_bool(to_app(t)->get_arg(1))) {
|
||||
m_frame_stack.push_back(frame(to_app(t), root, sign, 0));
|
||||
return false;
|
||||
}
|
||||
convert_atom(t, root, sign);
|
||||
return true;
|
||||
case OP_AND:
|
||||
case OP_XOR:
|
||||
case OP_IMPLIES:
|
||||
case OP_DISTINCT:
|
||||
TRACE("assertion_set2sat_not_handled", tout << mk_ismt2_pp(t, m) << "\n";);
|
||||
throw_op_not_handled();
|
||||
default:
|
||||
convert_atom(t, root, sign);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void convert_or(app * t, bool root, bool sign) {
|
||||
TRACE("assertion_set2sat", tout << "convert_or:\n" << mk_ismt2_pp(t, m) << "\n";);
|
||||
unsigned num = t->get_num_args();
|
||||
if (root) {
|
||||
SASSERT(num == m_result_stack.size());
|
||||
if (sign) {
|
||||
// this case should not really happen.
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
sat::literal l = m_result_stack[i];
|
||||
l.neg();
|
||||
mk_clause(l);
|
||||
}
|
||||
}
|
||||
else {
|
||||
mk_clause(m_result_stack.size(), m_result_stack.c_ptr());
|
||||
m_result_stack.reset();
|
||||
}
|
||||
}
|
||||
else {
|
||||
SASSERT(num <= m_result_stack.size());
|
||||
sat::bool_var k = m_solver.mk_var();
|
||||
sat::literal l(k, false);
|
||||
m_cache.insert(t, l);
|
||||
sat::literal * lits = m_result_stack.end() - num;
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
mk_clause(~lits[i], l);
|
||||
}
|
||||
m_result_stack.push_back(~l);
|
||||
lits = m_result_stack.end() - num - 1;
|
||||
// remark: mk_clause may perform destructive updated to lits.
|
||||
// I have to execute it after the binary mk_clause above.
|
||||
mk_clause(num+1, lits);
|
||||
unsigned old_sz = m_result_stack.size() - num - 1;
|
||||
m_result_stack.shrink(old_sz);
|
||||
if (sign)
|
||||
l.neg();
|
||||
m_result_stack.push_back(l);
|
||||
}
|
||||
}
|
||||
|
||||
void convert_ite(app * n, bool root, bool sign) {
|
||||
unsigned sz = m_result_stack.size();
|
||||
SASSERT(sz >= 3);
|
||||
sat::literal c = m_result_stack[sz-3];
|
||||
sat::literal t = m_result_stack[sz-2];
|
||||
sat::literal e = m_result_stack[sz-1];
|
||||
if (root) {
|
||||
SASSERT(sz == 3);
|
||||
if (sign) {
|
||||
mk_clause(~c, ~t);
|
||||
mk_clause(c, ~e);
|
||||
}
|
||||
else {
|
||||
mk_clause(~c, t);
|
||||
mk_clause(c, e);
|
||||
}
|
||||
m_result_stack.reset();
|
||||
}
|
||||
else {
|
||||
sat::bool_var k = m_solver.mk_var();
|
||||
sat::literal l(k, false);
|
||||
m_cache.insert(n, l);
|
||||
mk_clause(~l, ~c, t);
|
||||
mk_clause(~l, c, e);
|
||||
mk_clause(l, ~c, ~t);
|
||||
mk_clause(l, c, ~e);
|
||||
if (m_ite_extra) {
|
||||
mk_clause(~t, ~e, l);
|
||||
mk_clause(t, e, ~l);
|
||||
}
|
||||
m_result_stack.shrink(sz-3);
|
||||
if (sign)
|
||||
l.neg();
|
||||
m_result_stack.push_back(l);
|
||||
}
|
||||
}
|
||||
|
||||
void convert_iff(app * t, bool root, bool sign) {
|
||||
TRACE("assertion_set2sat", tout << "convert_iff " << root << " " << sign << "\n" << mk_ismt2_pp(t, m) << "\n";);
|
||||
unsigned sz = m_result_stack.size();
|
||||
SASSERT(sz >= 2);
|
||||
sat::literal l1 = m_result_stack[sz-1];
|
||||
sat::literal l2 = m_result_stack[sz-2];
|
||||
if (root) {
|
||||
SASSERT(sz == 2);
|
||||
if (sign) {
|
||||
mk_clause(l1, l2);
|
||||
mk_clause(~l1, ~l2);
|
||||
}
|
||||
else {
|
||||
mk_clause(l1, ~l2);
|
||||
mk_clause(~l1, l2);
|
||||
}
|
||||
m_result_stack.reset();
|
||||
}
|
||||
else {
|
||||
sat::bool_var k = m_solver.mk_var();
|
||||
sat::literal l(k, false);
|
||||
m_cache.insert(t, l);
|
||||
mk_clause(~l, l1, ~l2);
|
||||
mk_clause(~l, ~l1, l2);
|
||||
mk_clause(l, l1, l2);
|
||||
mk_clause(l, ~l1, ~l2);
|
||||
m_result_stack.shrink(sz-2);
|
||||
if (sign)
|
||||
l.neg();
|
||||
m_result_stack.push_back(l);
|
||||
}
|
||||
}
|
||||
|
||||
void convert(app * t, bool root, bool sign) {
|
||||
SASSERT(t->get_family_id() == m.get_basic_family_id());
|
||||
switch (to_app(t)->get_decl_kind()) {
|
||||
case OP_OR:
|
||||
convert_or(t, root, sign);
|
||||
break;
|
||||
case OP_ITE:
|
||||
convert_ite(t, root, sign);
|
||||
break;
|
||||
case OP_IFF:
|
||||
case OP_EQ:
|
||||
convert_iff(t, root, sign);
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void process(expr * n) {
|
||||
TRACE("assertion_set2sat", tout << "converting: " << mk_ismt2_pp(n, m) << "\n";);
|
||||
if (visit(n, true, false)) {
|
||||
SASSERT(m_result_stack.empty());
|
||||
return;
|
||||
}
|
||||
while (!m_frame_stack.empty()) {
|
||||
loop:
|
||||
cooperate("assertion_set2sat");
|
||||
if (m_cancel)
|
||||
throw assertion_set2sat_exception(STE_CANCELED_MSG);
|
||||
if (memory::get_allocation_size() > m_max_memory)
|
||||
throw assertion_set2sat_exception(STE_MAX_MEMORY_MSG);
|
||||
frame & fr = m_frame_stack.back();
|
||||
app * t = fr.m_t;
|
||||
bool root = fr.m_root;
|
||||
bool sign = fr.m_sign;
|
||||
TRACE("assertion_set2sat_bug", tout << "result stack\n";
|
||||
tout << mk_ismt2_pp(t, m) << " root: " << root << " sign: " << sign << "\n";
|
||||
for (unsigned i = 0; i < m_result_stack.size(); i++) tout << m_result_stack[i] << " ";
|
||||
tout << "\n";);
|
||||
if (fr.m_idx == 0 && process_cached(t, root, sign)) {
|
||||
m_frame_stack.pop_back();
|
||||
continue;
|
||||
}
|
||||
if (m.is_not(t)) {
|
||||
m_frame_stack.pop_back();
|
||||
visit(t->get_arg(0), root, !sign);
|
||||
continue;
|
||||
}
|
||||
unsigned num = t->get_num_args();
|
||||
while (fr.m_idx < num) {
|
||||
expr * arg = t->get_arg(fr.m_idx);
|
||||
fr.m_idx++;
|
||||
if (!visit(arg, false, false))
|
||||
goto loop;
|
||||
}
|
||||
TRACE("assertion_set2sat_bug", tout << "converting\n";
|
||||
tout << mk_ismt2_pp(t, m) << " root: " << root << " sign: " << sign << "\n";
|
||||
for (unsigned i = 0; i < m_result_stack.size(); i++) tout << m_result_stack[i] << " ";
|
||||
tout << "\n";);
|
||||
convert(t, root, sign);
|
||||
m_frame_stack.pop_back();
|
||||
}
|
||||
SASSERT(m_result_stack.empty());
|
||||
}
|
||||
|
||||
|
||||
void operator()(assertion_set const & s) {
|
||||
m_interface_vars.reset();
|
||||
collect_boolean_interface(s, m_interface_vars);
|
||||
|
||||
unsigned size = s.size();
|
||||
for (unsigned idx = 0; idx < size; idx++) {
|
||||
expr * f = s.form(idx);
|
||||
process(f);
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(unsigned sz, expr * const * fs) {
|
||||
m_interface_vars.reset();
|
||||
collect_boolean_interface(m, sz, fs, m_interface_vars);
|
||||
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
process(fs[i]);
|
||||
}
|
||||
|
||||
void set_cancel(bool f) { m_cancel = f; }
|
||||
};
|
||||
|
||||
struct unsupported_bool_proc {
|
||||
struct found {};
|
||||
ast_manager & m;
|
||||
unsupported_bool_proc(ast_manager & _m):m(_m) {}
|
||||
void operator()(var *) {}
|
||||
void operator()(quantifier *) {}
|
||||
void operator()(app * n) {
|
||||
if (n->get_family_id() == m.get_basic_family_id()) {
|
||||
switch (n->get_decl_kind()) {
|
||||
case OP_AND:
|
||||
case OP_XOR:
|
||||
case OP_IMPLIES:
|
||||
case OP_DISTINCT:
|
||||
throw found();
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
\brief Return true if s contains an unsupported Boolean operator.
|
||||
assertion_set_rewriter (with the following configuration) can be used to
|
||||
eliminate unsupported operators.
|
||||
:elim-and true
|
||||
:blast-distinct true
|
||||
*/
|
||||
bool assertion_set2sat::has_unsupported_bool(assertion_set const & s) {
|
||||
return test<unsupported_bool_proc>(s);
|
||||
}
|
||||
|
||||
assertion_set2sat::assertion_set2sat():m_imp(0) {
|
||||
}
|
||||
|
||||
void assertion_set2sat::collect_param_descrs(param_descrs & r) {
|
||||
insert_max_memory(r);
|
||||
r.insert(":ite-extra", CPK_BOOL, "(default: true) add redundant clauses (that improve unit propagation) when encoding if-then-else formulas");
|
||||
}
|
||||
|
||||
struct assertion_set2sat::scoped_set_imp {
|
||||
assertion_set2sat * m_owner;
|
||||
scoped_set_imp(assertion_set2sat * o, assertion_set2sat::imp * i):m_owner(o) {
|
||||
#pragma omp critical (assertion_set2sat)
|
||||
{
|
||||
m_owner->m_imp = i;
|
||||
}
|
||||
}
|
||||
~scoped_set_imp() {
|
||||
#pragma omp critical (assertion_set2sat)
|
||||
{
|
||||
m_owner->m_imp = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void assertion_set2sat::operator()(assertion_set const & s, params_ref const & p, sat::solver & t, atom2bool_var & m) {
|
||||
imp proc(s.m(), p, t, m);
|
||||
scoped_set_imp set(this, &proc);
|
||||
proc(s);
|
||||
}
|
||||
|
||||
void assertion_set2sat::operator()(ast_manager & mng, unsigned num, expr * const * fs, params_ref const & p, sat::solver & t, atom2bool_var & m) {
|
||||
imp proc(mng, p, t, m);
|
||||
scoped_set_imp set(this, &proc);
|
||||
proc(num, fs);
|
||||
}
|
||||
|
||||
void assertion_set2sat::set_cancel(bool f) {
|
||||
#pragma omp critical (assertion_set2sat)
|
||||
{
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
}
|
||||
|
||||
class sat_model_converter : public model_converter {
|
||||
sat::model_converter m_mc;
|
||||
// TODO: the following mapping is storing a lot of useless information, and may be a performance bottleneck.
|
||||
// We need to save only the expressions associated with variables that occur in m_mc.
|
||||
// This information may be stored as a vector of pairs.
|
||||
// The mapping is only created during the model conversion.
|
||||
expr_ref_vector m_var2expr;
|
||||
ref<filter_model_converter> m_fmc; // filter for eliminating fresh variables introduced in the assertion-set --> sat conversion
|
||||
|
||||
sat_model_converter(ast_manager & m):
|
||||
m_var2expr(m) {
|
||||
}
|
||||
|
||||
public:
|
||||
sat_model_converter(ast_manager & m, sat::solver const & s):m_var2expr(m) {
|
||||
m_mc.copy(s.get_model_converter());
|
||||
m_fmc = alloc(filter_model_converter, m);
|
||||
}
|
||||
|
||||
ast_manager & m() { return m_var2expr.get_manager(); }
|
||||
|
||||
void insert(expr * atom, bool aux) {
|
||||
m_var2expr.push_back(atom);
|
||||
if (aux) {
|
||||
SASSERT(is_uninterp_const(atom));
|
||||
SASSERT(m().is_bool(atom));
|
||||
m_fmc->insert(to_app(atom)->get_decl());
|
||||
}
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & md) {
|
||||
TRACE("sat_mc", tout << "before sat_mc\n"; model_v2_pp(tout, *md); display(tout););
|
||||
// REMARK: potential problem
|
||||
// model_evaluator can't evaluate quantifiers. Then,
|
||||
// an eliminated variable that depends on a quantified expression can't be recovered.
|
||||
// A similar problem also affects any model_converter that uses elim_var_model_converter.
|
||||
//
|
||||
// Possible solution:
|
||||
// model_converters reject any variable elimination that depends on a quantified expression.
|
||||
|
||||
model_evaluator ev(*md);
|
||||
ev.set_model_completion(false);
|
||||
|
||||
// create a SAT model using md
|
||||
sat::model sat_md;
|
||||
unsigned sz = m_var2expr.size();
|
||||
expr_ref val(m());
|
||||
for (sat::bool_var v = 0; v < sz; v++) {
|
||||
expr * atom = m_var2expr.get(v);
|
||||
ev(atom, val);
|
||||
if (m().is_true(val))
|
||||
sat_md.push_back(l_true);
|
||||
else if (m().is_false(val))
|
||||
sat_md.push_back(l_false);
|
||||
else
|
||||
sat_md.push_back(l_undef);
|
||||
}
|
||||
|
||||
// apply SAT model converter
|
||||
m_mc(sat_md);
|
||||
|
||||
// register value of non-auxiliary boolean variables back into md
|
||||
sz = m_var2expr.size();
|
||||
for (sat::bool_var v = 0; v < sz; v++) {
|
||||
expr * atom = m_var2expr.get(v);
|
||||
if (is_uninterp_const(atom)) {
|
||||
func_decl * d = to_app(atom)->get_decl();
|
||||
lbool new_val = sat_md[v];
|
||||
if (new_val == l_true)
|
||||
md->register_decl(d, m().mk_true());
|
||||
else if (new_val == l_false)
|
||||
md->register_decl(d, m().mk_false());
|
||||
}
|
||||
}
|
||||
|
||||
// apply filter model converter
|
||||
(*m_fmc)(md);
|
||||
TRACE("sat_mc", tout << "after sat_mc\n"; model_v2_pp(tout, *md););
|
||||
}
|
||||
|
||||
virtual model_converter * translate(ast_translation & translator) {
|
||||
sat_model_converter * res = alloc(sat_model_converter, translator.to());
|
||||
res->m_fmc = static_cast<filter_model_converter*>(m_fmc->translate(translator));
|
||||
unsigned sz = m_var2expr.size();
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
res->m_var2expr.push_back(translator(m_var2expr.get(i)));
|
||||
return res;
|
||||
}
|
||||
|
||||
void display(std::ostream & out) {
|
||||
out << "(sat-model-converter\n";
|
||||
m_mc.display(out);
|
||||
sat::bool_var_set vars;
|
||||
m_mc.collect_vars(vars);
|
||||
out << "(atoms";
|
||||
unsigned sz = m_var2expr.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (vars.contains(i)) {
|
||||
out << "\n (" << i << "\n " << mk_ismt2_pp(m_var2expr.get(i), m(), 2) << ")";
|
||||
}
|
||||
}
|
||||
out << ")\n";
|
||||
m_fmc->display(out);
|
||||
out << ")\n";
|
||||
}
|
||||
};
|
||||
|
||||
struct sat2assertion_set::imp {
|
||||
ast_manager & m;
|
||||
expr_ref_vector m_lit2expr;
|
||||
unsigned long long m_max_memory;
|
||||
bool m_learned;
|
||||
bool m_produce_models;
|
||||
volatile bool m_cancel;
|
||||
|
||||
imp(ast_manager & _m, params_ref const & p):m(_m), m_lit2expr(m), m_cancel(false) {
|
||||
updt_params(p);
|
||||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
m_produce_models = p.get_bool(":produce-models", false);
|
||||
m_learned = p.get_bool(":learned", false);
|
||||
m_max_memory = megabytes_to_bytes(p.get_uint(":max-memory", UINT_MAX));
|
||||
}
|
||||
|
||||
void checkpoint() {
|
||||
if (m_cancel)
|
||||
throw sat2assertion_set_exception(STE_CANCELED_MSG);
|
||||
if (memory::get_allocation_size() > m_max_memory)
|
||||
throw sat2assertion_set_exception(STE_MAX_MEMORY_MSG);
|
||||
}
|
||||
|
||||
void init_lit2expr(sat::solver const & s, atom2bool_var const & map, model_converter_ref & mc) {
|
||||
ref<sat_model_converter> _mc;
|
||||
if (m_produce_models) {
|
||||
_mc = alloc(sat_model_converter, m, s);
|
||||
}
|
||||
unsigned num_vars = s.num_vars();
|
||||
m_lit2expr.resize(num_vars * 2);
|
||||
map.mk_inv(m_lit2expr);
|
||||
sort * b = m.mk_bool_sort();
|
||||
for (sat::bool_var v = 0; v < num_vars; v++) {
|
||||
checkpoint();
|
||||
sat::literal l(v, false);
|
||||
if (m_lit2expr.get(l.index()) == 0) {
|
||||
SASSERT(m_lit2expr.get((~l).index()) == 0);
|
||||
app * aux = m.mk_fresh_const(0, b);
|
||||
if (_mc)
|
||||
_mc->insert(aux, true);
|
||||
m_lit2expr.set(l.index(), aux);
|
||||
m_lit2expr.set((~l).index(), m.mk_not(aux));
|
||||
}
|
||||
else {
|
||||
if (_mc)
|
||||
_mc->insert(m_lit2expr.get(l.index()), false);
|
||||
SASSERT(m_lit2expr.get((~l).index()) != 0);
|
||||
}
|
||||
}
|
||||
mc = _mc.get();
|
||||
}
|
||||
|
||||
expr * lit2expr(sat::literal l) {
|
||||
return m_lit2expr.get(l.index());
|
||||
}
|
||||
|
||||
void assert_clauses(sat::clause * const * begin, sat::clause * const * end, assertion_set & r) {
|
||||
ptr_buffer<expr> lits;
|
||||
for (sat::clause * const * it = begin; it != end; it++) {
|
||||
checkpoint();
|
||||
lits.reset();
|
||||
sat::clause const & c = *(*it);
|
||||
unsigned sz = c.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
lits.push_back(lit2expr(c[i]));
|
||||
}
|
||||
r.assert_expr(m.mk_or(lits.size(), lits.c_ptr()));
|
||||
}
|
||||
}
|
||||
|
||||
void operator()(sat::solver const & s, atom2bool_var const & map, assertion_set & r, model_converter_ref & mc) {
|
||||
if (s.inconsistent()) {
|
||||
r.assert_expr(m.mk_false());
|
||||
return;
|
||||
}
|
||||
init_lit2expr(s, map, mc);
|
||||
// collect units
|
||||
unsigned num_vars = s.num_vars();
|
||||
for (sat::bool_var v = 0; v < num_vars; v++) {
|
||||
checkpoint();
|
||||
switch (s.value(v)) {
|
||||
case l_true:
|
||||
r.assert_expr(lit2expr(sat::literal(v, false)));
|
||||
break;
|
||||
case l_false:
|
||||
r.assert_expr(lit2expr(sat::literal(v, true)));
|
||||
break;
|
||||
case l_undef:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// collect binary clauses
|
||||
svector<sat::solver::bin_clause> bin_clauses;
|
||||
s.collect_bin_clauses(bin_clauses, m_learned);
|
||||
svector<sat::solver::bin_clause>::iterator it = bin_clauses.begin();
|
||||
svector<sat::solver::bin_clause>::iterator end = bin_clauses.end();
|
||||
for (; it != end; ++it) {
|
||||
checkpoint();
|
||||
r.assert_expr(m.mk_or(lit2expr(it->first), lit2expr(it->second)));
|
||||
}
|
||||
// collect clauses
|
||||
assert_clauses(s.begin_clauses(), s.end_clauses(), r);
|
||||
if (m_learned)
|
||||
assert_clauses(s.begin_learned(), s.end_learned(), r);
|
||||
}
|
||||
|
||||
void set_cancel(bool f) { m_cancel = f; }
|
||||
};
|
||||
|
||||
sat2assertion_set::sat2assertion_set():m_imp(0) {
|
||||
}
|
||||
|
||||
void sat2assertion_set::collect_param_descrs(param_descrs & r) {
|
||||
insert_max_memory(r);
|
||||
r.insert(":learned", CPK_BOOL, "(default: false) collect also learned clauses.");
|
||||
}
|
||||
|
||||
struct sat2assertion_set::scoped_set_imp {
|
||||
sat2assertion_set * m_owner;
|
||||
scoped_set_imp(sat2assertion_set * o, sat2assertion_set::imp * i):m_owner(o) {
|
||||
#pragma omp critical (sat2assertion_set)
|
||||
{
|
||||
m_owner->m_imp = i;
|
||||
}
|
||||
}
|
||||
~scoped_set_imp() {
|
||||
#pragma omp critical (sat2assertion_set)
|
||||
{
|
||||
m_owner->m_imp = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void sat2assertion_set::operator()(sat::solver const & t, atom2bool_var const & m, params_ref const & p,
|
||||
assertion_set & s, model_converter_ref & mc) {
|
||||
imp proc(s.m(), p);
|
||||
scoped_set_imp set(this, &proc);
|
||||
proc(t, m, s, mc);
|
||||
}
|
||||
|
||||
void sat2assertion_set::set_cancel(bool f) {
|
||||
#pragma omp critical (sat2assertion_set)
|
||||
{
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
}
|
||||
|
||||
// HACK introduced during code reorg.
|
||||
// NOTE: the whole file will be deleted.
|
||||
struct collect_boolean_interface_proc2 {
|
||||
struct visitor {
|
||||
obj_hashtable<expr> & m_r;
|
||||
visitor(obj_hashtable<expr> & r):m_r(r) {}
|
||||
void operator()(var * n) {}
|
||||
void operator()(app * n) { if (is_uninterp_const(n)) m_r.insert(n); }
|
||||
void operator()(quantifier * n) {}
|
||||
};
|
||||
|
||||
ast_manager & m;
|
||||
expr_fast_mark2 fvisited;
|
||||
expr_fast_mark1 tvisited;
|
||||
ptr_vector<expr> todo;
|
||||
visitor proc;
|
||||
|
||||
collect_boolean_interface_proc2(ast_manager & _m, obj_hashtable<expr> & r):
|
||||
m(_m),
|
||||
proc(r) {
|
||||
}
|
||||
|
||||
void process(expr * f) {
|
||||
if (fvisited.is_marked(f))
|
||||
return;
|
||||
fvisited.mark(f);
|
||||
todo.push_back(f);
|
||||
while (!todo.empty()) {
|
||||
expr * t = todo.back();
|
||||
todo.pop_back();
|
||||
if (is_uninterp_const(t))
|
||||
continue;
|
||||
if (is_app(t) && to_app(t)->get_family_id() == m.get_basic_family_id() && to_app(t)->get_num_args() > 0) {
|
||||
decl_kind k = to_app(t)->get_decl_kind();
|
||||
if (k == OP_OR || k == OP_NOT || k == OP_IFF || ((k == OP_EQ || k == OP_ITE) && m.is_bool(to_app(t)->get_arg(1)))) {
|
||||
unsigned num = to_app(t)->get_num_args();
|
||||
for (unsigned i = 0; i < num; i++) {
|
||||
expr * arg = to_app(t)->get_arg(i);
|
||||
if (fvisited.is_marked(arg))
|
||||
continue;
|
||||
fvisited.mark(arg);
|
||||
todo.push_back(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
quick_for_each_expr(proc, tvisited, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void operator()(T const & g) {
|
||||
unsigned sz = g.size();
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
process(g.form(i));
|
||||
}
|
||||
|
||||
void operator()(unsigned sz, expr * const * fs) {
|
||||
for (unsigned i = 0; i < sz; i++)
|
||||
process(fs[i]);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
void collect_boolean_interface_core2(T const & s, obj_hashtable<expr> & r) {
|
||||
collect_boolean_interface_proc2 proc(s.m(), r);
|
||||
proc(s);
|
||||
}
|
||||
|
||||
void collect_boolean_interface(assertion_set const & s, obj_hashtable<expr> & r) {
|
||||
collect_boolean_interface_core2(s, r);
|
||||
}
|
98
src/assertion_set/sat_strategy/assertion_set2sat.h
Normal file
98
src/assertion_set/sat_strategy/assertion_set2sat.h
Normal file
|
@ -0,0 +1,98 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
assertion_set2sat.h
|
||||
|
||||
Abstract:
|
||||
|
||||
"Compile" an assertion set into the SAT engine.
|
||||
Atoms are "abstracted" into boolean variables.
|
||||
The mapping between boolean variables and atoms
|
||||
can be used to convert back the state of the
|
||||
SAT engine into an assertion set.
|
||||
|
||||
The idea is to support scenarios such as:
|
||||
1) simplify, blast, convert into SAT, and solve
|
||||
2) convert into SAT, apply SAT for a while, learn new units, and translate back into an assertion set.
|
||||
3) convert into SAT, apply SAT preprocessor (failed literal propagation, resolution, etc) and translate back into an assertion set.
|
||||
4) Convert boolean structure into SAT, convert atoms into another engine, combine engines using lazy combination, solve.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-05-22
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _ASSERTION_SET2SAT_H_
|
||||
#define _ASSERTION_SET2SAT_H_
|
||||
|
||||
#include"assertion_set.h"
|
||||
#include"sat_solver.h"
|
||||
#include"strategy_exception.h"
|
||||
#include"model_converter.h"
|
||||
#include"atom2bool_var.h"
|
||||
|
||||
class assertion_set; // TODO: delete
|
||||
void collect_boolean_interface(assertion_set const & s, obj_hashtable<expr> & r);
|
||||
|
||||
MK_ST_EXCEPTION(assertion_set2sat_exception);
|
||||
|
||||
class assertion_set2sat {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
struct scoped_set_imp;
|
||||
public:
|
||||
assertion_set2sat();
|
||||
|
||||
static void collect_param_descrs(param_descrs & r);
|
||||
|
||||
static bool has_unsupported_bool(assertion_set const & s);
|
||||
|
||||
/**
|
||||
\brief "Compile" the assertion set into the given sat solver.
|
||||
Store a mapping from atoms to boolean variables into m.
|
||||
|
||||
\remark m doesn't need to be empty. the definitions there are
|
||||
reused.
|
||||
*/
|
||||
void operator()(assertion_set const & s, params_ref const & p, sat::solver & t, atom2bool_var & m);
|
||||
|
||||
/**
|
||||
\brief "Compile" the formulas fs into the given sat solver.
|
||||
Store a mapping from atoms to boolean variables into m.
|
||||
|
||||
\remark m doesn't need to be empty. the definitions there are
|
||||
reused.
|
||||
*/
|
||||
void operator()(ast_manager & mng, unsigned num, expr * const * fs, params_ref const & p, sat::solver & t, atom2bool_var & m);
|
||||
|
||||
void operator()(ast_manager & mng, expr * f, params_ref const & p, sat::solver & t, atom2bool_var & m) { operator()(mng, 1, &f, p, t, m); }
|
||||
|
||||
void set_cancel(bool f);
|
||||
};
|
||||
|
||||
MK_ST_EXCEPTION(sat2assertion_set_exception);
|
||||
|
||||
class sat2assertion_set {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
struct scoped_set_imp;
|
||||
public:
|
||||
sat2assertion_set();
|
||||
|
||||
static void collect_param_descrs(param_descrs & r);
|
||||
|
||||
/**
|
||||
\brief Translate the state of the SAT engine back into an assertion set.
|
||||
The SAT solver may use variables that are not in \c m. The translator
|
||||
creates fresh boolean AST variables for them. They are stored in fvars.
|
||||
*/
|
||||
void operator()(sat::solver const & t, atom2bool_var const & m, params_ref const & p, assertion_set & s, model_converter_ref & mc);
|
||||
|
||||
void set_cancel(bool f);
|
||||
};
|
||||
|
||||
#endif
|
187
src/assertion_set/sat_strategy/sat_solver_strategy.cpp
Normal file
187
src/assertion_set/sat_strategy/sat_solver_strategy.cpp
Normal file
|
@ -0,0 +1,187 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
sat_solver_strategy.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Strategy for using the SAT solver preprocessing capabilities.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-05-23
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"sat_solver_strategy.h"
|
||||
#include"assertion_set2sat.h"
|
||||
#include"sat_solver.h"
|
||||
#include"filter_model_converter.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"model_v2_pp.h"
|
||||
|
||||
struct sat_solver_strategy::imp {
|
||||
ast_manager & m;
|
||||
assertion_set2sat m_as2sat;
|
||||
sat2assertion_set m_sat2as;
|
||||
sat::solver m_solver;
|
||||
params_ref m_params;
|
||||
bool m_produce_models;
|
||||
|
||||
imp(ast_manager & _m, params_ref const & p):
|
||||
m(_m),
|
||||
m_solver(p, 0),
|
||||
m_params(p) {
|
||||
SASSERT(!m.proofs_enabled());
|
||||
m_produce_models = p.get_bool(":produce-models", false);
|
||||
}
|
||||
|
||||
void operator()(assertion_set & s, model_converter_ref & mc) {
|
||||
if (s.m().proofs_enabled())
|
||||
throw sat::solver_exception("sat solver does not support proofs");
|
||||
TRACE("before_sat_solver", s.display(tout););
|
||||
s.elim_redundancies();
|
||||
if (s.inconsistent()) {
|
||||
mc = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
atom2bool_var map(m);
|
||||
m_as2sat(s, m_params, m_solver, map);
|
||||
TRACE("sat_solver_unknown", tout << "interpreted_atoms: " << map.interpreted_atoms() << "\n";
|
||||
atom2bool_var::iterator it = map.begin();
|
||||
atom2bool_var::iterator end = map.end();
|
||||
for (; it != end; ++it) {
|
||||
if (!is_uninterp_const(it->m_key))
|
||||
tout << mk_ismt2_pp(it->m_key, m) << "\n";
|
||||
});
|
||||
s.reset();
|
||||
s.m().compact_memory();
|
||||
CASSERT("sat_solver", m_solver.check_invariant());
|
||||
IF_VERBOSE(ST_VERBOSITY_LVL, m_solver.display_status(verbose_stream()););
|
||||
TRACE("sat_dimacs", m_solver.display_dimacs(tout););
|
||||
|
||||
lbool r = m_solver.check();
|
||||
if (r == l_false) {
|
||||
mc = 0;
|
||||
s.reset();
|
||||
s.assert_expr(m.mk_false(), 0);
|
||||
return;
|
||||
}
|
||||
else if (r == l_true && !map.interpreted_atoms()) {
|
||||
// register model
|
||||
model_ref md = alloc(model, m);
|
||||
sat::model const & ll_m = m_solver.get_model();
|
||||
TRACE("sat_solver_strategy", for (unsigned i = 0; i < ll_m.size(); i++) tout << i << ":" << ll_m[i] << " "; tout << "\n";);
|
||||
atom2bool_var::iterator it = map.begin();
|
||||
atom2bool_var::iterator end = map.end();
|
||||
for (; it != end; ++it) {
|
||||
expr * n = it->m_key;
|
||||
sat::bool_var v = it->m_value;
|
||||
TRACE("sat_solver_strategy", tout << "extracting value of " << mk_ismt2_pp(n, m) << "\nvar: " << v << "\n";);
|
||||
switch (sat::value_at(v, ll_m)) {
|
||||
case l_true:
|
||||
md->register_decl(to_app(n)->get_decl(), m.mk_true());
|
||||
break;
|
||||
case l_false:
|
||||
md->register_decl(to_app(n)->get_decl(), m.mk_false());
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
s.reset();
|
||||
TRACE("sat_solver_strategy", model_v2_pp(tout, *md););
|
||||
mc = model2model_converter(md.get());
|
||||
}
|
||||
else {
|
||||
// get simplified problem.
|
||||
#if 0
|
||||
IF_VERBOSE(ST_VERBOSITY_LVL, verbose_stream() << "\"formula constains interpreted atoms, recovering formula from sat solver...\"\n";);
|
||||
#endif
|
||||
m_solver.pop(m_solver.scope_lvl());
|
||||
m_sat2as(m_solver, map, m_params, s, mc);
|
||||
}
|
||||
}
|
||||
|
||||
void set_cancel(bool f) {
|
||||
m_as2sat.set_cancel(f);
|
||||
m_sat2as.set_cancel(f);
|
||||
m_solver.set_cancel(f);
|
||||
}
|
||||
};
|
||||
|
||||
sat_solver_strategy::sat_solver_strategy(ast_manager & m, params_ref const & p):
|
||||
m_imp(0),
|
||||
m_params(p) {
|
||||
}
|
||||
|
||||
sat_solver_strategy::~sat_solver_strategy() {
|
||||
SASSERT(m_imp == 0);
|
||||
}
|
||||
|
||||
void sat_solver_strategy::updt_params(params_ref const & p) {
|
||||
m_params = p;
|
||||
}
|
||||
|
||||
void sat_solver_strategy::get_param_descrs(param_descrs & r) {
|
||||
assertion_set2sat::collect_param_descrs(r);
|
||||
sat2assertion_set::collect_param_descrs(r);
|
||||
sat::solver::collect_param_descrs(r);
|
||||
insert_produce_models(r);
|
||||
}
|
||||
|
||||
|
||||
struct sat_solver_strategy::scoped_set_imp {
|
||||
sat_solver_strategy * m_owner;
|
||||
scoped_set_imp(sat_solver_strategy * o, sat_solver_strategy::imp * i):m_owner(o) {
|
||||
#pragma omp critical (sat_solver_strategy)
|
||||
{
|
||||
m_owner->m_imp = i;
|
||||
}
|
||||
}
|
||||
|
||||
~scoped_set_imp() {
|
||||
#pragma omp critical (sat_solver_strategy)
|
||||
{
|
||||
m_owner->m_imp = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void sat_solver_strategy::operator()(assertion_set & s, model_converter_ref & mc) {
|
||||
imp proc(s.m(), m_params);
|
||||
scoped_set_imp set(this, &proc);
|
||||
try {
|
||||
proc(s, mc);
|
||||
proc.m_solver.collect_statistics(m_stats);
|
||||
}
|
||||
catch (sat::solver_exception & ex) {
|
||||
proc.m_solver.collect_statistics(m_stats);
|
||||
throw ex;
|
||||
}
|
||||
TRACE("sat_stats", m_stats.display_smt2(tout););
|
||||
}
|
||||
|
||||
void sat_solver_strategy::cleanup() {
|
||||
SASSERT(m_imp == 0);
|
||||
}
|
||||
|
||||
void sat_solver_strategy::set_cancel(bool f) {
|
||||
#pragma omp critical (sat_solver_strategy)
|
||||
{
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
}
|
||||
|
||||
void sat_solver_strategy::reset_statistics() {
|
||||
m_stats.reset();
|
||||
}
|
||||
|
||||
void sat_solver_strategy::collect_statistics(statistics & st) const {
|
||||
st.copy(m_stats);
|
||||
}
|
65
src/assertion_set/sat_strategy/sat_solver_strategy.h
Normal file
65
src/assertion_set/sat_strategy/sat_solver_strategy.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
sat_solver_strategy.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Strategy for using the SAT solver.
|
||||
If the assertion set contains theory atoms, then the sat solver just
|
||||
checks whether the boolean abstraction is satisfiable or not.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-06-02
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _SAT_SOLVER_STRATEGY_H_
|
||||
#define _SAT_SOLVER_STRATEGY_H_
|
||||
|
||||
#include"assertion_set_strategy.h"
|
||||
|
||||
class assertion_set;
|
||||
|
||||
class sat_solver_strategy : public assertion_set_strategy {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
params_ref m_params;
|
||||
statistics m_stats;
|
||||
struct scoped_set_imp;
|
||||
public:
|
||||
sat_solver_strategy(ast_manager & m, params_ref const & p = params_ref());
|
||||
virtual ~sat_solver_strategy();
|
||||
|
||||
virtual void updt_params(params_ref const & p);
|
||||
static void get_param_descrs(param_descrs & r);
|
||||
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
|
||||
|
||||
virtual void operator()(assertion_set & s, model_converter_ref & mc);
|
||||
|
||||
virtual void cleanup();
|
||||
|
||||
virtual void collect_statistics(statistics & st) const;
|
||||
virtual void reset_statistics();
|
||||
protected:
|
||||
virtual void set_cancel(bool f);
|
||||
};
|
||||
|
||||
inline as_st * mk_sat_solver(ast_manager & m, params_ref const & p = params_ref()) {
|
||||
return clean(alloc(sat_solver_strategy, m, p));
|
||||
}
|
||||
|
||||
// Apply only simplification procedures
|
||||
inline as_st * mk_sat_preprocessor(ast_manager & m, params_ref const & p = params_ref()) {
|
||||
params_ref p_aux;
|
||||
p_aux.set_uint(":max-conflicts", 0);
|
||||
as_st * st = clean(using_params(mk_sat_solver(m), p_aux));
|
||||
st->updt_params(p);
|
||||
return st;
|
||||
}
|
||||
|
||||
#endif
|
257
src/assertion_set/shallow_context_simplifier.cpp
Normal file
257
src/assertion_set/shallow_context_simplifier.cpp
Normal file
|
@ -0,0 +1,257 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
shallow_context_simplifier.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Depth 1 context simplifier.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-04-28
|
||||
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"shallow_context_simplifier.h"
|
||||
#include"assertion_set_util.h"
|
||||
#include"expr_substitution.h"
|
||||
#include"th_rewriter.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"assertion_set_util.h"
|
||||
|
||||
struct shallow_context_simplifier::imp {
|
||||
ast_manager & m_manager;
|
||||
th_rewriter m_r;
|
||||
expr_substitution m_subst;
|
||||
assertion_set * m_set;
|
||||
as_shared_occs m_occs;
|
||||
unsigned m_idx;
|
||||
unsigned m_num_steps;
|
||||
unsigned m_max_rounds;
|
||||
bool m_modified;
|
||||
|
||||
imp(ast_manager & m, params_ref const & p):
|
||||
m_manager(m),
|
||||
m_r(m, p),
|
||||
m_subst(m),
|
||||
m_set(0),
|
||||
m_occs(m, true /* track atoms */) {
|
||||
m_r.set_substitution(&m_subst);
|
||||
updt_params_core(p);
|
||||
}
|
||||
|
||||
void updt_params_core(params_ref const & p) {
|
||||
m_max_rounds = p.get_uint(":max-rounds", 4);
|
||||
}
|
||||
|
||||
void updt_params(params_ref const & p) {
|
||||
m_r.updt_params(p);
|
||||
updt_params_core(p);
|
||||
}
|
||||
|
||||
ast_manager & m() const { return m_manager; }
|
||||
|
||||
void set_cancel(bool f) {
|
||||
m_r.set_cancel(f);
|
||||
}
|
||||
|
||||
void reset() {
|
||||
m_subst.reset();
|
||||
m_set = 0;
|
||||
m_num_steps = 0;
|
||||
}
|
||||
|
||||
void push_result(expr * new_curr, proof * new_pr) {
|
||||
if (m().proofs_enabled()) {
|
||||
proof * pr = m_set->pr(m_idx);
|
||||
new_pr = m().mk_modus_ponens(pr, new_pr);
|
||||
}
|
||||
|
||||
m_set->update(m_idx, new_curr, new_pr);
|
||||
|
||||
if (is_shared(new_curr)) {
|
||||
m_subst.insert(new_curr, m().mk_true(), m().mk_iff_true(new_pr));
|
||||
}
|
||||
expr * atom;
|
||||
if (is_shared_neg(new_curr, atom)) {
|
||||
m_subst.insert(atom, m().mk_false(), m().mk_iff_false(new_pr));
|
||||
}
|
||||
expr * lhs, * value;
|
||||
if (is_shared_eq(new_curr, lhs, value)) {
|
||||
TRACE("shallow_context_simplifier_bug", tout << "found eq:\n" << mk_ismt2_pp(new_curr, m()) << "\n";);
|
||||
m_subst.insert(lhs, value, new_pr);
|
||||
}
|
||||
}
|
||||
|
||||
void process_current() {
|
||||
expr * curr = m_set->form(m_idx);
|
||||
expr_ref new_curr(m());
|
||||
proof_ref new_pr(m());
|
||||
|
||||
|
||||
if (!m_subst.empty()) {
|
||||
m_r(curr, new_curr, new_pr);
|
||||
m_num_steps += m_r.get_num_steps();
|
||||
}
|
||||
else {
|
||||
new_curr = curr;
|
||||
if (m().proofs_enabled())
|
||||
new_pr = m().mk_reflexivity(curr);
|
||||
}
|
||||
|
||||
TRACE("shallow_context_simplifier_bug", tout << mk_ismt2_pp(curr, m()) << "\n---->\n" << mk_ismt2_pp(new_curr, m()) << "\n";);
|
||||
push_result(new_curr, new_pr);
|
||||
if (new_curr != curr)
|
||||
m_modified = true;
|
||||
}
|
||||
|
||||
void operator()(assertion_set & s) {
|
||||
SASSERT(is_well_sorted(s));
|
||||
as_st_report report("shallow-context-simplifier", s);
|
||||
m_num_steps = 0;
|
||||
if (s.inconsistent())
|
||||
return;
|
||||
SASSERT(m_set == 0);
|
||||
bool forward = true;
|
||||
m_set = &s;
|
||||
m_occs(*m_set);
|
||||
TRACE("shallow_context_simplifier_bug", m_occs.display(tout, m()); );
|
||||
|
||||
unsigned size = s.size();
|
||||
m_idx = 0;
|
||||
m_modified = false;
|
||||
|
||||
|
||||
expr_ref new_curr(m());
|
||||
proof_ref new_pr(m());
|
||||
|
||||
unsigned round = 0;
|
||||
|
||||
while (true) {
|
||||
TRACE("shallow_context_simplifier_round", s.display(tout););
|
||||
if (forward) {
|
||||
for (; m_idx < size; m_idx++) {
|
||||
process_current();
|
||||
if (m_set->inconsistent())
|
||||
goto end;
|
||||
}
|
||||
if (m_subst.empty() && !m_modified)
|
||||
goto end;
|
||||
m_occs(*m_set);
|
||||
m_idx = m_set->size();
|
||||
forward = false;
|
||||
m_subst.reset();
|
||||
m_r.set_substitution(&m_subst); // reset, but keep substitution
|
||||
}
|
||||
else {
|
||||
while (m_idx > 0) {
|
||||
m_idx--;
|
||||
process_current();
|
||||
if (m_set->inconsistent())
|
||||
goto end;
|
||||
}
|
||||
if (!m_modified)
|
||||
goto end;
|
||||
m_subst.reset();
|
||||
m_r.set_substitution(&m_subst); // reset, but keep substitution
|
||||
m_modified = false;
|
||||
m_occs(*m_set);
|
||||
m_idx = 0;
|
||||
size = m_set->size();
|
||||
forward = true;
|
||||
}
|
||||
round++;
|
||||
if (round >= m_max_rounds)
|
||||
break;
|
||||
IF_VERBOSE(100, verbose_stream() << "starting new round, assertion-set size: " << m_set->num_exprs() << std::endl;);
|
||||
TRACE("shallow_context_simplifier", tout << "round finished\n"; m_set->display(tout); tout << "\n";);
|
||||
}
|
||||
end:
|
||||
m_set = 0;
|
||||
SASSERT(is_well_sorted(s));
|
||||
}
|
||||
|
||||
bool is_shared(expr * t) {
|
||||
return m_occs.is_shared(t);
|
||||
}
|
||||
|
||||
bool is_shared_neg(expr * t, expr * & atom) {
|
||||
if (!m().is_not(t))
|
||||
return false;
|
||||
atom = to_app(t)->get_arg(0);
|
||||
return is_shared(atom);
|
||||
}
|
||||
|
||||
bool is_shared_eq(expr * t, expr * & lhs, expr * & value) {
|
||||
if (!m().is_eq(t))
|
||||
return false;
|
||||
expr * arg1 = to_app(t)->get_arg(0);
|
||||
expr * arg2 = to_app(t)->get_arg(1);
|
||||
if (m().is_value(arg1) && is_shared(arg2)) {
|
||||
lhs = arg2;
|
||||
value = arg1;
|
||||
return true;
|
||||
}
|
||||
if (m().is_value(arg2) && is_shared(arg1)) {
|
||||
lhs = arg1;
|
||||
value = arg2;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
unsigned get_num_steps() const { return m_num_steps; }
|
||||
};
|
||||
|
||||
shallow_context_simplifier::shallow_context_simplifier(ast_manager & m, params_ref const & p):
|
||||
m_params(p) {
|
||||
m_imp = alloc(imp, m, p);
|
||||
}
|
||||
|
||||
shallow_context_simplifier::~shallow_context_simplifier() {
|
||||
dealloc(m_imp);
|
||||
}
|
||||
|
||||
void shallow_context_simplifier::updt_params(params_ref const & p) {
|
||||
m_params = p;
|
||||
m_imp->updt_params(p);
|
||||
}
|
||||
|
||||
void shallow_context_simplifier::get_param_descrs(param_descrs & r) {
|
||||
th_rewriter::get_param_descrs(r);
|
||||
r.insert(":max-rounds", CPK_UINT, "(default: 2) maximum number of rounds.");
|
||||
}
|
||||
|
||||
void shallow_context_simplifier::operator()(assertion_set & s) {
|
||||
m_imp->operator()(s);
|
||||
}
|
||||
|
||||
void shallow_context_simplifier::set_cancel(bool f) {
|
||||
if (m_imp)
|
||||
m_imp->set_cancel(f);
|
||||
}
|
||||
|
||||
void shallow_context_simplifier::cleanup() {
|
||||
ast_manager & m = m_imp->m();
|
||||
imp * d = m_imp;
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = 0;
|
||||
}
|
||||
dealloc(d);
|
||||
d = alloc(imp, m, m_params);
|
||||
#pragma omp critical (as_st_cancel)
|
||||
{
|
||||
m_imp = d;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned shallow_context_simplifier::get_num_steps() const {
|
||||
return m_imp->get_num_steps();
|
||||
}
|
||||
|
59
src/assertion_set/shallow_context_simplifier.h
Normal file
59
src/assertion_set/shallow_context_simplifier.h
Normal file
|
@ -0,0 +1,59 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
shallow_context_simplifier.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Depth 1 context simplifier.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-04-28
|
||||
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _SHALLOW_CONTEXT_SIMPLIFIER_H_
|
||||
#define _SHALLOW_CONTEXT_SIMPLIFIER_H_
|
||||
|
||||
#include"assertion_set_strategy.h"
|
||||
|
||||
class shallow_context_simplifier : public assertion_set_strategy {
|
||||
struct imp;
|
||||
imp * m_imp;
|
||||
params_ref m_params;
|
||||
public:
|
||||
shallow_context_simplifier(ast_manager & m, params_ref const & p = params_ref());
|
||||
virtual ~shallow_context_simplifier();
|
||||
|
||||
virtual void updt_params(params_ref const & p);
|
||||
static void get_param_descrs(param_descrs & r);
|
||||
virtual void collect_param_descrs(param_descrs & r) { get_param_descrs(r); }
|
||||
|
||||
void operator()(assertion_set & s);
|
||||
|
||||
virtual void operator()(assertion_set & s, model_converter_ref & mc) {
|
||||
operator()(s);
|
||||
mc = 0;
|
||||
}
|
||||
|
||||
virtual void cleanup();
|
||||
|
||||
unsigned get_num_steps() const;
|
||||
protected:
|
||||
virtual void set_cancel(bool f);
|
||||
};
|
||||
|
||||
inline as_st * mk_shallow_simplifier(ast_manager & m, params_ref const & p = params_ref()) {
|
||||
return clean(alloc(shallow_context_simplifier, m, p));
|
||||
}
|
||||
|
||||
inline as_st * mk_constant_propagation(ast_manager & m, params_ref const & p = params_ref()) {
|
||||
return mk_shallow_simplifier(m, p);
|
||||
}
|
||||
|
||||
#endif
|
77
src/assertion_set/st2tactic.cpp
Normal file
77
src/assertion_set/st2tactic.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
st2tactic.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Temporary adapter that converts a assertion_set_strategy into a tactic.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2012-02-19
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"assertion_set_strategy.h"
|
||||
#include"tactic.h"
|
||||
|
||||
class st2tactic_wrapper : public tactic {
|
||||
assertion_set_strategy * m_st;
|
||||
params_ref m_params;
|
||||
public:
|
||||
st2tactic_wrapper(assertion_set_strategy * st):m_st(st) {}
|
||||
~st2tactic_wrapper() { dealloc(m_st); }
|
||||
|
||||
virtual tactic * translate(ast_manager & m) {
|
||||
// st2tactic_wrapper is a temporary hack to support the old strategy framework.
|
||||
// This class will be deleted in the future.
|
||||
UNREACHABLE();
|
||||
NOT_IMPLEMENTED_YET();
|
||||
return 0;
|
||||
}
|
||||
|
||||
virtual void operator()(goal_ref const & g, goal_ref_buffer & result, model_converter_ref & mc, proof_converter_ref & pc, expr_dependency_ref & core) {
|
||||
SASSERT(g->is_well_sorted());
|
||||
pc = 0; mc = 0; core = 0;
|
||||
fail_if_unsat_core_generation("st2tactic", g);
|
||||
assertion_set s(g->m());
|
||||
for (unsigned i = 0; i < g->size(); i++)
|
||||
s.assert_expr(g->form(i), g->pr(i));
|
||||
if (g->models_enabled()) {
|
||||
params_ref mp = m_params;
|
||||
mp.set_bool(":produce-models", true);
|
||||
m_st->updt_params(mp);
|
||||
}
|
||||
try {
|
||||
(*m_st)(s, mc);
|
||||
}
|
||||
catch (strategy_exception & ex) {
|
||||
throw tactic_exception(ex.msg());
|
||||
}
|
||||
g->reset();
|
||||
for (unsigned i = 0; i < s.size(); i++) {
|
||||
g->assert_expr(s.form(i), s.pr(i), 0);
|
||||
}
|
||||
g->inc_depth();
|
||||
result.push_back(g.get());
|
||||
SASSERT(g->is_well_sorted());
|
||||
}
|
||||
|
||||
virtual void updt_params(params_ref const & p) { m_params = p; m_st->updt_params(p); }
|
||||
virtual void collect_param_descrs(param_descrs & r) { m_st->collect_param_descrs(r); }
|
||||
virtual void cleanup() { m_st->cleanup(); }
|
||||
virtual void set_cancel(bool f) { m_st->set_cancel(f); }
|
||||
virtual void collect_statistics(statistics & st) const { m_st->collect_statistics(st); }
|
||||
virtual void reset_statistics() { m_st->reset_statistics(); }
|
||||
virtual void set_front_end_params(front_end_params & p) { m_st->set_front_end_params(p); }
|
||||
virtual void set_logic(symbol const & l) { m_st->set_logic(l); }
|
||||
virtual void set_progress_callback(progress_callback * callback) { m_st->set_progress_callback(callback); }
|
||||
};
|
||||
|
||||
tactic * st2tactic(assertion_set_strategy * st) {
|
||||
return alloc(st2tactic_wrapper, st);
|
||||
}
|
27
src/assertion_set/st2tactic.h
Normal file
27
src/assertion_set/st2tactic.h
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*++
|
||||
Copyright (c) 2012 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
st2tactic.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Temporary adapter that converts a assertion_set_strategy into a tactic.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2012-02-19
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _ST2TACTIC_H_
|
||||
#define _ST2TACTIC_H_
|
||||
|
||||
class tactic;
|
||||
class assertion_set_strategy;
|
||||
|
||||
tactic * st2tactic(assertion_set_strategy * st);
|
||||
|
||||
#endif
|
26
src/assertion_set/strategy_exception.cpp
Normal file
26
src/assertion_set/strategy_exception.cpp
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
strategy_exception.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Strategy exception
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-05-02
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"strategy_exception.h"
|
||||
|
||||
char const * strategy_exception::g_ste_canceled_msg = "canceled";
|
||||
char const * strategy_exception::g_ste_max_memory_msg = "max. memory exceeded";
|
||||
char const * strategy_exception::g_ste_max_scopes_msg = "max. scopes exceeded";
|
||||
char const * strategy_exception::g_ste_max_steps_msg = "max. steps exceeded";
|
||||
char const * strategy_exception::g_ste_max_frames_msg = "max. frames exceeded";
|
||||
char const * strategy_exception::g_ste_no_proofs_msg = "strategy does not support proof generation";
|
53
src/assertion_set/strategy_exception.h
Normal file
53
src/assertion_set/strategy_exception.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
strategy_exception.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Strategy exception
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-05-02
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _STRATEGY_EXCEPTION_H_
|
||||
#define _STRATEGY_EXCEPTION_H_
|
||||
|
||||
#include"z3_exception.h"
|
||||
|
||||
class strategy_exception : public z3_exception {
|
||||
public:
|
||||
static char const * g_ste_canceled_msg;
|
||||
static char const * g_ste_max_memory_msg;
|
||||
static char const * g_ste_max_scopes_msg;
|
||||
static char const * g_ste_max_steps_msg;
|
||||
static char const * g_ste_max_frames_msg;
|
||||
static char const * g_ste_no_proofs_msg;
|
||||
protected:
|
||||
char const * m_msg;
|
||||
public:
|
||||
strategy_exception(char const * msg):m_msg(msg) {}
|
||||
virtual ~strategy_exception() {}
|
||||
virtual char const * msg() const { return m_msg; }
|
||||
};
|
||||
|
||||
#define STE_CANCELED_MSG strategy_exception::g_ste_canceled_msg
|
||||
#define STE_MAX_MEMORY_MSG strategy_exception::g_ste_max_memory_msg
|
||||
#define STE_MAX_SCOPES_MSG strategy_exception::g_ste_max_scopes_msg
|
||||
#define STE_MAX_STEPS_MSG strategy_exception::g_ste_max_steps_msg
|
||||
#define STE_MAX_FRAMES_MSG strategy_exception::g_ste_max_frames_msg
|
||||
#define STE_NO_PROOF_GEN_MSG strategy_exception::g_ste_no_proofs_msg
|
||||
|
||||
#define MK_ST_EXCEPTION(NAME) \
|
||||
class NAME : public strategy_exception { \
|
||||
public: \
|
||||
NAME(char const * msg):strategy_exception(msg) {} \
|
||||
}
|
||||
|
||||
#endif
|
224
src/ast/act_cache.cpp
Normal file
224
src/ast/act_cache.cpp
Normal file
|
@ -0,0 +1,224 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
act_cache.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
expr -> expr activity cache
|
||||
It maintains at most N unused entries
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-12
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#include"act_cache.h"
|
||||
|
||||
#define MIN_MAX_UNUSED 1024
|
||||
#define INITIAL_CAPACITY 128
|
||||
|
||||
/*
|
||||
This cache is a mapping from expr -> tagged expressions
|
||||
A tagged expression is essentially a pair (expr, flag)
|
||||
Thus, an entry
|
||||
t -> (s, 0)
|
||||
maps the key t to value s, and says that key t was never accessed.
|
||||
That is, client code never executed find(t)
|
||||
Similarly, an entry
|
||||
t -> (s, 1)
|
||||
also maps the key t to value s, but signs that key t was already accessed
|
||||
by client code.
|
||||
|
||||
When a new key/value pair is inserted the flag is 0.
|
||||
The flag is set to 1 after the key is accessed.
|
||||
|
||||
The number of unused entries (m_unused) is equal to the number of entries
|
||||
of the form
|
||||
t -> (s, 0)
|
||||
That is, it is the number of keys that were never accessed by cliend code.
|
||||
|
||||
The cache maintains at most m_max_unused entries.
|
||||
When the maximum number of unused entries exceeds m_max_unused, then
|
||||
the cache will delete the oldest unused entry.
|
||||
*/
|
||||
|
||||
/**
|
||||
m_queue stores the recently added keys.
|
||||
The queue is implemented as pair: m_queue (vector), m_qhead (unsigned).
|
||||
The "active" part of m_queue is the range [m_qhead, m_queue.size())
|
||||
The "inactive" part [0, m_qhead) contains keys that were already used by client code.
|
||||
This procedure, deletes the inactive part, and makes m_qhead == 0.
|
||||
*/
|
||||
void act_cache::compress_queue() {
|
||||
SASSERT(m_qhead > 0);
|
||||
unsigned sz = m_queue.size();
|
||||
unsigned j = 0;
|
||||
for (unsigned i = m_qhead; i < sz; i++, j++) {
|
||||
m_queue[j] = m_queue[i];
|
||||
}
|
||||
m_queue.shrink(j);
|
||||
m_qhead = 0;
|
||||
}
|
||||
|
||||
void act_cache::init() {
|
||||
if (m_max_unused < MIN_MAX_UNUSED)
|
||||
m_max_unused = MIN_MAX_UNUSED;
|
||||
m_unused = 0;
|
||||
m_qhead = 0;
|
||||
}
|
||||
|
||||
void act_cache::dec_refs() {
|
||||
map::iterator it = m_table.begin();
|
||||
map::iterator end = m_table.end();
|
||||
for (; it != end; ++it) {
|
||||
m_manager.dec_ref((*it).m_key);
|
||||
m_manager.dec_ref(UNTAG(expr*, (*it).m_value));
|
||||
}
|
||||
}
|
||||
|
||||
act_cache::act_cache(ast_manager & m):
|
||||
m_manager(m),
|
||||
m_max_unused(m.get_num_asts()) {
|
||||
init();
|
||||
}
|
||||
|
||||
act_cache::act_cache(ast_manager & m, unsigned max_unused):
|
||||
m_manager(m),
|
||||
m_max_unused(max_unused) {
|
||||
init();
|
||||
}
|
||||
|
||||
act_cache::~act_cache() {
|
||||
dec_refs();
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Search m_queue from [m_qhead, m_queue.size()) until it finds
|
||||
an unused key. That is a key associated with an entry
|
||||
key -> (value, 0)
|
||||
*/
|
||||
void act_cache::del_unused() {
|
||||
unsigned sz = m_queue.size();
|
||||
while (m_qhead < sz) {
|
||||
expr * k = m_queue[m_qhead];
|
||||
m_qhead++;
|
||||
SASSERT(m_table.contains(k));
|
||||
map::key_value * entry = m_table.find_core(k);
|
||||
SASSERT(entry);
|
||||
if (GET_TAG(entry->m_value) == 0) {
|
||||
// Key k was never accessed by client code.
|
||||
// That is, find(k) was never executed by client code.
|
||||
m_unused--;
|
||||
expr * v = entry->m_value;
|
||||
m_table.erase(k);
|
||||
m_manager.dec_ref(k);
|
||||
m_manager.dec_ref(v);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (m_qhead == sz) {
|
||||
// The "active" part of the queue is empty.
|
||||
// So, we perform a "cheap" compress.
|
||||
m_queue.reset();
|
||||
m_qhead = 0;
|
||||
}
|
||||
else if (m_qhead > m_max_unused) {
|
||||
compress_queue();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Insert a new entry k -> v into the cache.
|
||||
*/
|
||||
void act_cache::insert(expr * k, expr * v) {
|
||||
SASSERT(k);
|
||||
if (m_unused >= m_max_unused)
|
||||
del_unused();
|
||||
expr * dummy = reinterpret_cast<expr*>(1);
|
||||
map::key_value & entry = m_table.insert_if_not_there(k, dummy);
|
||||
#if 0
|
||||
unsigned static counter = 0;
|
||||
counter++;
|
||||
if (counter % 100000 == 0)
|
||||
verbose_stream() << "[act-cache] counter: " << counter << " used_slots: " << m_table.used_slots() << " capacity: " << m_table.capacity() << " size: " << m_table.size() << " collisions: " << m_table.collisions() << "\n";
|
||||
#endif
|
||||
|
||||
#ifdef Z3DEBUG
|
||||
unsigned expected_tag;
|
||||
#endif
|
||||
if (entry.m_value == dummy) {
|
||||
// new entry;
|
||||
m_manager.inc_ref(k);
|
||||
m_manager.inc_ref(v);
|
||||
entry.m_value = v;
|
||||
m_queue.push_back(k);
|
||||
m_unused++;
|
||||
DEBUG_CODE(expected_tag = 0;); // new entry
|
||||
}
|
||||
else if (UNTAG(expr*, entry.m_value) == v) {
|
||||
// already there
|
||||
DEBUG_CODE(expected_tag = GET_TAG(entry.m_value););
|
||||
}
|
||||
else {
|
||||
// replacing old entry
|
||||
m_manager.inc_ref(v);
|
||||
m_manager.dec_ref(UNTAG(expr*, entry.m_value));
|
||||
entry.m_value = v;
|
||||
SASSERT(GET_TAG(entry.m_value) == 0);
|
||||
// replaced old entry, and reset the tag.
|
||||
DEBUG_CODE(expected_tag = 0;);
|
||||
}
|
||||
DEBUG_CODE({
|
||||
expr * v2;
|
||||
SASSERT(m_table.find(k, v2));
|
||||
SASSERT(v == UNTAG(expr*, v2));
|
||||
SASSERT(expected_tag == GET_TAG(v2));
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
\brief Search for key k in the cache.
|
||||
If entry k -> (v, tag) is found, we set tag to 1.
|
||||
*/
|
||||
expr * act_cache::find(expr * k) {
|
||||
map::key_value * entry = m_table.find_core(k);
|
||||
if (entry == 0)
|
||||
return 0;
|
||||
if (GET_TAG(entry->m_value) == 0) {
|
||||
entry->m_value = TAG(expr*, entry->m_value, 1);
|
||||
SASSERT(GET_TAG(entry->m_value) == 1);
|
||||
SASSERT(m_unused > 0);
|
||||
m_unused--;
|
||||
DEBUG_CODE({
|
||||
expr * v;
|
||||
SASSERT(m_table.find(k, v));
|
||||
SASSERT(GET_TAG(v) == 1);
|
||||
});
|
||||
}
|
||||
return UNTAG(expr*, entry->m_value);
|
||||
}
|
||||
|
||||
void act_cache::reset() {
|
||||
dec_refs();
|
||||
m_table.reset();
|
||||
m_queue.reset();
|
||||
m_unused = 0;
|
||||
m_qhead = 0;
|
||||
}
|
||||
|
||||
void act_cache::cleanup() {
|
||||
dec_refs();
|
||||
m_table.finalize();
|
||||
m_queue.finalize();
|
||||
m_unused = 0;
|
||||
m_qhead = 0;
|
||||
}
|
||||
|
||||
bool act_cache::check_invariant() const {
|
||||
return true;
|
||||
}
|
56
src/ast/act_cache.h
Normal file
56
src/ast/act_cache.h
Normal file
|
@ -0,0 +1,56 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
act_cache.h
|
||||
|
||||
Abstract:
|
||||
|
||||
expr -> expr activity cache
|
||||
It maintains at most N unused entries
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo (leonardo) 2011-04-12
|
||||
|
||||
Notes:
|
||||
|
||||
--*/
|
||||
#ifndef _ACT_CACHE_H_
|
||||
#define _ACT_CACHE_H_
|
||||
|
||||
#include"ast.h"
|
||||
#include"obj_hashtable.h"
|
||||
#include"chashtable.h"
|
||||
|
||||
class act_cache {
|
||||
ast_manager & m_manager;
|
||||
typedef cmap<expr*, expr*, obj_ptr_hash<expr>, default_eq<expr*> > map;
|
||||
map m_table;
|
||||
ptr_vector<expr> m_queue; // recently created queue
|
||||
unsigned m_qhead;
|
||||
unsigned m_unused;
|
||||
unsigned m_max_unused;
|
||||
|
||||
void compress_queue();
|
||||
void init();
|
||||
void dec_refs();
|
||||
void del_unused();
|
||||
|
||||
public:
|
||||
act_cache(ast_manager & m);
|
||||
act_cache(ast_manager & m, unsigned max_unused);
|
||||
~act_cache();
|
||||
void insert(expr * k, expr * v);
|
||||
expr * find(expr * k);
|
||||
void reset();
|
||||
void cleanup();
|
||||
unsigned size() const { return m_table.size(); }
|
||||
unsigned capacity() const { return m_table.capacity(); }
|
||||
bool empty() const { return m_table.empty(); }
|
||||
bool check_invariant() const;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
586
src/ast/arith_decl_plugin.cpp
Normal file
586
src/ast/arith_decl_plugin.cpp
Normal file
|
@ -0,0 +1,586 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
arith_decl_plugin.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-09
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include"arith_decl_plugin.h"
|
||||
#include"warning.h"
|
||||
#include"algebraic_numbers.h"
|
||||
#include"id_gen.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
|
||||
struct arith_decl_plugin::algebraic_numbers_wrapper {
|
||||
unsynch_mpq_manager m_qmanager;
|
||||
algebraic_numbers::manager m_amanager;
|
||||
id_gen m_id_gen;
|
||||
scoped_anum_vector m_nums;
|
||||
|
||||
algebraic_numbers_wrapper():
|
||||
m_amanager(m_qmanager),
|
||||
m_nums(m_amanager) {
|
||||
}
|
||||
|
||||
~algebraic_numbers_wrapper() {
|
||||
}
|
||||
|
||||
unsigned mk_id(algebraic_numbers::anum const & val) {
|
||||
SASSERT(!m_amanager.is_rational(val));
|
||||
// TODO: avoid linear scan. Use hashtable based on the floor of val
|
||||
unsigned sz = m_nums.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
algebraic_numbers::anum const & other = m_nums.get(i);
|
||||
if (m_amanager.eq(val, other))
|
||||
return i;
|
||||
}
|
||||
unsigned new_id = m_id_gen.mk();
|
||||
m_nums.reserve(new_id+1);
|
||||
m_amanager.set(m_nums[new_id], val);
|
||||
TRACE("algebraic2expr", tout << "mk_id -> " << new_id << "\n"; m_amanager.display(tout, val); tout << "\n";);
|
||||
return new_id;
|
||||
}
|
||||
|
||||
void recycle_id(unsigned idx) {
|
||||
SASSERT(idx < m_nums.size());
|
||||
SASSERT(!m_amanager.is_zero(m_nums[idx]));
|
||||
TRACE("algebraic2expr", tout << "recycling: " << idx << "\n";);
|
||||
m_id_gen.recycle(idx);
|
||||
m_amanager.del(m_nums[idx]);
|
||||
}
|
||||
|
||||
algebraic_numbers::anum const & idx2anum(unsigned idx) {
|
||||
return m_nums[idx];
|
||||
}
|
||||
|
||||
algebraic_numbers::anum const & to_anum(func_decl * f) {
|
||||
SASSERT(f->get_decl_kind() == OP_IRRATIONAL_ALGEBRAIC_NUM);
|
||||
return idx2anum(f->get_parameter(0).get_ext_id());
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
arith_decl_plugin::algebraic_numbers_wrapper & arith_decl_plugin::aw() {
|
||||
if (m_aw == 0)
|
||||
m_aw = alloc(algebraic_numbers_wrapper);
|
||||
return *m_aw;
|
||||
}
|
||||
|
||||
algebraic_numbers::manager & arith_decl_plugin::am() {
|
||||
return aw().m_amanager;
|
||||
}
|
||||
|
||||
app * arith_decl_plugin::mk_numeral(algebraic_numbers::anum const & val, bool is_int) {
|
||||
if (am().is_rational(val)) {
|
||||
rational rval;
|
||||
am().to_rational(val, rval);
|
||||
return mk_numeral(rval, is_int);
|
||||
}
|
||||
else {
|
||||
if (is_int)
|
||||
m_manager->raise_exception("invalid irrational value passed as an integer");
|
||||
unsigned idx = aw().mk_id(val);
|
||||
parameter p(idx, true);
|
||||
SASSERT(p.is_external());
|
||||
func_decl * decl = m_manager->mk_const_decl(m_rootv_sym, m_real_decl, func_decl_info(m_family_id, OP_IRRATIONAL_ALGEBRAIC_NUM, 1, &p));
|
||||
return m_manager->mk_const(decl);
|
||||
}
|
||||
}
|
||||
|
||||
app * arith_decl_plugin::mk_numeral(sexpr const * p, unsigned i) {
|
||||
scoped_anum r(am());
|
||||
am().mk_root(p, i, r);
|
||||
return mk_numeral(r, false);
|
||||
}
|
||||
|
||||
void arith_decl_plugin::del(parameter const & p) {
|
||||
SASSERT(p.is_external());
|
||||
if (m_aw != 0) {
|
||||
aw().recycle_id(p.get_ext_id());
|
||||
}
|
||||
}
|
||||
|
||||
parameter arith_decl_plugin::translate(parameter const & p, decl_plugin & target) {
|
||||
SASSERT(p.is_external());
|
||||
arith_decl_plugin & _target = static_cast<arith_decl_plugin&>(target);
|
||||
return parameter(_target.aw().mk_id(aw().idx2anum(p.get_ext_id())), true);
|
||||
}
|
||||
|
||||
void arith_decl_plugin::set_cancel(bool f) {
|
||||
if (m_aw)
|
||||
m_aw->m_amanager.set_cancel(f);
|
||||
}
|
||||
|
||||
void arith_decl_plugin::set_manager(ast_manager * m, family_id id) {
|
||||
decl_plugin::set_manager(m, id);
|
||||
|
||||
m_real_decl = m->mk_sort(symbol("Real"), sort_info(id, REAL_SORT));
|
||||
m->inc_ref(m_real_decl);
|
||||
sort * r = m_real_decl;
|
||||
|
||||
m_int_decl = m->mk_sort(symbol("Int"), sort_info(id, INT_SORT));
|
||||
m->inc_ref(m_int_decl);
|
||||
sort * i = m_int_decl;
|
||||
|
||||
sort * b = m->mk_bool_sort();
|
||||
|
||||
#define MK_PRED(FIELD, NAME, KIND, SORT) { \
|
||||
func_decl_info info(id, KIND); \
|
||||
info.set_chainable(true); \
|
||||
FIELD = m->mk_func_decl(symbol(NAME), SORT, SORT, b, info); \
|
||||
m->inc_ref(FIELD); \
|
||||
}
|
||||
|
||||
MK_PRED(m_r_le_decl, "<=", OP_LE, r);
|
||||
MK_PRED(m_r_ge_decl, ">=", OP_GE, r);
|
||||
MK_PRED(m_r_lt_decl, "<", OP_LT, r);
|
||||
MK_PRED(m_r_gt_decl, ">", OP_GT, r);
|
||||
|
||||
MK_PRED(m_i_le_decl, "<=", OP_LE, i);
|
||||
MK_PRED(m_i_ge_decl, ">=", OP_GE, i);
|
||||
MK_PRED(m_i_lt_decl, "<", OP_LT, i);
|
||||
MK_PRED(m_i_gt_decl, ">", OP_GT, i);
|
||||
|
||||
#define MK_AC_OP(FIELD, NAME, KIND, SORT) { \
|
||||
func_decl_info info(id, KIND); \
|
||||
info.set_associative(); \
|
||||
info.set_flat_associative(); \
|
||||
info.set_commutative(); \
|
||||
FIELD = m->mk_func_decl(symbol(NAME), SORT, SORT, SORT, info); \
|
||||
m->inc_ref(FIELD); \
|
||||
}
|
||||
|
||||
#define MK_OP(FIELD, NAME, KIND, SORT) \
|
||||
FIELD = m->mk_func_decl(symbol(NAME), SORT, SORT, SORT, func_decl_info(id, KIND)); \
|
||||
m->inc_ref(FIELD)
|
||||
|
||||
#define MK_UNARY(FIELD, NAME, KIND, SORT) \
|
||||
FIELD = m->mk_func_decl(symbol(NAME), SORT, SORT, func_decl_info(id, KIND)); \
|
||||
m->inc_ref(FIELD)
|
||||
|
||||
MK_AC_OP(m_r_add_decl, "+", OP_ADD, r);
|
||||
MK_OP(m_r_sub_decl, "-", OP_SUB, r);
|
||||
MK_AC_OP(m_r_mul_decl, "*", OP_MUL, r);
|
||||
MK_OP(m_r_div_decl, "/", OP_DIV, r);
|
||||
MK_UNARY(m_r_uminus_decl, "-", OP_UMINUS, r);
|
||||
|
||||
MK_AC_OP(m_i_add_decl, "+", OP_ADD, i);
|
||||
MK_OP(m_i_sub_decl, "-", OP_SUB, i);
|
||||
MK_AC_OP(m_i_mul_decl, "*", OP_MUL, i);
|
||||
MK_OP(m_i_div_decl, "div", OP_IDIV, i);
|
||||
MK_OP(m_i_rem_decl, "rem", OP_REM, i);
|
||||
MK_OP(m_i_mod_decl, "mod", OP_MOD, i);
|
||||
MK_UNARY(m_i_uminus_decl, "-", OP_UMINUS, i);
|
||||
|
||||
m_to_real_decl = m->mk_func_decl(symbol("to_real"), i, r, func_decl_info(id, OP_TO_REAL));
|
||||
m->inc_ref(m_to_real_decl);
|
||||
m_to_int_decl = m->mk_func_decl(symbol("to_int"), r, i, func_decl_info(id, OP_TO_INT));
|
||||
m->inc_ref(m_to_int_decl);
|
||||
m_is_int_decl = m->mk_func_decl(symbol("is_int"), r, m->mk_bool_sort(), func_decl_info(id, OP_IS_INT));
|
||||
m->inc_ref(m_is_int_decl);
|
||||
|
||||
MK_OP(m_r_power_decl, "^", OP_POWER, r);
|
||||
MK_OP(m_i_power_decl, "^", OP_POWER, i);
|
||||
|
||||
MK_UNARY(m_sin_decl, "sin", OP_SIN, r);
|
||||
MK_UNARY(m_cos_decl, "cos", OP_COS, r);
|
||||
MK_UNARY(m_tan_decl, "tan", OP_TAN, r);
|
||||
MK_UNARY(m_asin_decl, "asin", OP_ASIN, r);
|
||||
MK_UNARY(m_acos_decl, "acos", OP_ACOS, r);
|
||||
MK_UNARY(m_atan_decl, "atan", OP_ATAN, r);
|
||||
MK_UNARY(m_sinh_decl, "sinh", OP_SINH, r);
|
||||
MK_UNARY(m_cosh_decl, "cosh", OP_COSH, r);
|
||||
MK_UNARY(m_tanh_decl, "tanh", OP_TANH, r);
|
||||
MK_UNARY(m_asinh_decl, "asinh", OP_ASINH, r);
|
||||
MK_UNARY(m_acosh_decl, "acosh", OP_ACOSH, r);
|
||||
MK_UNARY(m_atanh_decl, "atanh", OP_ATANH, r);
|
||||
|
||||
func_decl * pi_decl = m->mk_const_decl(symbol("pi"), r, func_decl_info(id, OP_PI));
|
||||
m_pi = m->mk_const(pi_decl);
|
||||
m->inc_ref(m_pi);
|
||||
|
||||
func_decl * e_decl = m->mk_const_decl(symbol("euler"), r, func_decl_info(id, OP_E));
|
||||
m_e = m->mk_const(e_decl);
|
||||
m->inc_ref(m_e);
|
||||
}
|
||||
|
||||
arith_decl_plugin::arith_decl_plugin():
|
||||
m_aw(0),
|
||||
m_intv_sym("Int"),
|
||||
m_realv_sym("Real"),
|
||||
m_rootv_sym("RootObject"),
|
||||
m_real_decl(0),
|
||||
m_int_decl(0),
|
||||
m_r_le_decl(0),
|
||||
m_r_ge_decl(0),
|
||||
m_r_lt_decl(0),
|
||||
m_r_gt_decl(0),
|
||||
m_r_add_decl(0),
|
||||
m_r_sub_decl(0),
|
||||
m_r_uminus_decl(0),
|
||||
m_r_mul_decl(0),
|
||||
m_r_div_decl(0),
|
||||
m_i_le_decl(0),
|
||||
m_i_ge_decl(0),
|
||||
m_i_lt_decl(0),
|
||||
m_i_gt_decl(0),
|
||||
m_i_add_decl(0),
|
||||
m_i_sub_decl(0),
|
||||
m_i_uminus_decl(0),
|
||||
m_i_mul_decl(0),
|
||||
m_i_div_decl(0),
|
||||
m_i_mod_decl(0),
|
||||
m_i_rem_decl(0),
|
||||
m_to_real_decl(0),
|
||||
m_to_int_decl(0),
|
||||
m_is_int_decl(0),
|
||||
m_r_power_decl(0),
|
||||
m_i_power_decl(0),
|
||||
m_sin_decl(0),
|
||||
m_cos_decl(0),
|
||||
m_tan_decl(0),
|
||||
m_asin_decl(0),
|
||||
m_acos_decl(0),
|
||||
m_atan_decl(0),
|
||||
m_sinh_decl(0),
|
||||
m_cosh_decl(0),
|
||||
m_tanh_decl(0),
|
||||
m_asinh_decl(0),
|
||||
m_acosh_decl(0),
|
||||
m_atanh_decl(0),
|
||||
m_pi(0),
|
||||
m_e(0) {
|
||||
}
|
||||
|
||||
arith_decl_plugin::~arith_decl_plugin() {
|
||||
dealloc(m_aw);
|
||||
}
|
||||
|
||||
void arith_decl_plugin::finalize() {
|
||||
#define DEC_REF(decl) if (decl) { m_manager->dec_ref(decl); } ((void) 0)
|
||||
DEC_REF(m_real_decl);
|
||||
DEC_REF(m_int_decl);
|
||||
DEC_REF(m_r_le_decl);
|
||||
DEC_REF(m_r_ge_decl);
|
||||
DEC_REF(m_r_lt_decl);
|
||||
DEC_REF(m_r_gt_decl);
|
||||
DEC_REF(m_r_add_decl);
|
||||
DEC_REF(m_r_sub_decl);
|
||||
DEC_REF(m_r_uminus_decl);
|
||||
DEC_REF(m_r_mul_decl);
|
||||
DEC_REF(m_r_div_decl);
|
||||
DEC_REF(m_i_le_decl);
|
||||
DEC_REF(m_i_ge_decl);
|
||||
DEC_REF(m_i_lt_decl);
|
||||
DEC_REF(m_i_gt_decl);
|
||||
DEC_REF(m_i_add_decl);
|
||||
DEC_REF(m_i_sub_decl);
|
||||
DEC_REF(m_i_uminus_decl);
|
||||
DEC_REF(m_i_mul_decl);
|
||||
DEC_REF(m_i_div_decl);
|
||||
DEC_REF(m_i_mod_decl);
|
||||
DEC_REF(m_i_rem_decl);
|
||||
DEC_REF(m_to_real_decl);
|
||||
DEC_REF(m_to_int_decl);
|
||||
DEC_REF(m_is_int_decl);
|
||||
DEC_REF(m_i_power_decl);
|
||||
DEC_REF(m_r_power_decl);
|
||||
DEC_REF(m_sin_decl);
|
||||
DEC_REF(m_cos_decl);
|
||||
DEC_REF(m_tan_decl);
|
||||
DEC_REF(m_asin_decl);
|
||||
DEC_REF(m_acos_decl);
|
||||
DEC_REF(m_atan_decl);
|
||||
DEC_REF(m_sinh_decl);
|
||||
DEC_REF(m_cosh_decl);
|
||||
DEC_REF(m_tanh_decl);
|
||||
DEC_REF(m_asinh_decl);
|
||||
DEC_REF(m_acosh_decl);
|
||||
DEC_REF(m_atanh_decl);
|
||||
DEC_REF(m_pi);
|
||||
DEC_REF(m_e);
|
||||
m_manager->dec_array_ref(m_small_ints.size(), m_small_ints.c_ptr());
|
||||
m_manager->dec_array_ref(m_small_reals.size(), m_small_reals.c_ptr());
|
||||
}
|
||||
|
||||
sort * arith_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) {
|
||||
switch (k) {
|
||||
case REAL_SORT: return m_real_decl;
|
||||
case INT_SORT: return m_int_decl;
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, bool is_real) {
|
||||
switch (k) {
|
||||
case OP_LE: return is_real ? m_r_le_decl : m_i_le_decl;
|
||||
case OP_GE: return is_real ? m_r_ge_decl : m_i_ge_decl;
|
||||
case OP_LT: return is_real ? m_r_lt_decl : m_i_lt_decl;
|
||||
case OP_GT: return is_real ? m_r_gt_decl : m_i_gt_decl;
|
||||
case OP_ADD: return is_real ? m_r_add_decl : m_i_add_decl;
|
||||
case OP_SUB: return is_real ? m_r_sub_decl : m_i_sub_decl;
|
||||
case OP_UMINUS: return is_real ? m_r_uminus_decl : m_i_uminus_decl;
|
||||
case OP_MUL: return is_real ? m_r_mul_decl : m_i_mul_decl;
|
||||
case OP_DIV: return m_r_div_decl;
|
||||
case OP_IDIV: return m_i_div_decl;
|
||||
case OP_REM: return m_i_rem_decl;
|
||||
case OP_MOD: return m_i_mod_decl;
|
||||
case OP_TO_REAL: return m_to_real_decl;
|
||||
case OP_TO_INT: return m_to_int_decl;
|
||||
case OP_IS_INT: return m_is_int_decl;
|
||||
case OP_POWER: return is_real ? m_r_power_decl : m_i_power_decl;
|
||||
case OP_SIN: return m_sin_decl;
|
||||
case OP_COS: return m_cos_decl;
|
||||
case OP_TAN: return m_tan_decl;
|
||||
case OP_ASIN: return m_asin_decl;
|
||||
case OP_ACOS: return m_acos_decl;
|
||||
case OP_ATAN: return m_atan_decl;
|
||||
case OP_SINH: return m_sinh_decl;
|
||||
case OP_COSH: return m_cosh_decl;
|
||||
case OP_TANH: return m_tanh_decl;
|
||||
case OP_ASINH: return m_asinh_decl;
|
||||
case OP_ACOSH: return m_acosh_decl;
|
||||
case OP_ATANH: return m_atanh_decl;
|
||||
case OP_PI: return m_pi->get_decl();
|
||||
case OP_E: return m_e->get_decl();
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
inline decl_kind arith_decl_plugin::fix_kind(decl_kind k, unsigned arity) {
|
||||
if (k == OP_SUB && arity == 1) {
|
||||
return OP_UMINUS;
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
#define MAX_SMALL_NUM_TO_CACHE 16
|
||||
|
||||
app * arith_decl_plugin::mk_numeral(rational const & val, bool is_int) {
|
||||
if (is_int && !val.is_int()) {
|
||||
m_manager->raise_exception("invalid rational value passed as an integer");
|
||||
}
|
||||
if (val.is_unsigned()) {
|
||||
unsigned u_val = val.get_unsigned();
|
||||
if (u_val < MAX_SMALL_NUM_TO_CACHE) {
|
||||
if (is_int) {
|
||||
app * r = m_small_ints.get(u_val, 0);
|
||||
if (r == 0) {
|
||||
parameter p[2] = { parameter(val), parameter(1) };
|
||||
r = m_manager->mk_const(m_manager->mk_const_decl(m_intv_sym, m_int_decl, func_decl_info(m_family_id, OP_NUM, 2, p)));
|
||||
m_manager->inc_ref(r);
|
||||
m_small_ints.setx(u_val, r, 0);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
else {
|
||||
app * r = m_small_reals.get(u_val, 0);
|
||||
if (r == 0) {
|
||||
parameter p[2] = { parameter(val), parameter(0) };
|
||||
r = m_manager->mk_const(m_manager->mk_const_decl(m_realv_sym, m_real_decl, func_decl_info(m_family_id, OP_NUM, 2, p)));
|
||||
m_manager->inc_ref(r);
|
||||
m_small_reals.setx(u_val, r, 0);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
}
|
||||
}
|
||||
parameter p[2] = { parameter(val), parameter(static_cast<int>(is_int)) };
|
||||
func_decl * decl;
|
||||
if (is_int)
|
||||
decl = m_manager->mk_const_decl(m_intv_sym, m_int_decl, func_decl_info(m_family_id, OP_NUM, 2, p));
|
||||
else
|
||||
decl = m_manager->mk_const_decl(m_realv_sym, m_real_decl, func_decl_info(m_family_id, OP_NUM, 2, p));
|
||||
return m_manager->mk_const(decl);
|
||||
}
|
||||
|
||||
func_decl * arith_decl_plugin::mk_num_decl(unsigned num_parameters, parameter const * parameters, unsigned arity) {
|
||||
if (!(num_parameters == 2 && arity == 0 && parameters[0].is_rational() && parameters[1].is_int())) {
|
||||
m_manager->raise_exception("invalid numeral declaration");
|
||||
return 0;
|
||||
}
|
||||
if (parameters[1].get_int() != 0)
|
||||
return m_manager->mk_const_decl(m_intv_sym, m_int_decl, func_decl_info(m_family_id, OP_NUM, num_parameters, parameters));
|
||||
else
|
||||
return m_manager->mk_const_decl(m_realv_sym, m_real_decl, func_decl_info(m_family_id, OP_NUM, num_parameters, parameters));
|
||||
}
|
||||
|
||||
static bool use_coercion(decl_kind k) {
|
||||
return k == OP_ADD || k == OP_SUB || k == OP_MUL || k == OP_POWER || k == OP_LE || k == OP_GE || k == OP_LT || k == OP_GT || k == OP_UMINUS;
|
||||
}
|
||||
|
||||
static bool has_real_arg(unsigned arity, sort * const * domain, sort * real_sort) {
|
||||
for (unsigned i = 0; i < arity; i++)
|
||||
if (domain[i] == real_sort)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool has_real_arg(ast_manager * m, unsigned num_args, expr * const * args, sort * real_sort) {
|
||||
for (unsigned i = 0; i < num_args; i++)
|
||||
if (m->get_sort(args[i]) == real_sort)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned arity, sort * const * domain, sort * range) {
|
||||
if (k == OP_NUM)
|
||||
return mk_num_decl(num_parameters, parameters, arity);
|
||||
if (arity == 0 && k != OP_PI && k != OP_E) {
|
||||
m_manager->raise_exception("no arguments supplied to arithmetical operator");
|
||||
return 0;
|
||||
}
|
||||
if (m_manager->int_real_coercions() && use_coercion(k)) {
|
||||
return mk_func_decl(fix_kind(k, arity), has_real_arg(arity, domain, m_real_decl));
|
||||
}
|
||||
else {
|
||||
bool is_real = arity > 0 && domain[0] == m_real_decl;
|
||||
return mk_func_decl(fix_kind(k, arity), is_real);
|
||||
}
|
||||
}
|
||||
|
||||
func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned num_args, expr * const * args, sort * range) {
|
||||
if (k == OP_NUM)
|
||||
return mk_num_decl(num_parameters, parameters, num_args);
|
||||
if (num_args == 0 && k != OP_PI && k != OP_E) {
|
||||
m_manager->raise_exception("no arguments supplied to arithmetical operator");
|
||||
return 0;
|
||||
}
|
||||
if (m_manager->int_real_coercions() && use_coercion(k)) {
|
||||
return mk_func_decl(fix_kind(k, num_args), has_real_arg(m_manager, num_args, args, m_real_decl));
|
||||
}
|
||||
else {
|
||||
bool is_real = num_args > 0 && m_manager->get_sort(args[0]) == m_real_decl;
|
||||
return mk_func_decl(fix_kind(k, num_args), is_real);
|
||||
}
|
||||
}
|
||||
|
||||
void arith_decl_plugin::get_sort_names(svector<builtin_name>& sort_names, symbol const & logic) {
|
||||
// TODO: only define Int and Real in the right logics
|
||||
sort_names.push_back(builtin_name("Int", INT_SORT));
|
||||
sort_names.push_back(builtin_name("Real", REAL_SORT));
|
||||
}
|
||||
|
||||
void arith_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol const & logic) {
|
||||
op_names.push_back(builtin_name("<=",OP_LE));
|
||||
op_names.push_back(builtin_name(">=",OP_GE));
|
||||
op_names.push_back(builtin_name("<",OP_LT));
|
||||
op_names.push_back(builtin_name(">",OP_GT));
|
||||
op_names.push_back(builtin_name("+",OP_ADD));
|
||||
op_names.push_back(builtin_name("-",OP_SUB));
|
||||
op_names.push_back(builtin_name("~",OP_UMINUS));
|
||||
op_names.push_back(builtin_name("*",OP_MUL));
|
||||
op_names.push_back(builtin_name("/",OP_DIV));
|
||||
op_names.push_back(builtin_name("div",OP_IDIV));
|
||||
op_names.push_back(builtin_name("rem",OP_REM));
|
||||
op_names.push_back(builtin_name("mod",OP_MOD));
|
||||
op_names.push_back(builtin_name("to_real",OP_TO_REAL));
|
||||
op_names.push_back(builtin_name("to_int",OP_TO_INT));
|
||||
op_names.push_back(builtin_name("is_int",OP_IS_INT));
|
||||
if (logic == symbol::null) {
|
||||
op_names.push_back(builtin_name("^", OP_POWER));
|
||||
op_names.push_back(builtin_name("sin", OP_SIN));
|
||||
op_names.push_back(builtin_name("cos", OP_COS));
|
||||
op_names.push_back(builtin_name("tan", OP_TAN));
|
||||
op_names.push_back(builtin_name("asin", OP_ASIN));
|
||||
op_names.push_back(builtin_name("acos", OP_ACOS));
|
||||
op_names.push_back(builtin_name("atan", OP_ATAN));
|
||||
op_names.push_back(builtin_name("sinh", OP_SINH));
|
||||
op_names.push_back(builtin_name("cosh", OP_COSH));
|
||||
op_names.push_back(builtin_name("tanh", OP_TANH));
|
||||
op_names.push_back(builtin_name("asinh", OP_ASINH));
|
||||
op_names.push_back(builtin_name("acosh", OP_ACOSH));
|
||||
op_names.push_back(builtin_name("atanh", OP_ATANH));
|
||||
op_names.push_back(builtin_name("pi", OP_PI));
|
||||
op_names.push_back(builtin_name("euler", OP_E));
|
||||
}
|
||||
}
|
||||
|
||||
bool arith_decl_plugin::is_value(app* e) const {
|
||||
return is_app_of(e, m_family_id, OP_NUM);
|
||||
}
|
||||
|
||||
bool arith_decl_plugin::are_distinct(app* a, app* b) const {
|
||||
TRACE("are_distinct_bug", tout << mk_ismt2_pp(a, *m_manager) << "\n" << mk_ismt2_pp(b, *m_manager) << "\n";);
|
||||
if (decl_plugin::are_distinct(a,b)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
#define is_non_zero(e) is_app_of(e,m_family_id, OP_NUM) && !to_app(e)->get_decl()->get_parameter(0).get_rational().is_zero()
|
||||
|
||||
if (is_app_of(a, m_family_id, OP_ADD) &&
|
||||
a->get_num_args() == 2 &&
|
||||
to_app(a)->get_arg(0) == b &&
|
||||
is_non_zero(to_app(a)->get_arg(1))) {
|
||||
return true;
|
||||
}
|
||||
if (is_app_of(a, m_family_id, OP_ADD) &&
|
||||
a->get_num_args() == 2 &&
|
||||
to_app(a)->get_arg(1) == b &&
|
||||
is_non_zero(to_app(a)->get_arg(0))) {
|
||||
return true;
|
||||
}
|
||||
if (is_app_of(b, m_family_id, OP_ADD) &&
|
||||
b->get_num_args() == 2 &&
|
||||
to_app(b)->get_arg(1) == a &&
|
||||
is_non_zero(to_app(b)->get_arg(0))) {
|
||||
return true;
|
||||
}
|
||||
if (is_app_of(b, m_family_id, OP_ADD) &&
|
||||
b->get_num_args() == 2 &&
|
||||
to_app(b)->get_arg(0) == a &&
|
||||
is_non_zero(to_app(b)->get_arg(1))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
expr * arith_decl_plugin::get_some_value(sort * s) {
|
||||
SASSERT(s == m_int_decl || s == m_real_decl);
|
||||
return mk_numeral(rational(0), s == m_int_decl);
|
||||
}
|
||||
|
||||
arith_util::arith_util(ast_manager & m):
|
||||
m_manager(m),
|
||||
m_afid(m.get_family_id("arith")),
|
||||
m_plugin(0) {
|
||||
}
|
||||
|
||||
void arith_util::init_plugin() {
|
||||
SASSERT(m_plugin == 0);
|
||||
m_plugin = static_cast<arith_decl_plugin*>(m_manager.get_plugin(m_afid));
|
||||
}
|
||||
|
||||
bool arith_util::is_numeral(expr const * n, rational & val, bool & is_int) const {
|
||||
if (!is_app_of(n, m_afid, OP_NUM))
|
||||
return false;
|
||||
func_decl * decl = to_app(n)->get_decl();
|
||||
val = decl->get_parameter(0).get_rational();
|
||||
is_int = decl->get_parameter(1).get_int() != 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool arith_util::is_irrational_algebraic_numeral(expr const * n, algebraic_numbers::anum & val) {
|
||||
if (!is_app_of(n, m_afid, OP_IRRATIONAL_ALGEBRAIC_NUM))
|
||||
return false;
|
||||
am().set(val, to_irrational_algebraic_numeral(n));
|
||||
return true;
|
||||
}
|
||||
|
||||
algebraic_numbers::anum const & arith_util::to_irrational_algebraic_numeral(expr const * n) {
|
||||
SASSERT(is_irrational_algebraic_numeral(n));
|
||||
return plugin().aw().to_anum(to_app(n)->get_decl());
|
||||
}
|
348
src/ast/arith_decl_plugin.h
Normal file
348
src/ast/arith_decl_plugin.h
Normal file
|
@ -0,0 +1,348 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
arith_decl_plugin.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-09
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ARITH_DECL_PLUGIN_H_
|
||||
#define _ARITH_DECL_PLUGIN_H_
|
||||
|
||||
#include"ast.h"
|
||||
class sexpr;
|
||||
|
||||
namespace algebraic_numbers {
|
||||
class anum;
|
||||
class manager;
|
||||
};
|
||||
|
||||
enum arith_sort_kind {
|
||||
REAL_SORT,
|
||||
INT_SORT
|
||||
};
|
||||
|
||||
enum arith_op_kind {
|
||||
OP_NUM, // rational & integers
|
||||
OP_IRRATIONAL_ALGEBRAIC_NUM, // irrationals that are roots of polynomials with integer coefficients
|
||||
OP_LE,
|
||||
OP_GE,
|
||||
OP_LT,
|
||||
OP_GT,
|
||||
OP_ADD,
|
||||
OP_SUB,
|
||||
OP_UMINUS,
|
||||
OP_MUL,
|
||||
OP_DIV,
|
||||
OP_IDIV,
|
||||
OP_REM,
|
||||
OP_MOD,
|
||||
OP_TO_REAL,
|
||||
OP_TO_INT,
|
||||
OP_IS_INT,
|
||||
OP_POWER,
|
||||
// hyperbolic and trigonometric functions
|
||||
OP_SIN,
|
||||
OP_COS,
|
||||
OP_TAN,
|
||||
OP_ASIN,
|
||||
OP_ACOS,
|
||||
OP_ATAN,
|
||||
OP_SINH,
|
||||
OP_COSH,
|
||||
OP_TANH,
|
||||
OP_ASINH,
|
||||
OP_ACOSH,
|
||||
OP_ATANH,
|
||||
// constants
|
||||
OP_PI,
|
||||
OP_E,
|
||||
LAST_ARITH_OP
|
||||
};
|
||||
|
||||
class arith_util;
|
||||
|
||||
class arith_decl_plugin : public decl_plugin {
|
||||
protected:
|
||||
struct algebraic_numbers_wrapper;
|
||||
algebraic_numbers_wrapper * m_aw;
|
||||
symbol m_intv_sym;
|
||||
symbol m_realv_sym;
|
||||
symbol m_rootv_sym;
|
||||
sort * m_real_decl;
|
||||
sort * m_int_decl;
|
||||
func_decl * m_r_le_decl;
|
||||
func_decl * m_r_ge_decl;
|
||||
func_decl * m_r_lt_decl;
|
||||
func_decl * m_r_gt_decl;
|
||||
|
||||
func_decl * m_r_add_decl;
|
||||
func_decl * m_r_sub_decl;
|
||||
func_decl * m_r_uminus_decl;
|
||||
func_decl * m_r_mul_decl;
|
||||
func_decl * m_r_div_decl;
|
||||
|
||||
func_decl * m_i_le_decl;
|
||||
func_decl * m_i_ge_decl;
|
||||
func_decl * m_i_lt_decl;
|
||||
func_decl * m_i_gt_decl;
|
||||
|
||||
func_decl * m_i_add_decl;
|
||||
func_decl * m_i_sub_decl;
|
||||
func_decl * m_i_uminus_decl;
|
||||
func_decl * m_i_mul_decl;
|
||||
func_decl * m_i_div_decl;
|
||||
func_decl * m_i_mod_decl;
|
||||
func_decl * m_i_rem_decl;
|
||||
|
||||
func_decl * m_to_real_decl;
|
||||
func_decl * m_to_int_decl;
|
||||
func_decl * m_is_int_decl;
|
||||
func_decl * m_r_power_decl;
|
||||
func_decl * m_i_power_decl;
|
||||
|
||||
func_decl * m_sin_decl;
|
||||
func_decl * m_cos_decl;
|
||||
func_decl * m_tan_decl;
|
||||
func_decl * m_asin_decl;
|
||||
func_decl * m_acos_decl;
|
||||
func_decl * m_atan_decl;
|
||||
func_decl * m_sinh_decl;
|
||||
func_decl * m_cosh_decl;
|
||||
func_decl * m_tanh_decl;
|
||||
func_decl * m_asinh_decl;
|
||||
func_decl * m_acosh_decl;
|
||||
func_decl * m_atanh_decl;
|
||||
|
||||
app * m_pi;
|
||||
app * m_e;
|
||||
|
||||
ptr_vector<app> m_small_ints;
|
||||
ptr_vector<app> m_small_reals;
|
||||
|
||||
func_decl * mk_func_decl(decl_kind k, bool is_real);
|
||||
virtual void set_manager(ast_manager * m, family_id id);
|
||||
decl_kind fix_kind(decl_kind k, unsigned arity);
|
||||
func_decl * mk_num_decl(unsigned num_parameters, parameter const * parameters, unsigned arity);
|
||||
|
||||
public:
|
||||
arith_decl_plugin();
|
||||
|
||||
virtual ~arith_decl_plugin();
|
||||
virtual void finalize();
|
||||
|
||||
algebraic_numbers::manager & am();
|
||||
algebraic_numbers_wrapper & aw();
|
||||
|
||||
virtual void del(parameter const & p);
|
||||
virtual parameter translate(parameter const & p, decl_plugin & target);
|
||||
|
||||
virtual decl_plugin * mk_fresh() {
|
||||
return alloc(arith_decl_plugin);
|
||||
}
|
||||
|
||||
virtual sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters);
|
||||
|
||||
virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned arity, sort * const * domain, sort * range);
|
||||
|
||||
virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned num_args, expr * const * args, sort * range);
|
||||
|
||||
virtual bool is_value(app* e) const;
|
||||
|
||||
virtual bool are_distinct(app* a, app* b) const;
|
||||
|
||||
virtual void get_op_names(svector<builtin_name> & op_names, symbol const & logic);
|
||||
|
||||
virtual void get_sort_names(svector<builtin_name> & sort_names, symbol const & logic);
|
||||
|
||||
app * mk_numeral(rational const & n, bool is_int);
|
||||
|
||||
app * mk_numeral(algebraic_numbers::anum const & val, bool is_int);
|
||||
|
||||
// Create a (real) numeral that is the i-th root of the polynomial encoded using the given sexpr.
|
||||
app * mk_numeral(sexpr const * p, unsigned i);
|
||||
|
||||
app * mk_pi() const { return m_pi; }
|
||||
|
||||
app * mk_e() const { return m_e; }
|
||||
|
||||
virtual expr * get_some_value(sort * s);
|
||||
|
||||
void set_cancel(bool f);
|
||||
};
|
||||
|
||||
class arith_util {
|
||||
ast_manager & m_manager;
|
||||
family_id m_afid;
|
||||
arith_decl_plugin * m_plugin;
|
||||
|
||||
void init_plugin();
|
||||
|
||||
arith_decl_plugin & plugin() const {
|
||||
if (!m_plugin) const_cast<arith_util*>(this)->init_plugin();
|
||||
SASSERT(m_plugin != 0);
|
||||
return *m_plugin;
|
||||
}
|
||||
|
||||
public:
|
||||
arith_util(ast_manager & m);
|
||||
|
||||
ast_manager & get_manager() const { return m_manager; }
|
||||
family_id get_family_id() const { return m_afid; }
|
||||
|
||||
algebraic_numbers::manager & am() {
|
||||
return plugin().am();
|
||||
}
|
||||
|
||||
bool is_arith_expr(expr const * n) const { return is_app(n) && to_app(n)->get_family_id() == m_afid; }
|
||||
bool is_numeral(expr const * n, rational & val, bool & is_int) const;
|
||||
bool is_numeral(expr const * n, rational & val) const { bool is_int; return is_numeral(n, val, is_int); }
|
||||
bool is_numeral(expr const * n) const { return is_app_of(n, m_afid, OP_NUM); }
|
||||
bool is_irrational_algebraic_numeral(expr const * n) const { return is_app_of(n, m_afid, OP_IRRATIONAL_ALGEBRAIC_NUM); }
|
||||
bool is_irrational_algebraic_numeral(expr const * n, algebraic_numbers::anum & val);
|
||||
algebraic_numbers::anum const & to_irrational_algebraic_numeral(expr const * n);
|
||||
bool is_zero(expr const * n) const { rational val; return is_numeral(n, val) && val.is_zero(); }
|
||||
bool is_minus_one(expr * n) const { rational tmp; return is_numeral(n, tmp) && tmp.is_minus_one(); }
|
||||
// return true if \c n is a term of the form (* -1 r)
|
||||
bool is_times_minus_one(expr * n, expr * & r) const {
|
||||
if (is_mul(n) && to_app(n)->get_num_args() == 2 && is_minus_one(to_app(n)->get_arg(0))) {
|
||||
r = to_app(n)->get_arg(1);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
bool is_le(expr const * n) const { return is_app_of(n, m_afid, OP_LE); }
|
||||
bool is_ge(expr const * n) const { return is_app_of(n, m_afid, OP_GE); }
|
||||
bool is_lt(expr const * n) const { return is_app_of(n, m_afid, OP_LT); }
|
||||
bool is_gt(expr const * n) const { return is_app_of(n, m_afid, OP_GT); }
|
||||
bool is_add(expr const * n) const { return is_app_of(n, m_afid, OP_ADD); }
|
||||
bool is_sub(expr const * n) const { return is_app_of(n, m_afid, OP_SUB); }
|
||||
bool is_uminus(expr const * n) const { return is_app_of(n, m_afid, OP_UMINUS); }
|
||||
bool is_mul(expr const * n) const { return is_app_of(n, m_afid, OP_MUL); }
|
||||
bool is_div(expr const * n) const { return is_app_of(n, m_afid, OP_DIV); }
|
||||
bool is_idiv(expr const * n) const { return is_app_of(n, m_afid, OP_IDIV); }
|
||||
bool is_mod(expr const * n) const { return is_app_of(n, m_afid, OP_MOD); }
|
||||
bool is_rem(expr const * n) const { return is_app_of(n, m_afid, OP_REM); }
|
||||
bool is_to_real(expr const * n) const { return is_app_of(n, m_afid, OP_TO_REAL); }
|
||||
bool is_to_int(expr const * n) const { return is_app_of(n, m_afid, OP_TO_INT); }
|
||||
bool is_is_int(expr const * n) const { return is_app_of(n, m_afid, OP_IS_INT); }
|
||||
bool is_power(expr const * n) const { return is_app_of(n, m_afid, OP_POWER); }
|
||||
|
||||
bool is_int(sort const * s) const { return is_sort_of(s, m_afid, INT_SORT); }
|
||||
bool is_int(expr const * n) const { return is_int(m_manager.get_sort(n)); }
|
||||
bool is_real(sort const * s) const { return is_sort_of(s, m_afid, REAL_SORT); }
|
||||
bool is_real(expr const * n) const { return is_real(m_manager.get_sort(n)); }
|
||||
bool is_int_real(sort const * s) const { return s->get_family_id() == m_afid; }
|
||||
bool is_int_real(expr const * n) const { return is_int_real(m_manager.get_sort(n)); }
|
||||
|
||||
MATCH_UNARY(is_uminus);
|
||||
|
||||
MATCH_BINARY(is_sub);
|
||||
MATCH_BINARY(is_add);
|
||||
MATCH_BINARY(is_mul);
|
||||
MATCH_BINARY(is_le);
|
||||
MATCH_BINARY(is_ge);
|
||||
MATCH_BINARY(is_lt);
|
||||
MATCH_BINARY(is_gt);
|
||||
MATCH_BINARY(is_mod);
|
||||
MATCH_BINARY(is_rem);
|
||||
MATCH_BINARY(is_div);
|
||||
MATCH_BINARY(is_idiv);
|
||||
|
||||
|
||||
sort * mk_int() { return m_manager.mk_sort(m_afid, INT_SORT); }
|
||||
sort * mk_real() { return m_manager.mk_sort(m_afid, REAL_SORT); }
|
||||
|
||||
app * mk_numeral(rational const & val, bool is_int) const {
|
||||
return plugin().mk_numeral(val, is_int);
|
||||
}
|
||||
app * mk_numeral(rational const & val, sort const * s) const {
|
||||
SASSERT(is_int(s) || is_real(s));
|
||||
return mk_numeral(val, is_int(s));
|
||||
}
|
||||
app * mk_numeral(algebraic_numbers::anum const & val, bool is_int) {
|
||||
return plugin().mk_numeral(val, is_int);
|
||||
}
|
||||
app * mk_numeral(sexpr const * p, unsigned i) {
|
||||
return plugin().mk_numeral(p, i);
|
||||
}
|
||||
app * mk_le(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_LE, arg1, arg2); }
|
||||
app * mk_ge(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_GE, arg1, arg2); }
|
||||
app * mk_lt(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_LT, arg1, arg2); }
|
||||
app * mk_gt(expr * arg1, expr * arg2) const { return m_manager.mk_app(m_afid, OP_GT, arg1, arg2); }
|
||||
|
||||
app * mk_add(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_afid, OP_ADD, num_args, args); }
|
||||
app * mk_add(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2); }
|
||||
app * mk_add(expr * arg1, expr * arg2, expr* arg3) { return m_manager.mk_app(m_afid, OP_ADD, arg1, arg2, arg3); }
|
||||
|
||||
app * mk_sub(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_SUB, arg1, arg2); }
|
||||
app * mk_sub(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_afid, OP_SUB, num_args, args); }
|
||||
app * mk_mul(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2); }
|
||||
app * mk_mul(expr * arg1, expr * arg2, expr* arg3) { return m_manager.mk_app(m_afid, OP_MUL, arg1, arg2, arg3); }
|
||||
app * mk_mul(unsigned num_args, expr * const * args) { return m_manager.mk_app(m_afid, OP_MUL, num_args, args); }
|
||||
app * mk_uminus(expr * arg) { return m_manager.mk_app(m_afid, OP_UMINUS, arg); }
|
||||
app * mk_div(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_DIV, arg1, arg2); }
|
||||
app * mk_idiv(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_IDIV, arg1, arg2); }
|
||||
app * mk_rem(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_REM, arg1, arg2); }
|
||||
app * mk_mod(expr * arg1, expr * arg2) { return m_manager.mk_app(m_afid, OP_MOD, arg1, arg2); }
|
||||
app * mk_to_real(expr * arg1) { return m_manager.mk_app(m_afid, OP_TO_REAL, arg1); }
|
||||
app * mk_to_int(expr * arg1) { return m_manager.mk_app(m_afid, OP_TO_INT, arg1); }
|
||||
app * mk_is_int(expr * arg1) { return m_manager.mk_app(m_afid, OP_IS_INT, arg1); }
|
||||
app * mk_power(expr* arg1, expr* arg2) { return m_manager.mk_app(m_afid, OP_POWER, arg1, arg2); }
|
||||
|
||||
app * mk_sin(expr * arg) { return m_manager.mk_app(m_afid, OP_SIN, arg); }
|
||||
app * mk_cos(expr * arg) { return m_manager.mk_app(m_afid, OP_COS, arg); }
|
||||
app * mk_tan(expr * arg) { return m_manager.mk_app(m_afid, OP_TAN, arg); }
|
||||
app * mk_asin(expr * arg) { return m_manager.mk_app(m_afid, OP_ASIN, arg); }
|
||||
app * mk_acos(expr * arg) { return m_manager.mk_app(m_afid, OP_ACOS, arg); }
|
||||
app * mk_atan(expr * arg) { return m_manager.mk_app(m_afid, OP_ATAN, arg); }
|
||||
|
||||
app * mk_sinh(expr * arg) { return m_manager.mk_app(m_afid, OP_SINH, arg); }
|
||||
app * mk_cosh(expr * arg) { return m_manager.mk_app(m_afid, OP_COSH, arg); }
|
||||
app * mk_tanh(expr * arg) { return m_manager.mk_app(m_afid, OP_TANH, arg); }
|
||||
app * mk_asinh(expr * arg) { return m_manager.mk_app(m_afid, OP_ASINH, arg); }
|
||||
app * mk_acosh(expr * arg) { return m_manager.mk_app(m_afid, OP_ACOSH, arg); }
|
||||
app * mk_atanh(expr * arg) { return m_manager.mk_app(m_afid, OP_ATANH, arg); }
|
||||
|
||||
bool is_pi(expr * arg) { return is_app_of(arg, m_afid, OP_PI); }
|
||||
bool is_e(expr * arg) { return is_app_of(arg, m_afid, OP_E); }
|
||||
|
||||
app * mk_pi() { return plugin().mk_pi(); }
|
||||
app * mk_e() { return plugin().mk_e(); }
|
||||
|
||||
/**
|
||||
\brief Return the equality (= lhs rhs), but it makes sure that
|
||||
if one of the arguments is a numeral, then it will be in the right-hand-side;
|
||||
if none of them are numerals, then the left-hand-side has a smaller id than the right hand side.
|
||||
*/
|
||||
app * mk_eq(expr * lhs, expr * rhs) {
|
||||
if (is_numeral(lhs) || (!is_numeral(rhs) && lhs->get_id() > rhs->get_id()))
|
||||
std::swap(lhs, rhs);
|
||||
if (lhs == rhs)
|
||||
return m_manager.mk_true();
|
||||
if (is_numeral(lhs) && is_numeral(rhs)) {
|
||||
SASSERT(lhs != rhs);
|
||||
return m_manager.mk_false();
|
||||
}
|
||||
return m_manager.mk_eq(lhs, rhs);
|
||||
}
|
||||
|
||||
void set_cancel(bool f) {
|
||||
plugin().set_cancel(f);
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _ARITH_DECL_PLUGIN_H_ */
|
||||
|
570
src/ast/array_decl_plugin.cpp
Normal file
570
src/ast/array_decl_plugin.cpp
Normal file
|
@ -0,0 +1,570 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_decl_plugin.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-09
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#include<sstream>
|
||||
#include"array_decl_plugin.h"
|
||||
#include"warning.h"
|
||||
#include"ast_pp.h"
|
||||
#include"ast_ll_pp.h"
|
||||
|
||||
array_decl_plugin::array_decl_plugin():
|
||||
m_store_sym("store"),
|
||||
m_select_sym("select"),
|
||||
m_const_sym("const"),
|
||||
m_default_sym("default"),
|
||||
m_map_sym("map"),
|
||||
m_set_union_sym("union"),
|
||||
m_set_intersect_sym("intersect"),
|
||||
m_set_difference_sym("difference"),
|
||||
m_set_complement_sym("complement"),
|
||||
m_set_subset_sym("subset"),
|
||||
m_array_ext_sym("array-ext"),
|
||||
m_as_array_sym("as-array") {
|
||||
}
|
||||
|
||||
#define ARRAY_SORT_STR "Array"
|
||||
|
||||
sort * array_decl_plugin::mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters) {
|
||||
SASSERT(k == ARRAY_SORT);
|
||||
if (num_parameters < 2) {
|
||||
m_manager->raise_exception("invalid array sort definition, invalid number of parameters");
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < num_parameters; i++) {
|
||||
if (!parameters[i].is_ast() || !is_sort(parameters[i].get_ast())) {
|
||||
m_manager->raise_exception("invalid array sort definition, parameter is not a sort");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
sort * range = to_sort(parameters[num_parameters - 1].get_ast());
|
||||
TRACE("array_decl_plugin_bug", tout << mk_pp(range, *m_manager) << "\n";);
|
||||
if (!range->is_infinite() && !range->is_very_big() && (1 == range->get_num_elements().size())) {
|
||||
return m_manager->mk_sort(symbol(ARRAY_SORT_STR), sort_info(m_family_id, ARRAY_SORT, 1,
|
||||
num_parameters, parameters));
|
||||
}
|
||||
bool is_infinite = false;
|
||||
bool is_very_big = false;
|
||||
for (unsigned i = 0; i < num_parameters; i++) {
|
||||
sort * s = to_sort(parameters[i].get_ast());
|
||||
if (s->is_infinite()) {
|
||||
is_infinite = true;
|
||||
}
|
||||
if (s->is_very_big()) {
|
||||
is_very_big = true;
|
||||
}
|
||||
}
|
||||
if (is_infinite) {
|
||||
return m_manager->mk_sort(symbol(ARRAY_SORT_STR), sort_info(m_family_id, ARRAY_SORT, num_parameters, parameters));
|
||||
}
|
||||
else if (is_very_big) {
|
||||
return m_manager->mk_sort(symbol(ARRAY_SORT_STR), sort_info(m_family_id, ARRAY_SORT, sort_size::mk_very_big(),
|
||||
num_parameters, parameters));
|
||||
}
|
||||
else {
|
||||
rational domain_sz(1);
|
||||
rational num_elements;
|
||||
for (unsigned i = 0; i < num_parameters - 1; i++) {
|
||||
domain_sz *= rational(to_sort(parameters[i].get_ast())->get_num_elements().size(),rational::ui64());
|
||||
}
|
||||
if (domain_sz <= rational(128)) {
|
||||
num_elements = rational(range->get_num_elements().size(),rational::ui64());
|
||||
num_elements = power(num_elements, static_cast<int>(domain_sz.get_int64()));
|
||||
}
|
||||
|
||||
if (domain_sz > rational(128) || !num_elements.is_uint64()) {
|
||||
// too many elements...
|
||||
return m_manager->mk_sort(symbol(ARRAY_SORT_STR),
|
||||
sort_info(m_family_id,
|
||||
ARRAY_SORT,
|
||||
sort_size::mk_very_big(),
|
||||
num_parameters,
|
||||
parameters));
|
||||
}
|
||||
else {
|
||||
return m_manager->mk_sort(symbol(ARRAY_SORT_STR), sort_info(m_family_id, ARRAY_SORT, num_elements.get_uint64(),
|
||||
num_parameters, parameters));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool array_decl_plugin::is_array_sort(sort* s) const {
|
||||
return m_family_id == s->get_family_id() && s->get_decl_kind() == ARRAY_SORT;
|
||||
}
|
||||
|
||||
|
||||
func_decl * array_decl_plugin::mk_const(sort * s, unsigned arity, sort * const * domain) {
|
||||
if (arity != 1) {
|
||||
m_manager->raise_exception("invalid const array definition, invalid domain size");
|
||||
return 0;
|
||||
}
|
||||
unsigned num_parameters = s->get_num_parameters();
|
||||
|
||||
if (num_parameters == 0) {
|
||||
m_manager->raise_exception("parameter mismatch");
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TBD check that range sort corresponds to last parameter.
|
||||
|
||||
parameter param(s);
|
||||
func_decl_info info(m_family_id, OP_CONST_ARRAY, 1, ¶m);
|
||||
info.m_private_parameters = true;
|
||||
return m_manager->mk_func_decl(m_const_sym, arity, domain, s, info);
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_map(func_decl* f, unsigned arity, sort* const* domain) {
|
||||
if (arity != f->get_arity()) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "map expects to take as many arguments as the function being mapped, "
|
||||
<< "it was given " << arity << " but expects " << f->get_arity();
|
||||
m_manager->raise_exception(buffer.str().c_str());
|
||||
return 0;
|
||||
}
|
||||
if (arity == 0) {
|
||||
m_manager->raise_exception("don't use map on constants");
|
||||
return 0;
|
||||
}
|
||||
//
|
||||
// check that each domain[i] is an array sort
|
||||
// with the same domains and same ranges.
|
||||
// and that the ranges coincide with the domain of f.
|
||||
//
|
||||
unsigned dom_arity = get_array_arity(domain[0]);
|
||||
for (unsigned i = 0; i < arity; ++i) {
|
||||
if (!is_array_sort(domain[i])) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "map expects an array sort as argument at position " << i;
|
||||
m_manager->raise_exception(buffer.str().c_str());
|
||||
return 0;
|
||||
}
|
||||
if (get_array_arity(domain[i]) != dom_arity) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "map expects all arguments to have the same array domain, "
|
||||
<< "this is not the case for argument " << i;
|
||||
m_manager->raise_exception(buffer.str().c_str());
|
||||
return 0;
|
||||
}
|
||||
for (unsigned j = 0; j < dom_arity; ++j) {
|
||||
if (get_array_domain(domain[i],j) != get_array_domain(domain[0],j)) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "map expects all arguments to have the same array domain, "
|
||||
<< "this is not the case for argument " << i;
|
||||
m_manager->raise_exception(buffer.str().c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (get_array_range(domain[i]) != f->get_domain(i)) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "map expects the argument at position " << i
|
||||
<< " to have the array range the same as the function";
|
||||
m_manager->raise_exception(buffer.str().c_str());
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
vector<parameter> parameters;
|
||||
for (unsigned i = 0; i < dom_arity; ++i) {
|
||||
parameters.push_back(domain[0]->get_parameter(i));
|
||||
}
|
||||
parameters.push_back(parameter(f->get_range()));
|
||||
sort* range = mk_sort(ARRAY_SORT, parameters.size(), parameters.c_ptr());
|
||||
parameter param(f);
|
||||
func_decl_info info(m_family_id, OP_ARRAY_MAP, 1, ¶m);
|
||||
//
|
||||
// left_associative, right_associative, commutative are inherited.
|
||||
// m_injective is inherited, since:
|
||||
// forall x . g(f(x)) = x implies forall X . map(g)(map(f)(X)) = X
|
||||
// since map(g)(map(f)(X))[i] = g(f(X[i])) = X[i]
|
||||
//
|
||||
|
||||
info.set_right_associative(f->is_right_associative());
|
||||
info.set_left_associative(f->is_left_associative());
|
||||
info.set_commutative(f->is_commutative());
|
||||
info.set_injective(f->is_injective());
|
||||
return m_manager->mk_func_decl(m_map_sym, arity, domain, range, info);
|
||||
}
|
||||
|
||||
|
||||
func_decl * array_decl_plugin::mk_default(unsigned domain_size, sort * const * domain) {
|
||||
if (domain_size != 1) {
|
||||
m_manager->raise_exception("invalid default array definition, invalid domain size");
|
||||
return 0;
|
||||
}
|
||||
// check that domain[0] is an array sort.
|
||||
unsigned num_parameters = domain[0]->get_num_parameters();
|
||||
|
||||
if (num_parameters <= 1) {
|
||||
m_manager->raise_exception("parameter mismatch. There should be more than one parameter to defaults");
|
||||
return 0;
|
||||
}
|
||||
parameter param(domain[0]->get_parameter(num_parameters-1));
|
||||
if (!param.is_ast() || !is_sort(param.get_ast())) {
|
||||
m_manager->raise_exception("last parameter should be a sort");
|
||||
return 0;
|
||||
}
|
||||
sort * s = to_sort(param.get_ast());
|
||||
|
||||
return m_manager->mk_func_decl(m_default_sym, domain_size, domain, s,
|
||||
func_decl_info(m_family_id, OP_ARRAY_DEFAULT));
|
||||
}
|
||||
|
||||
|
||||
func_decl* array_decl_plugin::mk_select(unsigned arity, sort * const * domain) {
|
||||
if (arity <= 1) {
|
||||
m_manager->raise_exception("select takes at least two arguments");
|
||||
return 0;
|
||||
}
|
||||
sort * s = domain[0];
|
||||
unsigned num_parameters = s->get_num_parameters();
|
||||
parameter const* parameters = s->get_parameters();
|
||||
|
||||
if (num_parameters != arity) {
|
||||
m_manager->raise_exception("select requires as many arguments as the size of the domain");
|
||||
return 0;
|
||||
}
|
||||
ptr_buffer<sort> new_domain; // we need this because of coercions.
|
||||
new_domain.push_back(s);
|
||||
for (unsigned i = 0; i + 1 < num_parameters; ++i) {
|
||||
if (!parameters[i].is_ast() ||
|
||||
!is_sort(parameters[i].get_ast()) ||
|
||||
!m_manager->compatible_sorts(domain[i+1], to_sort(parameters[i].get_ast()))) {
|
||||
m_manager->raise_exception("domain sort and parameter do not match");
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
new_domain.push_back(to_sort(parameters[i].get_ast()));
|
||||
}
|
||||
SASSERT(new_domain.size() == arity);
|
||||
return m_manager->mk_func_decl(m_select_sym, arity, new_domain.c_ptr(), get_array_range(domain[0]),
|
||||
func_decl_info(m_family_id, OP_SELECT));
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_store(unsigned arity, sort * const * domain) {
|
||||
if (arity < 3) {
|
||||
m_manager->raise_exception("store takes at least 3 arguments");
|
||||
return 0;
|
||||
}
|
||||
sort * s = domain[0];
|
||||
unsigned num_parameters = s->get_num_parameters();
|
||||
parameter const * parameters = s->get_parameters();
|
||||
if (!is_array_sort(s)) {
|
||||
m_manager->raise_exception("store expects the first argument sort to be an array");
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
if (arity != num_parameters+1) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "store expects the first argument to be an array taking " << num_parameters+1
|
||||
<< ", instead it was passed " << (arity - 1) << "arguments";
|
||||
m_manager->raise_exception(buffer.str().c_str());
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
ptr_buffer<sort> new_domain; // we need this because of coercions.
|
||||
new_domain.push_back(s);
|
||||
for (unsigned i = 0; i < num_parameters; ++i) {
|
||||
if (!parameters[i].is_ast() || !is_sort(parameters[i].get_ast())) {
|
||||
m_manager->raise_exception("expecting sort parameter");
|
||||
return 0;
|
||||
}
|
||||
if (!m_manager->compatible_sorts(to_sort(parameters[i].get_ast()), domain[i+1])) {
|
||||
m_manager->raise_exception("domain sort and parameter do not match");
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
new_domain.push_back(to_sort(parameters[i].get_ast()));
|
||||
}
|
||||
SASSERT(new_domain.size() == arity);
|
||||
return m_manager->mk_func_decl(m_store_sym, arity, new_domain.c_ptr(), domain[0],
|
||||
func_decl_info(m_family_id, OP_STORE));
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_array_ext_skolem(unsigned arity, sort * const * domain, unsigned i) {
|
||||
if (arity != 2 || domain[0] != domain[1]) {
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
sort * s = domain[0];
|
||||
unsigned num_parameters = s->get_num_parameters();
|
||||
if (num_parameters == 0 || i >= num_parameters - 1) {
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
sort * r = to_sort(s->get_parameter(i).get_ast());
|
||||
parameter param(s);
|
||||
return m_manager->mk_func_decl(m_array_ext_sym, arity, domain, r, func_decl_info(m_family_id, OP_ARRAY_EXT_SKOLEM, 1, ¶m));
|
||||
}
|
||||
|
||||
|
||||
bool array_decl_plugin::check_set_arguments(unsigned arity, sort * const * domain) {
|
||||
for (unsigned i = 0; i < arity; ++i) {
|
||||
if (domain[i] != domain[0]) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "arguments " << 1 << " and " << (i+1) << " have different sorts";
|
||||
m_manager->raise_exception(buffer.str().c_str());
|
||||
return false;
|
||||
}
|
||||
if (domain[i]->get_family_id() != m_family_id) {
|
||||
std::ostringstream buffer;
|
||||
buffer << "argument " << (i+1) << " is not of array sort";
|
||||
m_manager->raise_exception(buffer.str().c_str());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (arity > 0) {
|
||||
unsigned num_params = domain[0]->get_num_parameters();
|
||||
parameter const* params = domain[0]->get_parameters();
|
||||
if (1 >= num_params) {
|
||||
m_manager->raise_exception("expecting 2 or more parameters");
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
if (!params[num_params-1].is_ast()) {
|
||||
m_manager->raise_exception("expecting term parameters");
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
if (!is_sort(params[num_params-1].get_ast()) || !m_manager->is_bool(to_sort(params[num_params-1].get_ast()))) {
|
||||
m_manager->raise_exception("expecting boolean range");
|
||||
UNREACHABLE();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_set_union(unsigned arity, sort * const * domain) {
|
||||
|
||||
if (arity == 0) {
|
||||
m_manager->raise_exception("union takes at least one argument");
|
||||
return 0;
|
||||
}
|
||||
sort * s = domain[0];
|
||||
if (!check_set_arguments(arity, domain)) {
|
||||
return 0;
|
||||
}
|
||||
parameter param(s);
|
||||
func_decl_info info(m_family_id, OP_SET_UNION, 1, ¶m);
|
||||
info.set_associative();
|
||||
info.set_commutative();
|
||||
info.set_idempotent();
|
||||
sort* domain2[2] = { domain[0], domain[0] };
|
||||
return m_manager->mk_func_decl(m_set_union_sym, 2, domain2, domain[0], info);
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_set_intersect(unsigned arity, sort * const * domain) {
|
||||
|
||||
if (arity == 0) {
|
||||
m_manager->raise_exception("intersection takes at least one argument");
|
||||
return 0;
|
||||
}
|
||||
if (!check_set_arguments(arity, domain)) {
|
||||
return 0;
|
||||
}
|
||||
func_decl_info info(m_family_id, OP_SET_INTERSECT);
|
||||
info.set_associative();
|
||||
info.set_commutative();
|
||||
info.set_idempotent();
|
||||
sort* domain2[2] = { domain[0], domain[0] };
|
||||
return m_manager->mk_func_decl(m_set_intersect_sym, 2, domain2, domain[0], info);
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_set_difference(unsigned arity, sort * const * domain) {
|
||||
if (arity != 2) {
|
||||
m_manager->raise_exception("set difference takes precisely two arguments");
|
||||
return 0;
|
||||
}
|
||||
if (!check_set_arguments(arity, domain)) {
|
||||
return 0;
|
||||
}
|
||||
return m_manager->mk_func_decl(m_set_difference_sym, arity, domain, domain[0],
|
||||
func_decl_info(m_family_id, OP_SET_DIFFERENCE));
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_set_complement(unsigned arity, sort * const * domain) {
|
||||
if (arity != 1) {
|
||||
m_manager->raise_exception("set complement takes one argument");
|
||||
return 0;
|
||||
}
|
||||
if (!check_set_arguments(arity, domain)) {
|
||||
return 0;
|
||||
}
|
||||
return m_manager->mk_func_decl(m_set_complement_sym, arity, domain, domain[0],
|
||||
func_decl_info(m_family_id, OP_SET_COMPLEMENT));
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_set_subset(unsigned arity, sort * const * domain) {
|
||||
if (arity != 2) {
|
||||
m_manager->raise_exception("subset takes two arguments");
|
||||
return 0;
|
||||
}
|
||||
if (!check_set_arguments(arity, domain)) {
|
||||
return 0;
|
||||
}
|
||||
sort * bool_sort = m_manager->mk_bool_sort();
|
||||
return m_manager->mk_func_decl(m_set_subset_sym, arity, domain, bool_sort,
|
||||
func_decl_info(m_family_id, OP_SET_SUBSET));
|
||||
}
|
||||
|
||||
func_decl * array_decl_plugin::mk_as_array(func_decl * f) {
|
||||
vector<parameter> parameters;
|
||||
for (unsigned i = 0; i < f->get_arity(); i++) {
|
||||
parameters.push_back(parameter(f->get_domain(i)));
|
||||
}
|
||||
parameters.push_back(parameter(f->get_range()));
|
||||
sort * s = mk_sort(ARRAY_SORT, parameters.size(), parameters.c_ptr());
|
||||
parameter param(f);
|
||||
func_decl_info info(m_family_id, OP_AS_ARRAY, 1, ¶m);
|
||||
return m_manager->mk_const_decl(m_as_array_sym, s, info);
|
||||
}
|
||||
|
||||
|
||||
func_decl * array_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned arity, sort * const * domain, sort * range) {
|
||||
switch (k) {
|
||||
case OP_SELECT:
|
||||
return mk_select(arity, domain);
|
||||
case OP_STORE:
|
||||
return mk_store(arity, domain);
|
||||
case OP_CONST_ARRAY: {
|
||||
if (num_parameters == 1 && parameters[0].is_ast() && is_sort(parameters[0].get_ast())) {
|
||||
sort * s = to_sort(parameters[0].get_ast());
|
||||
return mk_const(s, arity, domain);
|
||||
}
|
||||
else if (range != 0) {
|
||||
return mk_const(range, arity, domain);
|
||||
}
|
||||
else {
|
||||
m_manager->raise_exception("array operation requires one sort parameter (the array sort)");
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
case OP_ARRAY_MAP: {
|
||||
if (num_parameters != 1 || !parameters[0].is_ast() || !is_func_decl(parameters[0].get_ast())) {
|
||||
m_manager->raise_exception("array operation requires one function declaration parameter (the function to be mapped)");
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
func_decl * f = to_func_decl(parameters[0].get_ast());
|
||||
return mk_map(f, arity, domain);
|
||||
}
|
||||
case OP_ARRAY_EXT_SKOLEM:
|
||||
if (num_parameters != 1 || !parameters[0].is_int()) {
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
return mk_array_ext_skolem(arity, domain, parameters[0].get_int());
|
||||
case OP_ARRAY_DEFAULT:
|
||||
return mk_default(arity, domain);
|
||||
case OP_SET_UNION:
|
||||
return mk_set_union(arity, domain);
|
||||
case OP_SET_INTERSECT:
|
||||
return mk_set_intersect(arity, domain);
|
||||
case OP_SET_DIFFERENCE:
|
||||
return mk_set_difference(arity, domain);
|
||||
case OP_SET_COMPLEMENT:
|
||||
return mk_set_complement(arity, domain);
|
||||
case OP_SET_SUBSET:
|
||||
return mk_set_subset(arity, domain);
|
||||
case OP_AS_ARRAY: {
|
||||
if (num_parameters != 1 ||
|
||||
!parameters[0].is_ast() ||
|
||||
!is_func_decl(parameters[0].get_ast()) ||
|
||||
to_func_decl(parameters[0].get_ast())->get_arity() == 0) {
|
||||
TRACE("array_bug",
|
||||
tout << "num_parameters: " << num_parameters << std::endl;
|
||||
tout << "parameter.kind: " << parameters[0].is_int() << " " << parameters[0].is_ast() << " " << parameters[0].is_symbol() << "\n";
|
||||
tout << "as-array-bug: " << to_func_decl(parameters[0].get_ast())->get_name() << " " << to_func_decl(parameters[0].get_ast())->get_arity() << std::endl;);
|
||||
m_manager->raise_exception("as-array takes one parameter, a function declaration with arity greater than zero");
|
||||
UNREACHABLE();
|
||||
return 0;
|
||||
}
|
||||
func_decl * f = to_func_decl(parameters[0].get_ast());
|
||||
return mk_as_array(f);
|
||||
}
|
||||
default: return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void array_decl_plugin::get_sort_names(svector<builtin_name>& sort_names, symbol const & logic) {
|
||||
sort_names.push_back(builtin_name(ARRAY_SORT_STR, ARRAY_SORT));
|
||||
}
|
||||
|
||||
void array_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol const & logic) {
|
||||
op_names.push_back(builtin_name("store",OP_STORE));
|
||||
op_names.push_back(builtin_name("select",OP_SELECT));
|
||||
if (logic == symbol::null) {
|
||||
// none of the SMT2 logics support these extensions
|
||||
op_names.push_back(builtin_name("const",OP_CONST_ARRAY));
|
||||
op_names.push_back(builtin_name("map",OP_ARRAY_MAP));
|
||||
op_names.push_back(builtin_name("default",OP_ARRAY_DEFAULT));
|
||||
op_names.push_back(builtin_name("union",OP_SET_UNION));
|
||||
op_names.push_back(builtin_name("intersect",OP_SET_INTERSECT));
|
||||
op_names.push_back(builtin_name("difference",OP_SET_DIFFERENCE));
|
||||
op_names.push_back(builtin_name("complement",OP_SET_COMPLEMENT));
|
||||
op_names.push_back(builtin_name("subset",OP_SET_SUBSET));
|
||||
op_names.push_back(builtin_name("as-array", OP_AS_ARRAY));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
expr * array_decl_plugin::get_some_value(sort * s) {
|
||||
SASSERT(s->is_sort_of(m_family_id, ARRAY_SORT));
|
||||
sort * r = to_sort(s->get_parameter(s->get_num_parameters() - 1).get_ast());
|
||||
expr * v = m_manager->get_some_value(r);
|
||||
parameter p(s);
|
||||
return m_manager->mk_app(m_family_id, OP_CONST_ARRAY, 1, &p, 1, &v);
|
||||
}
|
||||
|
||||
bool array_decl_plugin::is_fully_interp(sort const * s) const {
|
||||
SASSERT(s->is_sort_of(m_family_id, ARRAY_SORT));
|
||||
unsigned sz = get_array_arity(s);
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (!m_manager->is_fully_interp(get_array_domain(s, i)))
|
||||
return false;
|
||||
}
|
||||
return m_manager->is_fully_interp(get_array_range(s));
|
||||
}
|
||||
|
||||
bool array_util::is_as_array_tree(expr * n) {
|
||||
ptr_buffer<expr, 32> todo;
|
||||
todo.push_back(n);
|
||||
while (!todo.empty()) {
|
||||
expr * curr = todo.back();
|
||||
todo.pop_back();
|
||||
if (is_as_array(curr))
|
||||
continue;
|
||||
if (m_manager.is_ite(curr)) {
|
||||
todo.push_back(to_app(curr)->get_arg(1));
|
||||
todo.push_back(to_app(curr)->get_arg(2));
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
sort * array_util::mk_array_sort(unsigned arity, sort* const* domain, sort* range) {
|
||||
vector<parameter> params;
|
||||
for (unsigned i = 0; i < arity; ++i) {
|
||||
params.push_back(parameter(domain[i]));
|
||||
}
|
||||
params.push_back(parameter(range));
|
||||
return m_manager.mk_sort(m_fid, ARRAY_SORT, params.size(), params.c_ptr());
|
||||
}
|
170
src/ast/array_decl_plugin.h
Normal file
170
src/ast/array_decl_plugin.h
Normal file
|
@ -0,0 +1,170 @@
|
|||
/*++
|
||||
Copyright (c) 2006 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_decl_plugin.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2008-01-09.
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ARRAY_DECL_PLUGIN_H_
|
||||
#define _ARRAY_DECL_PLUGIN_H_
|
||||
|
||||
#include"ast.h"
|
||||
|
||||
|
||||
inline sort* get_array_range(sort const * s) {
|
||||
return to_sort(s->get_parameter(s->get_num_parameters() - 1).get_ast());
|
||||
}
|
||||
|
||||
inline unsigned get_array_arity(sort const * s) {
|
||||
return s->get_num_parameters() -1;
|
||||
}
|
||||
|
||||
inline sort* get_array_domain(sort const * s, unsigned idx) {
|
||||
return to_sort(s->get_parameter(idx).get_ast());
|
||||
}
|
||||
|
||||
enum array_sort_kind {
|
||||
ARRAY_SORT
|
||||
};
|
||||
|
||||
enum array_op_kind {
|
||||
OP_STORE,
|
||||
OP_SELECT,
|
||||
OP_CONST_ARRAY,
|
||||
OP_ARRAY_EXT_SKOLEM,
|
||||
OP_ARRAY_DEFAULT,
|
||||
OP_ARRAY_MAP,
|
||||
OP_SET_UNION,
|
||||
OP_SET_INTERSECT,
|
||||
OP_SET_DIFFERENCE,
|
||||
OP_SET_COMPLEMENT,
|
||||
OP_SET_SUBSET,
|
||||
OP_AS_ARRAY, // used for model construction
|
||||
LAST_ARRAY_OP
|
||||
};
|
||||
|
||||
class array_decl_plugin : public decl_plugin {
|
||||
symbol m_store_sym;
|
||||
symbol m_select_sym;
|
||||
symbol m_const_sym;
|
||||
symbol m_default_sym;
|
||||
symbol m_map_sym;
|
||||
symbol m_set_union_sym;
|
||||
symbol m_set_intersect_sym;
|
||||
symbol m_set_difference_sym;
|
||||
symbol m_set_complement_sym;
|
||||
symbol m_set_subset_sym;
|
||||
symbol m_array_ext_sym;
|
||||
symbol m_as_array_sym;
|
||||
|
||||
bool check_set_arguments(unsigned arity, sort * const * domain);
|
||||
|
||||
func_decl * mk_const(sort* ty, unsigned arity, sort * const * domain);
|
||||
|
||||
func_decl * mk_map(func_decl* f, unsigned arity, sort* const* domain);
|
||||
|
||||
func_decl * mk_default(unsigned arity, sort* const* domain);
|
||||
|
||||
func_decl * mk_select(unsigned arity, sort * const * domain);
|
||||
|
||||
func_decl * mk_store(unsigned arity, sort * const * domain);
|
||||
|
||||
func_decl * mk_array_ext_skolem(unsigned arity, sort * const * domain, unsigned i);
|
||||
|
||||
func_decl * mk_set_union(unsigned arity, sort * const * domain);
|
||||
|
||||
func_decl * mk_set_intersect(unsigned arity, sort * const * domain);
|
||||
|
||||
func_decl * mk_set_difference(unsigned arity, sort * const * domain);
|
||||
|
||||
func_decl * mk_set_complement(unsigned arity, sort * const * domain);
|
||||
|
||||
func_decl * mk_set_subset(unsigned arity, sort * const * domain);
|
||||
|
||||
func_decl * mk_as_array(func_decl * f);
|
||||
|
||||
bool is_array_sort(sort* s) const;
|
||||
public:
|
||||
array_decl_plugin();
|
||||
virtual ~array_decl_plugin() {}
|
||||
|
||||
virtual decl_plugin * mk_fresh() {
|
||||
return alloc(array_decl_plugin);
|
||||
}
|
||||
|
||||
//
|
||||
// Contract for sort:
|
||||
// parameters[0] - 1st dimension
|
||||
// ...
|
||||
// parameters[n-1] - nth dimension
|
||||
// parameters[n] - range
|
||||
//
|
||||
virtual sort * mk_sort(decl_kind k, unsigned num_parameters, parameter const * parameters);
|
||||
|
||||
//
|
||||
// Contract for func_decl:
|
||||
// parameters[0] - array sort
|
||||
// Contract for others:
|
||||
// no parameters
|
||||
virtual func_decl * mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
|
||||
unsigned arity, sort * const * domain, sort * range);
|
||||
|
||||
virtual void get_op_names(svector<builtin_name> & op_names, symbol const & logic);
|
||||
|
||||
virtual void get_sort_names(svector<builtin_name> & sort_names, symbol const & logic);
|
||||
|
||||
virtual expr * get_some_value(sort * s);
|
||||
|
||||
virtual bool is_fully_interp(sort const * s) const;
|
||||
};
|
||||
|
||||
class array_util {
|
||||
ast_manager & m_manager;
|
||||
family_id m_fid;
|
||||
public:
|
||||
array_util(ast_manager& m): m_manager(m), m_fid(m.get_family_id("array")) {}
|
||||
ast_manager & get_manager() const { return m_manager; }
|
||||
family_id get_family_id() const { return m_fid; }
|
||||
bool is_array(sort* s) const { return is_sort_of(s, m_fid, ARRAY_SORT);}
|
||||
bool is_array(expr* n) const { return is_array(m_manager.get_sort(n)); }
|
||||
bool is_select(expr* n) const { return is_app_of(n, m_fid, OP_SELECT); }
|
||||
bool is_store(expr* n) const { return is_app_of(n, m_fid, OP_STORE); }
|
||||
bool is_const(expr* n) const { return is_app_of(n, m_fid, OP_CONST_ARRAY); }
|
||||
bool is_map(expr* n) const { return is_app_of(n, m_fid, OP_ARRAY_MAP); }
|
||||
bool is_as_array(expr * n) const { return is_app_of(n, m_fid, OP_AS_ARRAY); }
|
||||
bool is_as_array_tree(expr * n);
|
||||
func_decl * get_as_array_func_decl(app * n) const { SASSERT(is_as_array(n)); return to_func_decl(n->get_decl()->get_parameter(0).get_ast()); }
|
||||
app * mk_map(func_decl * f, unsigned num_args, expr * const * args) {
|
||||
parameter p(f);
|
||||
return m_manager.mk_app(m_fid, OP_ARRAY_MAP, 1, &p, num_args, args);
|
||||
}
|
||||
app * mk_const_array(sort * s, expr * v) {
|
||||
parameter param(s);
|
||||
return m_manager.mk_app(m_fid, OP_CONST_ARRAY, 1, ¶m, 1, &v);
|
||||
}
|
||||
app * mk_empty_set(sort * s) {
|
||||
return mk_const_array(s, m_manager.mk_false());
|
||||
}
|
||||
app * mk_full_set(sort * s) {
|
||||
return mk_const_array(s, m_manager.mk_true());
|
||||
}
|
||||
|
||||
sort * mk_array_sort(sort* dom, sort* range) { return mk_array_sort(1, &dom, range); }
|
||||
|
||||
sort * mk_array_sort(unsigned arity, sort* const* domain, sort* range);
|
||||
};
|
||||
|
||||
|
||||
#endif /* _ARRAY_DECL_PLUGIN_H_ */
|
||||
|
208
src/ast/array_property/array_property_expander.cpp
Normal file
208
src/ast/array_property/array_property_expander.cpp
Normal file
|
@ -0,0 +1,208 @@
|
|||
/*++
|
||||
Copyright (c) 2010 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_property_expander.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Expand array operations for the array property fragment formulas.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2010-16-12
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"array_property_expander.h"
|
||||
#include"obj_hashtable.h"
|
||||
#include"var_subst.h"
|
||||
#include"array_decl_plugin.h"
|
||||
#include"for_each_expr.h"
|
||||
|
||||
array_property_expander::array_property_expander(ast_manager& m):
|
||||
m_manager(m) {
|
||||
}
|
||||
|
||||
namespace array_property_exp {
|
||||
class proc {
|
||||
ast_manager& m_manager;
|
||||
unsigned& m_offset;
|
||||
expr_ref_vector m_trail;
|
||||
family_id m_fid;
|
||||
array_util m_util;
|
||||
obj_map<expr, expr*> m_mem;
|
||||
|
||||
|
||||
void insert(expr* a, expr* b) {
|
||||
m_trail.push_back(b);
|
||||
m_mem.insert(a, b);
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
proc(ast_manager& m, unsigned& offset) :
|
||||
m_manager(m),
|
||||
m_offset(offset),
|
||||
m_trail(m),
|
||||
m_fid(m.get_family_id("array")),
|
||||
m_util(m)
|
||||
{}
|
||||
|
||||
expr* find(expr* e) {
|
||||
expr* result = 0;
|
||||
VERIFY(m_mem.find(e, result));
|
||||
return result;
|
||||
}
|
||||
|
||||
void operator()(var* n) { insert(n, n); }
|
||||
|
||||
void operator()(quantifier* q) {
|
||||
expr* e = find(q->get_expr());
|
||||
quantifier* q2 = m_manager.update_quantifier(q, e);
|
||||
insert(q, q2);
|
||||
}
|
||||
|
||||
void operator()(app* n) {
|
||||
ast_manager& m = m_manager;
|
||||
unsigned num_args = n->get_num_args();
|
||||
ptr_buffer<expr> args;
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
args.push_back(find(n->get_arg(i)));
|
||||
}
|
||||
if (m_manager.is_eq(n) && m_util.is_array(args[0])) {
|
||||
visit_eq(n);
|
||||
return;
|
||||
}
|
||||
if (m_manager.is_distinct(n) && num_args > 0 && m_util.is_array(args[0])) {
|
||||
ptr_buffer<expr> eqs;
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
for (unsigned j = i + 1; j < num_args; ++j) {
|
||||
eqs.push_back(m.mk_not(m.mk_eq(args[i], args[j])));
|
||||
}
|
||||
}
|
||||
insert(n, m.mk_and(eqs.size(), eqs.c_ptr()));
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_util.is_select(n)) {
|
||||
SASSERT(num_args > 0);
|
||||
|
||||
// select(store(A,i,v),j) -> ite(i = j, v, select(A,j))
|
||||
if (m_util.is_store(args[0])) {
|
||||
app* a = to_app(args[0]);
|
||||
expr* b = find(a->get_arg(0));
|
||||
expr* v = find(a->get_arg(a->get_num_args()-1));
|
||||
ptr_buffer<expr> eqs;
|
||||
SASSERT(num_args + 1 == a->get_num_args());
|
||||
for (unsigned i = 1; i < num_args; ++i) {
|
||||
eqs.push_back(m.mk_eq(args[i], find(a->get_arg(i))));
|
||||
}
|
||||
expr* r = m.mk_ite(m.mk_and(eqs.size(), eqs.c_ptr()), v, mk_select(b, num_args-1, args.c_ptr()+1));
|
||||
insert(n, r);
|
||||
return;
|
||||
}
|
||||
|
||||
// select(ite(a,b,c),i) -> ite(a, select(b,i), select(c, i))
|
||||
if (m.is_ite(args[0])) {
|
||||
app* k = to_app(args[0]);
|
||||
expr* a = k->get_arg(0);
|
||||
expr* b = mk_select(k->get_arg(1), args.size()-1, args.c_ptr()+1);
|
||||
expr* c = mk_select(k->get_arg(2), args.size()-1, args.c_ptr()+1);
|
||||
expr* r = m.mk_ite(a, b, c);
|
||||
insert(n, r);
|
||||
return;
|
||||
}
|
||||
|
||||
// select(map_f(A,B),i) -> f(select(A,i), select(B,i))
|
||||
if (m_util.is_map(args[0])) {
|
||||
app* a = to_app(args[0]);
|
||||
func_decl* f = a->get_decl();
|
||||
SASSERT(f->get_num_parameters() == 1);
|
||||
SASSERT(f->get_parameter(0).is_ast());
|
||||
SASSERT(is_func_decl(f->get_parameter(0).get_ast()));
|
||||
parameter p = f->get_parameter(0);
|
||||
func_decl* d = to_func_decl(p.get_ast());
|
||||
ptr_buffer<expr> args2;
|
||||
for (unsigned i = 0; i < a->get_num_args(); ++i) {
|
||||
args2.push_back(mk_select(find(a->get_arg(i)), args.size()-1, args.c_ptr()+1));
|
||||
}
|
||||
expr* r = m.mk_app(d, args2.size(), args2.c_ptr());
|
||||
insert(n, r);
|
||||
return;
|
||||
}
|
||||
|
||||
// select(const v, i) -> v
|
||||
if (m_util.is_const(args[0])) {
|
||||
insert(n, to_app(args[0])->get_arg(0));
|
||||
return;
|
||||
}
|
||||
}
|
||||
expr* r = m_manager.mk_app(n->get_decl(), args.size(), args.c_ptr());
|
||||
insert(n, r);
|
||||
}
|
||||
|
||||
private:
|
||||
void visit_eq(app* eq) {
|
||||
ast_manager& m = m_manager;
|
||||
SASSERT(m.is_eq(eq));
|
||||
sort* s = m.get_sort(eq->get_arg(0));
|
||||
SASSERT(is_sort_of(s, m_fid, ARRAY_SORT));
|
||||
// sort* rng = get_array_range(s);
|
||||
unsigned arity = get_array_arity(s);
|
||||
shift_vars sh(m);
|
||||
expr_ref e1(m), e2(m);
|
||||
sh(find(eq->get_arg(0)), arity, e1);
|
||||
sh(find(eq->get_arg(1)), arity, e2);
|
||||
expr_ref_vector args(m);
|
||||
buffer<symbol> names;
|
||||
ptr_buffer<sort> sorts;
|
||||
args.push_back(e1);
|
||||
for (unsigned i = 0; i < arity; ++i) {
|
||||
args.push_back(m.mk_var(i, get_array_domain(s, i)));
|
||||
sorts.push_back(get_array_domain(s, arity - i - 1));
|
||||
names.push_back(symbol(m_offset++));
|
||||
}
|
||||
e1 = mk_select(args.size(), args.c_ptr());
|
||||
args[0] = e2;
|
||||
e2 = mk_select(args.size(), args.c_ptr());
|
||||
e1 = m.mk_eq(e1, e2);
|
||||
|
||||
e1 = m.mk_quantifier(true, arity, sorts.c_ptr(), names.c_ptr(), e1, 1);
|
||||
insert(eq, e1);
|
||||
}
|
||||
|
||||
app* mk_select(unsigned n, expr* const* args) {
|
||||
return m_manager.mk_app(m_fid, OP_SELECT, 0, 0, n, args);
|
||||
}
|
||||
|
||||
app* mk_select(expr* a, unsigned n, expr* const* args) {
|
||||
ptr_buffer<expr> args2;
|
||||
args2.push_back(a);
|
||||
args2.append(n, args);
|
||||
return mk_select(n+1, args2.c_ptr());
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
void array_property_expander::operator()(unsigned num_fmls, expr* const* fmls, expr_ref_vector& result) {
|
||||
ast_manager& m = m_manager;
|
||||
unsigned offset = 0;
|
||||
for (unsigned i = 0; i < num_fmls; ++i) {
|
||||
bool change = false;
|
||||
expr_ref e(m);
|
||||
result.push_back(fmls[i]);
|
||||
do {
|
||||
array_property_exp::proc p(m, offset);
|
||||
e = result[i].get();
|
||||
for_each_expr(p, e);
|
||||
result[i] = p.find(e);
|
||||
change = e != result[i].get();
|
||||
}
|
||||
while (change);
|
||||
}
|
||||
}
|
||||
|
33
src/ast/array_property/array_property_expander.h
Normal file
33
src/ast/array_property/array_property_expander.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*++
|
||||
Copyright (c) 2010 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_property_expander.h
|
||||
|
||||
Abstract:
|
||||
|
||||
Expand array operations for the array property fragment formulas.
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2010-16-12
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ARRAY_PROPERTY_EXPANDER_H_
|
||||
#define _ARRAY_PROPERTY_EXPANDER_H_
|
||||
|
||||
#include"ast.h"
|
||||
|
||||
class array_property_expander {
|
||||
ast_manager& m_manager;
|
||||
public:
|
||||
array_property_expander(ast_manager& m);
|
||||
void operator()(unsigned num_fmls, expr* const* fmls, expr_ref_vector& result);
|
||||
};
|
||||
|
||||
|
||||
#endif /* _ARRAY_PROPERTY_EXPANDER_H_ */
|
||||
|
103
src/ast/array_property/array_property_recognizer.cpp
Normal file
103
src/ast/array_property/array_property_recognizer.cpp
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*++
|
||||
Copyright (c) 2010 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_property_recognizer.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2010-16-12
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
|
||||
#include"array_decl_plugin.h"
|
||||
#include"array_property_recognizer.h"
|
||||
#include"for_each_expr.h"
|
||||
|
||||
|
||||
array_property_recognizer::array_property_recognizer(ast_manager& m):
|
||||
m_manager(m) {}
|
||||
|
||||
namespace is_array_property_ns {
|
||||
struct bad {};
|
||||
class proc {
|
||||
ast_manager& m_manager;
|
||||
family_id m_fid;
|
||||
bool m_has_quantifier;
|
||||
|
||||
void check_array_sort(expr* n) {
|
||||
if (is_sort_of(m_manager.get_sort(n), m_fid, ARRAY_SORT)) {
|
||||
throw bad();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
proc(ast_manager& m) :
|
||||
m_manager(m),
|
||||
m_fid(m.get_family_id("array")),
|
||||
m_has_quantifier(false) {}
|
||||
|
||||
bool has_quantifier() const { return m_has_quantifier; }
|
||||
|
||||
void operator()(var* n) {
|
||||
check_array_sort(n);
|
||||
}
|
||||
|
||||
void operator()(quantifier * ) {
|
||||
m_has_quantifier = true;
|
||||
}
|
||||
|
||||
void operator()(app* n) {
|
||||
unsigned num_args = n->get_num_args();
|
||||
if (m_manager.is_eq(n) || m_manager.is_distinct(n)) {
|
||||
return;
|
||||
}
|
||||
family_id fid = n->get_family_id();
|
||||
if (fid == m_fid) {
|
||||
switch(n->get_decl_kind()) {
|
||||
case OP_STORE:
|
||||
for (unsigned i = 1; i + 1 < num_args; ++i) {
|
||||
check_array_sort(n->get_arg(i));
|
||||
}
|
||||
return;
|
||||
case OP_SELECT:
|
||||
for (unsigned i = 1; i < num_args; ++i) {
|
||||
check_array_sort(n->get_arg(i));
|
||||
}
|
||||
return;
|
||||
case OP_CONST_ARRAY:
|
||||
case OP_ARRAY_MAP:
|
||||
return;
|
||||
default:
|
||||
throw bad();
|
||||
}
|
||||
}
|
||||
// arrays cannot be arguments of other functions.
|
||||
for (unsigned i = 0; i < num_args; ++i) {
|
||||
check_array_sort(n->get_arg(i));
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
bool array_property_recognizer::operator()(unsigned num_fmls, expr* const* fmls) {
|
||||
is_array_property_ns::proc p(m_manager);
|
||||
try {
|
||||
for (unsigned i = 0; i < num_fmls; ++i) {
|
||||
for_each_expr(p, fmls[i]);
|
||||
}
|
||||
}
|
||||
catch (is_array_property_ns::bad) {
|
||||
return false;
|
||||
}
|
||||
return p.has_quantifier();
|
||||
}
|
||||
|
||||
|
33
src/ast/array_property/array_property_recognizer.h
Normal file
33
src/ast/array_property/array_property_recognizer.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
/*++
|
||||
Copyright (c) 2010 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
array_property_recognizer.h
|
||||
|
||||
Abstract:
|
||||
|
||||
<abstract>
|
||||
|
||||
Author:
|
||||
|
||||
Nikolaj Bjorner (nbjorner) 2010-16-12
|
||||
|
||||
Revision History:
|
||||
|
||||
--*/
|
||||
#ifndef _ARRAY_PROPERTY_RECOGNIZER_H_
|
||||
#define _ARRAY_PROPERTY_RECOGNIZER_H_
|
||||
|
||||
#include"ast.h"
|
||||
|
||||
class array_property_recognizer {
|
||||
ast_manager& m_manager;
|
||||
public:
|
||||
array_property_recognizer(ast_manager& m);
|
||||
bool operator()(unsigned num_fmls, expr* const* fmls);
|
||||
};
|
||||
|
||||
|
||||
#endif /* _ARRAY_PROPERTY_RECOGNIZER_H_ */
|
||||
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue