3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-13 04:28:17 +00:00

Merge branch 'master' into develop

This commit is contained in:
Murphy Berzish 2018-08-07 12:57:02 -04:00
commit 7a84486df2
206 changed files with 3045 additions and 1887 deletions

View file

@ -1155,6 +1155,30 @@ static void parse_example() {
// expr b = c.parse_string("(benchmark tst :extrafuns ((x Int) (y Int)) :formula (> x y) :formula (> x 0))");
}
void mk_model_example() {
context c;
// construct empty model
model m(c);
// create constants "a", "b" and get their func_decl
expr a = c.int_const("a");
expr b = c.int_const("b");
func_decl a_decl = a.decl();
func_decl b_decl = b.decl();
// create numerals to be used in model
expr zero_numeral = c.int_val(0);
expr one_numeral = c.int_val(1);
// add assignment to model
m.add_const_interp(a_decl, zero_numeral);
m.add_const_interp(b_decl, one_numeral);
// evaluate a + b < 2 in the model
std::cout << m.eval(a + b < 2)<< std::endl;
}
int main() {
@ -1202,6 +1226,7 @@ int main() {
sudoku_example(); std::cout << "\n";
consequence_example(); std::cout << "\n";
parse_example(); std::cout << "\n";
mk_model_example(); std::cout << "\n";
std::cout << "done\n";
}
catch (exception & ex) {

View file

@ -1754,7 +1754,6 @@ void parser_example5() {
err:
printf("Z3 error: %s.\n", Z3_get_error_msg(ctx, e));
if (ctx != NULL) {
printf("Error message: '%s'.\n",Z3_get_parser_error(ctx));
del_solver(ctx, s);
Z3_del_context(ctx);
}

View file

@ -54,6 +54,8 @@ def init_project_def():
add_lib('smt_tactic', ['smt'], 'smt/tactic')
add_lib('sls_tactic', ['tactic', 'normal_forms', 'core_tactics', 'bv_tactics'], 'tactic/sls')
add_lib('qe', ['smt','sat','nlsat','tactic','nlsat_tactic'], 'qe')
add_lib('sat_solver', ['solver', 'core_tactics', 'aig_tactic', 'bv_tactics', 'arith_tactics', 'sat_tactic'], 'sat/sat_solver')
add_lib('fd_solver', ['core_tactics', 'arith_tactics', 'sat_solver'], 'tactic/fd_solver')
add_lib('muz', ['smt', 'sat', 'smt2parser', 'aig_tactic', 'qe'], 'muz/base')
add_lib('dataflow', ['muz'], 'muz/dataflow')
add_lib('transforms', ['muz', 'hilbert', 'dataflow'], 'muz/transforms')
@ -61,14 +63,13 @@ def init_project_def():
add_lib('spacer', ['muz', 'transforms', 'arith_tactics', 'smt_tactic'], 'muz/spacer')
add_lib('clp', ['muz', 'transforms'], 'muz/clp')
add_lib('tab', ['muz', 'transforms'], 'muz/tab')
add_lib('bmc', ['muz', 'transforms'], 'muz/bmc')
add_lib('ddnf', ['muz', 'transforms', 'rel'], 'muz/ddnf')
add_lib('bmc', ['muz', 'transforms', 'fd_solver'], 'muz/bmc')
add_lib('fp', ['muz', 'clp', 'tab', 'rel', 'bmc', 'ddnf', 'spacer'], 'muz/fp')
add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv')
add_lib('sat_solver', ['solver', 'core_tactics', 'aig_tactic', 'bv_tactics', 'arith_tactics', 'sat_tactic'], 'sat/sat_solver')
add_lib('smtlogic_tactics', ['ackermannization', 'sat_solver', 'arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt_tactic', 'aig_tactic', 'fp', 'muz','qe'], 'tactic/smtlogics')
add_lib('fpa_tactics', ['fpa', 'core_tactics', 'bv_tactics', 'sat_tactic', 'smt_tactic', 'arith_tactics', 'smtlogic_tactics'], 'tactic/fpa')
add_lib('portfolio', ['smtlogic_tactics', 'sat_solver', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'qe','sls_tactic', 'subpaving_tactic'], 'tactic/portfolio')
add_lib('portfolio', ['smtlogic_tactics', 'sat_solver', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'fd_solver', 'qe','sls_tactic', 'subpaving_tactic'], 'tactic/portfolio')
add_lib('opt', ['smt', 'smtlogic_tactics', 'sls_tactic', 'sat_solver'], 'opt')
API_files = ['z3_api.h', 'z3_ast_containers.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_fixedpoint.h', 'z3_optimization.h', 'z3_fpa.h', 'z3_spacer.h']
add_lib('api', ['portfolio', 'realclosure', 'opt'],
@ -89,6 +90,7 @@ def init_project_def():
set_z3py_dir('api/python')
add_python(_libz3Component)
add_python_install(_libz3Component)
add_js()
# Examples
add_cpp_example('cpp_example', 'c++')
add_cpp_example('z3_tptp', 'tptp')

View file

@ -82,6 +82,7 @@ VS_ARM = False
LINUX_X64 = True
ONLY_MAKEFILES = False
Z3PY_SRC_DIR=None
Z3JS_SRC_DIR=None
VS_PROJ = False
TRACE = False
PYTHON_ENABLED=False
@ -89,6 +90,7 @@ DOTNET_ENABLED=False
DOTNET_KEY_FILE=getenv("Z3_DOTNET_KEY_FILE", None)
JAVA_ENABLED=False
ML_ENABLED=False
JS_ENABLED=False
PYTHON_INSTALL_ENABLED=False
STATIC_LIB=False
STATIC_BIN=False
@ -654,6 +656,7 @@ def display_help(exit_code):
print(" --dotnet-key=<file> sign the .NET assembly using the private key in <file>.")
print(" --java generate Java bindings.")
print(" --ml generate OCaml bindings.")
print(" --js generate JScript bindings.")
print(" --python generate Python bindings.")
print(" --staticlib build Z3 static library.")
print(" --staticbin build a statically linked Z3 binary.")
@ -687,14 +690,14 @@ def display_help(exit_code):
# Parse configuration option for mk_make script
def parse_options():
global VERBOSE, DEBUG_MODE, IS_WINDOWS, VS_X64, ONLY_MAKEFILES, SHOW_CPPS, VS_PROJ, TRACE, VS_PAR, VS_PAR_NUM
global DOTNET_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED, PYTHON_ENABLED
global DOTNET_ENABLED, DOTNET_KEY_FILE, JAVA_ENABLED, ML_ENABLED, JS_ENABLED, STATIC_LIB, STATIC_BIN, PREFIX, GMP, PYTHON_PACKAGE_DIR, GPROF, GIT_HASH, GIT_DESCRIBE, PYTHON_INSTALL_ENABLED, PYTHON_ENABLED
global LINUX_X64, SLOW_OPTIMIZE, USE_OMP, LOG_SYNC
global GUARD_CF, ALWAYS_DYNAMIC_BASE
try:
options, remainder = getopt.gnu_getopt(sys.argv[1:],
'b:df:sxhmcvtnp:gj',
['build=', 'debug', 'silent', 'x64', 'help', 'makefiles', 'showcpp', 'vsproj', 'guardcf',
'trace', 'dotnet', 'dotnet-key=', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof',
'trace', 'dotnet', 'dotnet-key=', 'staticlib', 'prefix=', 'gmp', 'java', 'parallel=', 'gprof', 'js',
'githash=', 'git-describe', 'x86', 'ml', 'optimize', 'noomp', 'pypkgdir=', 'python', 'staticbin', 'log-sync'])
except:
print("ERROR: Invalid command line option")
@ -755,6 +758,8 @@ def parse_options():
GIT_DESCRIBE = True
elif opt in ('', '--ml'):
ML_ENABLED = True
elif opt == "--js":
JS_ENABLED = True
elif opt in ('', '--noomp'):
USE_OMP = False
elif opt in ('', '--log-sync'):
@ -817,6 +822,16 @@ def set_build_dir(d):
BUILD_DIR = norm_path(d)
REV_BUILD_DIR = reverse_path(d)
def set_z3js_dir(p):
global SRC_DIR, Z3JS_SRC_DIR
p = norm_path(p)
full = os.path.join(SRC_DIR, p)
if not os.path.exists(full):
raise MKException("Python bindings directory '%s' does not exist" % full)
Z3JS_SRC_DIR = full
if VERBOSE:
print("Js bindings directory was detected.")
def set_z3py_dir(p):
global SRC_DIR, Z3PY_SRC_DIR
p = norm_path(p)
@ -852,6 +867,10 @@ def get_components():
def get_z3py_dir():
return Z3PY_SRC_DIR
# Return directory where the js bindings are located
def get_z3js_dir():
return Z3JS_SRC_DIR
# Return true if in verbose mode
def is_verbose():
return VERBOSE
@ -862,6 +881,9 @@ def is_java_enabled():
def is_ml_enabled():
return ML_ENABLED
def is_js_enabled():
return JS_ENABLED
def is_dotnet_enabled():
return DOTNET_ENABLED
@ -1411,6 +1433,22 @@ class DLLComponent(Component):
shutil.copy('%s.a' % os.path.join(build_path, self.dll_name),
'%s.a' % os.path.join(dist_path, INSTALL_BIN_DIR, self.dll_name))
class JsComponent(Component):
def __init__(self):
Component.__init__(self, "js", None, [])
def main_component(self):
return False
def mk_win_dist(self, build_path, dist_path):
return
def mk_unix_dist(self, build_path, dist_path):
return
def mk_makefile(self, out):
return
class PythonComponent(Component):
def __init__(self, name, libz3Component):
assert isinstance(libz3Component, DLLComponent)
@ -2320,6 +2358,9 @@ def add_python(libz3Component):
name = 'python'
reg_component(name, PythonComponent(name, libz3Component))
def add_js():
reg_component('js', JsComponent())
def add_python_install(libz3Component):
name = 'python_install'
reg_component(name, PythonInstallComponent(name, libz3Component))
@ -2949,6 +2990,9 @@ def mk_bindings(api_files):
ml_output_dir = None
if is_ml_enabled():
ml_output_dir = get_component('ml').src_dir
if is_js_enabled():
set_z3js_dir("api/js")
js_output_dir = get_component('js').src_dir
# Get the update_api module to do the work for us
update_api.generate_files(api_files=new_api_files,
api_output_dir=get_component('api').src_dir,
@ -2956,6 +3000,7 @@ def mk_bindings(api_files):
dotnet_output_dir=dotnet_output_dir,
java_output_dir=java_output_dir,
java_package_name=java_package_name,
js_output_dir=get_z3js_dir(),
ml_output_dir=ml_output_dir,
ml_src_dir=ml_output_dir
)

View file

@ -311,7 +311,7 @@ def display_args_to_z3(params):
core_py.write("a%s" % i)
i = i + 1
NULLWrapped = [ 'Z3_mk_context', 'Z3_mk_context_rc', 'Z3_mk_interpolation_context' ]
NULLWrapped = [ 'Z3_mk_context', 'Z3_mk_context_rc' ]
Unwrapped = [ 'Z3_del_context', 'Z3_get_error_code' ]
def mk_py_wrappers():
@ -741,6 +741,59 @@ def mk_java(java_dir, package_name):
if mk_util.is_verbose():
print("Generated '%s'" % java_nativef)
Type2Napi = { VOID : '', VOID_PTR : '', INT : 'number', UINT : 'number', INT64 : 'number', UINT64 : 'number', DOUBLE : 'number',
FLOAT : 'number', STRING : 'string', STRING_PTR : 'array',
BOOL : 'number', SYMBOL : 'external', PRINT_MODE : 'number', ERROR_CODE : 'number' }
def type2napi(t):
try:
return Type2Napi[t]
except:
return "external"
Type2NapiBuilder = { VOID : '', VOID_PTR : '', INT : 'int32', UINT : 'uint32', INT64 : 'int64', UINT64 : 'uint64', DOUBLE : 'double',
FLOAT : 'float', STRING : 'string', STRING_PTR : 'array',
BOOL : 'bool', SYMBOL : 'external', PRINT_MODE : 'int32', ERROR_CODE : 'int32' }
def type2napibuilder(t):
try:
return Type2NapiBuilder[t]
except:
return "external"
def mk_js(js_output_dir):
with open(os.path.join(js_output_dir, "z3.json"), 'w') as ous:
ous.write("{\n")
ous.write(" \"api\": [\n")
for name, result, params in _dotnet_decls:
ous.write(" {\n")
ous.write(" \"name\": \"%s\",\n" % name)
ous.write(" \"c_type\": \"%s\",\n" % Type2Str[result])
ous.write(" \"napi_type\": \"%s\",\n" % type2napi(result))
ous.write(" \"arg_list\": [")
first = True
for p in params:
if first:
first = False
ous.write("\n {\n")
else:
ous.write(",\n {\n")
t = param_type(p)
k = t
ous.write(" \"name\": \"%s\",\n" % "") # TBD
ous.write(" \"c_type\": \"%s\",\n" % type2str(t))
ous.write(" \"napi_type\": \"%s\",\n" % type2napi(t))
ous.write(" \"napi_builder\": \"%s\"\n" % type2napibuilder(t))
ous.write( " }")
ous.write("],\n")
ous.write(" \"napi_builder\": \"%s\"\n" % type2napibuilder(result))
ous.write(" },\n")
ous.write(" ]\n")
ous.write("}\n")
def mk_log_header(file, name, params):
file.write("void log_%s(" % name)
i = 0
@ -955,9 +1008,9 @@ def def_API(name, result, params):
log_c.write(" Au(a%s);\n" % sz)
exe_c.write("in.get_uint_array(%s)" % i)
elif ty == INT:
log_c.write("U(a%s[i]);" % i)
log_c.write("I(a%s[i]);" % i)
log_c.write(" }\n")
log_c.write(" Au(a%s);\n" % sz)
log_c.write(" Ai(a%s);\n" % sz)
exe_c.write("in.get_int_array(%s)" % i)
elif ty == BOOL:
log_c.write("U(a%s[i]);" % i)
@ -1665,6 +1718,7 @@ for v in ('Z3_LIBRARY_PATH', 'PATH', 'PYTHONPATH'):
_all_dirs.extend(_default_dirs)
_failures = []
for d in _all_dirs:
try:
d = os.path.realpath(d)
@ -1673,14 +1727,16 @@ for d in _all_dirs:
if os.path.isfile(d):
_lib = ctypes.CDLL(d)
break
except:
except Exception as e:
_failures += [e]
pass
if _lib is None:
# If all else failed, ask the system to find it.
try:
_lib = ctypes.CDLL('libz3.%s' % _ext)
except:
except Exception as e:
_failures += [e]
pass
if _lib is None:
@ -1739,6 +1795,7 @@ def generate_files(api_files,
dotnet_output_dir=None,
java_output_dir=None,
java_package_name=None,
js_output_dir=None,
ml_output_dir=None,
ml_src_dir=None):
"""
@ -1819,6 +1876,9 @@ def generate_files(api_files,
assert not ml_src_dir is None
mk_ml(ml_src_dir, ml_output_dir)
if js_output_dir:
mk_js(js_output_dir)
def main(args):
logging.basicConfig(level=logging.INFO)
parser = argparse.ArgumentParser(description=__doc__)
@ -1852,6 +1912,10 @@ def main(args):
dest="ml_output_dir",
default=None,
help="Directory to emit OCaml files. If not specified no files are emitted.")
parser.add_argument("--js_output_dir",
dest="js_output_dir",
default=None,
help="Directory to emit js bindings. If not specified no files are emitted.")
pargs = parser.parse_args(args)
if pargs.java_output_dir:
@ -1875,6 +1939,7 @@ def main(args):
dotnet_output_dir=pargs.dotnet_output_dir,
java_output_dir=pargs.java_output_dir,
java_package_name=pargs.java_package_name,
js_output_dir=pargs.js_output_dir,
ml_output_dir=pargs.ml_output_dir,
ml_src_dir=pargs.ml_src_dir)
return 0

View file

@ -91,6 +91,7 @@ add_subdirectory(tactic/ufbv)
add_subdirectory(sat/sat_solver)
add_subdirectory(tactic/smtlogics)
add_subdirectory(tactic/fpa)
add_subdirectory(tactic/fd_solver)
add_subdirectory(tactic/portfolio)
add_subdirectory(opt)
add_subdirectory(api)

View file

@ -29,14 +29,14 @@ Notes:
#define CHECK_IS_ALGEBRAIC(ARG, RET) { \
if (!Z3_algebraic_is_value_core(c, ARG)) { \
SET_ERROR_CODE(Z3_INVALID_ARG); \
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr); \
return RET; \
} \
}
#define CHECK_IS_ALGEBRAIC_X(ARG, RET) { \
if (!Z3_algebraic_is_value_core(c, ARG)) { \
SET_ERROR_CODE(Z3_INVALID_ARG); \
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr); \
RETURN_Z3(RET); \
} \
}
@ -196,7 +196,7 @@ extern "C" {
CHECK_IS_ALGEBRAIC_X(b, nullptr);
if ((is_rational(c, b) && get_rational(c, b).is_zero()) ||
(!is_rational(c, b) && am(c).is_zero(get_irrational(c, b)))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
BIN_OP(/,div);
@ -211,7 +211,7 @@ extern "C" {
if (k % 2 == 0) {
if ((is_rational(c, a) && get_rational(c, a).is_neg()) ||
(!is_rational(c, a) && am(c).is_neg(get_irrational(c, a)))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -360,13 +360,13 @@ extern "C" {
expr2polynomial converter(mk_c(c)->m(), pm, nullptr, true);
if (!converter.to_polynomial(to_expr(p), _p, d) ||
static_cast<unsigned>(max_var(_p)) >= n + 1) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
algebraic_numbers::manager & _am = am(c);
scoped_anum_vector as(_am);
if (!to_anum_vector(c, n, a, as)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
scoped_anum_vector roots(_am);
@ -396,13 +396,13 @@ extern "C" {
expr2polynomial converter(mk_c(c)->m(), pm, nullptr, true);
if (!converter.to_polynomial(to_expr(p), _p, d) ||
static_cast<unsigned>(max_var(_p)) >= n) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
algebraic_numbers::manager & _am = am(c);
scoped_anum_vector as(_am);
if (!to_anum_vector(c, n, a, as)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
{

View file

@ -51,7 +51,7 @@ extern "C" {
LOG_Z3_mk_real(c, num, den);
RESET_ERROR_CODE();
if (den == 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
sort* s = mk_c(c)->m().mk_sort(mk_c(c)->get_arith_fid(), REAL_SORT);
@ -97,7 +97,7 @@ extern "C" {
LOG_Z3_mk_sub(c, num_args, args);
RESET_ERROR_CODE();
if (num_args == 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr* r = to_expr(args[0]);
@ -129,7 +129,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr * e = to_expr(a);
@ -147,7 +147,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr * e = to_expr(a);
@ -167,7 +167,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr * r = mk_c(c)->autil().mk_numeral(numerator(val), true);
@ -183,7 +183,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
expr * r = mk_c(c)->autil().mk_numeral(denominator(val), true);

View file

@ -58,7 +58,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
sort * domain[2] = {a_ty, i_ty};
@ -81,7 +81,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<sort> domain;
@ -113,7 +113,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
sort * domain[3] = {a_ty, i_ty, v_ty};
@ -136,7 +136,7 @@ extern "C" {
sort * a_ty = m.get_sort(_a);
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);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<sort> domain;
@ -163,7 +163,7 @@ extern "C" {
LOG_Z3_mk_map(c, f, n, args);
RESET_ERROR_CODE();
if (n == 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ast_manager & m = mk_c(c)->m();
@ -298,7 +298,7 @@ extern "C" {
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(0).get_ast());
RETURN_Z3(r);
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
Z3_CATCH_RETURN(nullptr);
}
@ -314,7 +314,7 @@ extern "C" {
Z3_sort r = reinterpret_cast<Z3_sort>(to_sort(t)->get_parameter(n-1).get_ast());
RETURN_Z3(r);
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
Z3_CATCH_RETURN(nullptr);
}

View file

@ -48,7 +48,7 @@ extern "C" {
LOG_Z3_mk_int_symbol(c, i);
RESET_ERROR_CODE();
if (i < 0 || (size_t)i >= (SIZE_MAX >> PTR_ALIGNMENT)) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return nullptr;
}
Z3_symbol result = of_symbol(symbol(i));
@ -281,7 +281,7 @@ extern "C" {
if (_s.is_numerical()) {
return _s.get_num();
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return -1;
Z3_CATCH_RETURN(-1);
}
@ -355,7 +355,7 @@ extern "C" {
LOG_Z3_get_app_decl(c, a);
RESET_ERROR_CODE();
if (!is_app(reinterpret_cast<ast*>(a))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_func_decl(to_app(a)->get_decl()));
@ -371,11 +371,11 @@ extern "C" {
LOG_Z3_get_app_arg(c, a, i);
RESET_ERROR_CODE();
if (!is_app(reinterpret_cast<ast*>(a))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
if (i >= to_app(a)->get_num_args()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_ast(to_app(a)->get_arg(i)));
@ -384,12 +384,14 @@ extern "C" {
Z3_symbol Z3_API Z3_get_decl_name(Z3_context c, Z3_func_decl d) {
LOG_Z3_get_decl_name(c, d);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, nullptr);
return of_symbol(to_func_decl(d)->get_name());
}
unsigned Z3_API Z3_get_decl_num_parameters(Z3_context c, Z3_func_decl d) {
LOG_Z3_get_decl_num_parameters(c, d);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
return to_func_decl(d)->get_num_parameters();
}
@ -397,8 +399,9 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_parameter_kind(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, Z3_PARAMETER_INT);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return Z3_PARAMETER_INT;
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
@ -429,13 +432,14 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_int_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_int()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return p.get_int();
@ -446,13 +450,14 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_double_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_double()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return p.get_double();
@ -463,13 +468,14 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_symbol_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return nullptr;
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_symbol()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
return of_symbol(p.get_symbol());
@ -480,13 +486,14 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_sort_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_ast() || !is_sort(p.get_ast())) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_sort(to_sort(p.get_ast())));
@ -497,13 +504,14 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_ast_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_ast()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_ast(p.get_ast()));
@ -514,13 +522,14 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_func_decl_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_ast() || !is_func_decl(p.get_ast())) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(of_func_decl(to_func_decl(p.get_ast())));
@ -531,13 +540,14 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_decl_rational_parameter(c, d, idx);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, "");
if (idx >= to_func_decl(d)->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return "";
}
parameter const& p = to_func_decl(d)->get_parameters()[idx];
if (!p.is_rational()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
return mk_c(c)->mk_external_string(p.get_rational().to_string());
@ -549,6 +559,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_sort_name(c, t);
RESET_ERROR_CODE();
CHECK_VALID_AST(t, nullptr);
return of_symbol(to_sort(t)->get_name());
Z3_CATCH_RETURN(nullptr);
}
@ -567,6 +578,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_arity(c, d);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
return to_func_decl(d)->get_arity();
Z3_CATCH_RETURN(0);
}
@ -575,6 +587,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_domain_size(c, d);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
return to_func_decl(d)->get_arity();
Z3_CATCH_RETURN(0);
}
@ -583,8 +596,9 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_domain(c, d, i);
RESET_ERROR_CODE();
CHECK_VALID_AST(d, 0);
if (i >= to_func_decl(d)->get_arity()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_sort r = of_sort(to_func_decl(d)->get_domain(i));
@ -740,7 +754,7 @@ extern "C" {
case AST_APP: {
app* e = to_app(a);
if (e->get_num_args() != num_args) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
}
else {
a = m.mk_app(e->get_decl(), num_args, args);
@ -749,7 +763,7 @@ extern "C" {
}
case AST_QUANTIFIER: {
if (num_args != 1) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
}
else {
a = m.update_quantifier(to_quantifier(a), args[0]);
@ -779,7 +793,7 @@ extern "C" {
expr * r = nullptr;
for (unsigned i = 0; i < num_exprs; i++) {
if (m.get_sort(from[i]) != m.get_sort(to[i])) {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(of_expr(nullptr));
}
SASSERT(from[i]->get_ref_count() > 0);
@ -881,7 +895,7 @@ extern "C" {
RESET_ERROR_CODE();
func_decl* _d = to_func_decl(d);
if (null_family_id == _d->get_family_id()) {
if (d == nullptr || null_family_id == _d->get_family_id()) {
return Z3_OP_UNINTERPRETED;
}
if (mk_c(c)->get_basic_fid() == _d->get_family_id()) {
@ -1212,14 +1226,14 @@ extern "C" {
RESET_ERROR_CODE();
ast* _a = reinterpret_cast<ast*>(a);
if (!_a || _a->get_kind() != AST_VAR) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
var* va = to_var(_a);
if (va) {
return va->get_idx();
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
Z3_CATCH_RETURN(0);
}
@ -1230,7 +1244,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_VALID_AST(a, nullptr);
if (c == target) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
SASSERT(mk_c(c)->m().contains(to_ast(a)));

View file

@ -71,7 +71,7 @@ extern "C" {
RESET_ERROR_CODE();
obj_map<ast, ast*>::obj_map_entry * entry = to_ast_map_ref(m).find_core(to_ast(k));
if (entry == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
else {

View file

@ -65,7 +65,7 @@ extern "C" {
LOG_Z3_ast_vector_get(c, v, i);
RESET_ERROR_CODE();
if (i >= to_ast_vector_ref(v).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
// Remark: Don't need to invoke save_object.
@ -79,7 +79,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_IOB, nullptr);
return;
}
to_ast_vector_ref(v).set(i, to_ast(a));
@ -107,8 +107,7 @@ extern "C" {
LOG_Z3_ast_vector_translate(c, v, t);
RESET_ERROR_CODE();
if (c == t) {
SET_ERROR_CODE(Z3_INVALID_ARG);
RETURN_Z3(nullptr);
RETURN_Z3(v);
}
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), mk_c(t)->m());

View file

@ -27,9 +27,6 @@ extern "C" {
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);
@ -163,7 +160,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
// 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);
SET_ERROR_CODE(Z3_INVALID_ARG, "zero length bit-vector supplied");
return nullptr;
}
Z3_ast x = Z3_mk_int64(c, 1, s);
@ -393,7 +390,7 @@ Z3_ast Z3_API NAME(Z3_context c, unsigned i, Z3_ast n) { \
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "sort is not a bit-vector");
return 0;
Z3_CATCH_RETURN(0);
}

View file

@ -144,9 +144,11 @@ namespace api {
}
}
void context::set_error_code(Z3_error_code err) {
void context::set_error_code(Z3_error_code err, char const* opt_msg) {
m_error_code = err;
if (err != Z3_OK) {
m_exception_msg.clear();
if (opt_msg) m_exception_msg = opt_msg;
invoke_error_handler(err);
}
}
@ -159,7 +161,7 @@ namespace api {
void context::check_searching() {
if (m_searching) {
set_error_code(Z3_INVALID_USAGE); // TBD: error code could be fixed.
set_error_code(Z3_INVALID_USAGE, "cannot use function while searching"); // TBD: error code could be fixed.
}
}
@ -248,25 +250,24 @@ namespace api {
if (ex.has_error_code()) {
switch(ex.error_code()) {
case ERR_MEMOUT:
set_error_code(Z3_MEMOUT_FAIL);
set_error_code(Z3_MEMOUT_FAIL, nullptr);
break;
case ERR_PARSER:
set_error_code(Z3_PARSER_ERROR);
set_error_code(Z3_PARSER_ERROR, ex.msg());
break;
case ERR_INI_FILE:
set_error_code(Z3_INVALID_ARG);
set_error_code(Z3_INVALID_ARG, nullptr);
break;
case ERR_OPEN_FILE:
set_error_code(Z3_FILE_ACCESS_ERROR);
set_error_code(Z3_FILE_ACCESS_ERROR, nullptr);
break;
default:
set_error_code(Z3_INTERNAL_FATAL);
set_error_code(Z3_INTERNAL_FATAL, nullptr);
break;
}
}
else {
m_exception_msg = ex.msg();
set_error_code(Z3_EXCEPTION);
set_error_code(Z3_EXCEPTION, ex.msg());
}
}
@ -301,7 +302,7 @@ namespace api {
case AST_FUNC_DECL:
break;
}
set_error_code(Z3_SORT_ERROR);
set_error_code(Z3_SORT_ERROR, nullptr);
}
}
@ -378,11 +379,13 @@ extern "C" {
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);
if (a && to_ast(a)->get_ref_count() == 0) {
SET_ERROR_CODE(Z3_DEC_REF_ERROR, nullptr);
return;
}
mk_c(c)->m().dec_ref(to_ast(a));
if (a) {
mk_c(c)->m().dec_ref(to_ast(a));
}
Z3_CATCH;
}
@ -440,10 +443,14 @@ extern "C" {
}
void Z3_API Z3_set_error(Z3_context c, Z3_error_code e) {
SET_ERROR_CODE(e);
SET_ERROR_CODE(e, nullptr);
}
static char const * _get_error_msg(Z3_context c, Z3_error_code err) {
if (c) {
char const* msg = mk_c(c)->get_exception_msg();
if (msg && *msg) return msg;
}
switch(err) {
case Z3_OK: return "ok";
case Z3_SORT_ERROR: return "type error";
@ -457,7 +464,7 @@ extern "C" {
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 == nullptr ? "Z3 exception" : mk_c(c)->get_exception_msg();
case Z3_EXCEPTION: return "Z3 exception";
default: return "unknown";
}
}

View file

@ -141,7 +141,7 @@ namespace api {
Z3_error_code get_error_code() const { return m_error_code; }
void reset_error_code();
void set_error_code(Z3_error_code err);
void set_error_code(Z3_error_code err, char const* opt_msg);
void set_error_handler(Z3_error_handler h) { m_error_handler = h; }
// Sign an error if solver is searching
void check_searching();
@ -219,14 +219,6 @@ namespace api {
//
// ------------------------
smt_params & fparams() { return m_fparams; }
// ------------------------
//
// Parser interface
//
// ------------------------
std::string m_parser_error_buffer;
};
@ -234,14 +226,14 @@ namespace api {
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 SET_ERROR_CODE(ERR, MSG) { mk_c(c)->set_error_code(ERR, MSG); }
#define CHECK_NON_NULL(_p_,_ret_) { if (_p_ == 0) { SET_ERROR_CODE(Z3_INVALID_ARG, "ast is null"); return _ret_; } }
#define CHECK_VALID_AST(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_)) { SET_ERROR_CODE(Z3_INVALID_ARG, "not a valid ast"); return _ret_; } }
#define CHECK_SEARCHING(c) mk_c(c)->check_searching();
inline bool is_expr(Z3_ast a) { return is_expr(to_ast(a)); }
#define CHECK_IS_EXPR(_p_, _ret_) { if (_p_ == 0 || !is_expr(_p_)) { SET_ERROR_CODE(Z3_INVALID_ARG); return _ret_; } }
#define CHECK_IS_EXPR(_p_, _ret_) { if (_p_ == 0 || !is_expr(_p_)) { SET_ERROR_CODE(Z3_INVALID_ARG, "ast is not an expression"); return _ret_; } }
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_; } }
#define CHECK_FORMULA(_a_, _ret_) { if (_a_ == 0 || !CHECK_REF_COUNT(_a_) || !is_bool_expr(c, _a_)) { SET_ERROR_CODE(Z3_INVALID_ARG, nullptr); return _ret_; } }
inline void check_sorts(Z3_context c, ast * n) { mk_c(c)->check_sorts(n); }
#endif

View file

@ -157,7 +157,7 @@ extern "C" {
RESET_ERROR_CODE();
sort * r = to_sort(s);
if (Z3_get_sort_kind(c, s) != Z3_RELATION_SORT) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "sort should be a relation");
return 0;
}
return r->get_num_parameters();
@ -170,18 +170,18 @@ extern "C" {
RESET_ERROR_CODE();
sort * r = to_sort(s);
if (Z3_get_sort_kind(c, s) != Z3_RELATION_SORT) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "sort should be a relation");
RETURN_Z3(nullptr);
}
if (col >= r->get_num_parameters()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
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);
SET_ERROR_CODE(Z3_INTERNAL_FATAL, "sort parameter expected");
RETURN_Z3(nullptr);
}
Z3_sort res = of_sort(to_sort(p.get_ast()));
@ -364,7 +364,7 @@ extern "C" {
install_dl_collect_cmds(coll, ctx);
ctx.set_ignore_check(true);
if (!parse_smt2_commands(ctx, s)) {
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, nullptr);
return nullptr;
}
@ -408,7 +408,7 @@ extern "C" {
LOG_Z3_fixedpoint_from_file(c, d, s);
std::ifstream is(s);
if (!is) {
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, nullptr);
RETURN_Z3(nullptr);
}
RETURN_Z3(Z3_fixedpoint_from_stream(c, d, is));

View file

@ -56,7 +56,7 @@ extern "C" {
del_datatype_decl(dt);
if (!is_ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -118,7 +118,7 @@ extern "C" {
del_datatype_decl(dt);
if (!is_ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -180,7 +180,7 @@ extern "C" {
del_datatype_decl(decl);
if (!is_ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -274,7 +274,7 @@ extern "C" {
RESET_ERROR_CODE();
mk_c(c)->reset_last_result();
if (!constr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return;
}
ast_manager& m = mk_c(c)->m();
@ -282,7 +282,7 @@ extern "C" {
func_decl* f = reinterpret_cast<constructor*>(constr)->m_constructor.get();
if (!f) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return;
}
if (constructor_decl) {
@ -353,7 +353,7 @@ extern "C" {
del_datatype_decl(data);
if (!is_ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -416,7 +416,7 @@ extern "C" {
del_datatype_decls(datas.size(), datas.c_ptr());
if (!ok) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return;
}
@ -445,7 +445,7 @@ extern "C" {
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(_t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return dt_util.get_datatype_constructors(_t)->size();
@ -458,12 +458,12 @@ extern "C" {
sort * _t = to_sort(t);
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(_t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(_t);
if (idx >= decls.size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
func_decl* decl = (decls)[idx];
@ -488,12 +488,12 @@ extern "C" {
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(_t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(_t);
if (idx >= decls.size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
func_decl* decl = (decls)[idx];
@ -511,23 +511,23 @@ extern "C" {
datatype_util& dt_util = mk_c(c)->dtutil();
if (!dt_util.is_datatype(_t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(_t);
if (idx_c >= decls.size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
func_decl* decl = (decls)[idx_c];
if (decl->get_arity() <= idx_a) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & accs = *dt_util.get_constructor_accessors(decl);
SASSERT(accs.size() == decl->get_arity());
if (accs.size() <= idx_a) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
decl = (accs)[idx_a];
@ -543,7 +543,7 @@ extern "C" {
sort * tuple = to_sort(t);
datatype_util& dt_util = mk_c(c)->dtutil();
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
Z3_func_decl r = get_datatype_sort_constructor_core(c, t, 0);
@ -558,12 +558,12 @@ extern "C" {
sort * tuple = to_sort(t);
datatype_util& dt_util = mk_c(c)->dtutil();
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(tuple);
if (decls.size() != 1) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
ptr_vector<func_decl> const & accs = *dt_util.get_constructor_accessors(decls[0]);
@ -578,17 +578,17 @@ extern "C" {
sort * tuple = to_sort(t);
datatype_util& dt_util = mk_c(c)->dtutil();
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & decls = *dt_util.get_datatype_constructors(tuple);
if (decls.size() != 1) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
ptr_vector<func_decl> const & accs = *dt_util.get_constructor_accessors((decls)[0]);
if (accs.size() <= i) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
func_decl* acc = (accs)[i];

View file

@ -175,7 +175,7 @@ extern "C" {
LOG_Z3_mk_fpa_sort(c, ebits, sbits);
RESET_ERROR_CODE();
if (ebits < 2 || sbits < 3) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "ebits should be at least 2, sbits at least 3");
}
api::context * ctx = mk_c(c);
sort * s = ctx->fpautil().mk_float_sort(ebits, sbits);
@ -222,7 +222,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_VALID_AST(s, nullptr);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -238,7 +238,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_VALID_AST(s, nullptr);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -255,7 +255,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_VALID_AST(s, nullptr);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -271,7 +271,7 @@ extern "C" {
LOG_Z3_mk_fpa_fp(c, sgn, exp, sig);
RESET_ERROR_CODE();
if (!is_bv(c, sgn) || !is_bv(c, exp) || !is_bv(c, sig)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "bv sorts expected for arguments");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -286,7 +286,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_float(c, v, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG,"fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -306,7 +306,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_double(c, v, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -323,7 +323,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_int(c, v, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -343,7 +343,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_int64_uint64(c, sgn, exp, sig, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -363,7 +363,7 @@ extern "C" {
LOG_Z3_mk_fpa_numeral_int64_uint64(c, sgn, exp, sig, ty);
RESET_ERROR_CODE();
if (!is_fp_sort(c, ty)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -383,7 +383,7 @@ extern "C" {
LOG_Z3_mk_fpa_abs(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -398,7 +398,7 @@ extern "C" {
LOG_Z3_mk_fpa_neg(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -413,7 +413,7 @@ extern "C" {
LOG_Z3_mk_fpa_add(c, rm, t1, t2);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -428,7 +428,7 @@ extern "C" {
LOG_Z3_mk_fpa_add(c, rm, t1, t2);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -443,7 +443,7 @@ extern "C" {
LOG_Z3_mk_fpa_add(c, rm, t1, t2);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -458,7 +458,7 @@ extern "C" {
LOG_Z3_mk_fpa_add(c, rm, t1, t2);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -473,7 +473,7 @@ extern "C" {
LOG_Z3_mk_fpa_fma(c, rm, t1, t2, t3);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t1) || !is_fp(c, t2) || !is_fp(c, t3)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -488,7 +488,7 @@ extern "C" {
LOG_Z3_mk_fpa_sqrt(c, rm, t);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -503,7 +503,7 @@ extern "C" {
LOG_Z3_mk_fpa_rem(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -518,7 +518,7 @@ extern "C" {
LOG_Z3_mk_fpa_round_to_integral(c, rm, t);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -533,7 +533,7 @@ extern "C" {
LOG_Z3_mk_fpa_min(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -548,7 +548,7 @@ extern "C" {
LOG_Z3_mk_fpa_max(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -563,7 +563,7 @@ extern "C" {
LOG_Z3_mk_fpa_leq(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -578,7 +578,7 @@ extern "C" {
LOG_Z3_mk_fpa_lt(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -593,7 +593,7 @@ extern "C" {
LOG_Z3_mk_fpa_geq(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -608,7 +608,7 @@ extern "C" {
LOG_Z3_mk_fpa_gt(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -623,7 +623,7 @@ extern "C" {
LOG_Z3_mk_fpa_eq(c, t1, t2);
RESET_ERROR_CODE();
if (!is_fp(c, t1) || !is_fp(c, t2)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -638,7 +638,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_normal(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -653,7 +653,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_subnormal(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -668,7 +668,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_zero(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -683,7 +683,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_infinite(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -698,7 +698,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_nan(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -713,7 +713,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_negative(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -728,7 +728,7 @@ extern "C" {
LOG_Z3_mk_fpa_is_positive(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -744,14 +744,14 @@ extern "C" {
LOG_Z3_mk_fpa_to_fp_bv(c, bv, s);
RESET_ERROR_CODE();
if (!is_bv(c, bv) || !is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "bv then fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!ctx->bvutil().is_bv(to_expr(bv)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "bv sort the flaot sort expected");
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(bv));
@ -769,7 +769,7 @@ extern "C" {
if (!fu.is_rm(to_expr(rm)) ||
!fu.is_float(to_expr(t)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t));
@ -787,7 +787,7 @@ extern "C" {
if (!fu.is_rm(to_expr(rm)) ||
!ctx->autil().is_real(to_expr(t)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t));
@ -805,7 +805,7 @@ extern "C" {
if (!fu.is_rm(to_expr(rm)) ||
!ctx->bvutil().is_bv(to_expr(t)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(t));
@ -823,7 +823,7 @@ extern "C" {
if (!fu.is_rm(to_expr(rm)) ||
!ctx->bvutil().is_bv(to_expr(t)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
return nullptr;
}
expr * a = fu.mk_to_fp_unsigned(to_sort(s), to_expr(rm), to_expr(t));
@ -837,7 +837,7 @@ extern "C" {
LOG_Z3_mk_fpa_to_ubv(c, rm, t, sz);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -852,7 +852,7 @@ extern "C" {
LOG_Z3_mk_fpa_to_sbv(c, rm, t, sz);
RESET_ERROR_CODE();
if (!is_rm(c, rm) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "rm and float sorts expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -867,7 +867,7 @@ extern "C" {
LOG_Z3_mk_fpa_to_real(c, t);
RESET_ERROR_CODE();
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -884,7 +884,7 @@ extern "C" {
CHECK_NON_NULL(s, 0);
CHECK_VALID_AST(s, 0);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(0);
}
return mk_c(c)->fpautil().get_ebits(to_sort(s));
@ -898,7 +898,7 @@ extern "C" {
CHECK_NON_NULL(s, 0);
CHECK_VALID_AST(s, 0);
if (!is_fp_sort(c, s)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(0);
}
return mk_c(c)->fpautil().get_sbits(to_sort(s));
@ -912,7 +912,7 @@ extern "C" {
CHECK_NON_NULL(t, 0);
CHECK_VALID_AST(t, 0);
if (sgn == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "sign cannot be a nullpointer");
return 0;
}
ast_manager & m = mk_c(c)->m();
@ -921,13 +921,13 @@ extern "C" {
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid);
expr * e = to_expr(t);
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return 0;
}
scoped_mpf val(mpfm);
bool r = plugin->is_numeral(to_expr(t), val);
if (!r || mpfm.is_nan(val)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return 0;
}
*sgn = mpfm.sgn(val);
@ -948,13 +948,13 @@ extern "C" {
api::context * ctx = mk_c(c);
expr * e = to_expr(t);
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
RETURN_Z3(nullptr);
}
scoped_mpf val(mpfm);
bool r = plugin->is_numeral(to_expr(t), val);
if (!r || mpfm.is_nan(val)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return nullptr;
}
app * a;
@ -981,13 +981,13 @@ extern "C" {
SASSERT(plugin != 0);
expr * e = to_expr(t);
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
RETURN_Z3(nullptr);
}
scoped_mpf val(mpfm);
bool r = plugin->is_numeral(e, val);
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
RETURN_Z3(nullptr);
}
unsigned sbits = val.get().get_sbits();
@ -1014,13 +1014,13 @@ extern "C" {
SASSERT(plugin != 0);
expr * e = to_expr(t);
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return "";
}
scoped_mpf val(mpfm);
bool r = plugin->is_numeral(e, val);
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return "";
}
unsigned sbits = val.get().get_sbits();
@ -1042,7 +1042,7 @@ extern "C" {
CHECK_NON_NULL(t, 0);
CHECK_VALID_AST(t, 0);
if (n == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid nullptr argument");
return 0;
}
ast_manager & m = mk_c(c)->m();
@ -1053,7 +1053,7 @@ extern "C" {
SASSERT(plugin != 0);
expr * e = to_expr(t);
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
*n = 0;
return 0;
}
@ -1063,7 +1063,7 @@ extern "C" {
if (!r ||
!(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val)) ||
!mpzm.is_uint64(z)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
*n = 0;
return 0;
}
@ -1085,13 +1085,13 @@ extern "C" {
SASSERT(plugin != 0);
expr * e = to_expr(t);
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return "";
}
scoped_mpf val(mpfm);
bool r = plugin->is_numeral(e, val);
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
return "";
}
unsigned ebits = val.get().get_ebits();
@ -1120,7 +1120,7 @@ extern "C" {
CHECK_NON_NULL(t, 0);
CHECK_VALID_AST(t, 0);
if (n == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid null argument");
return 0;
}
ast_manager & m = mk_c(c)->m();
@ -1130,14 +1130,14 @@ extern "C" {
SASSERT(plugin != 0);
expr * e = to_expr(t);
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
*n = 0;
return 0;
}
scoped_mpf val(mpfm);
bool r = plugin->is_numeral(e, val);
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
*n = 0;
return 0;
}
@ -1169,13 +1169,13 @@ extern "C" {
fpa_decl_plugin * plugin = (fpa_decl_plugin*)m.get_plugin(fid);
expr * e = to_expr(t);
if (!is_app(e) || is_app_of(e, fid, OP_FPA_NAN) || !is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
RETURN_Z3(nullptr);
}
scoped_mpf val(mpfm);
bool r = plugin->is_numeral(e, val);
if (!r || !(mpfm.is_normal(val) || mpfm.is_denormal(val) || mpfm.is_zero(val) || mpfm.is_inf(val))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "invalid expression argument, expecting a valid fp, not a NaN");
RETURN_Z3(nullptr);
}
unsigned ebits = val.get().get_ebits();
@ -1204,7 +1204,7 @@ extern "C" {
CHECK_NON_NULL(t, nullptr);
CHECK_VALID_AST(t, nullptr);
if (!is_fp(c, t)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "fp sort expected");
RETURN_Z3(nullptr);
}
api::context * ctx = mk_c(c);
@ -1223,7 +1223,7 @@ extern "C" {
!ctx->autil().is_int(to_expr(exp)) ||
!ctx->autil().is_real(to_expr(sig)) ||
!fu.is_float(to_sort(s))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
expr * a = fu.mk_to_fp(to_sort(s), to_expr(rm), to_expr(exp), to_expr(sig));
@ -1239,7 +1239,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_nan(to_expr(t));
@ -1253,7 +1253,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_inf(to_expr(t));
@ -1267,7 +1267,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_zero(to_expr(t));
@ -1281,7 +1281,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_normal(to_expr(t));
@ -1295,7 +1295,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_subnormal(to_expr(t));
@ -1309,7 +1309,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_positive(to_expr(t));
@ -1323,7 +1323,7 @@ extern "C" {
api::context * ctx = mk_c(c);
fpa_util & fu = ctx->fpautil();
if (!is_expr(t) || !fu.is_numeral(to_expr(t))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return fu.is_negative(to_expr(t));

View file

@ -30,7 +30,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "proofs are required, but proofs are not enabled on the context");
RETURN_Z3(nullptr);
}
Z3_goal_ref * g = alloc(Z3_goal_ref, *mk_c(c));
@ -119,7 +119,7 @@ extern "C" {
LOG_Z3_goal_formula(c, g, idx);
RESET_ERROR_CODE();
if (idx >= to_goal_ref(g)->size()) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
expr * result = to_goal_ref(g)->form(idx);
@ -198,6 +198,10 @@ extern "C" {
LOG_Z3_goal_to_dimacs_string(c, g);
RESET_ERROR_CODE();
std::ostringstream buffer;
if (!to_goal_ref(g)->is_cnf()) {
SET_ERROR_CODE(Z3_INVALID_ARG, "If this is not what you want, then preprocess by optional bit-blasting and applying tseitin-cnf");
RETURN_Z3(nullptr);
}
to_goal_ref(g)->display_dimacs(buffer);
// Hack for removing the trailing '\n'
std::string result = buffer.str();

View file

@ -94,7 +94,7 @@ extern "C" {
CHECK_NON_NULL(m, nullptr);
func_interp * _fi = to_model_ref(m)->get_func_interp(to_func_decl(f));
if (!_fi) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
Z3_func_interp_ref * fi = alloc(Z3_func_interp_ref, *mk_c(c), to_model_ref(m));
@ -123,7 +123,7 @@ extern "C" {
RETURN_Z3(of_func_decl(_m->get_constant(i)));
}
else {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -142,7 +142,7 @@ extern "C" {
CHECK_NON_NULL(m, nullptr);
model * _m = to_model_ref(m);
if (i >= _m->get_num_functions()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return nullptr;
}
return of_func_decl(_m->get_function(i));
@ -187,7 +187,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
sort * s = to_model_ref(m)->get_uninterpreted_sort(i);
@ -200,15 +200,14 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
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), 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]);
for (expr * e : universe) {
v->m_ast_vector.push_back(e);
}
RETURN_Z3(of_ast_vector(v));
Z3_CATCH_RETURN(nullptr);
@ -230,7 +229,7 @@ extern "C" {
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);
return a && 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);
}
@ -238,11 +237,11 @@ extern "C" {
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)) {
if (a && is_expr(to_ast(a)) && is_app_of(to_expr(a), mk_c(c)->get_array_fid(), OP_AS_ARRAY)) {
RETURN_Z3(of_func_decl(to_func_decl(to_app(a)->get_decl()->get_parameter(0).get_ast())));
}
else {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -252,6 +251,7 @@ extern "C" {
Z3_TRY;
LOG_Z3_add_func_interp(c, m, f, else_val);
RESET_ERROR_CODE();
CHECK_NON_NULL(f, nullptr);
func_decl* d = to_func_decl(f);
model* mdl = to_model_ref(m);
Z3_func_interp_ref * f_ref = alloc(Z3_func_interp_ref, *mk_c(c), mdl);
@ -268,8 +268,8 @@ extern "C" {
LOG_Z3_add_const_interp(c, m, f, a);
RESET_ERROR_CODE();
func_decl* d = to_func_decl(f);
if (d->get_arity() != 0) {
SET_ERROR_CODE(Z3_INVALID_ARG);
if (!d || d->get_arity() != 0) {
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
}
else {
model* mdl = to_model_ref(m);
@ -313,7 +313,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_NON_NULL(f, nullptr);
if (i >= to_func_interp_ref(f)->num_entries()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_func_entry_ref * e = alloc(Z3_func_entry_ref, *mk_c(c), to_func_interp(f)->m_model.get());
@ -364,7 +364,7 @@ extern "C" {
func_interp* _fi = to_func_interp_ref(fi);
expr* _value = to_expr(value);
if (to_ast_vector_ref(args).size() != _fi->get_arity()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return;
}
// check sorts of value
@ -416,7 +416,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
expr * r = to_func_entry(e)->m_func_entry->get_arg(i);
@ -434,7 +434,7 @@ extern "C" {
if (g) {
return g->num_entries();
}
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
return 0;
@ -448,7 +448,7 @@ extern "C" {
RESET_ERROR_CODE();
CHECK_NON_NULL(m, 0);
if (j >= get_model_func_num_entries_core(c, m, i)) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
Z3_func_decl d = get_model_func_decl_core(c, m, i);

View file

@ -26,6 +26,7 @@ Revision History:
#include "ast/fpa_decl_plugin.h"
bool is_numeral_sort(Z3_context c, Z3_sort ty) {
if (!ty) return false;
sort * _ty = to_sort(ty);
family_id fid = _ty->get_family_id();
if (fid != mk_c(c)->get_arith_fid() &&
@ -40,7 +41,7 @@ bool is_numeral_sort(Z3_context c, Z3_sort ty) {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
}
return is_num;
}
@ -55,7 +56,7 @@ extern "C" {
RETURN_Z3(nullptr);
}
if (!n) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
sort * _ty = to_sort(ty);
@ -67,12 +68,11 @@ extern "C" {
('/' == *m) || ('-' == *m) ||
(' ' == *m) || ('\n' == *m) ||
('.' == *m) || ('e' == *m) ||
('E' == *m) ||
('E' == *m) || ('+' == *m) ||
(is_float &&
(('p' == *m) ||
('P' == *m) ||
('+' == *m))))) {
SET_ERROR_CODE(Z3_PARSER_ERROR);
('P' == *m))))) {
SET_ERROR_CODE(Z3_PARSER_ERROR, nullptr);
RETURN_Z3(nullptr);
}
++m;
@ -145,7 +145,8 @@ extern "C" {
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();
RESET_ERROR_CODE();
CHECK_IS_EXPR(a, Z3_FALSE);
expr* e = to_expr(a);
return
mk_c(c)->autil().is_numeral(e) ||
@ -160,11 +161,8 @@ extern "C" {
Z3_TRY;
// This function is not part of the public API
RESET_ERROR_CODE();
CHECK_IS_EXPR(a, Z3_FALSE);
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;
}
@ -187,6 +185,7 @@ extern "C" {
// 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();
CHECK_IS_EXPR(a, "");
rational r;
Z3_bool ok = Z3_get_numeral_rational(c, a, r);
if (ok == Z3_TRUE) {
@ -221,7 +220,7 @@ extern "C" {
return mk_c(c)->mk_external_string(fu.fm().to_string(tmp));
}
else {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
}
@ -232,11 +231,8 @@ extern "C" {
Z3_TRY;
LOG_Z3_get_numeral_decimal_string(c, a, precision);
RESET_ERROR_CODE();
CHECK_IS_EXPR(a, "");
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()) {
@ -256,7 +252,7 @@ extern "C" {
return mk_c(c)->mk_external_string(r.to_string());
}
else {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
Z3_CATCH_RETURN("");
@ -267,6 +263,7 @@ extern "C" {
// 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();
CHECK_IS_EXPR(a, Z3_FALSE);
rational r;
Z3_bool ok = Z3_get_numeral_rational(c, a, r);
if (ok == Z3_TRUE) {
@ -281,7 +278,7 @@ extern "C" {
return Z3_FALSE;
}
}
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
Z3_CATCH_RETURN(Z3_FALSE);
}
@ -292,8 +289,9 @@ extern "C" {
// 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();
CHECK_IS_EXPR(v, Z3_FALSE);
if (!i) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
int64_t l;
@ -310,8 +308,9 @@ extern "C" {
// 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();
CHECK_IS_EXPR(v, Z3_FALSE);
if (!u) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
uint64_t l;
@ -328,8 +327,9 @@ extern "C" {
// 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();
CHECK_IS_EXPR(v, Z3_FALSE);
if (!u) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
rational r;
@ -348,8 +348,9 @@ extern "C" {
// 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();
CHECK_IS_EXPR(v, Z3_FALSE);
if (!i) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
rational r;
@ -367,8 +368,9 @@ extern "C" {
// 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();
CHECK_IS_EXPR(v, Z3_FALSE);
if (!num || !den) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return Z3_FALSE;
}
rational r;

View file

@ -318,17 +318,15 @@ extern "C" {
ctx->set_ignore_check(true);
try {
if (!parse_smt2_commands(*ctx.get(), s)) {
mk_c(c)->m_parser_error_buffer = errstrm.str();
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return;
}
}
catch (z3_exception& e) {
errstrm << e.msg();
mk_c(c)->m_parser_error_buffer = errstrm.str();
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return;
}

View file

@ -171,7 +171,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_symbol result = of_symbol(to_param_descrs_ptr(p)->get_param_name(i));
@ -185,7 +185,7 @@ extern "C" {
RESET_ERROR_CODE();
char const* result = to_param_descrs_ptr(p)->get_descr(to_symbol(s));
if (result == nullptr) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
return mk_c(c)->mk_external_string(result);

View file

@ -30,15 +30,6 @@ Revision History:
extern "C" {
Z3_string Z3_API Z3_get_parser_error(Z3_context c) {
Z3_TRY;
LOG_Z3_get_parser_error(c);
RESET_ERROR_CODE();
return mk_c(c)->m_parser_error_buffer.c_str();
Z3_CATCH_RETURN("");
}
// ---------------
// Support for SMTLIB2
@ -70,16 +61,14 @@ extern "C" {
try {
if (!parse_smt2_commands(*ctx.get(), is)) {
ctx = nullptr;
mk_c(c)->m_parser_error_buffer = errstrm.str();
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return of_ast_vector(v);
}
}
catch (z3_exception& e) {
errstrm << e.msg();
mk_c(c)->m_parser_error_buffer = errstrm.str();
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return of_ast_vector(v);
}
ptr_vector<expr>::const_iterator it = ctx->begin_assertions();
@ -118,7 +107,7 @@ extern "C" {
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_FILE_ACCESS_ERROR);
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR, nullptr);
return nullptr;
}
Z3_ast_vector r = parse_smtlib2_stream(false, c, is, num_sorts, sort_names, sorts, num_decls, decl_names, decls);
@ -141,15 +130,13 @@ extern "C" {
ctx->set_diagnostic_stream(ous);
try {
if (!parse_smt2_commands(*ctx.get(), is)) {
mk_c(c)->m_parser_error_buffer = ous.str();
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, ous.str().c_str());
RETURN_Z3(mk_c(c)->mk_external_string(ous.str()));
}
}
catch (z3_exception& e) {
if (ous.str().empty()) ous << e.msg();
mk_c(c)->m_parser_error_buffer = ous.str();
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, ous.str().c_str());
RETURN_Z3(mk_c(c)->mk_external_string(ous.str()));
}
RETURN_Z3(mk_c(c)->mk_external_string(ous.str()));

View file

@ -26,17 +26,6 @@ Notes:
#include "util/scoped_timer.h"
#include "ast/expr2var.h"
namespace api {
pmanager::pmanager(reslimit& lim):
m_pm(lim, m_nm) {
}
pmanager::~pmanager() {
}
};
extern "C" {
Z3_ast_vector Z3_API Z3_polynomial_subresultants(Z3_context c, Z3_ast p, Z3_ast q, Z3_ast x) {
@ -49,7 +38,7 @@ extern "C" {
default_expr2polynomial converter(mk_c(c)->m(), pm);
if (!converter.to_polynomial(to_expr(p), _p, d) ||
!converter.to_polynomial(to_expr(q), _q, d)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return nullptr;
}
Z3_ast_vector_ref* result = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());

View file

@ -23,13 +23,13 @@ Notes:
namespace api {
class pmanager {
class pmanager final {
unsynch_mpz_manager m_nm;
polynomial::manager m_pm;
// TODO: add support for caching expressions -> polynomial and back
public:
pmanager(reslimit& limx);
virtual ~pmanager();
pmanager(reslimit& lim) : m_pm(lim, m_nm) {}
~pmanager() {}
polynomial::manager & pm() { return m_pm; }
};

View file

@ -55,7 +55,7 @@ extern "C"
app_ref_vector vars(mk_c(c)->m ());
if (!to_apps(num_bounds, bound, vars)) {
SET_ERROR_CODE (Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
@ -141,7 +141,7 @@ extern "C"
for (unsigned i = 0; i < vVars.size (); ++i) {
app *a = to_app (vVars.get (i));
if (a->get_kind () != AST_APP) {
SET_ERROR_CODE (Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
vApps.push_back (a);

View file

@ -62,11 +62,11 @@ extern "C" {
Z3_TRY;
RESET_ERROR_CODE();
if (!mk_c(c)->m().is_bool(to_expr(body))) {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return nullptr;
}
if (num_patterns > 0 && num_no_patterns > 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
return nullptr;
}
expr * const* ps = reinterpret_cast<expr * const*>(patterns);
@ -77,7 +77,7 @@ extern "C" {
pattern_validator v(mk_c(c)->m());
for (unsigned i = 0; i < num_patterns; i++) {
if (!v(num_decls, ps[i], 0, 0)) {
SET_ERROR_CODE(Z3_INVALID_PATTERN);
SET_ERROR_CODE(Z3_INVALID_PATTERN, nullptr);
return nullptr;
}
}
@ -154,7 +154,7 @@ extern "C" {
RESET_ERROR_CODE();
expr_ref result(mk_c(c)->m());
if (num_decls == 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
RETURN_Z3(0);
}
@ -177,7 +177,7 @@ extern "C" {
LOG_Z3_mk_lambda_const(c, num_decls, vars, body);
RESET_ERROR_CODE();
if (num_decls == 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
RETURN_Z3(0);
}
@ -220,17 +220,17 @@ extern "C" {
svector<Z3_sort> types;
ptr_vector<expr> bound_asts;
if (num_patterns > 0 && num_no_patterns > 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, nullptr);
RETURN_Z3(nullptr);
}
if (num_bound == 0) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "number of bound variables is 0");
RETURN_Z3(nullptr);
}
for (unsigned i = 0; i < num_bound; ++i) {
app* a = to_app(bound[i]);
if (a->get_kind() != AST_APP) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
symbol s(to_app(a)->get_decl()->get_name());
@ -238,7 +238,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -259,7 +259,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
app* pat = to_app(to_expr(no_patterns[i]));
@ -323,7 +323,7 @@ extern "C" {
RESET_ERROR_CODE();
for (unsigned i = 0; i < num_patterns; ++i) {
if (!is_app(to_expr(terms[i]))) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
}
@ -377,7 +377,7 @@ extern "C" {
return to_quantifier(_a)->get_weight();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -392,7 +392,7 @@ extern "C" {
return to_quantifier(_a)->get_num_patterns();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -408,7 +408,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -424,7 +424,7 @@ extern "C" {
return to_quantifier(_a)->get_num_no_patterns();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -440,7 +440,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -455,7 +455,7 @@ extern "C" {
return of_symbol(to_quantifier(_a)->get_decl_names()[i]);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return nullptr;
}
Z3_CATCH_RETURN(nullptr);
@ -471,7 +471,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -487,7 +487,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);
@ -503,7 +503,7 @@ extern "C" {
return to_quantifier(_a)->get_num_decls();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -518,7 +518,7 @@ extern "C" {
return _p->get_num_args();
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
return 0;
}
Z3_CATCH_RETURN(0);
@ -534,7 +534,7 @@ extern "C" {
RETURN_Z3(r);
}
else {
SET_ERROR_CODE(Z3_SORT_ERROR);
SET_ERROR_CODE(Z3_SORT_ERROR, nullptr);
RETURN_Z3(nullptr);
}
Z3_CATCH_RETURN(nullptr);

View file

@ -123,7 +123,7 @@ extern "C" {
}
if (rz == 0) {
// it is the zero polynomial
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
av.shrink(rz);

View file

@ -107,7 +107,7 @@ extern "C" {
RESET_ERROR_CODE();
zstring str;
if (!mk_c(c)->sutil().str.is_string(to_expr(s), str)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, "expression is not a string literal");
return "";
}
std::string result = str.encode();

View file

@ -145,10 +145,12 @@ extern "C" {
void solver_from_stream(Z3_context c, Z3_solver s, std::istream& is) {
scoped_ptr<cmd_context> ctx = alloc(cmd_context, false, &(mk_c(c)->m()));
ctx->set_ignore_check(true);
std::stringstream errstrm;
ctx->set_regular_stream(errstrm);
if (!parse_smt2_commands(*ctx.get(), is)) {
ctx = nullptr;
SET_ERROR_CODE(Z3_PARSER_ERROR);
SET_ERROR_CODE(Z3_PARSER_ERROR, errstrm.str().c_str());
return;
}
@ -178,7 +180,7 @@ extern "C" {
char const* ext = get_extension(file_name);
std::ifstream is(file_name);
if (!is) {
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR);
SET_ERROR_CODE(Z3_FILE_ACCESS_ERROR, nullptr);
}
else if (ext && std::string("dimacs") == ext) {
ast_manager& m = to_solver_ref(s)->get_manager();
@ -291,7 +293,7 @@ extern "C" {
RESET_ERROR_CODE();
init_solver(c, s);
if (n > to_solver_ref(s)->get_scope_level()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return;
}
if (n > 0)
@ -372,7 +374,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_INVALID_ARG, "assumption is not an expression");
return Z3_L_UNDEF;
}
}
@ -430,7 +432,7 @@ extern "C" {
model_ref _m;
to_solver_ref(s)->get_model(_m);
if (!_m) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "there is no current model");
RETURN_Z3(nullptr);
}
if (_m) {
@ -450,7 +452,7 @@ extern "C" {
init_solver(c, s);
proof * p = to_solver_ref(s)->get_proof();
if (!p) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "there is no current proof");
RETURN_Z3(nullptr);
}
mk_c(c)->save_ast_trail(p);
@ -542,7 +544,7 @@ extern "C" {
for (ast* e : __assumptions) {
if (!is_expr(e)) {
_assumptions.finalize(); _consequences.finalize(); _variables.finalize();
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "assumption is not an expression");
return Z3_L_UNDEF;
}
_assumptions.push_back(to_expr(e));
@ -551,7 +553,7 @@ extern "C" {
for (ast* a : __variables) {
if (!is_expr(a)) {
_assumptions.finalize(); _consequences.finalize(); _variables.finalize();
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "variable is not an expression");
return Z3_L_UNDEF;
}
_variables.push_back(to_expr(a));
@ -593,7 +595,7 @@ extern "C" {
expr_ref_vector result(m), vars(m);
for (ast* a : to_ast_vector_ref(vs)) {
if (!is_expr(a)) {
SET_ERROR_CODE(Z3_INVALID_USAGE);
SET_ERROR_CODE(Z3_INVALID_USAGE, "cube contains a non-expression");
}
else {
vars.push_back(to_expr(a));

View file

@ -67,7 +67,7 @@ extern "C" {
LOG_Z3_stats_get_key(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return "";
}
return to_stats_ref(s).get_key(idx);
@ -79,7 +79,7 @@ extern "C" {
LOG_Z3_stats_is_uint(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return Z3_FALSE;
}
return to_stats_ref(s).is_uint(idx);
@ -91,7 +91,7 @@ extern "C" {
LOG_Z3_stats_is_double(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return Z3_FALSE;
}
return !to_stats_ref(s).is_uint(idx);
@ -103,11 +103,11 @@ extern "C" {
LOG_Z3_stats_get_uint_value(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0;
}
if (!to_stats_ref(s).is_uint(idx)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0;
}
return to_stats_ref(s).get_uint_value(idx);
@ -119,11 +119,11 @@ extern "C" {
LOG_Z3_stats_get_double_value(c, s, idx);
RESET_ERROR_CODE();
if (idx >= to_stats_ref(s).size()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return 0.0;
}
if (to_stats_ref(s).is_uint(idx)) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return 0.0;
}
return to_stats_ref(s).get_double_value(idx);

View file

@ -52,7 +52,7 @@ extern "C" {
RESET_ERROR_CODE();
tactic_cmd * t = mk_c(c)->find_tactic_cmd(symbol(name));
if (t == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
tactic * new_t = t->mk(mk_c(c)->m());
@ -82,7 +82,7 @@ extern "C" {
RESET_ERROR_CODE();
probe_info * p = mk_c(c)->find_probe(symbol(name));
if (p == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
RETURN_Z3(nullptr);
}
probe * new_p = p->get();
@ -324,7 +324,7 @@ extern "C" {
LOG_Z3_get_tactic_name(c, idx);
RESET_ERROR_CODE();
if (idx >= mk_c(c)->num_tactics()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return "";
}
return mk_c(c)->get_tactic(idx)->get_name().bare_str();
@ -344,7 +344,7 @@ extern "C" {
LOG_Z3_get_probe_name(c, idx);
RESET_ERROR_CODE();
if (idx >= mk_c(c)->num_probes()) {
SET_ERROR_CODE(Z3_IOB);
SET_ERROR_CODE(Z3_IOB, nullptr);
return "";
}
return mk_c(c)->get_probe(idx)->get_name().bare_str();
@ -381,7 +381,7 @@ extern "C" {
RESET_ERROR_CODE();
tactic_cmd * t = mk_c(c)->find_tactic_cmd(symbol(name));
if (t == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
return t->get_descr();
@ -394,7 +394,7 @@ extern "C" {
RESET_ERROR_CODE();
probe_info * p = mk_c(c)->find_probe(symbol(name));
if (p == nullptr) {
SET_ERROR_CODE(Z3_INVALID_ARG);
SET_ERROR_CODE(Z3_INVALID_ARG, nullptr);
return "";
}
return p->get_descr();
@ -504,7 +504,7 @@ extern "C" {
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);
SET_ERROR_CODE(Z3_IOB, nullptr);
RETURN_Z3(nullptr);
}
Z3_goal_ref * g = alloc(Z3_goal_ref, *mk_c(c));

View file

@ -167,11 +167,6 @@ namespace z3 {
}
void check_parser_error() const {
Z3_error_code e = Z3_get_error_code(*this);
if (e != Z3_OK && enable_exceptions()) {
Z3_string s = Z3_get_parser_error(*this);
if (s && *s) Z3_THROW(exception(s));
}
check_error();
}

View file

@ -89,6 +89,15 @@ namespace Microsoft.Z3
}
}
/// <summary>
/// The i'th argument of the expression.
/// </summary>
public Expr Arg(uint i)
{
Contract.Ensures(Contract.Result<Expr>() != null);
return Expr.Create(Context, Native.Z3_get_app_arg(Context.nCtx, NativeObject, i));
}
/// <summary>
/// Update the arguments of the expression using the arguments <paramref name="args"/>
/// The number of new arguments should coincide with the current number of arguments.
@ -315,6 +324,41 @@ namespace Microsoft.Z3
/// </summary>
public bool IsImplies { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_IMPLIES; } }
/// <summary>
/// Indicates whether the term is at-most
/// </summary>
public bool IsAtMost { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PB_AT_MOST; } }
/// <summary>
/// Retrieve bound of at-most
/// </summary>
public uint AtMostBound { get { Contract.Requires(IsAtMost); return (uint)FuncDecl.Parameters[0].Int; } }
/// <summary>
/// Indicates whether the term is at-least
/// </summary>
public bool IsAtLeast { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PB_AT_LEAST; } }
/// <summary>
/// Retrieve bound of at-least
/// </summary>
public uint AtLeastBound { get { Contract.Requires(IsAtLeast); return (uint)FuncDecl.Parameters[0].Int; } }
/// <summary>
/// Indicates whether the term is pbeq
/// </summary>
public bool IsPbEq { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PB_EQ; } }
/// <summary>
/// Indicates whether the term is pble
/// </summary>
public bool IsPbLe { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PB_LE; } }
/// <summary>
/// Indicates whether the term is pbge
/// </summary>
public bool IsPbGe { get { return IsApp && FuncDecl.DeclKind == Z3_decl_kind.Z3_OP_PB_GE; } }
#endregion
#region Arithmetic Terms

View file

@ -146,7 +146,7 @@ namespace Microsoft.Z3
/// The query is satisfiable if there is an instance of some relation that is non-empty.
/// The query is unsatisfiable if there are no derivations satisfying any of the relations.
/// </summary>
public Status Query(FuncDecl[] relations)
public Status Query(params FuncDecl[] relations)
{
Contract.Requires(relations != null);
Contract.Requires(Contract.ForAll(0, relations.Length, i => relations[i] != null));
@ -262,7 +262,7 @@ namespace Microsoft.Z3
/// <summary>
/// Convert benchmark given as set of axioms, rules and queries to a string.
/// </summary>
public string ToString(BoolExpr[] queries)
public string ToString(params BoolExpr[] queries)
{
return Native.Z3_fixedpoint_to_string(Context.nCtx, NativeObject,

View file

@ -2505,7 +2505,7 @@ public class Context implements AutoCloseable {
* with the sorts of the bound variables, {@code names} is an array with the
* 'names' of the bound variables, and {@code body} is the body of the
* lambda.
* Note that the bound variables are de-Bruijn indices created using {@see #MkBound}
* Note that the bound variables are de-Bruijn indices created using {@link #mkBound}
* Z3 applies the convention that the last element in {@code names} and
* {@code sorts} refers to the variable with index 0, the second to last element
* of {@code names} and {@code sorts} refers to the variable

View file

@ -314,6 +314,23 @@ public class Optimize extends Z3Object {
Native.optimizeFromString(getContext().nCtx(), getNativeObject(), s);
}
/**
* The set of asserted formulas.
*/
public BoolExpr[] getAssertions()
{
ASTVector assertions = new ASTVector(getContext(), Native.optimizeGetAssertions(getContext().nCtx(), getNativeObject()));
return assertions.ToBoolExprArray();
}
/**
* The set of asserted formulas.
*/
public Expr[] getObjectives()
{
ASTVector objectives = new ASTVector(getContext(), Native.optimizeGetObjectives(getContext().nCtx(), getNativeObject()));
return objectives.ToExprArray();
}
/**
* Optimize statistics.

View file

@ -6,6 +6,7 @@ import subprocess
import multiprocessing
import re
from setuptools import setup
from distutils.util import get_platform
from distutils.errors import LibError
from distutils.command.build import build as _build
from distutils.command.sdist import sdist as _sdist
@ -45,13 +46,14 @@ def _clean_bins():
shutil.rmtree(HEADERS_DIR, ignore_errors=True)
def _z3_version():
post = os.getenv('Z3_VERSION_SUFFIX', '')
fn = os.path.join(SRC_DIR, 'scripts', 'mk_project.py')
if os.path.exists(fn):
if os.path.exists(fn):
with open(fn) as f:
for line in f:
n = re.match(".*set_version\((.*), (.*), (.*), (.*)\).*", line)
if not n is None:
return n.group(1) + '.' + n.group(2) + '.' + n.group(3) + '.' + n.group(4)
return n.group(1) + '.' + n.group(2) + '.' + n.group(3) + '.' + n.group(4) + post
return "?.?.?.?"
def _configure_z3():
@ -97,7 +99,10 @@ def _copy_bins():
os.mkdir(os.path.join(HEADERS_DIR, 'c++'))
shutil.copy(os.path.join(BUILD_DIR, LIBRARY_FILE), LIBS_DIR)
shutil.copy(os.path.join(BUILD_DIR, EXECUTABLE_FILE), BINS_DIR)
for fname in ('z3.h', 'z3_v1.h', 'z3_macros.h', 'z3_api.h', 'z3_algebraic.h', 'z3_polynomial.h', 'z3_rcf.h', 'z3_interp.h', 'z3_fpa.h', os.path.join('c++', 'z3++.h')):
header_files = [x for x in os.listdir(os.path.join(SRC_DIR, 'src', 'api')) if x.endswith('.h')]
header_files += [os.path.join('c++', x) for x in os.listdir(os.path.join(SRC_DIR, 'src', 'api', 'c++')) if x.endswith('.h')]
for fname in header_files:
shutil.copy(os.path.join(SRC_DIR, 'src', 'api', fname), os.path.join(HEADERS_DIR, fname))
def _copy_sources():
@ -118,6 +123,7 @@ def _copy_sources():
os.mkdir(os.path.join(SRC_DIR_LOCAL, 'src', 'api', 'python'))
os.mkdir(os.path.join(SRC_DIR_LOCAL, 'src', 'api', 'python', 'z3'))
open(os.path.join(SRC_DIR_LOCAL, 'src', 'api', 'python', 'z3', '.placeholder'), 'w').close()
open(os.path.join(SRC_DIR_LOCAL, 'src', 'api', 'python', 'z3test.py'), 'w').close()
class build(_build):
def run(self):
@ -148,14 +154,34 @@ class sdist(_sdist):
#try: os.makedirs(os.path.join(ROOT_DIR, 'build'))
#except OSError: pass
if 'bdist_wheel' in sys.argv and '--plat-name' not in sys.argv:
idx = sys.argv.index('bdist_wheel') + 1
sys.argv.insert(idx, '--plat-name')
name = get_platform()
if 'linux' in name:
# linux_* platform tags are disallowed because the python ecosystem is fubar
# linux builds should be built in the centos 5 vm for maximum compatibility
# see https://github.com/pypa/manylinux
# see also https://github.com/angr/angr-dev/blob/master/admin/bdist.py
sys.argv.insert(idx + 1, 'manylinux1_' + platform.machine())
elif 'mingw' in name:
if platform.architecture()[0] == '64bit':
sys.argv.insert(idx + 1, 'win_amd64')
else:
sys.argv.insert(idx + 1, 'win32')
else:
# https://www.python.org/dev/peps/pep-0425/
sys.argv.insert(idx + 1, name.replace('.', '_').replace('-', '_'))
setup(
name='z3-solver',
version=_z3_version(),
description='an efficient SMT solver library',
long_description='Z3 is a theorem prover from Microsoft Research with support for bitvectors, booleans, arrays, floating point numbers, strings, and other data types.\n\nFor documentation, please read http://z3prover.github.io/api/html/z3.html\n\nIn the event of technical difficulties related to configuration, compiliation, or installation, please submit issues to https://github.com/angr/angr-z3',
author="The Z3 Theorem Prover Project",
maintainer="Andrew Dutcher",
maintainer_email="andrew@andrewdutcher.com",
maintainer="Audrey Dutcher",
maintainer_email="audrey@rhelmot.io",
url='https://github.com/Z3Prover/z3',
license='MIT License',
keywords=['z3', 'smt', 'sat', 'prover', 'theorem'],

View file

@ -1675,7 +1675,6 @@ def Or(*args):
class PatternRef(ExprRef):
"""Patterns are hints for quantifier instantiation.
See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
"""
def as_ast(self):
return Z3_pattern_to_ast(self.ctx_ref(), self.ast)
@ -1686,8 +1685,6 @@ class PatternRef(ExprRef):
def is_pattern(a):
"""Return `True` if `a` is a Z3 pattern (hint for quantifier instantiation.
See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
>>> f = Function('f', IntSort(), IntSort())
>>> x = Int('x')
>>> q = ForAll(x, f(x) == 0, patterns = [ f(x) ])
@ -1705,8 +1702,6 @@ def is_pattern(a):
def MultiPattern(*args):
"""Create a Z3 multi-pattern using the given expressions `*args`
See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
>>> f = Function('f', IntSort(), IntSort())
>>> g = Function('g', IntSort(), IntSort())
>>> x = Int('x')
@ -1966,8 +1961,6 @@ def ForAll(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
>>> f = Function('f', IntSort(), IntSort(), IntSort())
>>> x = Int('x')
>>> y = Int('y')
@ -1985,7 +1978,6 @@ def Exists(vs, body, weight=1, qid="", skid="", patterns=[], no_patterns=[]):
The parameters `weight`, `qif`, `skid`, `patterns` and `no_patterns` are optional annotations.
See http://rise4fun.com/Z3Py/tutorial/advanced for more details.
>>> f = Function('f', IntSort(), IntSort(), IntSort())
>>> x = Int('x')
@ -7241,11 +7233,13 @@ class Optimize(Z3PPObject):
def assert_exprs(self, *args):
"""Assert constraints as background axioms for the optimize solver."""
args = _get_args(args)
s = BoolSort(self.ctx)
for arg in args:
if isinstance(arg, Goal) or isinstance(arg, AstVector):
for f in arg:
Z3_optimize_assert(self.ctx.ref(), self.optimize, f.as_ast())
else:
arg = s.cast(arg)
Z3_optimize_assert(self.ctx.ref(), self.optimize, arg.as_ast())
def add(self, *args):
@ -8395,11 +8389,6 @@ def _dict2darray(decls, ctx):
i = i + 1
return sz, _names, _decls
def _handle_parse_error(ex, ctx):
msg = Z3_get_parser_error(ctx.ref())
if msg != "":
raise Z3Exception(msg)
raise ex
def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
"""Parse a string in SMT 2.0 format using the given sorts and decls.
@ -8419,10 +8408,7 @@ def parse_smt2_string(s, sorts={}, decls={}, ctx=None):
ctx = _get_ctx(ctx)
ssz, snames, ssorts = _dict2sarray(sorts, ctx)
dsz, dnames, ddecls = _dict2darray(decls, ctx)
try:
return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
except Z3Exception as e:
_handle_parse_error(e, ctx)
return AstVector(Z3_parse_smtlib2_string(ctx.ref(), s, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
"""Parse a file in SMT 2.0 format using the given sorts and decls.
@ -8432,10 +8418,7 @@ def parse_smt2_file(f, sorts={}, decls={}, ctx=None):
ctx = _get_ctx(ctx)
ssz, snames, ssorts = _dict2sarray(sorts, ctx)
dsz, dnames, ddecls = _dict2darray(decls, ctx)
try:
return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
except Z3Exception as e:
_handle_parse_error(e, ctx)
return AstVector(Z3_parse_smtlib2_file(ctx.ref(), f, ssz, snames, ssorts, dsz, dnames, ddecls), ctx)
#########################################

View file

@ -5280,12 +5280,6 @@ extern "C" {
Z3_string Z3_API Z3_eval_smtlib2_string(Z3_context, Z3_string str);
/**
\brief Retrieve that last error message information generated from parsing.
def_API('Z3_get_parser_error', STRING, (_in(CONTEXT), ))
*/
Z3_string Z3_API Z3_get_parser_error(Z3_context c);
/*@}*/
/** @name Error Handling */
@ -5332,11 +5326,6 @@ extern "C" {
*/
Z3_string Z3_API Z3_get_error_msg(Z3_context c, Z3_error_code err);
/**
\brief Return a string describing the given error code.
Retained function name for backwards compatibility within v4.1
*/
Z3_string Z3_API Z3_get_error_msg_ex(Z3_context c, Z3_error_code err);
/*@}*/
/** @name Miscellaneous */
@ -5536,6 +5525,11 @@ extern "C" {
/**
\brief Convert a goal into a DIMACS formatted string.
The goal must be in CNF. You can convert a goal to CNF
by applying the tseitin-cnf tactic. Bit-vectors are not automatically
converted to Booleans either, so the caller intends to
preserve satisfiability, it should apply bit-blasting tactics.
Quantifiers and theory atoms will not be encoded.
def_API('Z3_goal_to_dimacs_string', STRING, (_in(CONTEXT), _in(GOAL)))
*/

View file

@ -42,6 +42,7 @@ static void __declspec(noinline) Sy(Z3_symbol sym) {
}
static void __declspec(noinline) Ap(unsigned sz) { *g_z3_log << "p " << sz << "\n"; g_z3_log->flush(); }
static void __declspec(noinline) Au(unsigned sz) { *g_z3_log << "u " << sz << "\n"; g_z3_log->flush(); }
static void __declspec(noinline) Ai(unsigned sz) { *g_z3_log << "i " << sz << "\n"; g_z3_log->flush(); }
static void __declspec(noinline) Asy(unsigned sz) { *g_z3_log << "s " << sz << "\n"; g_z3_log->flush(); }
static void __declspec(noinline) C(unsigned id) { *g_z3_log << "C " << id << "\n"; g_z3_log->flush(); }
void __declspec(noinline) _Z3_append_log(char const * msg) { *g_z3_log << "M \"" << ll_escaped(msg) << "\"\n"; g_z3_log->flush(); }

View file

@ -78,6 +78,7 @@ struct z3_replayer::imp {
std::stringstream strm;
strm << "expecting " << kind2string(k) << " at position "
<< pos << " but got " << kind2string(m_args[pos].m_kind);
TRACE("z3_replayer", tout << strm.str() << "\n";);
throw z3_replayer_exception(strm.str().c_str());
}
}
@ -186,10 +187,10 @@ struct z3_replayer::imp {
sz++;
}
else {
throw z3_replayer_exception("invalid scaped character");
throw z3_replayer_exception("invalid escaped character");
}
if (val > 255)
throw z3_replayer_exception("invalid scaped character");
throw z3_replayer_exception("invalid escaped character");
next();
}
TRACE("z3_replayer_escape", tout << "val: " << val << "\n";);
@ -497,6 +498,7 @@ struct z3_replayer::imp {
case 'p':
case 's':
case 'u':
case 'i':
// push array
next(); skip_blank(); read_uint64();
TRACE("z3_replayer", tout << "[" << m_line << "] " << "A " << m_uint64 << "\n";);
@ -504,6 +506,8 @@ struct z3_replayer::imp {
push_array(static_cast<unsigned>(m_uint64), OBJECT);
else if (c == 's')
push_array(static_cast<unsigned>(m_uint64), SYMBOL);
else if (c == 'i')
push_array(static_cast<unsigned>(m_uint64), INT64);
else
push_array(static_cast<unsigned>(m_uint64), UINT64);
break;

View file

@ -351,6 +351,7 @@ inline func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, bool is_real) {
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_IDIVIDES: UNREACHABLE();
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;
@ -482,6 +483,14 @@ func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
m_manager->raise_exception("no arguments supplied to arithmetical operator");
return nullptr;
}
if (k == OP_IDIVIDES) {
if (arity != 1 || domain[0] != m_int_decl || num_parameters != 1 || !parameters[0].is_int()) {
m_manager->raise_exception("invalid divides application. Expects integer parameter and one argument of sort integer");
}
return m_manager->mk_func_decl(symbol("divides"), 1, &m_int_decl, m_manager->mk_bool_sort(),
func_decl_info(m_family_id, k, num_parameters, parameters));
}
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));
}
@ -499,6 +508,13 @@ func_decl * arith_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
m_manager->raise_exception("no arguments supplied to arithmetical operator");
return nullptr;
}
if (k == OP_IDIVIDES) {
if (num_args != 1 || m_manager->get_sort(args[0]) != m_int_decl || num_parameters != 1 || !parameters[0].is_int()) {
m_manager->raise_exception("invalid divides application. Expects integer parameter and one argument of sort integer");
}
return m_manager->mk_func_decl(symbol("divides"), 1, &m_int_decl, m_manager->mk_bool_sort(),
func_decl_info(m_family_id, k, num_parameters, parameters));
}
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));
}
@ -533,6 +549,8 @@ void arith_decl_plugin::get_op_names(svector<builtin_name>& op_names, symbol con
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));
// clashes with user-defined functions
// op_names.push_back(builtin_name("divides",OP_IDIVIDES));
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));

View file

@ -46,6 +46,7 @@ enum arith_op_kind {
OP_MUL,
OP_DIV,
OP_IDIV,
OP_IDIVIDES,
OP_REM,
OP_MOD,
OP_TO_REAL,

View file

@ -1057,7 +1057,7 @@ sort* basic_decl_plugin::join(sort* s1, sort* s2) {
}
std::ostringstream buffer;
buffer << "Sorts " << mk_pp(s1, *m_manager) << " and " << mk_pp(s2, *m_manager) << " are incompatible";
throw ast_exception(buffer.str().c_str());
throw ast_exception(buffer.str());
}
@ -1086,7 +1086,7 @@ func_decl * basic_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters
if (domain[i] != domain[0]) {
std::ostringstream buffer;
buffer << "Sort mismatch between first argument and argument " << (i+1);
throw ast_exception(buffer.str().c_str());
throw ast_exception(buffer.str());
}
}
return m_manager->mk_func_decl(symbol("distinct"), arity, domain, m_bool_sort, info);
@ -1403,6 +1403,7 @@ void ast_manager::init() {
inc_ref(m_false);
}
template<typename T>
static void mark_array_ref(ast_mark& mark, unsigned sz, T * const * a) {
for(unsigned i = 0; i < sz; i++) {
@ -1701,9 +1702,9 @@ ast * ast_manager::register_node_core(ast * n) {
SASSERT(m_ast_table.contains(n));
if (is_func_decl(r) && to_func_decl(r)->get_range() != to_func_decl(n)->get_range()) {
std::ostringstream buffer;
buffer << "Recycling of declaration for the same name '" << to_func_decl(r)->get_name().str().c_str() << "'"
<< " and domain, but different range type is not permitted";
throw ast_exception(buffer.str().c_str());
buffer << "Recycling of declaration for the same name '" << to_func_decl(r)->get_name().str()
<< "' and domain, but different range type is not permitted";
throw ast_exception(buffer.str());
}
deallocate_node(n, ::get_node_size(n));
return r;
@ -1715,6 +1716,7 @@ ast * ast_manager::register_node_core(ast * n) {
n->m_id = is_decl(n) ? m_decl_id_gen.mk() : m_expr_id_gen.mk();
TRACE("ast", tout << "Object " << n->m_id << " was created.\n";);
TRACE("mk_var_bug", tout << "mk_ast: " << n->m_id << "\n";);
@ -1934,8 +1936,7 @@ sort * ast_manager::substitute(sort* s, unsigned n, sort * const * src, sort * c
vector<parameter> ps;
bool change = false;
sort_ref_vector sorts(*this);
for (unsigned i = 0; i < s->get_num_parameters(); ++i) {
parameter const& p = s->get_parameter(i);
for (parameter const& p : s->parameters()) {
if (p.is_ast()) {
SASSERT(is_sort(p.get_ast()));
change = true;
@ -1992,7 +1993,7 @@ void ast_manager::check_sort(func_decl const * decl, unsigned num_args, expr * c
buff << "invalid function application for " << decl->get_name() << ", ";
buff << "sort mismatch on argument at position " << (i+1) << ", ";
buff << "expected " << mk_pp(expected, m) << " but given " << mk_pp(given, m);
throw ast_exception(buff.str().c_str());
throw ast_exception(buff.str());
}
}
}
@ -2008,7 +2009,7 @@ void ast_manager::check_sort(func_decl const * decl, unsigned num_args, expr * c
buff << "invalid function application for " << decl->get_name() << ", ";
buff << "sort mismatch on argument at position " << (i+1) << ", ";
buff << "expected " << mk_pp(expected, m) << " but given " << mk_pp(given, m);
throw ast_exception(buff.str().c_str());
throw ast_exception(buff.str());
}
}
}
@ -2170,7 +2171,7 @@ void ast_manager::check_args(func_decl* f, unsigned n, expr* const* es) {
<< " for function " << mk_pp(f,*this)
<< " supplied sort is "
<< mk_pp(actual_sort, *this);
throw ast_exception(buffer.str().c_str());
throw ast_exception(buffer.str());
}
}
}
@ -2194,7 +2195,7 @@ app * ast_manager::mk_app(func_decl * decl, unsigned num_args, expr * const * ar
std::ostringstream buffer;
buffer << "Wrong number of arguments (" << num_args
<< ") passed to function " << mk_pp(decl, *this);
throw ast_exception(buffer.str().c_str());
throw ast_exception(buffer.str());
}
app * r = nullptr;
if (num_args == 1 && decl->is_chainable() && decl->get_arity() == 2) {
@ -2330,8 +2331,8 @@ bool ast_manager::is_label_lit(expr const * n, buffer<symbol> & names) const {
return false;
}
func_decl const * decl = to_app(n)->get_decl();
for (unsigned i = 0; i < decl->get_num_parameters(); i++)
names.push_back(decl->get_parameter(i).get_symbol());
for (parameter const& p : decl->parameters())
names.push_back(p.get_symbol());
return true;
}
@ -2370,6 +2371,15 @@ bool ast_manager::is_pattern(expr const * n, ptr_vector<expr> &args) {
return true;
}
static void trace_quant(std::ostream& strm, quantifier* q) {
strm << (is_lambda(q) ? "[mk-lambda]" : "[mk-quant]")
<< " #" << q->get_id() << " " << q->get_qid();
for (unsigned i = 0; i < q->get_num_patterns(); ++i) {
strm << " #" << q->get_pattern(i)->get_id();
}
strm << " #" << q->get_expr()->get_id() << "\n";
}
quantifier * ast_manager::mk_quantifier(quantifier_kind k, unsigned num_decls, sort * const * decl_sorts, symbol const * decl_names,
expr * body, int weight , symbol const & qid, symbol const & skid,
@ -2402,12 +2412,7 @@ quantifier * ast_manager::mk_quantifier(quantifier_kind k, unsigned num_decls, s
quantifier * r = register_node(new_node);
if (m_trace_stream && r == new_node) {
*m_trace_stream << "[mk-quant] #" << r->get_id() << " " << qid;
for (unsigned i = 0; i < num_patterns; ++i) {
*m_trace_stream << " #" << patterns[i]->get_id();
}
*m_trace_stream << " #" << body->get_id() << "\n";
trace_quant(*m_trace_stream, r);
}
return r;
@ -2421,6 +2426,9 @@ quantifier * ast_manager::mk_lambda(unsigned num_decls, sort * const * decl_sort
sort* s = autil.mk_array_sort(num_decls, decl_sorts, ::get_sort(body));
quantifier * new_node = new (mem) quantifier(num_decls, decl_sorts, decl_names, body, s);
quantifier * r = register_node(new_node);
if (m_trace_stream && r == new_node) {
trace_quant(*m_trace_stream, r);
}
return r;
}
@ -2928,8 +2936,8 @@ bool ast_manager::is_quant_inst(expr const* e, expr*& not_q_or_i, ptr_vector<exp
not_q_or_i = to_app(e)->get_arg(0);
func_decl* d = to_app(e)->get_decl();
SASSERT(binding.empty());
for (unsigned i = 0; i < d->get_num_parameters(); ++i) {
binding.push_back(to_expr(d->get_parameter(i).get_ast()));
for (parameter const& p : d->parameters()) {
binding.push_back(to_expr(p.get_ast()));
}
return true;
}

View file

@ -69,7 +69,7 @@ class ast_manager;
*/
class ast_exception : public default_exception {
public:
ast_exception(char const * msg):default_exception(msg) {}
ast_exception(std::string && msg) : default_exception(std::move(msg)) {}
};
typedef int family_id;
@ -122,6 +122,7 @@ public:
explicit parameter(ast * p): m_kind(PARAM_AST), m_ast(p) {}
explicit parameter(symbol const & s): m_kind(PARAM_SYMBOL), m_symbol(s.c_ptr()) {}
explicit parameter(rational const & r): m_kind(PARAM_RATIONAL), m_rational(alloc(rational, r)) {}
explicit parameter(rational && r) : m_kind(PARAM_RATIONAL), m_rational(alloc(rational, std::move(r))) {}
explicit parameter(double d):m_kind(PARAM_DOUBLE), m_dval(d) {}
explicit parameter(const char *s):m_kind(PARAM_SYMBOL), m_symbol(symbol(s).c_ptr()) {}
explicit parameter(unsigned ext_id, bool):m_kind(PARAM_EXTERNAL), m_ext_id(ext_id) {}
@ -273,6 +274,14 @@ public:
parameter const * get_parameters() const { return m_parameters.begin(); }
bool private_parameters() const { return m_private_parameters; }
struct iterator {
decl_info const& d;
iterator(decl_info const& d) : d(d) {}
parameter const* begin() const { return d.get_parameters(); }
parameter const* end() const { return begin() + d.get_num_parameters(); }
};
iterator parameters() const { return iterator(*this); }
unsigned hash() const;
bool operator==(decl_info const & info) const;
};
@ -571,6 +580,16 @@ public:
parameter const & get_parameter(unsigned idx) const { return m_info->get_parameter(idx); }
parameter const * get_parameters() const { return m_info == nullptr ? nullptr : m_info->get_parameters(); }
bool private_parameters() const { return m_info != nullptr && m_info->private_parameters(); }
struct iterator {
decl const& d;
iterator(decl const& d) : d(d) {}
parameter const* begin() const { return d.get_parameters(); }
parameter const* end() const { return begin() + d.get_num_parameters(); }
};
iterator parameters() const { return iterator(*this); }
};
// -----------------------------------
@ -2401,11 +2420,7 @@ public:
}
void reset() {
ptr_buffer<ast>::iterator it = m_to_unmark.begin();
ptr_buffer<ast>::iterator end = m_to_unmark.end();
for (; it != end; ++it) {
reset_mark(*it);
}
for (ast* a : m_to_unmark) reset_mark(a);
m_to_unmark.reset();
}

View file

@ -401,7 +401,7 @@ bool bv_decl_plugin::get_int2bv_size(unsigned num_parameters, parameter const *
m_manager->raise_exception("int2bv expects one parameter");
return false;
}
parameter p(parameters[0]);
const parameter &p = parameters[0];
if (p.is_int()) {
result = p.get_int();
return true;
@ -428,7 +428,7 @@ func_decl * bv_decl_plugin::mk_num_decl(unsigned num_parameters, parameter const
// After SMT-COMP, I should find all offending modules.
// For now, I will just simplify the numeral here.
parameter p0(mod(parameters[0].get_rational(), rational::power_of_two(bv_size)));
parameter ps[2] = { p0, parameters[1] };
parameter ps[2] = { std::move(p0), parameters[1] };
sort * bv = get_bv_sort(bv_size);
return m_manager->mk_const_decl(m_bv_sym, bv, func_decl_info(m_family_id, OP_BV_NUM, num_parameters, ps));
}
@ -746,7 +746,7 @@ void bv_decl_plugin::get_op_names(svector<builtin_name> & op_names, symbol const
expr * bv_decl_plugin::get_some_value(sort * s) {
SASSERT(s->is_sort_of(m_family_id, BV_SORT));
unsigned bv_size = s->get_parameter(0).get_int();
parameter p[2] = { parameter(rational(0)), parameter(static_cast<int>(bv_size)) };
parameter p[2] = { parameter(rational::zero()), parameter(static_cast<int>(bv_size)) };
return m_manager->mk_app(m_family_id, OP_BV_NUM, 2, p, 0, nullptr);
}

View file

@ -692,6 +692,7 @@ namespace datatype {
}
unsigned num_well_founded = 0, id = 0;
bool changed;
ptr_vector<sort> subsorts;
do {
changed = false;
for (unsigned tid = 0; tid < num_types; tid++) {
@ -701,23 +702,25 @@ namespace datatype {
sort* s = sorts[tid];
def const& d = get_def(s);
for (constructor const* c : d) {
bool found_nonwf = false;
for (accessor const* a : *c) {
if (sort2id.find(a->range(), id) && !well_founded[id]) {
found_nonwf = true;
break;
subsorts.reset();
get_subsorts(a->range(), subsorts);
for (sort* srt : subsorts) {
if (sort2id.find(srt, id) && !well_founded[id]) {
goto next_constructor;
}
}
}
if (!found_nonwf) {
changed = true;
well_founded[tid] = true;
num_well_founded++;
break;
}
changed = true;
well_founded[tid] = true;
num_well_founded++;
break;
next_constructor:
;
}
}
}
while(changed && num_well_founded < num_types);
while (changed && num_well_founded < num_types);
return num_well_founded == num_types;
}
@ -727,8 +730,7 @@ namespace datatype {
void util::get_subsorts(sort* s, ptr_vector<sort>& sorts) const {
sorts.push_back(s);
for (unsigned i = 0; i < s->get_num_parameters(); ++i) {
parameter const& p = s->get_parameter(i);
for (parameter const& p : s->parameters()) {
if (p.is_ast() && is_sort(p.get_ast())) {
get_subsorts(to_sort(p.get_ast()), sorts);
}

View file

@ -134,13 +134,25 @@ namespace datatype {
~plus() override { m_arg1->dec_ref(); m_arg2->dec_ref(); }
size* subst(obj_map<sort,size*>& S) override { return mk_plus(m_arg1->subst(S), m_arg2->subst(S)); }
sort_size eval(obj_map<sort, sort_size> const& S) override {
sort_size s1 = m_arg1->eval(S);
sort_size s2 = m_arg2->eval(S);
if (s1.is_infinite()) return s1;
if (s2.is_infinite()) return s2;
if (s1.is_very_big()) return s1;
if (s2.is_very_big()) return s2;
rational r = rational(s1.size(), rational::ui64()) + rational(s2.size(), rational::ui64());
rational r(0);
ptr_vector<size> todo;
todo.push_back(m_arg1);
todo.push_back(m_arg2);
while (!todo.empty()) {
size* s = todo.back();
todo.pop_back();
plus* p = dynamic_cast<plus*>(s);
if (p) {
todo.push_back(p->m_arg1);
todo.push_back(p->m_arg2);
}
else {
sort_size sz = s->eval(S);
if (sz.is_infinite()) return sz;
if (sz.is_very_big()) return sz;
r += rational(sz.size(), rational::ui64());
}
}
return sort_size(r);
}
};

View file

@ -192,7 +192,7 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
expr* t1 = nullptr, *t2 = nullptr;
expr* s1 = nullptr, *s2 = nullptr;
expr* u1 = nullptr, *u2 = nullptr;
expr* fact = nullptr, *body1 = nullptr, *body2 = nullptr;
expr* fact = nullptr, *body1 = nullptr;
expr* l1 = nullptr, *l2 = nullptr, *r1 = nullptr, *r2 = nullptr;
func_decl* d1 = nullptr, *d2 = nullptr, *d3 = nullptr;
proof* p0 = nullptr, *p1 = nullptr, *p2 = nullptr;
@ -389,14 +389,14 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
match_fact(p, fact) &&
match_fact(p1, fml) &&
match_and(fml, terms)) {
for (expr* t : terms)
for (expr* t : terms)
if (t == fact) return true;
}
UNREACHABLE();
return false;
}
case PR_NOT_OR_ELIM: {
if (match_proof(p, p1) &&
match_fact(p, fact) &&
match_fact(p1, fml) &&
@ -605,6 +605,7 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
bool found = false;
for (expr* term2 : terms2) {
found = term1 == term2;
if (found) break;
}
if (!found) {
IF_VERBOSE(0, verbose_stream() << "Premise not found:" << mk_pp(term1, m) << "\n";);
@ -738,9 +739,9 @@ bool proof_checker::check1_basic(proof* p, expr_ref_vector& side_conditions) {
}
if (is_quantifier(e)) {
SASSERT(!is_lambda(e));
q = to_quantifier(e);
q = to_quantifier(e);
// TBD check that quantifier is properly instantiated
return is_forall == ::is_forall(q);
return is_forall == ::is_forall(q);
}
}
UNREACHABLE();
@ -1004,7 +1005,7 @@ bool proof_checker::match_op(expr const* e, decl_kind k, ptr_vector<expr>& terms
if (e->get_kind() == AST_APP &&
to_app(e)->get_family_id() == m.get_basic_family_id() &&
to_app(e)->get_decl_kind() == k) {
for (expr* arg : *to_app(e))
for (expr* arg : *to_app(e))
terms.push_back(arg);
return true;
}

View file

@ -66,6 +66,7 @@ br_status arith_rewriter::mk_app_core(func_decl * f, unsigned num_args, expr * c
SASSERT(num_args == 2); st = mk_div_core(args[0], args[1], result); break;
case OP_IDIV: if (num_args == 1) { result = args[0]; st = BR_DONE; break; }
SASSERT(num_args == 2); st = mk_idiv_core(args[0], args[1], result); break;
case OP_IDIVIDES: SASSERT(num_args == 1); st = mk_idivides(f->get_parameter(0).get_int(), args[0], result); break;
case OP_MOD: SASSERT(num_args == 2); st = mk_mod_core(args[0], args[1], result); break;
case OP_REM: SASSERT(num_args == 2); st = mk_rem_core(args[0], args[1], result); break;
case OP_UMINUS: SASSERT(num_args == 1); st = mk_uminus(args[0], result); break;
@ -792,6 +793,11 @@ br_status arith_rewriter::mk_div_core(expr * arg1, expr * arg2, expr_ref & resul
return BR_FAILED;
}
br_status arith_rewriter::mk_idivides(unsigned k, expr * arg, expr_ref & result) {
result = m().mk_eq(m_util.mk_mod(arg, m_util.mk_int(k)), m_util.mk_int(0));
return BR_REWRITE2;
}
br_status arith_rewriter::mk_idiv_core(expr * arg1, expr * arg2, expr_ref & result) {
set_curr_sort(m().get_sort(arg1));
numeral v1, v2;
@ -812,6 +818,28 @@ br_status arith_rewriter::mk_idiv_core(expr * arg1, expr * arg2, expr_ref & resu
result = m().mk_ite(m().mk_eq(arg1, zero), m_util.mk_idiv(zero, zero), m_util.mk_int(1));
return BR_REWRITE3;
}
if (m_util.is_numeral(arg2, v2, is_int) && v2.is_pos() && m_util.is_add(arg1)) {
expr_ref_buffer args(m());
bool change = false;
rational add(0);
for (expr* arg : *to_app(arg1)) {
rational arg_v;
if (m_util.is_numeral(arg, arg_v) && arg_v.is_pos() && mod(arg_v, v2) != arg_v) {
change = true;
args.push_back(m_util.mk_numeral(mod(arg_v, v2), true));
add += div(arg_v, v2);
}
else {
args.push_back(arg);
}
}
if (change) {
result = m_util.mk_idiv(m().mk_app(to_app(arg1)->get_decl(), args.size(), args.c_ptr()), arg2);
result = m_util.mk_add(m_util.mk_numeral(add, true), result);
TRACE("div_bug", tout << "mk_div result: " << result << "\n";);
return BR_REWRITE3;
}
}
if (divides(arg1, arg2, result)) {
return BR_REWRITE_FULL;
}
@ -914,9 +942,8 @@ br_status arith_rewriter::mk_mod_core(expr * arg1, expr * arg2, expr_ref & resul
}
if (arg1 == arg2 && !m_util.is_numeral(arg2)) {
expr_ref zero(m_util.mk_int(0), m()), abs(m());
mk_abs_core(arg2, abs);
result = m().mk_ite(m().mk_eq(arg2, zero), m_util.mk_mod(zero, zero), abs);
expr_ref zero(m_util.mk_int(0), m());
result = m().mk_ite(m().mk_eq(arg2, zero), m_util.mk_mod(zero, zero), zero);
return BR_DONE;
}
@ -927,30 +954,29 @@ br_status arith_rewriter::mk_mod_core(expr * arg1, expr * arg2, expr_ref & resul
return BR_DONE;
}
// propagate mod inside only if not all arguments are not already mod.
// propagate mod inside only if there is something to reduce.
if (m_util.is_numeral(arg2, v2, is_int) && is_int && v2.is_pos() && (is_add(arg1) || is_mul(arg1))) {
TRACE("mod_bug", tout << "mk_mod:\n" << mk_ismt2_pp(arg1, m()) << "\n" << mk_ismt2_pp(arg2, m()) << "\n";);
unsigned num_args = to_app(arg1)->get_num_args();
unsigned i;
rational arg_v;
for (i = 0; i < num_args; i++) {
expr * arg = to_app(arg1)->get_arg(i);
if (m_util.is_mod(arg))
continue;
if (m_util.is_numeral(arg, arg_v) && mod(arg_v, v2) == arg_v)
continue;
if (m().is_ite(arg))
continue;
// found target for rewriting
break;
expr_ref_buffer args(m());
bool change = false;
for (expr* arg : *to_app(arg1)) {
rational arg_v;
if (m_util.is_numeral(arg, arg_v) && mod(arg_v, v2) != arg_v) {
change = true;
args.push_back(m_util.mk_numeral(mod(arg_v, v2), true));
}
else if (m_util.is_mod(arg, t1, t2) && t2 == arg2) {
change = true;
args.push_back(t1);
}
else {
args.push_back(arg);
}
}
TRACE("mod_bug", tout << "mk_mod target: " << i << "\n";);
if (i == num_args)
if (!change) {
return BR_FAILED; // did not find any target for applying simplification
ptr_buffer<expr> new_args;
for (unsigned i = 0; i < num_args; i++)
new_args.push_back(m_util.mk_mod(to_app(arg1)->get_arg(i), arg2));
result = m_util.mk_mod(m().mk_app(to_app(arg1)->get_decl(), new_args.size(), new_args.c_ptr()), arg2);
}
result = m_util.mk_mod(m().mk_app(to_app(arg1)->get_decl(), args.size(), args.c_ptr()), arg2);
TRACE("mod_bug", tout << "mk_mod result: " << mk_ismt2_pp(result, m()) << "\n";);
return BR_REWRITE3;
}

View file

@ -143,6 +143,7 @@ public:
br_status mk_div_core(expr * arg1, expr * arg2, expr_ref & result);
br_status mk_idiv_core(expr * arg1, expr * arg2, expr_ref & result);
br_status mk_idivides(unsigned k, expr * arg, expr_ref & result);
br_status mk_mod_core(expr * arg1, expr * arg2, expr_ref & result);
br_status mk_rem_core(expr * arg1, expr * arg2, expr_ref & result);
br_status mk_power_core(expr* arg1, expr* arg2, expr_ref & result);

View file

@ -89,6 +89,7 @@ struct blaster_rewriter_cfg : public default_rewriter_cfg {
expr_ref_vector m_out;
obj_map<func_decl, expr*> m_const2bits;
expr_ref_vector m_bindings;
unsigned_vector m_shifts;
func_decl_ref_vector m_keys;
expr_ref_vector m_values;
unsigned_vector m_keyval_lim;
@ -579,19 +580,36 @@ MK_PARAMETRIC_UNARY_REDUCE(reduce_sign_extend, mk_sign_extend);
}
SASSERT(new_bindings.size() == q->get_num_decls());
i = q->get_num_decls();
unsigned shift = j;
if (!m_shifts.empty()) shift += m_shifts.back();
while (i > 0) {
i--;
m_bindings.push_back(new_bindings[i]);
m_shifts.push_back(shift);
}
}
return true;
}
bool reduce_var(var * t, expr_ref & result, proof_ref & result_pr) {
if (m_blast_quant) {
if (t->get_idx() >= m_bindings.size())
if (m_blast_quant) {
if (m_bindings.empty())
return false;
result = m_bindings.get(m_bindings.size() - t->get_idx() - 1);
unsigned shift = m_shifts.back();
if (t->get_idx() >= m_bindings.size()) {
if (shift == 0)
return false;
result = m_manager.mk_var(t->get_idx() + shift, t->get_sort());
}
else {
unsigned offset = m_bindings.size() - t->get_idx() - 1;
result = m_bindings.get(offset);
shift = shift - m_shifts[offset];
if (shift > 0) {
var_shifter vs(m_manager);
vs(result, shift, result);
}
}
result_pr = nullptr;
return true;
}
@ -641,6 +659,7 @@ MK_PARAMETRIC_UNARY_REDUCE(reduce_sign_extend, mk_sign_extend);
old_q->get_num_patterns(), new_patterns, old_q->get_num_no_patterns(), new_no_patterns);
result_pr = nullptr;
m_bindings.shrink(old_sz);
m_shifts.shrink(old_sz);
return true;
}
};

View file

@ -613,12 +613,12 @@ br_status bool_rewriter::try_ite_value(app * ite, app * val, expr_ref & result)
expr* cond2 = nullptr, *t2 = nullptr, *e2 = nullptr;
if (m().is_ite(t, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
try_ite_value(to_app(t), val, result);
VERIFY(BR_FAILED != try_ite_value(to_app(t), val, result));
result = m().mk_ite(cond, result, m().mk_eq(e, val));
return BR_REWRITE2;
}
if (m().is_ite(e, cond2, t2, e2) && m().is_value(t2) && m().is_value(e2)) {
try_ite_value(to_app(e), val, result);
VERIFY(BR_FAILED != try_ite_value(to_app(e), val, result));
result = m().mk_ite(cond, m().mk_eq(t, val), result);
return BR_REWRITE2;
}
@ -640,19 +640,21 @@ br_status bool_rewriter::mk_eq_core(expr * lhs, expr * rhs, expr_ref & result) {
br_status r = BR_FAILED;
if (m().is_ite(lhs) && m().is_value(rhs)) {
r = try_ite_value(to_app(lhs), to_app(rhs), result);
CTRACE("try_ite_value", r != BR_FAILED,
tout << mk_bounded_pp(lhs, m()) << "\n" << mk_bounded_pp(rhs, m()) << "\n--->\n" << mk_bounded_pp(result, m()) << "\n";);
if (m_ite_extra_rules) {
if (m().is_ite(lhs) && m().is_value(rhs)) {
r = try_ite_value(to_app(lhs), to_app(rhs), result);
CTRACE("try_ite_value", r != BR_FAILED,
tout << mk_bounded_pp(lhs, m()) << "\n" << mk_bounded_pp(rhs, m()) << "\n--->\n" << mk_bounded_pp(result, m()) << "\n";);
}
else if (m().is_ite(rhs) && m().is_value(lhs)) {
r = try_ite_value(to_app(rhs), to_app(lhs), result);
CTRACE("try_ite_value", r != BR_FAILED,
tout << mk_bounded_pp(lhs, m()) << "\n" << mk_bounded_pp(rhs, m()) << "\n--->\n" << mk_bounded_pp(result, m()) << "\n";);
}
if (r != BR_FAILED)
return r;
}
else if (m().is_ite(rhs) && m().is_value(lhs)) {
r = try_ite_value(to_app(rhs), to_app(lhs), result);
CTRACE("try_ite_value", r != BR_FAILED,
tout << mk_bounded_pp(lhs, m()) << "\n" << mk_bounded_pp(rhs, m()) << "\n--->\n" << mk_bounded_pp(result, m()) << "\n";);
}
if (r != BR_FAILED)
return r;
if (m().is_bool(lhs)) {
bool unfolded = false;

View file

@ -865,8 +865,8 @@ struct pb2bv_rewriter::imp {
// definitions used for sorting network
pliteral mk_false() { return m.mk_false(); }
pliteral mk_true() { return m.mk_true(); }
pliteral mk_max(pliteral a, pliteral b) { return trail(m.mk_or(a, b)); }
pliteral mk_min(pliteral a, pliteral b) { return trail(m.mk_and(a, b)); }
pliteral mk_max(unsigned n, pliteral const* lits) { return trail(m.mk_or(n, lits)); }
pliteral mk_min(unsigned n, pliteral const* lits) { return trail(m.mk_and(n, lits)); }
pliteral mk_not(pliteral a) { if (m.is_not(a,a)) return a; return trail(m.mk_not(a)); }
std::ostream& pp(std::ostream& out, pliteral lit) { return out << mk_ismt2_pp(lit, m); }
@ -889,7 +889,7 @@ struct pb2bv_rewriter::imp {
m_keep_cardinality_constraints = f;
}
void set_at_most1(sorting_network_encoding enc) { m_sort.cfg().m_encoding = enc; }
void set_cardinality_encoding(sorting_network_encoding enc) { m_sort.cfg().m_encoding = enc; }
};
@ -904,7 +904,7 @@ struct pb2bv_rewriter::imp {
card2bv_rewriter_cfg(imp& i, ast_manager & m):m_r(i, m) {}
void keep_cardinality_constraints(bool f) { m_r.keep_cardinality_constraints(f); }
void set_pb_solver(symbol const& s) { m_r.set_pb_solver(s); }
void set_at_most1(sorting_network_encoding enc) { m_r.set_at_most1(enc); }
void set_cardinality_encoding(sorting_network_encoding enc) { m_r.set_cardinality_encoding(enc); }
};
@ -916,7 +916,7 @@ struct pb2bv_rewriter::imp {
m_cfg(i, m) {}
void keep_cardinality_constraints(bool f) { m_cfg.keep_cardinality_constraints(f); }
void set_pb_solver(symbol const& s) { m_cfg.set_pb_solver(s); }
void set_at_most1(sorting_network_encoding e) { m_cfg.set_at_most1(e); }
void set_cardinality_encoding(sorting_network_encoding e) { m_cfg.set_cardinality_encoding(e); }
void rewrite(bool full, expr* e, expr_ref& r, proof_ref& p) {
expr_ref ee(e, m());
if (m_cfg.m_r.mk_app(full, e, r)) {
@ -947,15 +947,17 @@ struct pb2bv_rewriter::imp {
return gparams::get_module("sat").get_sym("pb.solver", symbol("solver"));
}
sorting_network_encoding atmost1_encoding() const {
symbol enc = m_params.get_sym("atmost1_encoding", symbol());
sorting_network_encoding cardinality_encoding() const {
symbol enc = m_params.get_sym("cardinality.encoding", symbol());
if (enc == symbol()) {
enc = gparams::get_module("sat").get_sym("atmost1_encoding", symbol());
enc = gparams::get_module("sat").get_sym("cardinality.encoding", symbol());
}
if (enc == symbol("grouped")) return sorting_network_encoding::grouped_at_most_1;
if (enc == symbol("bimander")) return sorting_network_encoding::bimander_at_most_1;
if (enc == symbol("ordered")) return sorting_network_encoding::ordered_at_most_1;
return grouped_at_most_1;
if (enc == symbol("grouped")) return sorting_network_encoding::grouped_at_most;
if (enc == symbol("bimander")) return sorting_network_encoding::bimander_at_most;
if (enc == symbol("ordered")) return sorting_network_encoding::ordered_at_most;
if (enc == symbol("unate")) return sorting_network_encoding::unate_at_most;
if (enc == symbol("circuit")) return sorting_network_encoding::circuit_at_most;
return grouped_at_most;
}
@ -973,10 +975,11 @@ struct pb2bv_rewriter::imp {
m_params.append(p);
m_rw.keep_cardinality_constraints(keep_cardinality());
m_rw.set_pb_solver(pb_solver());
m_rw.set_at_most1(atmost1_encoding());
m_rw.set_cardinality_encoding(cardinality_encoding());
}
void collect_param_descrs(param_descrs& r) const {
r.insert("keep_cardinality_constraints", CPK_BOOL, "(default: true) retain cardinality constraints (don't bit-blast them) and use built-in cardinality solver");
r.insert("keep_cardinality_constraints", CPK_BOOL, "(default: false) retain cardinality constraints (don't bit-blast them) and use built-in cardinality solver");
r.insert("pb.solver", CPK_SYMBOL, "(default: solver) retain pb constraints (don't bit-blast them) and use built-in pb solver");
}

View file

@ -1866,6 +1866,52 @@ bool seq_rewriter::reduce_eq(expr* l, expr* r, expr_ref_vector& lhs, expr_ref_ve
}
}
bool seq_rewriter::reduce_contains(expr* a, expr* b, expr_ref_vector& disj) {
m_lhs.reset();
m_util.str.get_concat(a, m_lhs);
TRACE("seq", tout << expr_ref(a, m()) << " " << expr_ref(b, m()) << "\n";);
zstring s;
for (unsigned i = 0; i < m_lhs.size(); ++i) {
expr* e = m_lhs.get(i);
if (m_util.str.is_empty(e)) {
continue;
}
if (m_util.str.is_string(e, s)) {
unsigned sz = s.length();
expr_ref_vector es(m());
for (unsigned j = 0; j < sz; ++j) {
es.push_back(m_util.str.mk_unit(m_util.str.mk_char(s, j)));
}
es.append(m_lhs.size() - i, m_lhs.c_ptr() + i);
for (unsigned j = 0; j < sz; ++j) {
disj.push_back(m_util.str.mk_prefix(b, m_util.str.mk_concat(es.size() - j, es.c_ptr() + j)));
}
continue;
}
if (m_util.str.is_unit(e)) {
disj.push_back(m_util.str.mk_prefix(b, m_util.str.mk_concat(m_lhs.size() - i, m_lhs.c_ptr() + i)));
continue;
}
if (m_util.str.is_string(b, s)) {
expr* all = m_util.re.mk_full_seq(m_util.re.mk_re(m().get_sort(b)));
disj.push_back(m_util.re.mk_in_re(m_util.str.mk_concat(m_lhs.size() - i, m_lhs.c_ptr() + i),
m_util.re.mk_concat(all, m_util.re.mk_concat(m_util.re.mk_to_re(b), all))));
return true;
}
if (i == 0) {
return false;
}
disj.push_back(m_util.str.mk_contains(m_util.str.mk_concat(m_lhs.size() - i, m_lhs.c_ptr() + i), b));
return true;
}
disj.push_back(m().mk_eq(b, m_util.str.mk_empty(m().get_sort(b))));
return true;
}
expr* seq_rewriter::concat_non_empty(unsigned n, expr* const* as) {
SASSERT(n > 0);
ptr_vector<expr> bs;

View file

@ -168,6 +168,8 @@ public:
bool reduce_eq(expr_ref_vector& ls, expr_ref_vector& rs, expr_ref_vector& lhs, expr_ref_vector& rhs, bool& change);
bool reduce_contains(expr* a, expr* b, expr_ref_vector& disj);
void add_seqs(expr_ref_vector const& ls, expr_ref_vector const& rs, expr_ref_vector& lhs, expr_ref_vector& rhs);

View file

@ -363,12 +363,12 @@ bool seq_decl_plugin::is_sort_param(sort* s, unsigned& idx) {
bool seq_decl_plugin::match(ptr_vector<sort>& binding, sort* s, sort* sP) {
if (s == sP) return true;
unsigned i;
if (is_sort_param(sP, i)) {
if (binding.size() <= i) binding.resize(i+1);
if (binding[i] && (binding[i] != s)) return false;
TRACE("seq_verbose", tout << "setting binding @ " << i << " to " << mk_pp(s, *m_manager) << "\n";);
binding[i] = s;
unsigned idx;
if (is_sort_param(sP, idx)) {
if (binding.size() <= idx) binding.resize(idx+1);
if (binding[idx] && (binding[idx] != s)) return false;
TRACE("seq_verbose", tout << "setting binding @ " << idx << " to " << mk_pp(s, *m_manager) << "\n";);
binding[idx] = s;
return true;
}
@ -376,8 +376,8 @@ bool seq_decl_plugin::match(ptr_vector<sort>& binding, sort* s, sort* sP) {
if (s->get_family_id() == sP->get_family_id() &&
s->get_decl_kind() == sP->get_decl_kind() &&
s->get_num_parameters() == sP->get_num_parameters()) {
for (unsigned i = 0; i < s->get_num_parameters(); ++i) {
parameter const& p = s->get_parameter(i);
for (unsigned i = 0, sz = s->get_num_parameters(); i < sz; ++i) {
parameter const& p = s->get_parameter(i);
if (p.is_ast() && is_sort(p.get_ast())) {
parameter const& p2 = sP->get_parameter(i);
if (!match(binding, to_sort(p.get_ast()), to_sort(p2.get_ast()))) return false;

View file

@ -1063,7 +1063,7 @@ void cmd_context::mk_app(symbol const & s, unsigned num_args, expr * const * arg
return;
}
if (num_indices > 0)
throw cmd_exception("invalid use of indexed indentifier, unknown builtin function ", s);
throw cmd_exception("invalid use of indexed identifier, unknown builtin function ", s);
expr* _t;
if (macros_find(s, num_args, args, _t)) {
TRACE("macro_bug", tout << "well_sorted_check_enabled(): " << well_sorted_check_enabled() << "\n";

View file

@ -37,6 +37,7 @@ context_params::context_params() {
m_model_compress = true;
m_timeout = UINT_MAX;
m_rlimit = 0;
m_statistics = false;
updt_params();
}
@ -109,6 +110,9 @@ void context_params::set(char const * param, char const * value) {
else if (p == "dump_models") {
set_bool(m_dump_models, param, value);
}
else if (p == "stats") {
set_bool(m_statistics, param, value);
}
else if (p == "trace") {
set_bool(m_trace, param, value);
}
@ -158,6 +162,7 @@ void context_params::updt_params(params_ref const & p) {
m_unsat_core = p.get_bool("unsat_core", m_unsat_core);
m_debug_ref_count = p.get_bool("debug_ref_count", m_debug_ref_count);
m_smtlib2_compliant = p.get_bool("smtlib2_compliant", m_smtlib2_compliant);
m_statistics = p.get_bool("stats", m_statistics);
}
void context_params::collect_param_descrs(param_descrs & d) {
@ -174,6 +179,8 @@ void context_params::collect_param_descrs(param_descrs & d) {
d.insert("dot_proof_file", CPK_STRING, "file in which to output graphical proofs", "proof.dot");
d.insert("debug_ref_count", CPK_BOOL, "debug support for AST reference counting", "false");
d.insert("smtlib2_compliant", CPK_BOOL, "enable/disable SMT-LIB 2.0 compliance", "false");
d.insert("stats", CPK_BOOL, "enable/disable statistics", "false");
// statistics are hidden as they are controlled by the /st option.
collect_solver_param_descrs(d);
}

View file

@ -45,6 +45,7 @@ public:
bool m_unsat_core;
bool m_smtlib2_compliant; // it must be here because it enable/disable the use of coercions in the ast_manager.
unsigned m_timeout;
bool m_statistics;
unsigned rlimit() const { return m_rlimit; }
context_params();

View file

@ -2629,17 +2629,15 @@ namespace algebraic_numbers {
}
else if (a.is_basic()) {
mpq const & v = basic_value(a);
scoped_mpz neg_n(qm());
mpz neg_n;
qm().set(neg_n, v.numerator());
qm().neg(neg_n);
unsynch_mpz_manager zmgr;
// FIXME: remove these copies
mpz coeffs[2] = { zmgr.dup(neg_n.get()), zmgr.dup(v.denominator()) };
mpz coeffs[2] = { std::move(neg_n), qm().dup(v.denominator()) };
out << "(";
upm().display(out, 2, coeffs, "#");
out << ", 1)"; // first root of the polynomial d*# - n
zmgr.del(coeffs[0]);
zmgr.del(coeffs[1]);
qm().del(coeffs[0]);
qm().del(coeffs[1]);
}
else {
algebraic_cell * c = a.to_algebraic();
@ -2679,17 +2677,15 @@ namespace algebraic_numbers {
}
else if (a.is_basic()) {
mpq const & v = basic_value(a);
scoped_mpz neg_n(qm());
mpz neg_n;
qm().set(neg_n, v.numerator());
qm().neg(neg_n);
unsynch_mpz_manager zmgr;
// FIXME: remove these copies
mpz coeffs[2] = { zmgr.dup(neg_n.get()), zmgr.dup(v.denominator()) };
mpz coeffs[2] = { std::move(neg_n), qm().dup(v.denominator()) };
out << "(root-obj ";
upm().display_smt2(out, 2, coeffs, "x");
out << " 1)"; // first root of the polynomial d*# - n
zmgr.del(coeffs[0]);
zmgr.del(coeffs[1]);
qm().del(coeffs[0]);
qm().del(coeffs[1]);
}
else {
algebraic_cell * c = a.to_algebraic();

View file

@ -166,7 +166,7 @@ namespace opt {
return true;
}
#define PASSERT(_e_) if (!(_e_)) { TRACE("opt", display(tout, r);); SASSERT(_e_); }
#define PASSERT(_e_) if (!(_e_)) { TRACE("opt1", display(tout, r); display(tout);); SASSERT(_e_); }
bool model_based_opt::invariant(unsigned index, row const& r) {
vector<var> const& vars = r.m_vars;
@ -539,7 +539,7 @@ namespace opt {
rational slack = (abs_src_c - rational::one()) * (abs_dst_c - rational::one());
rational dst_val = dst.m_value - x_val*dst_c;
rational src_val = src.m_value - x_val*src_c;
rational distance = src_c * dst_val + dst_c * src_val + slack;
rational distance = abs_src_c * dst_val + abs_dst_c * src_val + slack;
bool use_case1 = distance.is_nonpos() || abs_src_c.is_one() || abs_dst_c.is_one();
#if 0
@ -655,7 +655,10 @@ namespace opt {
void model_based_opt::normalize(unsigned row_id) {
row& r = m_rows[row_id];
if (r.m_vars.empty()) return;
if (r.m_vars.empty()) {
retire_row(row_id);
return;
}
if (r.m_type == t_mod) return;
rational g(abs(r.m_vars[0].m_coeff));
bool all_int = g.is_int();
@ -1085,14 +1088,16 @@ namespace opt {
if (D.is_zero()) {
throw default_exception("modulo 0 is not defined");
}
TRACE("opt", display(tout << "lcm: " << D << " tableau\n"););
TRACE("opt1", display(tout << "lcm: " << D << " x: v" << x << " tableau\n"););
rational val_x = m_var2value[x];
rational u = mod(val_x, D);
SASSERT(u.is_nonneg() && u < D);
for (unsigned idx : mod_rows) {
replace_var(idx, x, u);
SASSERT(invariant(idx, m_rows[idx]));
normalize(idx);
}
TRACE("opt1", display(tout << "tableau after replace x under mod\n"););
//
// update inequalities such that u is added to t and
// D is multiplied to coefficient of x.
@ -1112,8 +1117,10 @@ namespace opt {
// x |-> D*y + u
replace_var(row_id, x, D, y, u);
visited.insert(row_id);
normalize(row_id);
}
}
TRACE("opt1", display(tout << "tableau after replace x by y := v" << y << "\n"););
def result = project(y, compute_def);
if (compute_def) {
result = (result * D) + u;

View file

@ -64,7 +64,7 @@ expr_ref bind_variables::abstract(expr* term, cache_t& cache, unsigned scope) {
}
switch(e->get_kind()) {
case AST_VAR: {
SASSERT(to_var(e)->get_idx() < scope);
// SASSERT(to_var(e)->get_idx() >= scope);
// mixing bound variables and free is possible for the caller,
// but not proper use.
// So we assert here even though we don't check for it.

View file

@ -57,7 +57,8 @@ namespace datalog {
m_hnf(m),
m_qe(m, params_ref(), false),
m_rwr(m),
m_ufproc(m) {}
m_ufproc(m),
m_fd_proc(m) {}
void rule_manager::inc_ref(rule * r) {
if (r) {
@ -928,6 +929,23 @@ namespace datalog {
return exist || univ;
}
bool rule_manager::is_finite_domain(rule const& r) const {
m_visited.reset();
m_fd_proc.reset();
for (unsigned i = r.get_uninterpreted_tail_size(); i < r.get_tail_size(); ++i) {
for_each_expr_core<fd_finder_proc,expr_sparse_mark, true, false>(m_fd_proc, m_visited, r.get_tail(i));
}
for (unsigned i = 0; i < r.get_uninterpreted_tail_size(); ++i) {
for (expr* arg : *r.get_tail(i)) {
for_each_expr_core<fd_finder_proc,expr_sparse_mark, true, false>(m_fd_proc, m_visited, arg);
}
}
for (expr* arg : *r.get_head()) {
for_each_expr_core<fd_finder_proc,expr_sparse_mark, true, false>(m_fd_proc, m_visited, arg);
}
return m_fd_proc.is_fd();
}
bool rule::has_negation() const {
for (unsigned i = 0; i < get_uninterpreted_tail_size(); ++i) {
if (is_neg_tail(i)) {

View file

@ -92,6 +92,20 @@ namespace datalog {
void reset() { m_exist = m_univ = false; }
};
struct fd_finder_proc {
ast_manager& m;
bv_util m_bv;
bool m_is_fd;
fd_finder_proc(ast_manager& m): m(m), m_bv(m), m_is_fd(true) {}
bool is_fd() const { return m_is_fd; }
bool is_fd(sort* s) { return m.is_bool(s) || m_bv.is_bv_sort(s); }
void operator()(var* n) { m_is_fd &= is_fd(n->get_sort()); }
void operator()(quantifier* ) { m_is_fd = false; }
void operator()(app* n) { m_is_fd &= is_fd(n->get_decl()->get_range()); }
void reset() { m_is_fd = true; }
};
/**
\brief Manager for the \c rule class
@ -117,6 +131,7 @@ namespace datalog {
mutable uninterpreted_function_finder_proc m_ufproc;
mutable quantifier_finder_proc m_qproc;
mutable expr_sparse_mark m_visited;
mutable fd_finder_proc m_fd_proc;
// only the context can create a rule_manager
@ -265,6 +280,7 @@ namespace datalog {
bool has_uninterpreted_non_predicates(rule const& r, func_decl*& f) const;
void has_quantifiers(rule const& r, bool& existential, bool& universal) const;
bool has_quantifiers(rule const& r) const;
bool is_finite_domain(rule const& r) const;
};

View file

@ -501,6 +501,14 @@ namespace datalog {
}
}
bool rule_set::is_finite_domain() const {
for (rule * r : *this) {
if (!get_rule_manager().is_finite_domain(*r))
return false;
}
return true;
}
void rule_set::display_deps( std::ostream & out ) const
{

View file

@ -253,6 +253,7 @@ namespace datalog {
const func_decl_set & get_output_predicates() const { return m_output_preds; }
func_decl* get_output_predicate() const { SASSERT(m_output_preds.size() == 1); return *m_output_preds.begin(); }
bool is_finite_domain() const;
void display(std::ostream & out) const;

View file

@ -1,8 +1,7 @@
def_module_params('fp',
description='fixedpoint parameters',
export=True,
params=(('timeout', UINT, UINT_MAX, 'set timeout'),
('engine', SYMBOL, 'auto-config',
params=(('engine', SYMBOL, 'auto-config',
'Select: auto-config, datalog, bmc, spacer'),
('datalog.default_table', SYMBOL, 'sparse',
'default table implementation: sparse, hashtable, bitvector, interval'),
@ -84,9 +83,9 @@ def_module_params('fp',
('print_boogie_certificate', BOOL, False,
'print certificate for reachability or non-reachability using a ' +
'format understood by Boogie'),
('print_statistics', BOOL, False, 'print statistics'),
('print_aig', SYMBOL, '',
'Dump clauses in AIG text format (AAG) to the given file name'),
('print_statistics', BOOL, False, 'print statistics'),
('tab.selection', SYMBOL, 'weight',
'selection method for tabular strategy: weight (default), first, var-use'),
('xform.bit_blast', BOOL, False,

View file

@ -17,22 +17,22 @@ Revision History:
--*/
#include "ast/datatype_decl_plugin.h"
#include "ast/dl_decl_plugin.h"
#include "ast/ast_smt_pp.h"
#include "ast/well_sorted.h"
#include "ast/rewriter/bool_rewriter.h"
#include "ast/rewriter/rewriter_def.h"
#include "ast/scoped_proof.h"
#include "smt/smt_solver.h"
#include "tactic/fd_solver/fd_solver.h"
#include "muz/base/dl_context.h"
#include "muz/base/dl_rule_transformer.h"
#include "muz/bmc/dl_bmc_engine.h"
#include "muz/transforms/dl_mk_slice.h"
#include "smt/smt_kernel.h"
#include "ast/datatype_decl_plugin.h"
#include "ast/dl_decl_plugin.h"
#include "ast/rewriter/bool_rewriter.h"
#include "model/model_smt2_pp.h"
#include "ast/ast_smt_pp.h"
#include "ast/well_sorted.h"
#include "ast/rewriter/rewriter_def.h"
#include "muz/transforms/dl_transforms.h"
#include "muz/transforms/dl_mk_rule_inliner.h"
#include "ast/scoped_proof.h"
#include "muz/base/fp_params.hpp"
namespace datalog {
@ -53,7 +53,7 @@ namespace datalog {
m_bit_width = 4;
lbool res = l_false;
while (res == l_false) {
b.m_solver.push();
b.m_solver->push();
IF_VERBOSE(1, verbose_stream() << "bit_width: " << m_bit_width << "\n";);
compile();
b.checkpoint();
@ -61,12 +61,12 @@ namespace datalog {
expr* T = m.mk_const(symbol("T"), mk_index_sort());
expr_ref fml(m.mk_app(q, T), m);
b.assert_expr(fml);
res = b.m_solver.check();
res = b.m_solver->check_sat(0, nullptr);
if (res == l_true) {
res = get_model();
}
b.m_solver.pop(1);
b.m_solver->pop(1);
++m_bit_width;
}
return res;
@ -141,10 +141,10 @@ namespace datalog {
}
void setup() {
b.m_fparams.m_relevancy_lvl = 2;
b.m_fparams.m_model = true;
b.m_fparams.m_model_compact = true;
b.m_fparams.m_mbqi = true;
params_ref p;
p.set_uint("smt.relevancy", 2ul);
p.set_bool("smt.mbqi", true);
b.m_solver->updt_params(p);
b.m_rule_trace.reset();
}
@ -252,7 +252,7 @@ namespace datalog {
rational num;
unsigned level, bv_size;
b.m_solver.get_model(md);
b.m_solver->get_model(md);
func_decl* pred = b.m_query_pred;
dl_decl_util util(m);
T = m.mk_const(symbol("T"), mk_index_sort());
@ -468,10 +468,9 @@ namespace datalog {
}
void setup() {
b.m_fparams.m_model = true;
b.m_fparams.m_model_compact = true;
// b.m_fparams.m_mbqi = true;
b.m_fparams.m_relevancy_lvl = 2;
params_ref p;
p.set_uint("smt.relevancy", 2ul);
b.m_solver->updt_params(p);
b.m_rule_trace.reset();
}
@ -482,7 +481,7 @@ namespace datalog {
q_at_level = m.mk_implies(q, p);
b.assert_expr(q_at_level);
expr* qr = q.get();
return b.m_solver.check(1, &qr);
return b.m_solver->check_sat(1, &qr);
}
proof_ref get_proof(model_ref& md, func_decl* pred, app* prop, unsigned level) {
@ -548,7 +547,7 @@ namespace datalog {
scoped_proof _sp(m);
expr_ref level_query = compile_query(b.m_query_pred, level);
model_ref md;
b.m_solver.get_model(md);
b.m_solver->get_model(md);
IF_VERBOSE(2, model_smt2_pp(verbose_stream(), m, *md, 0););
proof_ref pr(m);
pr = get_proof(md, b.m_query_pred, to_app(level_query), level);
@ -755,11 +754,10 @@ namespace datalog {
m_pred2sort.reset();
m_pinned.reset();
m_sort2pred.reset();
b.m_fparams.m_relevancy_lvl = 0;
b.m_fparams.m_model = true;
b.m_fparams.m_model_compact = true;
b.m_fparams.m_mbqi = false;
b.m_fparams.m_relevancy_lvl = 2;
params_ref p;
p.set_uint("smt.relevancy", 2ul);
p.set_bool("smt.mbqi", false);
b.m_solver->updt_params(p);
b.m_rule_trace.reset();
}
@ -1096,12 +1094,12 @@ namespace datalog {
fml = m.mk_app(q, trace.get(), path.get());
b.assert_expr(fml);
while (true) {
lbool is_sat = b.m_solver.check();
lbool is_sat = b.m_solver->check_sat(0, nullptr);
model_ref md;
if (is_sat == l_false) {
return is_sat;
}
b.m_solver.get_model(md);
b.m_solver->get_model(md);
mk_answer(md, trace, path);
return l_true;
}
@ -1111,13 +1109,13 @@ namespace datalog {
expr_ref trace_val(m), eq(m);
trace_val = (*md)(trace);
eq = m.mk_eq(trace, trace_val);
b.m_solver.push();
b.m_solver.assert_expr(eq);
lbool is_sat = b.m_solver.check();
b.m_solver->push();
b.m_solver->assert_expr(eq);
lbool is_sat = b.m_solver->check_sat(0, nullptr);
if (is_sat != l_false) {
b.m_solver.get_model(md);
b.m_solver->get_model(md);
}
b.m_solver.pop(1);
b.m_solver->pop(1);
if (is_sat == l_false) {
IF_VERBOSE(1, verbose_stream() << "infeasible trace " << mk_pp(trace_val, m) << "\n";);
eq = m.mk_not(eq);
@ -1131,8 +1129,8 @@ namespace datalog {
trace = (*md)(trace);
path = (*md)(path);
IF_VERBOSE(2, verbose_stream() << mk_pp(trace, m) << "\n";
for (unsigned i = 0; i < b.m_solver.size(); ++i) {
verbose_stream() << mk_pp(b.m_solver.get_formula(i), m) << "\n";
for (unsigned i = 0; i < b.m_solver->get_num_assertions(); ++i) {
verbose_stream() << mk_pp(b.m_solver->get_assertion(i), m) << "\n";
});
scoped_proof _sp(m);
proof_ref pr(m);
@ -1183,7 +1181,7 @@ namespace datalog {
model_ref md;
proof_ref pr(m);
rule_unifier unifier(b.m_ctx);
b.m_solver.get_model(md);
b.m_solver->get_model(md);
func_decl* pred = b.m_query_pred;
SASSERT(m.is_true(md->get_const_interp(to_app(level_query)->get_decl())));
@ -1283,11 +1281,10 @@ namespace datalog {
void setup() {
b.m_fparams.m_relevancy_lvl = 0;
b.m_fparams.m_model = true;
b.m_fparams.m_model_compact = true;
b.m_fparams.m_mbqi = false;
// m_fparams.m_auto_config = false;
params_ref p;
p.set_uint("smt.relevancy", 0ul);
p.set_bool("smt.mbqi", false);
b.m_solver->updt_params(p);
b.m_rule_trace.reset();
}
@ -1295,7 +1292,7 @@ namespace datalog {
lbool check(unsigned level) {
expr_ref level_query = mk_level_predicate(b.m_query_pred, level);
expr* q = level_query.get();
return b.m_solver.check(1, &q);
return b.m_solver->check_sat(1, &q);
}
expr_ref mk_level_predicate(func_decl* p, unsigned level) {
@ -1428,7 +1425,7 @@ namespace datalog {
engine_base(ctx.get_manager(), "bmc"),
m_ctx(ctx),
m(ctx.get_manager()),
m_solver(m, m_fparams),
m_solver(nullptr),
m_rules(ctx),
m_query_pred(m),
m_answer(m),
@ -1438,7 +1435,7 @@ namespace datalog {
bmc::~bmc() {}
lbool bmc::query(expr* query) {
m_solver.reset();
m_solver = nullptr;
m_answer = nullptr;
m_ctx.ensure_opened();
m_rules.reset();
@ -1471,6 +1468,7 @@ namespace datalog {
IF_VERBOSE(2, m_ctx.display_rules(verbose_stream()););
params_ref p;
if (m_rules.get_num_rules() == 0) {
return l_false;
}
@ -1478,18 +1476,25 @@ namespace datalog {
return l_false;
}
if (is_linear()) {
if (m_ctx.get_engine() == QBMC_ENGINE) {
m_solver = mk_smt_solver(m, p, symbol::null);
qlinear ql(*this);
return ql.check();
}
else {
if (m_rules.is_finite_domain()) {
m_solver = mk_fd_solver(m, p);
}
else {
m_solver = mk_smt_solver(m, p, symbol::null);
}
linear lin(*this);
return lin.check();
}
}
else {
m_solver = mk_smt_solver(m, p, symbol::null);
IF_VERBOSE(0, verbose_stream() << "WARNING: non-linear BMC is highly inefficient\n";);
nonlinear nl(*this);
return nl.check();
@ -1498,7 +1503,7 @@ namespace datalog {
void bmc::assert_expr(expr* e) {
TRACE("bmc", tout << mk_pp(e, m) << "\n";);
m_solver.assert_expr(e);
m_solver->assert_expr(e);
}
bool bmc::is_linear() const {
@ -1525,11 +1530,11 @@ namespace datalog {
}
void bmc::collect_statistics(statistics& st) const {
m_solver.collect_statistics(st);
m_solver->collect_statistics(st);
}
void bmc::reset_statistics() {
m_solver.reset_statistics();
// m_solver->reset_statistics();
}
expr_ref bmc::get_answer() {

View file

@ -22,10 +22,8 @@ Revision History:
#include "util/params.h"
#include "util/statistics.h"
#include "smt/smt_kernel.h"
#include "ast/bv_decl_plugin.h"
#include "smt/params/smt_params.h"
#include "solver/solver.h"
namespace datalog {
class context;
@ -33,8 +31,7 @@ namespace datalog {
class bmc : public engine_base {
context& m_ctx;
ast_manager& m;
smt_params m_fparams;
smt::kernel m_solver;
solver_ref m_solver;
rule_set m_rules;
func_decl_ref m_query_pred;
expr_ref m_answer;

View file

@ -245,7 +245,8 @@ public:
datalog::context& dlctx = m_dl_ctx->dlctx();
set_background(ctx);
dlctx.updt_params(m_params);
unsigned timeout = m_dl_ctx->get_params().timeout();
unsigned timeout = ctx.params().m_timeout;
unsigned rlimit = ctx.params().rlimit();
cancel_eh<reslimit> eh(ctx.m().limit());
bool query_exn = false;
lbool status = l_undef;
@ -253,12 +254,14 @@ public:
IF_VERBOSE(10, verbose_stream() << "(query)\n";);
scoped_ctrl_c ctrlc(eh);
scoped_timer timer(timeout, &eh);
scoped_rlimit _rlimit(ctx.m().limit(), rlimit);
cmd_context::scoped_watch sw(ctx);
try {
status = dlctx.rel_query(1, &m_target);
}
catch (z3_error & ex) {
ctx.regular_stream() << "(error \"query failed: " << ex.msg() << "\")" << std::endl;
print_statistics(ctx);
throw ex;
}
catch (z3_exception& ex) {
@ -352,7 +355,7 @@ private:
}
void print_statistics(cmd_context& ctx) {
if (m_dl_ctx->get_params().print_statistics()) {
if (ctx.params().m_statistics) {
statistics st;
datalog::context& dlctx = m_dl_ctx->dlctx();
dlctx.collect_statistics(st);

View file

@ -2683,7 +2683,7 @@ lbool context::solve(unsigned from_lvl)
if (m_last_result == l_true) {
m_stats.m_cex_depth = get_cex_depth ();
}
if (m_params.print_statistics ()) {
statistics st;
collect_statistics (st);
@ -3063,13 +3063,13 @@ lbool context::solve_core (unsigned from_lvl)
IF_VERBOSE(1,verbose_stream() << "Entering level "<< lvl << "\n";);
STRACE("spacer_progress", tout << "\n* LEVEL " << lvl << "\n";);
IF_VERBOSE(1,
if (m_params.print_statistics ()) {
statistics st;
collect_statistics (st);
};
);
}
// communicate failure to datalog::context
if (m_context) { m_context->set_status(datalog::BOUNDED); }

View file

@ -42,26 +42,28 @@ tactic * mk_qfnra_nlsat_tactic(ast_manager & m, params_ref const & p) {
else
factor = mk_skip_tactic();
return and_then(and_then(using_params(mk_simplify_tactic(m, p),
main_p),
using_params(mk_purify_arith_tactic(m, p),
purify_p),
mk_propagate_values_tactic(m, p),
mk_solve_eqs_tactic(m, p),
using_params(mk_purify_arith_tactic(m, p),
purify_p),
mk_elim_uncnstr_tactic(m, p),
mk_elim_term_ite_tactic(m, p)),
and_then(/* mk_degree_shift_tactic(m, p), */ // may affect full dimensionality detection
factor,
mk_solve_eqs_tactic(m, p),
using_params(mk_purify_arith_tactic(m, p),
purify_p),
using_params(mk_simplify_tactic(m, p),
main_p),
mk_tseitin_cnf_core_tactic(m, p),
using_params(mk_simplify_tactic(m, p),
main_p),
mk_nlsat_tactic(m, p)));
return and_then(
mk_report_verbose_tactic("(qfnra-nlsat-tactic)", 10),
and_then(using_params(mk_simplify_tactic(m, p),
main_p),
using_params(mk_purify_arith_tactic(m, p),
purify_p),
mk_propagate_values_tactic(m, p),
mk_solve_eqs_tactic(m, p),
using_params(mk_purify_arith_tactic(m, p),
purify_p),
mk_elim_uncnstr_tactic(m, p),
mk_elim_term_ite_tactic(m, p)),
and_then(/* mk_degree_shift_tactic(m, p), */ // may affect full dimensionality detection
factor,
mk_solve_eqs_tactic(m, p),
using_params(mk_purify_arith_tactic(m, p),
purify_p),
using_params(mk_simplify_tactic(m, p),
main_p),
mk_tseitin_cnf_core_tactic(m, p),
using_params(mk_simplify_tactic(m, p),
main_p),
mk_nlsat_tactic(m, p)));
}

View file

@ -1012,8 +1012,7 @@ namespace opt {
}
}
// fix types of objectives:
for (unsigned i = 0; i < m_objectives.size(); ++i) {
objective & obj = m_objectives[i];
for (objective & obj : m_objectives) {
expr* t = obj.m_term;
switch(obj.m_type) {
case O_MINIMIZE:
@ -1189,13 +1188,12 @@ namespace opt {
void context::update_bound(bool is_lower) {
expr_ref val(m);
if (!m_model.get()) return;
for (unsigned i = 0; i < m_objectives.size(); ++i) {
objective const& obj = m_objectives[i];
for (objective const& obj : m_objectives) {
rational r;
switch(obj.m_type) {
case O_MINIMIZE: {
val = (*m_model)(obj.m_term);
TRACE("opt", tout << obj.m_term << " " << val << " " << is_numeral(val, r) << "\n";);
TRACE("opt", tout << obj.m_term << " " << val << "\n";);
if (is_numeral(val, r)) {
inf_eps val = inf_eps(obj.m_adjust_value(r));
TRACE("opt", tout << "adjusted value: " << val << "\n";);

View file

@ -230,11 +230,14 @@ namespace opt {
get_model(m_model);
inf_eps val2;
m_valid_objectives[i] = true;
TRACE("opt", tout << (has_shared?"has shared":"non-shared") << "\n";);
TRACE("opt", tout << (has_shared?"has shared":"non-shared") << " " << val << "\n";);
if (!m_models[i]) {
set_model(i);
}
if (m_context.get_context().update_model(has_shared)) {
if (!val.is_finite()) {
// skip model updates
}
else if (m_context.get_context().update_model(has_shared)) {
if (has_shared && val != current_objective_value(i)) {
decrement_value(i, val);
}

View file

@ -124,8 +124,8 @@ namespace opt {
// definitions used for sorting network
pliteral mk_false() { return m.mk_false(); }
pliteral mk_true() { return m.mk_true(); }
pliteral mk_max(pliteral a, pliteral b) { return trail(m.mk_or(a, b)); }
pliteral mk_min(pliteral a, pliteral b) { return trail(m.mk_and(a, b)); }
pliteral mk_max(unsigned n, pliteral const* as) { return trail(m.mk_or(n, as)); }
pliteral mk_min(unsigned n, pliteral const* as) { return trail(m.mk_and(n, as)); }
pliteral mk_not(pliteral a) { if (m.is_not(a,a)) return a; return trail(m.mk_not(a)); }
std::ostream& pp(std::ostream& out, pliteral lit) { return out << mk_pp(lit, m); }

View file

@ -1301,6 +1301,7 @@ namespace qe {
ptr_vector<expr> todo;
todo.push_back(a);
rational k1, k2;
expr* e1 = nullptr, *e2 = nullptr;
expr_ref rest(m);
while (!todo.empty()) {
expr* e = todo.back();
@ -1319,9 +1320,9 @@ namespace qe {
return false;
}
a = to_app(e);
if (m_util.m_arith.is_mod(e) &&
m_util.m_arith.is_numeral(to_app(e)->get_arg(1), k1) &&
m_util.get_coeff(contains_x, to_app(e)->get_arg(0), k2, rest)) {
if (m_util.m_arith.is_mod(e, e1, e2) &&
m_util.m_arith.is_numeral(e2, k1) &&
m_util.get_coeff(contains_x, e1, k2, rest)) {
app_ref z(m), z_bv(m);
m_util.mk_bounded_var(k1, z_bv, z);
m_nested_div_terms.push_back(rest);
@ -1331,10 +1332,9 @@ namespace qe {
m_nested_div_z.push_back(z);
continue;
}
unsigned num_args = a->get_num_args();
for (unsigned i = 0; i < num_args; ++i) {
todo.push_back(a->get_arg(i));
}
for (expr* arg : *a) {
todo.push_back(arg);
}
}
return true;
}

View file

@ -346,10 +346,50 @@ namespace qe {
func_decl_ref_vector no_shared(m);
tg1.set_vars(no_shared, false);
tg1.add_lits(lits);
arith_util a(m);
expr_ref_vector foreign = tg1.shared_occurrences(a.get_family_id());
obj_hashtable<expr> _foreign;
for (expr* e : foreign) _foreign.insert(e);
vector<expr_ref_vector> partition = tg1.get_partition(*mdl);
expr_ref_vector diseq = tg1.get_ackerman_disequalities();
lits.append(diseq);
TRACE("qe", tout << "diseq: " << diseq << "\n";);
TRACE("qe", tout << "diseq: " << diseq << "\n";
tout << "foreign: " << foreign << "\n";
for (auto const& v : partition) {
tout << "partition: {";
bool first = true;
for (expr* e : v) {
if (first) first = false; else tout << ", ";
tout << expr_ref(e, m);
}
tout << "}\n";
}
);
vector<expr_ref_vector> refined_partition;
for (auto & p : partition) {
unsigned j = 0;
for (expr* e : p) {
if (_foreign.contains(e) ||
(is_app(e) && m_shared.contains(to_app(e)->get_decl()))) {
p[j++] = e;
}
}
p.shrink(j);
if (!p.empty()) refined_partition.push_back(p);
}
TRACE("qe",
for (auto const& v : refined_partition) {
tout << "partition: {";
bool first = true;
for (expr* e : v) {
if (first) first = false; else tout << ", ";
tout << expr_ref(e, m);
}
tout << "}\n";
});
arith_project_plugin ap(m);
ap.set_check_purified(false);

View file

@ -99,7 +99,7 @@ namespace qe {
m_mark(false),
m_mark2(false),
m_interpreted(false) {
if (!is_app()) return;
if (!is_app(m_expr)) return;
for (expr* e : *to_app(m_expr)) {
term* t = app2term[e->get_id()];
t->get_root().m_parents.push_back(this);
@ -151,7 +151,7 @@ namespace qe {
unsigned get_id() const { return m_expr->get_id();}
unsigned get_decl_id() const { return is_app() ? get_app()->get_decl()->get_id() : m_expr->get_id(); }
unsigned get_decl_id() const { return is_app(m_expr) ? to_app(m_expr)->get_decl()->get_id() : m_expr->get_id(); }
bool is_marked() const {return m_mark;}
void set_mark(bool v){m_mark = v;}
@ -159,12 +159,10 @@ namespace qe {
void set_mark2(bool v){m_mark2 = v;} // NSB: where is this used?
bool is_interpreted() const {return m_interpreted;}
bool is_theory() const { return !is_app() || get_app()->get_family_id() != null_family_id; }
bool is_theory() const { return !is_app(m_expr) || to_app(m_expr)->get_family_id() != null_family_id; }
void mark_as_interpreted() {m_interpreted=true;}
expr* get_expr() const {return m_expr;}
bool is_app() const {return ::is_app(m_expr);}
app *get_app() const {return is_app() ? to_app(m_expr) : nullptr;}
unsigned get_num_args() const { return is_app() ? get_app()->get_num_args() : 0; }
unsigned get_num_args() const { return is_app(m_expr) ? to_app(m_expr)->get_num_args() : 0; }
term &get_root() const {return *m_root;}
bool is_root() const {return m_root == this;}
@ -226,7 +224,7 @@ namespace qe {
}
bool term_graph::is_variable_proc::operator()(const term &t) const {
return (*this)(t.get_app());
return (*this)(t.get_expr());
}
void term_graph::is_variable_proc::set_decls(const func_decl_ref_vector &decls, bool exclude) {
@ -444,7 +442,7 @@ namespace qe {
return expr_ref(res, m);
}
res = mk_app_core (r.get_app());
res = mk_app_core (r.get_expr());
m_term2app.insert(r.get_id(), res);
return expr_ref(res, m);
@ -463,7 +461,7 @@ namespace qe {
SASSERT(t.is_root());
expr_ref rep(mk_app(t), m);
for (term *it = &t.get_next(); it != &t; it = &it->get_next()) {
expr* mem = mk_app_core(it->get_app());
expr* mem = mk_app_core(it->get_expr());
out.push_back (m.mk_eq (rep, mem));
}
}
@ -472,9 +470,9 @@ namespace qe {
mk_equalities(t, out);
for (term *it = &t.get_next(); it != &t; it = &it->get_next ()) {
expr* a1 = mk_app_core (it->get_app());
expr* a1 = mk_app_core (it->get_expr());
for (term *it2 = &it->get_next(); it2 != &t; it2 = &it2->get_next()) {
expr* a2 = mk_app_core(it2->get_app());
expr* a2 = mk_app_core(it2->get_expr());
out.push_back (m.mk_eq (a1, a2));
}
}
@ -1000,6 +998,47 @@ namespace qe {
reset();
return res;
}
vector<expr_ref_vector> get_partition(model& mdl) {
vector<expr_ref_vector> result;
expr_ref_vector pinned(m);
obj_map<expr, unsigned> pid;
model::scoped_model_completion _smc(mdl, true);
for (term *t : m_tg.m_terms) {
expr* a = t->get_expr();
if (!is_app(a)) continue;
if (m.is_bool(a)) continue;
expr_ref val = mdl(a);
unsigned p = 0;
// NB. works for simple domains Integers, Rationals,
// but not for algebraic numerals.
if (!pid.find(val, p)) {
p = pid.size();
pid.insert(val, p);
pinned.push_back(val);
result.push_back(expr_ref_vector(m));
}
result[p].push_back(a);
}
return result;
}
expr_ref_vector shared_occurrences(family_id fid) {
expr_ref_vector result(m);
for (term *t : m_tg.m_terms) {
expr* e = t->get_expr();
if (m.get_sort(e)->get_family_id() != fid) continue;
for (term * p : term::parents(t->get_root())) {
expr* pe = p->get_expr();
if (!is_app(pe)) continue;
if (to_app(pe)->get_family_id() == fid) continue;
if (to_app(pe)->get_family_id() == m.get_basic_family_id()) continue;
result.push_back(e);
break;
}
}
return result;
}
};
void term_graph::set_vars(func_decl_ref_vector const& decls, bool exclude) {
@ -1033,5 +1072,14 @@ namespace qe {
return p.get_ackerman_disequalities();
}
vector<expr_ref_vector> term_graph::get_partition(model& mdl) {
term_graph::projector p(*this);
return p.get_partition(mdl);
}
expr_ref_vector term_graph::shared_occurrences(family_id fid) {
term_graph::projector p(*this);
return p.shared_occurrences(fid);
}
}

View file

@ -122,6 +122,19 @@ namespace qe {
*/
expr_ref_vector get_ackerman_disequalities();
/**
* Produce a model-based partition.
*/
vector<expr_ref_vector> get_partition(model& mdl);
/**
* Extract shared occurrences of terms whose sort are
* fid, but appear in a context that is not fid.
* for example f(x + y) produces the shared occurrence
* x + y when f is uninterpreted and x + y has sort Int or Real.
*/
expr_ref_vector shared_occurrences(family_id fid);
};
}

View file

@ -1976,6 +1976,7 @@ namespace sat {
for (unsigned i = 0; !found && i < c.k(); ++i) {
found = c[i] == l;
}
CTRACE("ba",!found, s().display(tout << l << ":" << c << "\n"););
SASSERT(found););
// IF_VERBOSE(0, if (_debug_conflict) verbose_stream() << "ante " << l << " " << c << "\n");
@ -2591,22 +2592,54 @@ namespace sat {
return literal(v, false);
}
literal ba_solver::ba_sort::mk_max(literal l1, literal l2) {
VERIFY(l1 != null_literal);
VERIFY(l2 != null_literal);
if (l1 == m_true) return l1;
if (l2 == m_true) return l2;
if (l1 == ~m_true) return l2;
if (l2 == ~m_true) return l1;
literal max = fresh("max");
s.s().mk_clause(~l1, max);
s.s().mk_clause(~l2, max);
s.s().mk_clause(~max, l1, l2);
return max;
literal ba_solver::ba_sort::mk_max(unsigned n, literal const* lits) {
m_lits.reset();
for (unsigned i = 0; i < n; ++i) {
if (lits[i] == m_true) return m_true;
if (lits[i] == ~m_true) continue;
m_lits.push_back(lits[i]);
}
switch (m_lits.size()) {
case 0:
return ~m_true;
case 1:
return m_lits[0];
default: {
literal max = fresh("max");
for (unsigned i = 0; i < n; ++i) {
s.s().mk_clause(~m_lits[i], max);
}
m_lits.push_back(~max);
s.s().mk_clause(m_lits.size(), m_lits.c_ptr());
return max;
}
}
}
literal ba_solver::ba_sort::mk_min(literal l1, literal l2) {
return ~mk_max(~l1, ~l2);
literal ba_solver::ba_sort::mk_min(unsigned n, literal const* lits) {
m_lits.reset();
for (unsigned i = 0; i < n; ++i) {
if (lits[i] == ~m_true) return ~m_true;
if (lits[i] == m_true) continue;
m_lits.push_back(lits[i]);
}
switch (m_lits.size()) {
case 0:
return m_true;
case 1:
return m_lits[0];
default: {
literal min = fresh("min");
for (unsigned i = 0; i < n; ++i) {
s.s().mk_clause(~min, m_lits[i]);
m_lits[i] = ~m_lits[i];
}
m_lits.push_back(min);
s.s().mk_clause(m_lits.size(), m_lits.c_ptr());
return min;
}
}
}
void ba_solver::ba_sort::mk_clause(unsigned n, literal const* lits) {

View file

@ -255,8 +255,8 @@ namespace sat {
pliteral mk_true();
pliteral mk_not(pliteral l);
pliteral fresh(char const*);
pliteral mk_max(pliteral l1, pliteral l2);
pliteral mk_min(pliteral l1, pliteral l2);
pliteral mk_min(unsigned, pliteral const* lits);
pliteral mk_max(unsigned, pliteral const* lits);
void mk_clause(unsigned n, literal const* lits);
std::ostream& pp(std::ostream& out, pliteral l) const;
};

View file

@ -23,7 +23,7 @@ Revision History:
#include "util/machine.h"
class sat_allocator {
static const unsigned CHUNK_SIZE = (1 << 16);
static const unsigned CHUNK_SIZE = (1 << 16) - sizeof(char*);
static const unsigned SMALL_OBJ_SIZE = 512;
static const unsigned MASK = ((1 << PTR_ALIGNMENT) - 1);
static const unsigned NUM_FREE = 1 + (SMALL_OBJ_SIZE >> PTR_ALIGNMENT);

View file

@ -43,7 +43,7 @@ def_module_params('sat',
('cardinality.solver', BOOL, True, 'use cardinality solver'),
('pb.solver', SYMBOL, 'solver', 'method for handling Pseudo-Boolean constraints: circuit (arithmetical circuit), sorting (sorting circuit), totalizer (use totalizer encoding), solver (use native solver)'),
('xor.solver', BOOL, False, 'use xor solver'),
('atmost1_encoding', SYMBOL, 'grouped', 'encoding used for at-most-1 constraints grouped, bimander, ordered'),
('cardinality.encoding', SYMBOL, 'grouped', 'encoding used for at-most-k constraints: grouped, bimander, ordered, unate, circuit'),
('local_search', BOOL, False, 'use local search instead of CDCL'),
('local_search_threads', UINT, 0, 'number of local search threads to find satisfiable solution'),
('local_search_mode', SYMBOL, 'wsat', 'local search algorithm, either default wsat or qsat'),

View file

@ -17,6 +17,7 @@ Revision History:
--*/
#include <cmath>
#include "sat/sat_solver.h"
#include "sat/sat_integrity_checker.h"
@ -298,6 +299,9 @@ namespace sat {
if (!c.is_learned()) {
m_stats.m_non_learned_generation++;
}
if (c.frozen()) {
--m_num_frozen;
}
if (m_config.m_drat && !m_drat.is_cleaned(c)) {
m_drat.del(c);
}
@ -481,9 +485,10 @@ namespace sat {
}
unsigned some_idx = c.size() >> 1;
literal block_lit = c[some_idx];
DEBUG_CODE(for (auto const& w : m_watches[(~c[0]).index()]) VERIFY(!w.is_clause() || w.get_clause_offset() != cls_off););
DEBUG_CODE(for (auto const& w : m_watches[(~c[1]).index()]) VERIFY(!w.is_clause() || w.get_clause_offset() != cls_off););
VERIFY(c[0] != c[1]);
VERIFY(!c.frozen());
DEBUG_CODE(for (auto const& w : m_watches[(~c[0]).index()]) SASSERT(!w.is_clause() || w.get_clause_offset() != cls_off););
DEBUG_CODE(for (auto const& w : m_watches[(~c[1]).index()]) SASSERT(!w.is_clause() || w.get_clause_offset() != cls_off););
SASSERT(c[0] != c[1]);
m_watches[(~c[0]).index()].push_back(watched(block_lit, cls_off));
m_watches[(~c[1]).index()].push_back(watched(block_lit, cls_off));
return reinit;
@ -1547,12 +1552,15 @@ namespace sat {
void solver::reinit_assumptions() {
if (tracking_assumptions() && at_base_lvl() && !inconsistent()) {
TRACE("sat", tout << m_assumptions << "\n";);
if (!propagate(false)) return;
push();
for (unsigned i = 0; !inconsistent() && i < m_user_scope_literals.size(); ++i) {
assign(~m_user_scope_literals[i], justification());
for (literal lit : m_user_scope_literals) {
if (inconsistent()) break;
assign(~lit, justification());
}
for (unsigned i = 0; !inconsistent() && i < m_assumptions.size(); ++i) {
assign(m_assumptions[i], justification());
for (literal lit : m_assumptions) {
if (inconsistent()) break;
assign(lit, justification());
}
TRACE("sat",
for (literal a : m_assumptions) {
@ -2139,7 +2147,6 @@ namespace sat {
else {
c.inc_inact_rounds();
if (c.inact_rounds() > m_config.m_gc_k) {
m_num_frozen--;
del_clause(c);
m_stats.m_gc_clause++;
deleted++;
@ -2930,7 +2937,7 @@ namespace sat {
break;
}
case justification::EXT_JUSTIFICATION: {
fill_ext_antecedents(m_lemma[i], js);
fill_ext_antecedents(~m_lemma[i], js);
for (literal l : m_ext_antecedents) {
update_lrb_reasoned(l);
}

View file

@ -682,10 +682,10 @@ namespace sat {
bool m_deleted;
public:
scoped_detach(solver& s, clause& c): s(s), c(c), m_deleted(false) {
s.detach_clause(c);
if (!c.frozen()) s.detach_clause(c);
}
~scoped_detach() {
if (!m_deleted) s.attach_clause(c);
if (!m_deleted && !c.frozen()) s.attach_clause(c);
}
void del_clause() {

View file

@ -483,6 +483,7 @@ public:
s2g(m_solver, m_map, m_params, g, m_sat_mc);
m_internalized_fmls.reset();
g.get_formulas(m_internalized_fmls);
TRACE("sat", m_solver.display(tout); tout << m_internalized_fmls << "\n";);
m_internalized_converted = true;
}
@ -529,7 +530,7 @@ private:
throw default_exception("generation of proof objects is not supported in this mode");
}
SASSERT(!g->proofs_enabled());
TRACE("sat", g->display(tout););
TRACE("sat", m_solver.display(tout); g->display(tout););
try {
(*m_preprocess)(g, m_subgoals);
}
@ -712,23 +713,35 @@ private:
m_asms.reset();
unsigned j = 0;
sat::literal lit;
sat::literal_set seen;
for (unsigned i = 0; i < sz; ++i) {
if (dep2asm.find(asms[i], lit)) {
SASSERT(lit.var() <= m_solver.num_vars());
m_asms.push_back(lit);
if (i != j && !m_weights.empty()) {
m_weights[j] = m_weights[i];
if (!seen.contains(lit)) {
m_asms.push_back(lit);
seen.insert(lit);
if (i != j && !m_weights.empty()) {
m_weights[j] = m_weights[i];
}
++j;
}
++j;
}
}
for (unsigned i = 0; i < get_num_assumptions(); ++i) {
if (dep2asm.find(get_assumption(i), lit)) {
SASSERT(lit.var() <= m_solver.num_vars());
m_asms.push_back(lit);
if (!seen.contains(lit)) {
m_asms.push_back(lit);
seen.insert(lit);
}
}
}
CTRACE("sat", dep2asm.size() != m_asms.size(),
tout << dep2asm.size() << " vs " << m_asms.size() << "\n";
tout << m_asms << "\n";
for (auto const& kv : dep2asm) {
tout << mk_pp(kv.m_key, m) << " " << kv.m_value << "\n";
});
SASSERT(dep2asm.size() == m_asms.size());
}
@ -751,6 +764,7 @@ private:
tout << mk_pp(kv.m_key, m) << " |-> " << mk_pp(kv.m_value, m) << "\n";
}
tout << "core: "; for (auto c : core) tout << c << " "; tout << "\n";
m_solver.display(tout);
);
m_core.reset();

View file

@ -1167,7 +1167,7 @@ struct sat2goal::imp {
}
void operator()(sat::solver & s, atom2bool_var const & map, goal & r, ref<mc> & mc) {
if (s.inconsistent()) {
if (s.at_base_lvl() && s.inconsistent()) {
r.assert_expr(m.mk_false());
return;
}

View file

@ -199,6 +199,7 @@ void parse_cmd_line_args(int argc, char ** argv) {
}
else if (strcmp(opt_name, "st") == 0) {
g_display_statistics = true;
gparams::set("stats", "true");
}
else if (strcmp(opt_name, "ist") == 0) {
g_display_istatistics = true;
@ -295,7 +296,13 @@ void parse_cmd_line_args(int argc, char ** argv) {
int STD_CALL main(int argc, char ** argv) {
try{
#ifdef DUMP_ARGS
std::cout << "args are: ";
for (int i = 0; i < argc; i++)
std::cout << argv[i] <<" ";
std::cout << std::endl;
#endif
try{
unsigned return_value = 0;
memory::initialize(0);
memory::exit_when_out_of_memory(true, "ERROR: out of memory");

View file

@ -401,7 +401,7 @@ namespace smt {
label_hasher & m_lbl_hasher;
func_decl * m_root_lbl;
unsigned m_num_args; //!< we need this information to avoid the nary *,+ crash bug
unsigned char m_filter_candidates;
bool m_filter_candidates;
unsigned m_num_regs;
unsigned m_num_choices;
instruction * m_root;
@ -531,7 +531,7 @@ namespace smt {
}
bool filter_candidates() const {
return m_filter_candidates != 0;
return m_filter_candidates;
}
const instruction * get_root() const {
@ -1847,7 +1847,10 @@ namespace smt {
enode * m_n2;
enode * m_app;
const bind * m_b;
ptr_vector<enode> m_used_enodes;
// equalities used for pattern match. The first element of the tuple gives the argument (or null) of some term that was matched against some higher level
// structure of the trigger, the second element gives the term that argument is replaced with in order to match the trigger. Used for logging purposes only.
vector<std::tuple<enode *, enode *>> m_used_enodes;
unsigned m_curr_used_enodes_size;
ptr_vector<enode> m_pattern_instances; // collect the pattern instances... used for computing min_top_generation and max_top_generation
unsigned_vector m_min_top_generation, m_max_top_generation;
@ -1864,11 +1867,11 @@ namespace smt {
m_pool.recycle(v);
}
void update_max_generation(enode * n) {
void update_max_generation(enode * n, enode * prev) {
m_max_generation = std::max(m_max_generation, n->get_generation());
if (m_ast_manager.has_trace_stream())
m_used_enodes.push_back(n);
m_used_enodes.push_back(std::make_tuple(prev, n));
}
// We have to provide the number of expected arguments because we have flat-assoc applications such as +.
@ -1877,7 +1880,7 @@ namespace smt {
enode * first = curr;
do {
if (curr->get_decl() == lbl && curr->is_cgr() && curr->get_num_args() == num_expected_args) {
update_max_generation(curr);
update_max_generation(curr, first);
return curr;
}
curr = curr->get_next();
@ -1890,7 +1893,7 @@ namespace smt {
curr = curr->get_next();
while (curr != first) {
if (curr->get_decl() == lbl && curr->is_cgr() && curr->get_num_args() == num_expected_args) {
update_max_generation(curr);
update_max_generation(curr, first);
return curr;
}
curr = curr->get_next();
@ -1914,7 +1917,7 @@ namespace smt {
do {
if (n->get_decl() == f &&
n->get_arg(0)->get_root() == m_args[0]) {
update_max_generation(n);
update_max_generation(n, first);
return true;
}
n = n->get_next();
@ -1929,7 +1932,7 @@ namespace smt {
if (n->get_decl() == f &&
n->get_arg(0)->get_root() == m_args[0] &&
n->get_arg(1)->get_root() == m_args[1]) {
update_max_generation(n);
update_max_generation(n, first);
return true;
}
n = n->get_next();
@ -1949,7 +1952,7 @@ namespace smt {
break;
}
if (i == num_args) {
update_max_generation(n);
update_max_generation(n, first);
return true;
}
}
@ -1975,10 +1978,10 @@ namespace smt {
#define INIT_ARGS_SIZE 16
public:
interpreter(context & ctx, mam & m, bool use_filters):
interpreter(context & ctx, mam & ma, bool use_filters):
m_context(ctx),
m_ast_manager(ctx.get_manager()),
m_mam(m),
m_mam(ma),
m_use_filters(use_filters) {
m_args.resize(INIT_ARGS_SIZE);
}
@ -1999,6 +2002,7 @@ namespace smt {
init(t);
if (t->filter_candidates()) {
for (enode* app : t->get_candidates()) {
TRACE("trigger_bug", tout << "candidate\n" << mk_ismt2_pp(app->get_owner(), m_ast_manager) << "\n";);
if (!app->is_marked() && app->is_cgr()) {
if (m_context.resource_limits_exceeded() || !execute_core(t, app))
return;
@ -2196,7 +2200,7 @@ namespace smt {
if (bp.m_it == bp.m_end)
return nullptr;
m_top++;
update_max_generation(*(bp.m_it));
update_max_generation(*(bp.m_it), nullptr);
return *(bp.m_it);
}
@ -2277,7 +2281,7 @@ namespace smt {
if (m_ast_manager.has_trace_stream()) {
m_used_enodes.reset();
m_used_enodes.push_back(n);
m_used_enodes.push_back(std::make_tuple(nullptr, n)); // null indicates that n was matched against the trigger at the top-level
}
m_pc = t->get_root();
@ -2382,6 +2386,10 @@ namespace smt {
SASSERT(m_n2 != 0);
if (m_n1->get_root() != m_n2->get_root())
goto backtrack;
// we used the equality m_n1 = m_n2 for the match and need to make sure it ends up in the log
m_used_enodes.push_back(std::make_tuple(m_n1, m_n2));
m_pc = m_pc->m_next;
goto main_loop;
@ -2776,7 +2784,7 @@ namespace smt {
m_pattern_instances.pop_back();
m_pattern_instances.push_back(m_app);
// continue succeeded
update_max_generation(m_app);
update_max_generation(m_app, nullptr); // null indicates a top-level match
TRACE("mam_int", tout << "continue next candidate:\n" << mk_ll_pp(m_app->get_owner(), m_ast_manager););
m_num_args = c->m_num_args;
m_oreg = c->m_oreg;
@ -2830,7 +2838,7 @@ namespace smt {
mk_tree_trail(ptr_vector<code_tree> & t, unsigned id):m_trees(t), m_lbl_id(id) {}
void undo(mam_impl & m) override {
dealloc(m_trees[m_lbl_id]);
m_trees[m_lbl_id] = 0;
m_trees[m_lbl_id] = nullptr;
}
};
@ -2863,8 +2871,8 @@ namespace smt {
app * p = to_app(mp->get_arg(first_idx));
func_decl * lbl = p->get_decl();
unsigned lbl_id = lbl->get_decl_id();
m_trees.reserve(lbl_id+1, 0);
if (m_trees[lbl_id] == 0) {
m_trees.reserve(lbl_id+1, nullptr);
if (m_trees[lbl_id] == nullptr) {
m_trees[lbl_id] = m_compiler.mk_tree(qa, mp, first_idx, false);
SASSERT(m_trees[lbl_id]->expected_num_args() == p->get_num_args());
DEBUG_CODE(m_trees[lbl_id]->set_context(m_context););
@ -2949,7 +2957,7 @@ namespace smt {
m_ground_arg(ground_arg),
m_pattern_idx(pat_idx),
m_child(child) {
SASSERT(ground_arg != 0 || ground_arg_idx == 0);
SASSERT(ground_arg != nullptr || ground_arg_idx == 0);
}
};
@ -3216,7 +3224,7 @@ namespace smt {
path_tree * mk_path_tree(path * p, quantifier * qa, app * mp) {
SASSERT(m_ast_manager.is_pattern(mp));
SASSERT(p != 0);
SASSERT(p != nullptr);
unsigned pat_idx = p->m_pattern_idx;
path_tree * head = nullptr;
path_tree * curr = nullptr;
@ -3509,9 +3517,7 @@ namespace smt {
std::cout << "Avg. " << static_cast<double>(total_sz)/static_cast<double>(counter) << ", Max. " << max_sz << "\n";
#endif
enode_vector::iterator it1 = v->begin();
enode_vector::iterator end1 = v->end();
for (; it1 != end1; ++it1) {
for (enode* n : *v) {
// Two different kinds of mark are used:
// - enode mark field: it is used to mark the already processed parents.
// - enode mark2 field: it is used to mark the roots already added to be processed in the next level.
@ -3520,7 +3526,7 @@ namespace smt {
// and Z3 may fail to find potential new matches.
//
// The file regression\acu.sx exposed this problem.
enode * curr_child = (*it1)->get_root();
enode * curr_child = n->get_root();
if (m_use_filters && curr_child->get_plbls().empty_intersection(filter))
continue;
@ -3584,7 +3590,7 @@ namespace smt {
is_eq(curr_tree->m_ground_arg, curr_parent->get_arg(curr_tree->m_ground_arg_idx))
)) {
if (curr_tree->m_code) {
TRACE("mam_path_tree", tout << "found candidate\n";);
TRACE("mam_path_tree", tout << "found candidate " << expr_ref(curr_parent->get_owner(), m_ast_manager) << "\n";);
add_candidate(curr_tree->m_code, curr_parent);
}
if (curr_tree->m_first_child) {
@ -3878,7 +3884,7 @@ namespace smt {
}
#endif
void on_match(quantifier * qa, app * pat, unsigned num_bindings, enode * const * bindings, unsigned max_generation, ptr_vector<enode> & used_enodes) override {
void on_match(quantifier * qa, app * pat, unsigned num_bindings, enode * const * bindings, unsigned max_generation, vector<std::tuple<enode *, enode *>> & used_enodes) override {
TRACE("trigger_bug", tout << "found match " << mk_pp(qa, m_ast_manager) << "\n";);
#ifdef Z3DEBUG
if (m_check_missing_instances) {

View file

@ -21,6 +21,7 @@ Revision History:
#include "ast/ast.h"
#include "smt/smt_types.h"
#include <tuple>
namespace smt {
/**
@ -57,7 +58,7 @@ namespace smt {
virtual void display(std::ostream& out) = 0;
virtual void on_match(quantifier * q, app * pat, unsigned num_bindings, enode * const * bindings, unsigned max_generation, ptr_vector<enode> & used_enodes) = 0;
virtual void on_match(quantifier * q, app * pat, unsigned num_bindings, enode * const * bindings, unsigned max_generation, vector<std::tuple<enode *, enode *>> & used_enodes) = 0;
virtual bool is_shared(enode * n) const = 0;

View file

@ -561,15 +561,24 @@ interval & interval::operator/=(interval const & other) {
TRACE("interval", other.display_with_dependencies(tout););
if (other.m_lower.is_pos() || (other.m_lower.is_zero() && other.m_lower_open)) {
// other.lower > 0
// x in ([0, 0] / [other.lo, other.up]), for other.lo > 0
// <=>
// x >= 0: because y*x >= 0 & y > 0
// x <= 0: because y*x <= 0 & y > 0
m_lower_dep = join(m_lower_dep, other.m_lower_dep);
m_upper_dep = join(m_upper_dep, other.m_lower_dep);
}
else {
// assertion must hold since !other.contains_zero()
SASSERT(other.m_upper.is_neg() || (other.m_upper.is_zero() && other.m_upper_open));
SASSERT(other.m_upper.is_neg() || (other.m_upper.is_zero() && other.m_upper_open));
// other.upper < 0
m_lower_dep = join(m_lower_dep, other.m_upper_dep);
m_upper_dep = join(m_upper_dep, other.m_upper_dep);
// x in ([0, 0] / [other.lo, other.up]), for up < 0
// <=>
// x >= 0: because y*x <= 0 & y < 0
// x <= 0: because y*x >= 0 & y < 0
v_dependency* lower_dep = m_lower_dep;
m_lower_dep = join(m_upper_dep, other.m_upper_dep);
m_upper_dep = join(lower_dep, other.m_upper_dep);
}
return *this;
}

View file

@ -19,7 +19,7 @@ Revision History:
#ifndef THEORY_ARITH_PARAMS_H_
#define THEORY_ARITH_PARAMS_H_
#include<limits.h>
#include<climits>
#include "util/params.h"
enum arith_solver_id {

View file

@ -51,6 +51,7 @@ namespace smt {
m_relevancy_propagator(mk_relevancy_propagator(*this)),
m_random(p.m_random_seed),
m_flushing(false),
m_lemma_id(0),
m_progress_callback(nullptr),
m_next_progress_sample(0),
m_fingerprints(m, m_region),
@ -227,7 +228,6 @@ namespace smt {
}
void context::copy_plugins(context& src, context& dst) {
// copy theory plugins
for (theory* old_th : src.m_theory_set) {
theory * new_th = old_th->mk_fresh(&dst);
@ -235,8 +235,8 @@ namespace smt {
}
}
context * context::mk_fresh(symbol const * l, smt_params * p) {
context * new_ctx = alloc(context, m_manager, p == nullptr ? m_fparams : *p);
context * context::mk_fresh(symbol const * l, smt_params * p, params_ref const& pa) {
context * new_ctx = alloc(context, m_manager, p ? *p : m_fparams, pa);
new_ctx->set_logic(l == nullptr ? m_setup.get_logic() : *l);
copy_plugins(*this, *new_ctx);
return new_ctx;
@ -562,6 +562,7 @@ namespace smt {
invert_trans(n1);
n1->m_trans.m_target = n2;
n1->m_trans.m_justification = js;
n1->m_proof_logged_status = smt::logged_status::NOT_LOGGED;
SASSERT(r1->trans_reaches(n1));
// ---------------
// r1 -> .. -> n1 -> n2 -> ... -> r2
@ -741,12 +742,14 @@ namespace smt {
eq_justification js = n->m_trans.m_justification;
prev->m_trans.m_target = nullptr;
prev->m_trans.m_justification = null_eq_justification;
prev->m_proof_logged_status = smt::logged_status::NOT_LOGGED;
while (curr != nullptr) {
SASSERT(prev->trans_reaches(n));
enode * new_curr = curr->m_trans.m_target;
eq_justification new_js = curr->m_trans.m_justification;
curr->m_trans.m_target = prev;
curr->m_trans.m_justification = js;
curr->m_proof_logged_status = smt::logged_status::NOT_LOGGED;
prev = curr;
js = new_js;
curr = new_curr;
@ -1040,6 +1043,7 @@ namespace smt {
SASSERT(r1->trans_reaches(n1));
n1->m_trans.m_target = nullptr;
n1->m_trans.m_justification = null_eq_justification;
n1->m_proof_logged_status = smt::logged_status::NOT_LOGGED;
invert_trans(r1);
// ---------------
// n1 -> ... -> r1
@ -1346,18 +1350,9 @@ namespace smt {
\remark The method assign_eq adds a new entry on this queue.
*/
bool context::propagate_eqs() {
for (unsigned i = 0; i < m_eq_propagation_queue.size(); i++) {
TRACE("add_eq", tout << m_eq_propagation_queue.size() << "\n";);
for (unsigned i = 0; i < m_eq_propagation_queue.size() && !get_cancel_flag(); i++) {
new_eq & entry = m_eq_propagation_queue[i];
#if 0
static unsigned counter1 = 0;
static unsigned counter2 = 0;
if (entry.m_lhs->is_eq() || entry.m_rhs->is_eq())
counter1++;
else
counter2++;
if ((counter1 + counter2) % 10000 == 0)
std::cout << counter1 << " " << counter2 << "\n";
#endif
add_eq(entry.m_lhs, entry.m_rhs, entry.m_justification);
if (inconsistent())
return false;
@ -1371,7 +1366,7 @@ namespace smt {
*/
bool context::propagate_atoms() {
SASSERT(!inconsistent());
for (unsigned i = 0; i < m_atom_propagation_queue.size(); i++) {
for (unsigned i = 0; i < m_atom_propagation_queue.size() && !get_cancel_flag(); i++) {
SASSERT(!inconsistent());
literal l = m_atom_propagation_queue[i];
bool_var v = l.var();
@ -1553,16 +1548,17 @@ namespace smt {
lbool context::get_assignment(expr * n) const {
if (m_manager.is_false(n))
return l_false;
if (m_manager.is_not(n))
return ~get_assignment_core(to_app(n)->get_arg(0));
expr* arg = nullptr;
if (m_manager.is_not(n, arg))
return ~get_assignment_core(arg);
return get_assignment_core(n);
}
lbool context::find_assignment(expr * n) const {
if (m_manager.is_false(n))
return l_false;
if (m_manager.is_not(n)) {
expr * arg = to_app(n)->get_arg(0);
expr* arg = nullptr;
if (m_manager.is_not(n, arg)) {
if (b_internalized(arg))
return ~get_assignment_core(arg);
return l_undef;
@ -1747,6 +1743,10 @@ namespace smt {
return false;
if (!propagate_eqs())
return false;
if (get_cancel_flag()) {
m_qhead = qhead;
return true;
}
propagate_th_eqs();
propagate_th_diseqs();
if (inconsistent())
@ -1786,7 +1786,7 @@ namespace smt {
}
bool context::add_instance(quantifier * q, app * pat, unsigned num_bindings, enode * const * bindings, expr* def, unsigned max_generation,
unsigned min_top_generation, unsigned max_top_generation, ptr_vector<enode> & used_enodes) {
unsigned min_top_generation, unsigned max_top_generation, vector<std::tuple<enode *, enode *>> & used_enodes) {
return m_qmanager->add_instance(q, pat, num_bindings, bindings, def, max_generation, min_top_generation, max_top_generation, used_enodes);
}
@ -2877,6 +2877,7 @@ namespace smt {
void context::push() {
TRACE("trigger_bug", tout << "context::push()\n";);
scoped_suspend_rlimit _suspend_cancel(m_manager.limit());
pop_to_base_lvl();
setup_context(false);
bool was_consistent = !inconsistent();
@ -3182,6 +3183,7 @@ namespace smt {
if (m_tmp_clauses.empty()) return l_true;
for (auto & tmp_clause : m_tmp_clauses) {
literal_vector& lits = tmp_clause.second;
literal unassigned = null_literal;
for (literal l : lits) {
switch (get_assignment(l)) {
case l_false:
@ -3189,13 +3191,17 @@ namespace smt {
case l_true:
goto next_clause;
default:
shuffle(lits.size(), lits.c_ptr(), m_random);
push_scope();
assign(l, b_justification::mk_axiom(), true);
return l_undef;
unassigned = l;
}
}
if (unassigned != null_literal) {
shuffle(lits.size(), lits.c_ptr(), m_random);
push_scope();
assign(unassigned, b_justification::mk_axiom(), true);
return l_undef;
}
if (lits.size() == 1) {
set_conflict(b_justification(), ~lits[0]);
}
@ -3254,6 +3260,7 @@ namespace smt {
}
void context::reset_assumptions() {
TRACE("unsat_core_bug", tout << "reset " << m_assumptions << "\n";);
for (literal lit : m_assumptions)
get_bdata(lit.var()).m_assumption = false;
m_assumptions.reset();
@ -4096,9 +4103,7 @@ namespace smt {
}
SASSERT(!inconsistent());
unsigned sz = m_b_internalized_stack.size();
for (unsigned i = 0; i < sz; i++) {
expr * curr = m_b_internalized_stack.get(i);
for (expr * curr : m_b_internalized_stack) {
if (is_relevant(curr) && get_assignment(curr) == l_true) {
// if curr is a label literal, then its tags will be copied to result.
m_manager.is_label_lit(curr, result);
@ -4114,9 +4119,7 @@ namespace smt {
void context::get_relevant_labeled_literals(bool at_lbls, expr_ref_vector & result) {
SASSERT(!inconsistent());
buffer<symbol> lbls;
unsigned sz = m_b_internalized_stack.size();
for (unsigned i = 0; i < sz; i++) {
expr * curr = m_b_internalized_stack.get(i);
for (expr * curr : m_b_internalized_stack) {
if (is_relevant(curr) && get_assignment(curr) == l_true) {
lbls.reset();
if (m_manager.is_label_lit(curr, lbls)) {

View file

@ -49,6 +49,7 @@ Revision History:
#include "util/timer.h"
#include "util/statistics.h"
#include "solver/progress_callback.h"
#include <tuple>
// there is a significant space overhead with allocating 1000+ contexts in
// the case that each context only references a few expressions.
@ -87,6 +88,7 @@ namespace smt {
scoped_ptr<relevancy_propagator> m_relevancy_propagator;
random_gen m_random;
bool m_flushing; // (debug support) true when flushing
mutable unsigned m_lemma_id;
progress_callback * m_progress_callback;
unsigned m_next_progress_sample;
@ -489,7 +491,7 @@ namespace smt {
}
bool tracking_assumptions() const {
return m_search_lvl > m_base_lvl;
return !m_assumptions.empty() && m_search_lvl > m_base_lvl;
}
expr * bool_var2expr(bool_var v) const {
@ -970,7 +972,7 @@ namespace smt {
bool contains_instance(quantifier * q, unsigned num_bindings, enode * const * bindings);
bool add_instance(quantifier * q, app * pat, unsigned num_bindings, enode * const * bindings, expr* def, unsigned max_generation,
unsigned min_top_generation, unsigned max_top_generation, ptr_vector<enode> & used_enodes);
unsigned min_top_generation, unsigned max_top_generation, vector<std::tuple<enode *, enode*>> & used_enodes /*gives the equalities used for the pattern match, see mam.cpp for more info*/);
void set_global_generation(unsigned generation) { m_generation = generation; }
@ -1009,6 +1011,7 @@ namespace smt {
void push_eq(enode * lhs, enode * rhs, eq_justification const & js) {
SASSERT(lhs != rhs);
SASSERT(lhs->get_root() != rhs->get_root());
m_eq_propagation_queue.push_back(new_eq(lhs, rhs, js));
}
@ -1317,12 +1320,12 @@ namespace smt {
void display_lemma_as_smt_problem(std::ostream & out, unsigned num_antecedents, literal const * antecedents, literal consequent = false_literal, symbol const& logic = symbol::null) const;
void display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents, literal consequent = false_literal, symbol const& logic = symbol::null) const;
unsigned display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents, literal consequent = false_literal, symbol const& logic = symbol::null) const;
void display_lemma_as_smt_problem(std::ostream & out, unsigned num_antecedents, literal const * antecedents,
unsigned num_antecedent_eqs, enode_pair const * antecedent_eqs,
literal consequent = false_literal, symbol const& logic = symbol::null) const;
void display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents,
unsigned display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents,
unsigned num_antecedent_eqs, enode_pair const * antecedent_eqs,
literal consequent = false_literal, symbol const& logic = symbol::null) const;
@ -1490,7 +1493,7 @@ namespace smt {
If l == 0, then the logic of this context is used in the new context.
If p == 0, then this->m_params is used
*/
context * mk_fresh(symbol const * l = nullptr, smt_params * p = nullptr);
context * mk_fresh(symbol const * l = nullptr, smt_params * smtp = nullptr, params_ref const & p = params_ref());
static void copy(context& src, context& dst);

View file

@ -419,23 +419,16 @@ namespace smt {
visitor.collect(fmls);
visitor.display_decls(out);
visitor.display_asserts(out, fmls, true);
out << "(check-sat)\n";
}
static unsigned g_lemma_id = 0;
#define BUFFER_SZ 128
void context::display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents, literal consequent, symbol const& logic) const {
char buffer[BUFFER_SZ];
#ifdef _WINDOWS
sprintf_s(buffer, BUFFER_SZ, "lemma_%d.smt2", g_lemma_id);
#else
sprintf(buffer, "lemma_%d.smt2", g_lemma_id);
#endif
std::ofstream out(buffer);
unsigned context::display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents, literal consequent, symbol const& logic) const {
std::stringstream strm;
strm << "lemma_" << (++m_lemma_id) << ".smt2";
std::ofstream out(strm.str());
display_lemma_as_smt_problem(out, num_antecedents, antecedents, consequent, logic);
out.close();
g_lemma_id++;
return m_lemma_id;
}
void context::display_lemma_as_smt_problem(std::ostream & out, unsigned num_antecedents, literal const * antecedents,
@ -464,21 +457,18 @@ namespace smt {
visitor.collect(fmls);
visitor.display_decls(out);
visitor.display_asserts(out, fmls, true);
out << "(check-sat)\n";
}
void context::display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents,
unsigned context::display_lemma_as_smt_problem(unsigned num_antecedents, literal const * antecedents,
unsigned num_eq_antecedents, enode_pair const * eq_antecedents,
literal consequent, symbol const& logic) const {
char buffer[BUFFER_SZ];
#ifdef _WINDOWS
sprintf_s(buffer, BUFFER_SZ, "lemma_%d.smt2", g_lemma_id);
#else
sprintf(buffer, "lemma_%d.smt2", g_lemma_id);
#endif
std::ofstream out(buffer);
std::stringstream strm;
strm << "lemma_" << (++m_lemma_id) << ".smt2";
std::ofstream out(strm.str());
display_lemma_as_smt_problem(out, num_antecedents, antecedents, num_eq_antecedents, eq_antecedents, consequent, logic);
out.close();
g_lemma_id++;
return m_lemma_id;
}
/**
@ -577,7 +567,7 @@ namespace smt {
case b_justification::BIN_CLAUSE: {
literal l2 = j.get_literal();
out << "bin-clause ";
display_literal_verbose(out, l2);
display_literal(out, l2);
break;
}
case b_justification::CLAUSE: {
@ -590,7 +580,7 @@ namespace smt {
out << "justification " << j.get_justification()->get_from_theory() << ": ";
literal_vector lits;
const_cast<conflict_resolution&>(*m_conflict_resolution).justification2literals(j.get_justification(), lits);
display_literals_verbose(out, lits);
display_literals(out, lits);
break;
}
default:

View file

@ -47,6 +47,7 @@ namespace smt {
n->m_cgc_enabled = cgc_enabled;
n->m_iscope_lvl = iscope_lvl;
n->m_lbl_hash = -1;
n->m_proof_logged_status = smt::logged_status::NOT_LOGGED;
unsigned num_args = n->get_num_args();
for (unsigned i = 0; i < num_args; i++) {
enode * arg = app2enode[owner->get_arg(i)->get_id()];

View file

@ -38,6 +38,15 @@ namespace smt {
}
};
/**
\brief Indicates whether the proof for membership in an equivalence class is already logged.
*/
enum logged_status {
NOT_LOGGED, //!< Proof is not logged or logged information is not up-to-date.
BEING_LOGGED, //!< We are currently in the process of logging all relevant information. This is used to prevent looping when logging congruence steps.
LOGGED //!< Proof is logged and logged information is still up-to-date.
};
/** \ brief Use sparse maps in SMT solver.
Define this to use hash maps rather than vectors over ast
@ -105,6 +114,7 @@ namespace smt {
enode_vector m_parents; //!< Parent enodes of the equivalence class.
theory_var_list m_th_var_list; //!< List of theories that 'care' about this enode.
trans_justification m_trans; //!< A justification for the enode being equal to its root.
logged_status m_proof_logged_status; //!< Indicates that the proof for the enode being equal to its root is in the log.
signed char m_lbl_hash; //!< It is different from -1, if enode is used in a pattern
approx_set m_lbls;
approx_set m_plbls;
@ -113,6 +123,7 @@ namespace smt {
friend class context;
friend class euf_manager;
friend class conflict_resolution;
friend class quantifier_manager;
theory_var_list * get_th_var_list() {
@ -361,6 +372,10 @@ namespace smt {
theory_var get_th_var(theory_id th_id) const;
trans_justification get_trans_justification() {
return m_trans;
}
unsigned get_generation() const {
return m_generation;
}

Some files were not shown because too many files have changed in this diff Show more