3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-06 19:21:22 +00:00

Merge pull request #1 from wintersteiger/bugfixes

Bugfixes
This commit is contained in:
AleksandarZeljic 2015-06-03 16:50:26 +02:00
commit 575dc20d22
53 changed files with 489 additions and 225 deletions

View file

@ -809,8 +809,12 @@ class env {
r = terms[0] / terms[1]; r = terms[0] / terms[1];
} }
else if (!strcmp(ch,"$distinct")) { else if (!strcmp(ch,"$distinct")) {
check_arity(terms.size(), 2); if (terms.size() == 2) {
r = terms[0] != terms[1]; r = terms[0] != terms[1];
}
else {
r = distinct(terms);
}
} }
else if (!strcmp(ch,"$floor") || !strcmp(ch,"$to_int")) { else if (!strcmp(ch,"$floor") || !strcmp(ch,"$to_int")) {
check_arity(terms.size(), 1); check_arity(terms.size(), 1);
@ -1089,12 +1093,11 @@ class env {
} }
z3::sort mk_sort(char const* s) { z3::sort mk_sort(char const* s) {
z3::symbol sym = symbol(s); return m_context.uninterpreted_sort(s);
return mk_sort(sym);
} }
z3::sort mk_sort(z3::symbol& s) { z3::sort mk_sort(z3::symbol& s) {
return z3::sort(m_context, Z3_mk_uninterpreted_sort(m_context, s)); return m_context.uninterpreted_sort(s);
} }
public: public:

View file

@ -55,7 +55,6 @@ def init_project_def():
add_lib('bv_tactics', ['tactic', 'bit_blaster'], 'tactic/bv') add_lib('bv_tactics', ['tactic', 'bit_blaster'], 'tactic/bv')
add_lib('fuzzing', ['ast'], 'test/fuzzing') add_lib('fuzzing', ['ast'], 'test/fuzzing')
add_lib('smt_tactic', ['smt'], 'smt/tactic') add_lib('smt_tactic', ['smt'], 'smt/tactic')
add_lib('fpa_tactics', ['fpa', 'core_tactics', 'bv_tactics', 'sat_tactic', 'smt_tactic'], 'tactic/fpa')
add_lib('sls_tactic', ['tactic', 'normal_forms', 'core_tactics', 'bv_tactics'], 'tactic/sls') add_lib('sls_tactic', ['tactic', 'normal_forms', 'core_tactics', 'bv_tactics'], 'tactic/sls')
add_lib('qe', ['smt','sat'], 'qe') add_lib('qe', ['smt','sat'], 'qe')
add_lib('duality', ['smt', 'interp', 'qe']) add_lib('duality', ['smt', 'interp', 'qe'])
@ -71,6 +70,7 @@ def init_project_def():
add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf', 'ddnf'], 'muz/fp') add_lib('fp', ['muz', 'pdr', 'clp', 'tab', 'rel', 'bmc', 'duality_intf', 'ddnf'], 'muz/fp')
add_lib('nlsat_smt_tactic', ['nlsat_tactic', 'smt_tactic'], 'tactic/nlsat_smt') add_lib('nlsat_smt_tactic', ['nlsat_tactic', 'smt_tactic'], 'tactic/nlsat_smt')
add_lib('smtlogic_tactics', ['arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt_tactic', 'aig_tactic', 'fp', 'muz','qe','nlsat_smt_tactic'], 'tactic/smtlogics') add_lib('smtlogic_tactics', ['arith_tactics', 'bv_tactics', 'nlsat_tactic', 'smt_tactic', 'aig_tactic', 'fp', 'muz','qe','nlsat_smt_tactic'], 'tactic/smtlogics')
add_lib('fpa_tactics', ['fpa', 'core_tactics', 'bv_tactics', 'sat_tactic', 'smt_tactic', 'arith_tactics', 'smtlogic_tactics'], 'tactic/fpa')
add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv') add_lib('ufbv_tactic', ['normal_forms', 'core_tactics', 'macros', 'smt_tactic', 'rewriter'], 'tactic/ufbv')
add_lib('portfolio', ['smtlogic_tactics', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'qe','sls_tactic', 'subpaving_tactic'], 'tactic/portfolio') add_lib('portfolio', ['smtlogic_tactics', 'ufbv_tactic', 'fpa_tactics', 'aig_tactic', 'fp', 'qe','sls_tactic', 'subpaving_tactic'], 'tactic/portfolio')
add_lib('smtparser', ['portfolio'], 'parsers/smt') add_lib('smtparser', ['portfolio'], 'parsers/smt')

View file

@ -568,10 +568,12 @@ def mk_java():
java_native.write(' public static class ObjArrayPtr { public long[] value; }\n') java_native.write(' public static class ObjArrayPtr { public long[] value; }\n')
java_native.write(' public static class UIntArrayPtr { public int[] value; }\n') java_native.write(' public static class UIntArrayPtr { public int[] value; }\n')
java_native.write(' public static native void setInternalErrorHandler(long ctx);\n\n') java_native.write(' public static native void setInternalErrorHandler(long ctx);\n\n')
if IS_WINDOWS or os.uname()[0]=="CYGWIN":
java_native.write(' static { System.loadLibrary("%s"); }\n' % get_component('java').dll_name) java_native.write(' static {\n')
else: java_native.write(' try { System.loadLibrary("z3java"); }\n')
java_native.write(' static { System.loadLibrary("%s"); }\n' % get_component('java').dll_name[3:]) # We need 3: to extract the prexi 'lib' form the dll_name java_native.write(' catch (UnsatisfiedLinkError ex) { System.loadLibrary("libz3java"); }\n')
java_native.write(' }\n')
java_native.write('\n') java_native.write('\n')
for name, result, params in _dotnet_decls: for name, result, params in _dotnet_decls:
java_native.write(' protected static native %s INTERNAL%s(' % (type2java(result), java_method_name(name))) java_native.write(' protected static native %s INTERNAL%s(' % (type2java(result), java_method_name(name)))

View file

@ -355,6 +355,10 @@ extern "C" {
init_solver(c, s); init_solver(c, s);
Z3_stats_ref * st = alloc(Z3_stats_ref); Z3_stats_ref * st = alloc(Z3_stats_ref);
to_solver_ref(s)->collect_statistics(st->m_stats); to_solver_ref(s)->collect_statistics(st->m_stats);
unsigned long long max_mem = memory::get_max_used_memory();
unsigned long long mem = memory::get_allocation_size();
st->m_stats.update("max memory", static_cast<double>(max_mem)/(1024.0*1024.0));
st->m_stats.update("memory", static_cast<double>(mem)/(1024.0*1024.0));
mk_c(c)->save_object(st); mk_c(c)->save_object(st);
Z3_stats r = of_stats(st); Z3_stats r = of_stats(st);
RETURN_Z3(r); RETURN_Z3(r);

View file

@ -203,6 +203,11 @@ namespace z3 {
and in \c ts the predicates for testing if terms of the enumeration sort correspond to an enumeration. and in \c ts the predicates for testing if terms of the enumeration sort correspond to an enumeration.
*/ */
sort enumeration_sort(char const * name, unsigned n, char const * const * enum_names, func_decl_vector & cs, func_decl_vector & ts); sort enumeration_sort(char const * name, unsigned n, char const * const * enum_names, func_decl_vector & cs, func_decl_vector & ts);
/**
\brief create an uninterpreted sort with the name given by the string or symbol.
*/
sort uninterpreted_sort(char const* name);
sort uninterpreted_sort(symbol const& name);
func_decl function(symbol const & name, unsigned arity, sort const * domain, sort const & range); func_decl function(symbol const & name, unsigned arity, sort const * domain, sort const & range);
func_decl function(char const * name, unsigned arity, sort const * domain, sort const & range); func_decl function(char const * name, unsigned arity, sort const * domain, sort const & range);
@ -678,7 +683,7 @@ namespace z3 {
friend expr operator+(expr const & a, expr const & b) { friend expr operator+(expr const & a, expr const & b) {
check_context(a, b); check_context(a, b);
Z3_ast r; Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) { if (a.is_arith() && b.is_arith()) {
Z3_ast args[2] = { a, b }; Z3_ast args[2] = { a, b };
r = Z3_mk_add(a.ctx(), 2, args); r = Z3_mk_add(a.ctx(), 2, args);
@ -698,7 +703,7 @@ namespace z3 {
friend expr operator*(expr const & a, expr const & b) { friend expr operator*(expr const & a, expr const & b) {
check_context(a, b); check_context(a, b);
Z3_ast r; Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) { if (a.is_arith() && b.is_arith()) {
Z3_ast args[2] = { a, b }; Z3_ast args[2] = { a, b };
r = Z3_mk_mul(a.ctx(), 2, args); r = Z3_mk_mul(a.ctx(), 2, args);
@ -725,7 +730,7 @@ namespace z3 {
friend expr operator/(expr const & a, expr const & b) { friend expr operator/(expr const & a, expr const & b) {
check_context(a, b); check_context(a, b);
Z3_ast r; Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) { if (a.is_arith() && b.is_arith()) {
r = Z3_mk_div(a.ctx(), a, b); r = Z3_mk_div(a.ctx(), a, b);
} }
@ -743,7 +748,7 @@ namespace z3 {
friend expr operator/(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) / b; } friend expr operator/(int a, expr const & b) { return b.ctx().num_val(a, b.get_sort()) / b; }
friend expr operator-(expr const & a) { friend expr operator-(expr const & a) {
Z3_ast r; Z3_ast r = 0;
if (a.is_arith()) { if (a.is_arith()) {
r = Z3_mk_unary_minus(a.ctx(), a); r = Z3_mk_unary_minus(a.ctx(), a);
} }
@ -760,7 +765,7 @@ namespace z3 {
friend expr operator-(expr const & a, expr const & b) { friend expr operator-(expr const & a, expr const & b) {
check_context(a, b); check_context(a, b);
Z3_ast r; Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) { if (a.is_arith() && b.is_arith()) {
Z3_ast args[2] = { a, b }; Z3_ast args[2] = { a, b };
r = Z3_mk_sub(a.ctx(), 2, args); r = Z3_mk_sub(a.ctx(), 2, args);
@ -780,7 +785,7 @@ namespace z3 {
friend expr operator<=(expr const & a, expr const & b) { friend expr operator<=(expr const & a, expr const & b) {
check_context(a, b); check_context(a, b);
Z3_ast r; Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) { if (a.is_arith() && b.is_arith()) {
r = Z3_mk_le(a.ctx(), a, b); r = Z3_mk_le(a.ctx(), a, b);
} }
@ -799,7 +804,7 @@ namespace z3 {
friend expr operator>=(expr const & a, expr const & b) { friend expr operator>=(expr const & a, expr const & b) {
check_context(a, b); check_context(a, b);
Z3_ast r; Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) { if (a.is_arith() && b.is_arith()) {
r = Z3_mk_ge(a.ctx(), a, b); r = Z3_mk_ge(a.ctx(), a, b);
} }
@ -818,7 +823,7 @@ namespace z3 {
friend expr operator<(expr const & a, expr const & b) { friend expr operator<(expr const & a, expr const & b) {
check_context(a, b); check_context(a, b);
Z3_ast r; Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) { if (a.is_arith() && b.is_arith()) {
r = Z3_mk_lt(a.ctx(), a, b); r = Z3_mk_lt(a.ctx(), a, b);
} }
@ -837,7 +842,7 @@ namespace z3 {
friend expr operator>(expr const & a, expr const & b) { friend expr operator>(expr const & a, expr const & b) {
check_context(a, b); check_context(a, b);
Z3_ast r; Z3_ast r = 0;
if (a.is_arith() && b.is_arith()) { if (a.is_arith() && b.is_arith()) {
r = Z3_mk_gt(a.ctx(), a, b); r = Z3_mk_gt(a.ctx(), a, b);
} }
@ -1184,7 +1189,7 @@ namespace z3 {
expr eval(expr const & n, bool model_completion=false) const { expr eval(expr const & n, bool model_completion=false) const {
check_context(*this, n); check_context(*this, n);
Z3_ast r; Z3_ast r = 0;
Z3_bool status = Z3_model_eval(ctx(), m_model, n, model_completion, &r); Z3_bool status = Z3_model_eval(ctx(), m_model, n, model_completion, &r);
check_error(); check_error();
if (status == Z3_FALSE) if (status == Z3_FALSE)
@ -1637,6 +1642,13 @@ namespace z3 {
for (unsigned i = 0; i < n; i++) { cs.push_back(func_decl(*this, _cs[i])); ts.push_back(func_decl(*this, _ts[i])); } for (unsigned i = 0; i < n; i++) { cs.push_back(func_decl(*this, _cs[i])); ts.push_back(func_decl(*this, _ts[i])); }
return s; return s;
} }
inline sort context::uninterpreted_sort(char const* name) {
Z3_symbol _name = Z3_mk_string_symbol(*this, name);
return to_sort(*this, Z3_mk_uninterpreted_sort(*this, _name));
}
inline sort context::uninterpreted_sort(symbol const& name) {
return to_sort(*this, Z3_mk_uninterpreted_sort(*this, name));
}
inline func_decl context::function(symbol const & name, unsigned arity, sort const * domain, sort const & range) { inline func_decl context::function(symbol const & name, unsigned arity, sort const * domain, sort const & range) {
array<Z3_sort> args(arity); array<Z3_sort> args(arity);

View file

@ -108,7 +108,8 @@ public class InterpolationContext extends Context
res.status = Z3_lbool.fromInt(Native.computeInterpolant(nCtx(), pat.getNativeObject(), p.getNativeObject(), n_i, n_m)); res.status = Z3_lbool.fromInt(Native.computeInterpolant(nCtx(), pat.getNativeObject(), p.getNativeObject(), n_i, n_m));
if (res.status == Z3_lbool.Z3_L_FALSE) if (res.status == Z3_lbool.Z3_L_FALSE)
res.interp = (new ASTVector(this, n_i.value)).ToBoolExprArray(); res.interp = (new ASTVector(this, n_i.value)).ToBoolExprArray();
if (res.status == Z3_lbool.Z3_L_TRUE) res.model = new Model(this, n_m.value); if (res.status == Z3_lbool.Z3_L_TRUE)
res.model = new Model(this, n_m.value);
return res; return res;
} }

View file

@ -5617,7 +5617,7 @@ class Statistics:
sat sat
>>> st = s.statistics() >>> st = s.statistics()
>>> len(st) >>> len(st)
2 4
""" """
return int(Z3_stats_size(self.ctx.ref(), self.stats)) return int(Z3_stats_size(self.ctx.ref(), self.stats))
@ -5631,7 +5631,7 @@ class Statistics:
sat sat
>>> st = s.statistics() >>> st = s.statistics()
>>> len(st) >>> len(st)
2 4
>>> st[0] >>> st[0]
('nlsat propagations', 2) ('nlsat propagations', 2)
>>> st[1] >>> st[1]
@ -5655,7 +5655,7 @@ class Statistics:
sat sat
>>> st = s.statistics() >>> st = s.statistics()
>>> st.keys() >>> st.keys()
['nlsat propagations', 'nlsat stages'] ['nlsat propagations', 'nlsat stages', 'max memory', 'memory']
""" """
return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))] return [Z3_stats_get_key(self.ctx.ref(), self.stats, idx) for idx in range(len(self))]
@ -5692,7 +5692,7 @@ class Statistics:
sat sat
>>> st = s.statistics() >>> st = s.statistics()
>>> st.keys() >>> st.keys()
['nlsat propagations', 'nlsat stages'] ['nlsat propagations', 'nlsat stages', 'max memory', 'memory']
>>> st.nlsat_propagations >>> st.nlsat_propagations
2 2
>>> st.nlsat_stages >>> st.nlsat_stages
@ -8194,23 +8194,24 @@ def FP(name, fpsort, ctx=None):
>>> eq(x, x2) >>> eq(x, x2)
True True
""" """
ctx = fpsort.ctx if isinstance(fpsort, FPSortRef):
ctx = fpsort.ctx
else:
ctx = _get_ctx(ctx)
return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx) return FPRef(Z3_mk_const(ctx.ref(), to_symbol(name, ctx), fpsort.ast), ctx)
def FPs(names, fpsort, ctx=None): def FPs(names, fpsort, ctx=None):
"""Return an array of floating-point constants. """Return an array of floating-point constants.
>>> x, y, z = BitVecs('x y z', 16) >>> x, y, z = FPs('x y z', FPSort(8, 24))
>>> x.size()
16
>>> x.sort() >>> x.sort()
BitVec(16) FPSort(8, 24)
>>> Sum(x, y, z) >>> x.sbits()
0 + x + y + z 24
>>> Product(x, y, z) >>> x.ebits()
1*x*y*z 8
>>> simplify(Product(x, y, z)) >>> fpMul(RNE(), fpAdd(RNE(), x, y), z)
x*y*z fpMul(RNE(), fpAdd(RNE(), x, y), z)
""" """
ctx = z3._get_ctx(ctx) ctx = z3._get_ctx(ctx)
if isinstance(names, str): if isinstance(names, str):

View file

@ -341,22 +341,22 @@ format * smt2_pp_environment::pp_arith_literal(app * t, bool decimal, unsigned d
} }
else { else {
SASSERT(u.is_irrational_algebraic_numeral(t)); SASSERT(u.is_irrational_algebraic_numeral(t));
anum const & val = u.to_irrational_algebraic_numeral(t); anum const & val2 = u.to_irrational_algebraic_numeral(t);
algebraic_numbers::manager & am = u.am(); algebraic_numbers::manager & am = u.am();
format * vf; format * vf;
std::ostringstream buffer; std::ostringstream buffer;
bool is_neg = false; bool is_neg = false;
if (decimal) { if (decimal) {
scoped_anum abs_val(am); scoped_anum abs_val(am);
am.set(abs_val, val); am.set(abs_val, val2);
if (am.is_neg(val)) { if (am.is_neg(val2)) {
is_neg = true; is_neg = true;
am.neg(abs_val); am.neg(abs_val);
} }
am.display_decimal(buffer, abs_val, decimal_prec); am.display_decimal(buffer, abs_val, decimal_prec);
} }
else { else {
am.display_root_smt2(buffer, val); am.display_root_smt2(buffer, val2);
} }
vf = mk_string(get_manager(), buffer.str().c_str()); vf = mk_string(get_manager(), buffer.str().c_str());
return is_neg ? mk_neg(vf) : vf; return is_neg ? mk_neg(vf) : vf;

View file

@ -44,12 +44,12 @@ app * mk_list_assoc_app(ast_manager & m, family_id fid, decl_kind k, unsigned nu
return mk_list_assoc_app(m, decl, num_args, args); return mk_list_assoc_app(m, decl, num_args, args);
} }
bool is_well_formed_vars(ptr_vector<sort>& bound, expr* e) { bool is_well_formed_vars(ptr_vector<sort>& bound, expr * top) {
ptr_vector<expr> todo; ptr_vector<expr> todo;
ast_mark mark; ast_mark mark;
todo.push_back(e); todo.push_back(top);
while (!todo.empty()) { while (!todo.empty()) {
expr* e = todo.back(); expr * e = todo.back();
todo.pop_back(); todo.pop_back();
if (mark.is_marked(e)) { if (mark.is_marked(e)) {
continue; continue;

View file

@ -501,8 +501,12 @@ func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p
func_decl * r = mk_func_decl(k, bv_size); func_decl * r = mk_func_decl(k, bv_size);
if (r != 0) { if (r != 0) {
if (arity != r->get_arity()) { if (arity != r->get_arity()) {
m_manager->raise_exception("declared arity mismatches supplied arity"); if (r->get_info()->is_associative())
return 0; arity = r->get_arity();
else {
m_manager->raise_exception("declared arity mismatches supplied arity");
return 0;
}
} }
for (unsigned i = 0; i < arity; ++i) { for (unsigned i = 0; i < arity; ++i) {
if (domain[i] != r->get_domain(i)) { if (domain[i] != r->get_domain(i)) {
@ -566,6 +570,7 @@ func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p
func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters, func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, parameter const * parameters,
unsigned num_args, expr * const * args, sort * range) { unsigned num_args, expr * const * args, sort * range) {
ast_manager& m = *m_manager;
int bv_size; int bv_size;
if (k == OP_INT2BV && get_int2bv_size(num_parameters, parameters, bv_size)) { if (k == OP_INT2BV && get_int2bv_size(num_parameters, parameters, bv_size)) {
// bv_size is filled in. // bv_size is filled in.
@ -589,11 +594,35 @@ func_decl * bv_decl_plugin::mk_func_decl(decl_kind k, unsigned num_parameters, p
return decl_plugin::mk_func_decl(k, num_parameters, parameters, num_args, args, range); return decl_plugin::mk_func_decl(k, num_parameters, parameters, num_args, args, range);
} }
else if (num_args == 0 || !get_bv_size(args[0], bv_size)) { else if (num_args == 0 || !get_bv_size(args[0], bv_size)) {
m_manager->raise_exception("operator is applied to arguments of the wrong sort"); m.raise_exception("operator is applied to arguments of the wrong sort");
return 0; return 0;
} }
func_decl * r = mk_func_decl(k, bv_size); func_decl * r = mk_func_decl(k, bv_size);
if (r != 0) { if (r != 0) {
if (num_args != r->get_arity()) {
if (r->get_info()->is_associative()) {
sort * fs = r->get_domain(0);
for (unsigned i = 0; i < num_args; ++i) {
if (m.get_sort(args[i]) != fs) {
m_manager->raise_exception("declared sorts do not match supplied sorts");
return 0;
}
}
return r;
}
else {
m.raise_exception("declared arity mismatches supplied arity");
return 0;
}
}
for (unsigned i = 0; i < num_args; ++i) {
if (m.get_sort(args[i]) != r->get_domain(i)) {
std::ostringstream buffer;
buffer << "Argument " << mk_pp(args[i], m) << " at position " << i << " does not match declaration " << mk_pp(r, m);
m.raise_exception(buffer.str().c_str());
return 0;
}
}
return r; return r;
} }
return decl_plugin::mk_func_decl(k, num_parameters, parameters, num_args, args, range); return decl_plugin::mk_func_decl(k, num_parameters, parameters, num_args, args, range);

View file

@ -149,10 +149,10 @@ enum status {
*/ */
static bool is_recursive_datatype(parameter const * parameters) { static bool is_recursive_datatype(parameter const * parameters) {
unsigned num_types = parameters[0].get_int(); unsigned num_types = parameters[0].get_int();
unsigned tid = parameters[1].get_int(); unsigned top_tid = parameters[1].get_int();
buffer<status> already_found(num_types, WHITE); buffer<status> already_found(num_types, WHITE);
buffer<unsigned> todo; buffer<unsigned> todo;
todo.push_back(tid); todo.push_back(top_tid);
while (!todo.empty()) { while (!todo.empty()) {
unsigned tid = todo.back(); unsigned tid = todo.back();
if (already_found[tid] == BLACK) { if (already_found[tid] == BLACK) {
@ -198,11 +198,11 @@ static bool is_recursive_datatype(parameter const * parameters) {
*/ */
static sort_size get_datatype_size(parameter const * parameters) { static sort_size get_datatype_size(parameter const * parameters) {
unsigned num_types = parameters[0].get_int(); unsigned num_types = parameters[0].get_int();
unsigned tid = parameters[1].get_int(); unsigned top_tid = parameters[1].get_int();
buffer<sort_size> szs(num_types, sort_size()); buffer<sort_size> szs(num_types, sort_size());
buffer<status> already_found(num_types, WHITE); buffer<status> already_found(num_types, WHITE);
buffer<unsigned> todo; buffer<unsigned> todo;
todo.push_back(tid); todo.push_back(top_tid);
while (!todo.empty()) { while (!todo.empty()) {
unsigned tid = todo.back(); unsigned tid = todo.back();
if (already_found[tid] == BLACK) { if (already_found[tid] == BLACK) {
@ -280,7 +280,7 @@ static sort_size get_datatype_size(parameter const * parameters) {
} }
} }
} }
return szs[tid]; return szs[top_tid];
} }
/** /**
@ -657,8 +657,8 @@ bool datatype_decl_plugin::is_fully_interp(sort const * s) const {
for (unsigned tid = 0; tid < num_types; tid++) { for (unsigned tid = 0; tid < num_types; tid++) {
unsigned o = parameters[2 + 2*tid + 1].get_int(); // constructor offset unsigned o = parameters[2 + 2*tid + 1].get_int(); // constructor offset
unsigned num_constructors = parameters[o].get_int(); unsigned num_constructors = parameters[o].get_int();
for (unsigned s = 1; s <= num_constructors; s++) { for (unsigned si = 1; si <= num_constructors; si++) {
unsigned k_i = parameters[o + s].get_int(); unsigned k_i = parameters[o + si].get_int();
unsigned num_accessors = parameters[k_i + 2].get_int(); unsigned num_accessors = parameters[k_i + 2].get_int();
unsigned r = 0; unsigned r = 0;
for (; r < num_accessors; r++) { for (; r < num_accessors; r++) {

View file

@ -367,16 +367,16 @@ struct expr2polynomial::imp {
begin_loop: begin_loop:
checkpoint(); checkpoint();
frame & fr = m_frame_stack.back(); frame & fr = m_frame_stack.back();
app * t = fr.m_curr; app * a = fr.m_curr;
TRACE("expr2polynomial", tout << "processing: " << fr.m_idx << "\n" << mk_ismt2_pp(t, m()) << "\n";); TRACE("expr2polynomial", tout << "processing: " << fr.m_idx << "\n" << mk_ismt2_pp(a, m()) << "\n";);
unsigned num_args = t->get_num_args(); unsigned num_args = a->get_num_args();
while (fr.m_idx < num_args) { while (fr.m_idx < num_args) {
expr * arg = t->get_arg(fr.m_idx); expr * arg = a->get_arg(fr.m_idx);
fr.m_idx++; fr.m_idx++;
if (!visit(arg)) if (!visit(arg))
goto begin_loop; goto begin_loop;
} }
process_app(t); process_app(a);
m_frame_stack.pop_back(); m_frame_stack.pop_back();
} }
} }

View file

@ -1079,12 +1079,16 @@ void fpa2bv_converter::mk_min(func_decl * f, unsigned num, expr * const * args,
mk_is_nan(y, y_is_nan); mk_is_nan(y, y_is_nan);
mk_pzero(f, pzero); mk_pzero(f, pzero);
expr_ref sgn_diff(m);
sgn_diff = m.mk_not(m.mk_eq(x_sgn, y_sgn));
expr_ref lt(m); expr_ref lt(m);
mk_float_lt(f, num, args, lt); mk_float_lt(f, num, args, lt);
result = y; result = y;
mk_ite(lt, x, result, result); mk_ite(lt, x, result, result);
mk_ite(both_zero, y, result, result); mk_ite(both_zero, y, result, result);
mk_ite(m.mk_and(both_zero, sgn_diff), pzero, result, result); // min(-0.0, +0.0) = min(+0.0, -0.0) = +0.0
mk_ite(y_is_nan, x, result, result); mk_ite(y_is_nan, x, result, result);
mk_ite(x_is_nan, y, result, result); mk_ite(x_is_nan, y, result, result);
@ -1109,12 +1113,16 @@ void fpa2bv_converter::mk_max(func_decl * f, unsigned num, expr * const * args,
mk_is_nan(y, y_is_nan); mk_is_nan(y, y_is_nan);
mk_pzero(f, pzero); mk_pzero(f, pzero);
expr_ref sgn_diff(m);
sgn_diff = m.mk_not(m.mk_eq(x_sgn, y_sgn));
expr_ref gt(m); expr_ref gt(m);
mk_float_gt(f, num, args, gt); mk_float_gt(f, num, args, gt);
result = y; result = y;
mk_ite(gt, x, result, result); mk_ite(gt, x, result, result);
mk_ite(both_zero, y, result, result); mk_ite(both_zero, y, result, result);
mk_ite(m.mk_and(both_zero, sgn_diff), pzero, result, result); // max(-0.0, +0.0) = max(+0.0, -0.0) = +0.0
mk_ite(y_is_nan, x, result, result); mk_ite(y_is_nan, x, result, result);
mk_ite(x_is_nan, y, result, result); mk_ite(x_is_nan, y, result, result);
@ -1395,13 +1403,19 @@ void fpa2bv_converter::mk_fma(func_decl * f, unsigned num, expr * const * args,
expr * res_sgn_or_args[3] = { res_sgn_c1, res_sgn_c2, res_sgn_c3 }; expr * res_sgn_or_args[3] = { res_sgn_c1, res_sgn_c2, res_sgn_c3 };
res_sgn = m_bv_util.mk_bv_or(3, res_sgn_or_args); res_sgn = m_bv_util.mk_bv_or(3, res_sgn_or_args);
sticky_raw = m_bv_util.mk_extract(sbits-5, 0, sig_abs); if (sbits > 5) {
sticky = m_bv_util.mk_zero_extend(sbits+3, m.mk_app(bvfid, OP_BREDOR, sticky_raw.get())); sticky_raw = m_bv_util.mk_extract(sbits - 5, 0, sig_abs);
sticky = m_bv_util.mk_zero_extend(sbits + 3, m.mk_app(bvfid, OP_BREDOR, sticky_raw.get()));
expr * res_or_args[2] = { m_bv_util.mk_extract(2 * sbits - 1, sbits - 4, sig_abs), sticky };
res_sig = m_bv_util.mk_bv_or(2, res_or_args);
}
else {
unsigned too_short = 6 - sbits;
sig_abs = m_bv_util.mk_concat(sig_abs, m_bv_util.mk_numeral(0, too_short));
res_sig = m_bv_util.mk_extract(sbits + 3, 0, sig_abs);
}
dbg_decouple("fpa2bv_fma_add_sum_sticky", sticky); dbg_decouple("fpa2bv_fma_add_sum_sticky", sticky);
SASSERT(m_bv_util.get_bv_size(res_sig) == sbits + 4);
expr * res_or_args[2] = { m_bv_util.mk_extract(2*sbits-1, sbits-4, sig_abs), sticky };
res_sig = m_bv_util.mk_bv_or(2, res_or_args);
SASSERT(m_bv_util.get_bv_size(res_sig) == sbits+4);
expr_ref is_zero_sig(m), nil_sbits4(m); expr_ref is_zero_sig(m), nil_sbits4(m);
nil_sbits4 = m_bv_util.mk_numeral(0, sbits+4); nil_sbits4 = m_bv_util.mk_numeral(0, sbits+4);
@ -2211,13 +2225,13 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
SASSERT(sz == 3); SASSERT(sz == 3);
BV_RM_VAL bv_rm = (BV_RM_VAL)tmp_rat.get_unsigned(); BV_RM_VAL bv_rm = (BV_RM_VAL)tmp_rat.get_unsigned();
mpf_rounding_mode rm; mpf_rounding_mode mrm;
switch (bv_rm) { switch (bv_rm) {
case BV_RM_TIES_TO_AWAY: rm = MPF_ROUND_NEAREST_TAWAY; break; case BV_RM_TIES_TO_AWAY: mrm = MPF_ROUND_NEAREST_TAWAY; break;
case BV_RM_TIES_TO_EVEN: rm = MPF_ROUND_NEAREST_TEVEN; break; case BV_RM_TIES_TO_EVEN: mrm = MPF_ROUND_NEAREST_TEVEN; break;
case BV_RM_TO_NEGATIVE: rm = MPF_ROUND_TOWARD_NEGATIVE; break; case BV_RM_TO_NEGATIVE: mrm = MPF_ROUND_TOWARD_NEGATIVE; break;
case BV_RM_TO_POSITIVE: rm = MPF_ROUND_TOWARD_POSITIVE; break; case BV_RM_TO_POSITIVE: mrm = MPF_ROUND_TOWARD_POSITIVE; break;
case BV_RM_TO_ZERO: rm = MPF_ROUND_TOWARD_ZERO; break; case BV_RM_TO_ZERO: mrm = MPF_ROUND_TOWARD_ZERO; break;
default: UNREACHABLE(); default: UNREACHABLE();
} }
@ -2229,17 +2243,15 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
return mk_pzero(f, result); return mk_pzero(f, result);
else { else {
scoped_mpf v(m_mpf_manager); scoped_mpf v(m_mpf_manager);
m_util.fm().set(v, ebits, sbits, rm, q.to_mpq()); m_util.fm().set(v, ebits, sbits, mrm, q.to_mpq());
expr_ref sgn(m), sig(m), exp(m), unbiased_exp(m);
expr_ref sgn(m), s(m), e(m), unbiased_exp(m);
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1); sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v)) ? 1 : 0, 1);
s = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits - 1); sig = m_bv_util.mk_numeral(m_util.fm().sig(v), sbits - 1);
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v), ebits); unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v), ebits);
mk_bias(unbiased_exp, e); mk_bias(unbiased_exp, exp);
mk_fp(sgn, e, s, result); mk_fp(sgn, exp, sig, result);
} }
} }
else if (m_util.au().is_numeral(x)) { else if (m_util.au().is_numeral(x)) {
@ -2267,37 +2279,37 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
expr_ref v1(m), v2(m), v3(m), v4(m); expr_ref v1(m), v2(m), v3(m), v4(m);
expr_ref sgn(m), s(m), e(m), unbiased_exp(m); expr_ref sgn(m), sig(m), exp(m), unbiased_exp(m);
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_nta)) ? 1 : 0, 1); sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_nta)) ? 1 : 0, 1);
s = m_bv_util.mk_numeral(m_util.fm().sig(v_nta), sbits - 1); sig = m_bv_util.mk_numeral(m_util.fm().sig(v_nta), sbits - 1);
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_nta), ebits); unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_nta), ebits);
mk_bias(unbiased_exp, e); mk_bias(unbiased_exp, exp);
mk_fp(sgn, e, s, v1); mk_fp(sgn, exp, sig, v1);
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_nte)) ? 1 : 0, 1); sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_nte)) ? 1 : 0, 1);
s = m_bv_util.mk_numeral(m_util.fm().sig(v_nte), sbits - 1); sig = m_bv_util.mk_numeral(m_util.fm().sig(v_nte), sbits - 1);
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_nte), ebits); unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_nte), ebits);
mk_bias(unbiased_exp, e); mk_bias(unbiased_exp, exp);
mk_fp(sgn, e, s, v2); mk_fp(sgn, exp, sig, v2);
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tp)) ? 1 : 0, 1); sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tp)) ? 1 : 0, 1);
s = m_bv_util.mk_numeral(m_util.fm().sig(v_tp), sbits - 1); sig = m_bv_util.mk_numeral(m_util.fm().sig(v_tp), sbits - 1);
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tp), ebits); unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tp), ebits);
mk_bias(unbiased_exp, e); mk_bias(unbiased_exp, exp);
mk_fp(sgn, e, s, v3); mk_fp(sgn, exp, sig, v3);
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tn)) ? 1 : 0, 1); sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tn)) ? 1 : 0, 1);
s = m_bv_util.mk_numeral(m_util.fm().sig(v_tn), sbits - 1); sig = m_bv_util.mk_numeral(m_util.fm().sig(v_tn), sbits - 1);
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tn), ebits); unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tn), ebits);
mk_bias(unbiased_exp, e); mk_bias(unbiased_exp, exp);
mk_fp(sgn, e, s, v4); mk_fp(sgn, exp, sig, v4);
sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tp)) ? 1 : 0, 1); sgn = m_bv_util.mk_numeral((m_util.fm().sgn(v_tp)) ? 1 : 0, 1);
s = m_bv_util.mk_numeral(m_util.fm().sig(v_tp), sbits - 1); sig = m_bv_util.mk_numeral(m_util.fm().sig(v_tp), sbits - 1);
unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tp), ebits); unbiased_exp = m_bv_util.mk_numeral(m_util.fm().exp(v_tp), ebits);
mk_bias(unbiased_exp, e); mk_bias(unbiased_exp, exp);
mk_fp(sgn, e, s, result); mk_fp(sgn, exp, sig, result);
mk_ite(rm_tn, v4, result, result); mk_ite(rm_tn, v4, result, result);
mk_ite(rm_tp, v3, result, result); mk_ite(rm_tp, v3, result, result);
mk_ite(rm_nte, v2, result, result); mk_ite(rm_nte, v2, result, result);
@ -2305,6 +2317,7 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
} }
} }
else { else {
SASSERT(!m_arith_util.is_numeral(x));
bv_util & bu = m_bv_util; bv_util & bu = m_bv_util;
arith_util & au = m_arith_util; arith_util & au = m_arith_util;
@ -2322,10 +2335,6 @@ void fpa2bv_converter::mk_to_fp_real(func_decl * f, sort * s, expr * rm, expr *
expr_ref rme(rm, m); expr_ref rme(rm, m);
round(s, rme, sgn, sig, exp, result); round(s, rme, sgn, sig, exp, result);
expr_ref c0(m);
mk_is_zero(x, c0);
mk_ite(c0, x, result, result);
expr * e = m.mk_eq(m_util.mk_to_real(result), x); expr * e = m.mk_eq(m_util.mk_to_real(result), x);
m_extra_assertions.push_back(e); m_extra_assertions.push_back(e);
} }
@ -2952,7 +2961,6 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg
SASSERT(m_bv_util.get_bv_size(shift_neg) == ebits + 2); SASSERT(m_bv_util.get_bv_size(shift_neg) == ebits + 2);
SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits + 2); SASSERT(m_bv_util.get_bv_size(shift_abs) == ebits + 2);
dbg_decouple("fpa2bv_to_sbv_shift", shift); dbg_decouple("fpa2bv_to_sbv_shift", shift);
dbg_decouple("fpa2bv_to_sbv_shift_abs", shift_abs);
// sig is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long // sig is of the form +- [1].[sig][r][g][s] ... and at least bv_sz + 3 long
// [1][ ... sig ... ][r][g][ ... s ...] // [1][ ... sig ... ][r][g][ ... s ...]
@ -2961,34 +2969,48 @@ void fpa2bv_converter::mk_to_sbv(func_decl * f, unsigned num, expr * const * arg
max_shift = m_bv_util.mk_numeral(sig_sz, sig_sz); max_shift = m_bv_util.mk_numeral(sig_sz, sig_sz);
shift_abs = m_bv_util.mk_zero_extend(sig_sz - ebits - 2, shift_abs); shift_abs = m_bv_util.mk_zero_extend(sig_sz - ebits - 2, shift_abs);
SASSERT(m_bv_util.get_bv_size(shift_abs) == sig_sz); SASSERT(m_bv_util.get_bv_size(shift_abs) == sig_sz);
dbg_decouple("fpa2bv_to_sbv_shift_abs", shift_abs);
expr_ref c_in_limits(m); expr_ref c_in_limits(m);
c_in_limits = m_bv_util.mk_sle(shift, m_bv_util.mk_numeral(0, ebits + 2)); c_in_limits = m_bv_util.mk_sle(shift, m_bv_util.mk_numeral(0, ebits + 2));
dbg_decouple("fpa2bv_to_sbv_in_limits", c_in_limits); dbg_decouple("fpa2bv_to_sbv_in_limits", c_in_limits);
expr_ref shifted_sig(m); expr_ref huge_sig(m), huge_shift(m), huge_shifted_sig(m);
shifted_sig = m_bv_util.mk_bv_lshr(sig, shift_abs); huge_sig = m_bv_util.mk_concat(sig, m_bv_util.mk_numeral(0, sig_sz));
dbg_decouple("fpa2bv_to_sbv_shifted_sig", shifted_sig); huge_shift = m_bv_util.mk_concat(m_bv_util.mk_numeral(0, sig_sz), shift_abs);
huge_shifted_sig = m_bv_util.mk_bv_lshr(huge_sig, huge_shift);
dbg_decouple("fpa2bv_to_sbv_huge_shifted_sig", huge_shifted_sig);
SASSERT(m_bv_util.get_bv_size(huge_shifted_sig) == 2 * sig_sz);
expr_ref upper_hss(m), lower_hss(m);
upper_hss = m_bv_util.mk_extract(2 * sig_sz - 1, sig_sz + 1, huge_shifted_sig);
lower_hss = m_bv_util.mk_extract(sig_sz, 0, huge_shifted_sig);
SASSERT(m_bv_util.get_bv_size(upper_hss) == sig_sz - 1);
SASSERT(m_bv_util.get_bv_size(lower_hss) == sig_sz + 1);
dbg_decouple("fpa2bv_to_sbv_upper_hss", upper_hss);
dbg_decouple("fpa2bv_to_sbv_lower_hss", lower_hss);
expr_ref last(m), round(m), sticky(m); expr_ref last(m), round(m), sticky(m);
last = m_bv_util.mk_extract(sig_sz - bv_sz - 0, sig_sz - bv_sz - 0, shifted_sig); last = m_bv_util.mk_extract(1, 1, upper_hss);
round = m_bv_util.mk_extract(sig_sz - bv_sz - 1, sig_sz - bv_sz - 1, shifted_sig); round = m_bv_util.mk_extract(0, 0, upper_hss);
sticky = m.mk_ite(m.mk_eq(m_bv_util.mk_extract(sig_sz - bv_sz - 2, 0, shifted_sig), sticky = m.mk_app(m_bv_util.get_fid(), OP_BREDOR, lower_hss.get());
m_bv_util.mk_numeral(0, sig_sz - (bv_sz + 3) + 2)),
bv0,
bv1);
dbg_decouple("fpa2bv_to_sbv_last", last); dbg_decouple("fpa2bv_to_sbv_last", last);
dbg_decouple("fpa2bv_to_sbv_round", round); dbg_decouple("fpa2bv_to_sbv_round", round);
dbg_decouple("fpa2bv_to_sbv_sticky", sticky); dbg_decouple("fpa2bv_to_sbv_sticky", sticky);
expr_ref upper_hss_w_sticky(m);
upper_hss_w_sticky = m_bv_util.mk_concat(upper_hss, sticky);
dbg_decouple("fpa2bv_to_sbv_upper_hss_w_sticky", upper_hss_w_sticky);
SASSERT(m_bv_util.get_bv_size(upper_hss_w_sticky) == sig_sz);
expr_ref rounding_decision(m); expr_ref rounding_decision(m);
rounding_decision = mk_rounding_decision(rm, sgn, last, round, sticky); rounding_decision = mk_rounding_decision(rm, sgn, last, round, sticky);
SASSERT(m_bv_util.get_bv_size(rounding_decision) == 1); SASSERT(m_bv_util.get_bv_size(rounding_decision) == 1);
dbg_decouple("fpa2bv_to_sbv_rounding_decision", rounding_decision); dbg_decouple("fpa2bv_to_sbv_rounding_decision", rounding_decision);
expr_ref unrounded_sig(m), pre_rounded(m), inc(m); expr_ref unrounded_sig(m), pre_rounded(m), inc(m);
unrounded_sig = m_bv_util.mk_zero_extend(1, m_bv_util.mk_extract(sig_sz - 1, sig_sz - bv_sz, shifted_sig)); unrounded_sig = m_bv_util.mk_extract(sig_sz - 1, sig_sz - bv_sz - 1, upper_hss_w_sticky);
inc = m_bv_util.mk_zero_extend(1, m_bv_util.mk_zero_extend(bv_sz - 1, rounding_decision)); inc = m_bv_util.mk_zero_extend(bv_sz, rounding_decision);
pre_rounded = m_bv_util.mk_bv_add(unrounded_sig, inc); pre_rounded = m_bv_util.mk_bv_add(unrounded_sig, inc);
dbg_decouple("fpa2bv_to_sbv_inc", inc); dbg_decouple("fpa2bv_to_sbv_inc", inc);
dbg_decouple("fpa2bv_to_sbv_unrounded_sig", unrounded_sig); dbg_decouple("fpa2bv_to_sbv_unrounded_sig", unrounded_sig);
@ -3345,7 +3367,7 @@ void fpa2bv_converter::unpack(expr * e, expr_ref & sgn, expr_ref & sig, expr_ref
// the maximum shift is `sbits', because after that the mantissa // the maximum shift is `sbits', because after that the mantissa
// would be zero anyways. So we can safely cut the shift variable down, // would be zero anyways. So we can safely cut the shift variable down,
// as long as we check the higher bits. // as long as we check the higher bits.
expr_ref sh(m), is_sh_zero(m), sl(m), zero_s(m), sbits_s(m), short_shift(m); expr_ref sh(m), is_sh_zero(m), sl(m), sbits_s(m), short_shift(m);
zero_s = m_bv_util.mk_numeral(0, sbits-1); zero_s = m_bv_util.mk_numeral(0, sbits-1);
sbits_s = m_bv_util.mk_numeral(sbits, sbits); sbits_s = m_bv_util.mk_numeral(sbits, sbits);
sh = m_bv_util.mk_extract(ebits-1, sbits, shift); sh = m_bv_util.mk_extract(ebits-1, sbits, shift);
@ -3406,6 +3428,17 @@ void fpa2bv_converter::dbg_decouple(const char * prefix, expr_ref & e) {
} }
expr_ref fpa2bv_converter::mk_rounding_decision(expr * rm, expr * sgn, expr * last, expr * round, expr * sticky) { expr_ref fpa2bv_converter::mk_rounding_decision(expr * rm, expr * sgn, expr * last, expr * round, expr * sticky) {
expr_ref rmr(rm, m);
expr_ref sgnr(sgn, m);
expr_ref lastr(last, m);
expr_ref roundr(round, m);
expr_ref stickyr(sticky, m);
dbg_decouple("fpa2bv_rnd_dec_rm", rmr);
dbg_decouple("fpa2bv_rnd_dec_sgn", sgnr);
dbg_decouple("fpa2bv_rnd_dec_last", lastr);
dbg_decouple("fpa2bv_rnd_dec_round", roundr);
dbg_decouple("fpa2bv_rnd_dec_sticky", stickyr);
expr_ref last_or_sticky(m), round_or_sticky(m), not_last(m), not_round(m), not_sticky(m), not_lors(m), not_rors(m), not_sgn(m); expr_ref last_or_sticky(m), round_or_sticky(m), not_last(m), not_round(m), not_sticky(m), not_lors(m), not_rors(m), not_sgn(m);
expr * last_sticky[2] = { last, sticky }; expr * last_sticky[2] = { last, sticky };
expr * round_sticky[2] = { round, sticky }; expr * round_sticky[2] = { round, sticky };
@ -3443,6 +3476,7 @@ expr_ref fpa2bv_converter::mk_rounding_decision(expr * rm, expr * sgn, expr * la
m_simp.mk_ite(rm_is_away, inc_taway, inc_c3, inc_c2); m_simp.mk_ite(rm_is_away, inc_taway, inc_c3, inc_c2);
m_simp.mk_ite(rm_is_even, inc_teven, inc_c2, res); m_simp.mk_ite(rm_is_even, inc_teven, inc_c2, res);
dbg_decouple("fpa2bv_rnd_dec_res", res);
return res; return res;
} }

View file

@ -145,24 +145,24 @@ class func_decl_dependencies::top_sort {
return false; return false;
m_todo.push_back(f); m_todo.push_back(f);
while (!m_todo.empty()) { while (!m_todo.empty()) {
func_decl * f = m_todo.back(); func_decl * cf = m_todo.back();
switch (get_color(f)) { switch (get_color(cf)) {
case CLOSED: case CLOSED:
m_todo.pop_back(); m_todo.pop_back();
break; break;
case OPEN: case OPEN:
set_color(f, IN_PROGRESS); set_color(cf, IN_PROGRESS);
if (visit_children(f)) { if (visit_children(cf)) {
SASSERT(m_todo.back() == f); SASSERT(m_todo.back() == cf);
m_todo.pop_back(); m_todo.pop_back();
set_color(f, CLOSED); set_color(cf, CLOSED);
} }
break; break;
case IN_PROGRESS: case IN_PROGRESS:
if (all_children_closed(f)) { if (all_children_closed(cf)) {
SASSERT(m_todo.back() == f); SASSERT(m_todo.back() == cf);
set_color(f, CLOSED); set_color(cf, CLOSED);
} else { } else {
m_todo.reset(); m_todo.reset();
return true; return true;

View file

@ -464,18 +464,18 @@ void bit_blaster_tpl<Cfg>::mk_udiv_urem(unsigned sz, expr * const * a_bits, expr
// update p // update p
if (i < sz - 1) { if (i < sz - 1) {
for (unsigned j = sz - 1; j > 0; j--) { for (unsigned j = sz - 1; j > 0; j--) {
expr_ref i(m()); expr_ref ie(m());
mk_ite(q, t.get(j-1), p.get(j-1), i); mk_ite(q, t.get(j-1), p.get(j-1), ie);
p.set(j, i); p.set(j, ie);
} }
p.set(0, a_bits[sz - i - 2]); p.set(0, a_bits[sz - i - 2]);
} }
else { else {
// last step: p contains the remainder // last step: p contains the remainder
for (unsigned j = 0; j < sz; j++) { for (unsigned j = 0; j < sz; j++) {
expr_ref i(m()); expr_ref ie(m());
mk_ite(q, t.get(j), p.get(j), i); mk_ite(q, t.get(j), p.get(j), ie);
p.set(j, i); p.set(j, ie);
} }
} }
} }

View file

@ -143,9 +143,9 @@ br_status fpa_rewriter::mk_to_sbv_unspecified(func_decl * f, expr_ref & result)
br_status fpa_rewriter::mk_to_real_unspecified(expr_ref & result) { br_status fpa_rewriter::mk_to_real_unspecified(expr_ref & result) {
if (m_hi_fp_unspecified) if (m_hi_fp_unspecified)
result = m_util.au().mk_numeral(0, false);
else
// The "hardware interpretation" is 0. // The "hardware interpretation" is 0.
result = m_util.au().mk_numeral(rational(0), false);
else
result = m_util.mk_internal_to_real_unspecified(); result = m_util.mk_internal_to_real_unspecified();
return BR_DONE; return BR_DONE;
@ -420,11 +420,15 @@ br_status fpa_rewriter::mk_min(expr * arg1, expr * arg2, expr_ref & result) {
arg2, arg2,
m().mk_ite(mk_eq_nan(arg2), m().mk_ite(mk_eq_nan(arg2),
arg1, arg1,
// min(-0.0, +0.0) = min(+0.0, -0.0) = +0.0
m().mk_ite(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2),
m().mk_not(m().mk_eq(m_util.mk_is_positive(arg1), m_util.mk_is_positive(arg2)))),
m_util.mk_pzero(m().get_sort(arg1)),
m().mk_ite(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)), m().mk_ite(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)),
arg2, arg2,
m().mk_ite(m_util.mk_lt(arg1, arg2), m().mk_ite(m_util.mk_lt(arg1, arg2),
arg1, arg1,
arg2)))); arg2)))));
return BR_REWRITE_FULL; return BR_REWRITE_FULL;
} }
@ -446,11 +450,15 @@ br_status fpa_rewriter::mk_max(expr * arg1, expr * arg2, expr_ref & result) {
arg2, arg2,
m().mk_ite(mk_eq_nan(arg2), m().mk_ite(mk_eq_nan(arg2),
arg1, arg1,
// max(-0.0, +0.0) = max(+0.0, -0.0) = +0.0
m().mk_ite(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2),
m().mk_not(m().mk_eq(m_util.mk_is_positive(arg1), m_util.mk_is_positive(arg2)))),
m_util.mk_pzero(m().get_sort(arg1)),
m().mk_ite(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)), m().mk_ite(m().mk_and(m_util.mk_is_zero(arg1), m_util.mk_is_zero(arg2)),
arg2, arg2,
m().mk_ite(m_util.mk_gt(arg1, arg2), m().mk_ite(m_util.mk_gt(arg1, arg2),
arg1, arg1,
arg2)))); arg2)))));
return BR_REWRITE_FULL; return BR_REWRITE_FULL;
} }
@ -583,6 +591,7 @@ br_status fpa_rewriter::mk_ge(expr * arg1, expr * arg2, expr_ref & result) {
br_status fpa_rewriter::mk_is_zero(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_zero(expr * arg1, expr_ref & result) {
scoped_mpf v(m_fm); scoped_mpf v(m_fm);
if (m_util.is_numeral(arg1, v)) { if (m_util.is_numeral(arg1, v)) {
result = (m_fm.is_zero(v)) ? m().mk_true() : m().mk_false(); result = (m_fm.is_zero(v)) ? m().mk_true() : m().mk_false();
return BR_DONE; return BR_DONE;
@ -593,6 +602,7 @@ br_status fpa_rewriter::mk_is_zero(expr * arg1, expr_ref & result) {
br_status fpa_rewriter::mk_is_nzero(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_nzero(expr * arg1, expr_ref & result) {
scoped_mpf v(m_fm); scoped_mpf v(m_fm);
if (m_util.is_numeral(arg1, v)) { if (m_util.is_numeral(arg1, v)) {
result = (m_fm.is_nzero(v)) ? m().mk_true() : m().mk_false(); result = (m_fm.is_nzero(v)) ? m().mk_true() : m().mk_false();
return BR_DONE; return BR_DONE;
@ -603,6 +613,7 @@ br_status fpa_rewriter::mk_is_nzero(expr * arg1, expr_ref & result) {
br_status fpa_rewriter::mk_is_pzero(expr * arg1, expr_ref & result) { br_status fpa_rewriter::mk_is_pzero(expr * arg1, expr_ref & result) {
scoped_mpf v(m_fm); scoped_mpf v(m_fm);
if (m_util.is_numeral(arg1, v)) { if (m_util.is_numeral(arg1, v)) {
result = (m_fm.is_pzero(v)) ? m().mk_true() : m().mk_false(); result = (m_fm.is_pzero(v)) ? m().mk_true() : m().mk_false();
return BR_DONE; return BR_DONE;

View file

@ -324,7 +324,7 @@ void rewriter_tpl<Config>::process_app(app * t, frame & fr) {
} }
result_stack().push_back(def); result_stack().push_back(def);
TRACE("get_macro", tout << "bindings:\n"; TRACE("get_macro", tout << "bindings:\n";
for (unsigned i = 0; i < m_bindings.size(); i++) tout << i << ": " << mk_ismt2_pp(m_bindings[i], m()) << "\n";); for (unsigned j = 0; j < m_bindings.size(); j++) tout << j << ": " << mk_ismt2_pp(m_bindings[j], m()) << "\n";);
begin_scope(); begin_scope();
m_num_qvars = 0; m_num_qvars = 0;
m_root = def; m_root = def;

View file

@ -75,7 +75,7 @@ public:
iterator end_shared() const { return m_shared.end(); } iterator end_shared() const { return m_shared.end(); }
void reset(); void reset();
void cleanup(); void cleanup();
void display(std::ostream & out, ast_manager & m) const; void display(std::ostream & out, ast_manager & mgr) const;
}; };
#endif #endif

View file

@ -40,6 +40,7 @@ Notes:
#include"for_each_expr.h" #include"for_each_expr.h"
#include"scoped_timer.h" #include"scoped_timer.h"
#include"interpolant_cmds.h" #include"interpolant_cmds.h"
#include"model_smt2_pp.h"
func_decls::func_decls(ast_manager & m, func_decl * f): func_decls::func_decls(ast_manager & m, func_decl * f):
m_decls(TAG(func_decl*, f, 0)) { m_decls(TAG(func_decl*, f, 0)) {
@ -528,6 +529,7 @@ bool cmd_context::logic_has_arith_core(symbol const & s) const {
s == "LRA" || s == "LRA" ||
s == "QF_FP" || s == "QF_FP" ||
s == "QF_FPBV" || s == "QF_FPBV" ||
s == "QF_BVFP" ||
s == "HORN"; s == "HORN";
} }
@ -547,6 +549,7 @@ bool cmd_context::logic_has_bv_core(symbol const & s) const {
s == "QF_AUFBV" || s == "QF_AUFBV" ||
s == "QF_BVRE" || s == "QF_BVRE" ||
s == "QF_FPBV" || s == "QF_FPBV" ||
s == "QF_BVFP" ||
s == "HORN"; s == "HORN";
} }
@ -1402,6 +1405,15 @@ void cmd_context::check_sat(unsigned num_assumptions, expr * const * assumptions
was_pareto = true; was_pareto = true;
get_opt()->display_assignment(regular_stream()); get_opt()->display_assignment(regular_stream());
regular_stream() << "\n"; regular_stream() << "\n";
if (get_opt()->print_model()) {
model_ref mdl;
get_opt()->get_model(mdl);
if (mdl) {
regular_stream() << "(model " << std::endl;
model_smt2_pp(regular_stream(), *this, *(mdl.get()), 2);
regular_stream() << ")" << std::endl;
}
}
r = get_opt()->optimize(); r = get_opt()->optimize();
} }
} }

View file

@ -124,6 +124,7 @@ public:
virtual void display_assignment(std::ostream& out) = 0; virtual void display_assignment(std::ostream& out) = 0;
virtual bool is_pareto() = 0; virtual bool is_pareto() = 0;
virtual void set_logic(symbol const& s) = 0; virtual void set_logic(symbol const& s) = 0;
virtual bool print_model() const = 0;
}; };
class cmd_context : public progress_callback, public tactic_manager, public ast_printer_context { class cmd_context : public progress_callback, public tactic_manager, public ast_printer_context {

View file

@ -616,6 +616,30 @@ void iz3mgr::get_assign_bounds_coeffs(const ast &proof, std::vector<rational>& r
extract_lcd(rats); extract_lcd(rats);
} }
void iz3mgr::get_gomory_cut_coeffs(const ast &proof, std::vector<ast>& coeffs){
std::vector<rational> rats;
get_gomory_cut_coeffs(proof,rats);
coeffs.resize(rats.size());
for(unsigned i = 0; i < rats.size(); i++){
coeffs[i] = make_int(rats[i]);
}
}
void iz3mgr::get_gomory_cut_coeffs(const ast &proof, std::vector<rational>& rats){
symb s = sym(proof);
int numps = s->get_num_parameters();
rats.resize(numps-2);
for(int i = 2; i < numps; i++){
rational r;
bool ok = s->get_parameter(i).is_rational(r);
if(!ok)
throw "Bad Farkas coefficient";
rats[i-2] = r;
}
abs_rat(rats);
extract_lcd(rats);
}
void iz3mgr::get_assign_bounds_rule_coeffs(const ast &proof, std::vector<ast>& coeffs){ void iz3mgr::get_assign_bounds_rule_coeffs(const ast &proof, std::vector<ast>& coeffs){
std::vector<rational> rats; std::vector<rational> rats;
get_assign_bounds_rule_coeffs(proof,rats); get_assign_bounds_rule_coeffs(proof,rats);

View file

@ -396,7 +396,7 @@ class iz3mgr {
return UnknownTheory; return UnknownTheory;
} }
enum lemma_kind {FarkasKind,Leq2EqKind,Eq2LeqKind,GCDTestKind,AssignBoundsKind,EqPropagateKind,ArithMysteryKind,UnknownKind}; enum lemma_kind {FarkasKind,Leq2EqKind,Eq2LeqKind,GCDTestKind,AssignBoundsKind,EqPropagateKind,GomoryCutKind,ArithMysteryKind,UnknownKind};
lemma_kind get_theory_lemma_kind(const ast &proof){ lemma_kind get_theory_lemma_kind(const ast &proof){
symb s = sym(proof); symb s = sym(proof);
@ -417,6 +417,8 @@ class iz3mgr {
return AssignBoundsKind; return AssignBoundsKind;
if(foo == "eq-propagate") if(foo == "eq-propagate")
return EqPropagateKind; return EqPropagateKind;
if(foo == "gomory-cut")
return GomoryCutKind;
return UnknownKind; return UnknownKind;
} }
@ -434,6 +436,10 @@ class iz3mgr {
void get_assign_bounds_rule_coeffs(const ast &proof, std::vector<ast>& rats); void get_assign_bounds_rule_coeffs(const ast &proof, std::vector<ast>& rats);
void get_gomory_cut_coeffs(const ast &proof, std::vector<rational>& rats);
void get_gomory_cut_coeffs(const ast &proof, std::vector<ast>& rats);
bool is_farkas_coefficient_negative(const ast &proof, int n); bool is_farkas_coefficient_negative(const ast &proof, int n);
bool is_true(ast t){ bool is_true(ast t){

View file

@ -1182,6 +1182,31 @@ public:
return res; return res;
} }
ast GomoryCutRule2Farkas(const ast &proof, const ast &con, std::vector<Iproof::node> prems){
std::vector<Iproof::node> my_prems = prems;
std::vector<ast> my_coeffs;
std::vector<Iproof::node> my_prem_cons;
get_gomory_cut_coeffs(proof,my_coeffs);
int nargs = num_prems(proof);
if(nargs != (int)(my_coeffs.size()))
throw "bad gomory-cut theory lemma";
for(int i = 0; i < nargs; i++)
my_prem_cons.push_back(conc(prem(proof,i)));
ast my_con = normalize_inequality(sum_inequalities(my_coeffs,my_prem_cons));
Iproof::node hyp = iproof->make_hypothesis(mk_not(my_con));
my_prems.push_back(hyp);
my_coeffs.push_back(make_int("1"));
my_prem_cons.push_back(mk_not(my_con));
Iproof::node res = iproof->make_farkas(mk_false(),my_prems,my_prem_cons,my_coeffs);
ast t = arg(my_con,0);
ast c = arg(my_con,1);
ast d = gcd_of_coefficients(t);
t = z3_simplify(mk_idiv(t,d));
c = z3_simplify(mk_idiv(c,d));
ast cut_con = make(op(my_con),t,c);
return iproof->make_cut_rule(my_con,d,cut_con,res);
}
Iproof::node RewriteClause(Iproof::node clause, const ast &rew){ Iproof::node RewriteClause(Iproof::node clause, const ast &rew){
if(pr(rew) == PR_MONOTONICITY){ if(pr(rew) == PR_MONOTONICITY){
int nequivs = num_prems(rew); int nequivs = num_prems(rew);
@ -1912,6 +1937,13 @@ public:
res = AssignBounds2Farkas(proof,conc(proof)); res = AssignBounds2Farkas(proof,conc(proof));
break; break;
} }
case GomoryCutKind: {
if(args.size() > 0)
res = GomoryCutRule2Farkas(proof, conc(proof), args);
else
throw unsupported();
break;
}
case EqPropagateKind: { case EqPropagateKind: {
std::vector<ast> prems(nprems); std::vector<ast> prems(nprems);
for(unsigned i = 0; i < nprems; i++) for(unsigned i = 0; i < nprems; i++)

View file

@ -609,6 +609,7 @@ struct euclidean_solver::imp {
// neg coeffs... to make sure that m_next_x is -1 // neg coeffs... to make sure that m_next_x is -1
neg_coeffs(eq.m_as); neg_coeffs(eq.m_as);
neg_coeffs(eq.m_bs); neg_coeffs(eq.m_bs);
m().neg(eq.m_c);
} }
unsigned sz = eq.size(); unsigned sz = eq.size();
for (unsigned i = 0; i < sz; i++) { for (unsigned i = 0; i < sz; i++) {

View file

@ -4075,7 +4075,7 @@ namespace realclosure {
void refine_rational_interval(rational_value * v, unsigned prec) { void refine_rational_interval(rational_value * v, unsigned prec) {
mpbqi & i = interval(v); mpbqi & i = interval(v);
if (!i.lower_is_open() && !i.lower_is_open()) { if (!i.lower_is_open() && !i.upper_is_open()) {
SASSERT(bqm().eq(i.lower(), i.upper())); SASSERT(bqm().eq(i.lower(), i.upper()));
return; return;
} }

View file

@ -945,6 +945,10 @@ namespace datalog {
if (m_engine) { if (m_engine) {
m_engine->collect_statistics(st); m_engine->collect_statistics(st);
} }
unsigned long long max_mem = memory::get_max_used_memory();
unsigned long long mem = memory::get_allocation_size();
st.update("max memory", static_cast<double>(max_mem)/(1024.0*1024.0));
st.update("memory", static_cast<double>(mem)/(1024.0*1024.0));
} }

View file

@ -194,7 +194,6 @@ void rule_properties::operator()(app* n) {
} }
} }
else { else {
std::cout << mk_pp(n, m) << "\n";
} }
} }

View file

@ -85,7 +85,7 @@ namespace datalog {
removed_cols.size(), removed_cols.c_ptr(), result)); removed_cols.size(), removed_cols.c_ptr(), result));
} }
void compiler::make_select_equal_and_project(reg_idx src, const relation_element & val, unsigned col, void compiler::make_select_equal_and_project(reg_idx src, const relation_element val, unsigned col,
reg_idx & result, bool reuse, instruction_block & acc) { reg_idx & result, bool reuse, instruction_block & acc) {
relation_signature res_sig; relation_signature res_sig;
relation_signature::from_project(m_reg_signatures[src], 1, &col, res_sig); relation_signature::from_project(m_reg_signatures[src], 1, &col, res_sig);
@ -139,7 +139,7 @@ namespace datalog {
return r; return r;
} }
compiler::reg_idx compiler::get_single_column_register(const relation_sort & s) { compiler::reg_idx compiler::get_single_column_register(const relation_sort s) {
relation_signature singl_sig; relation_signature singl_sig;
singl_sig.push_back(s); singl_sig.push_back(s);
return get_fresh_register(singl_sig); return get_fresh_register(singl_sig);
@ -165,7 +165,7 @@ namespace datalog {
} }
} }
void compiler::make_add_constant_column(func_decl* head_pred, reg_idx src, const relation_sort & s, const relation_element & val, void compiler::make_add_constant_column(func_decl* head_pred, reg_idx src, const relation_sort s, const relation_element val,
reg_idx & result, bool & dealloc, instruction_block & acc) { reg_idx & result, bool & dealloc, instruction_block & acc) {
reg_idx singleton_table; reg_idx singleton_table;
if(!m_constant_registers.find(s, val, singleton_table)) { if(!m_constant_registers.find(s, val, singleton_table)) {
@ -185,7 +185,7 @@ namespace datalog {
} }
} }
void compiler::make_add_unbound_column(rule* compiled_rule, unsigned col_idx, func_decl* pred, reg_idx src, const relation_sort & s, reg_idx & result, void compiler::make_add_unbound_column(rule* compiled_rule, unsigned col_idx, func_decl* pred, reg_idx src, const relation_sort s, reg_idx & result,
bool & dealloc, instruction_block & acc) { bool & dealloc, instruction_block & acc) {
TRACE("dl", tout << "Adding unbound column " << mk_pp(pred, m_context.get_manager()) << "\n";); TRACE("dl", tout << "Adding unbound column " << mk_pp(pred, m_context.get_manager()) << "\n";);
@ -862,9 +862,11 @@ namespace datalog {
ast_manager& m = m_context.get_manager(); ast_manager& m = m_context.get_manager();
unsigned pt_len = r->get_positive_tail_size(); unsigned pt_len = r->get_positive_tail_size();
unsigned ut_len = r->get_uninterpreted_tail_size(); unsigned ut_len = r->get_uninterpreted_tail_size();
if (pt_len == ut_len) {
// no negated predicates
if (pt_len == ut_len)
return; return;
}
// populate negative variables: // populate negative variables:
for (unsigned i = pt_len; i < ut_len; ++i) { for (unsigned i = pt_len; i < ut_len; ++i) {
app * neg_tail = r->get_tail(i); app * neg_tail = r->get_tail(i);

View file

@ -135,7 +135,7 @@ namespace datalog {
reg_idx get_fresh_register(const relation_signature & sig); reg_idx get_fresh_register(const relation_signature & sig);
reg_idx get_register(const relation_signature & sig, bool reuse, reg_idx r); reg_idx get_register(const relation_signature & sig, bool reuse, reg_idx r);
reg_idx get_single_column_register(const relation_sort & s); reg_idx get_single_column_register(const relation_sort s);
/** /**
\brief Allocate registers for predicates in \c pred and add them into the \c regs map. \brief Allocate registers for predicates in \c pred and add them into the \c regs map.
@ -150,7 +150,7 @@ namespace datalog {
const unsigned_vector & removed_cols, reg_idx & result, bool reuse_t1, instruction_block & acc); const unsigned_vector & removed_cols, reg_idx & result, bool reuse_t1, instruction_block & acc);
void make_filter_interpreted_and_project(reg_idx src, app_ref & cond, void make_filter_interpreted_and_project(reg_idx src, app_ref & cond,
const unsigned_vector & removed_cols, reg_idx & result, bool reuse, instruction_block & acc); const unsigned_vector & removed_cols, reg_idx & result, bool reuse, instruction_block & acc);
void make_select_equal_and_project(reg_idx src, const relation_element & val, unsigned col, void make_select_equal_and_project(reg_idx src, const relation_element val, unsigned col,
reg_idx & result, bool reuse, instruction_block & acc); reg_idx & result, bool reuse, instruction_block & acc);
/** /**
\brief Create add an union or widen operation and put it into \c acc. \brief Create add an union or widen operation and put it into \c acc.
@ -174,10 +174,10 @@ namespace datalog {
void make_dealloc_non_void(reg_idx r, instruction_block & acc); void make_dealloc_non_void(reg_idx r, instruction_block & acc);
void make_add_constant_column(func_decl* pred, reg_idx src, const relation_sort & s, const relation_element & val, void make_add_constant_column(func_decl* pred, reg_idx src, const relation_sort s, const relation_element val,
reg_idx & result, bool & dealloc, instruction_block & acc); reg_idx & result, bool & dealloc, instruction_block & acc);
void make_add_unbound_column(rule* compiled_rule, unsigned col_idx, func_decl* pred, reg_idx src, const relation_sort & s, reg_idx & result, void make_add_unbound_column(rule* compiled_rule, unsigned col_idx, func_decl* pred, reg_idx src, const relation_sort s, reg_idx & result,
bool & dealloc, instruction_block & acc); bool & dealloc, instruction_block & acc);
void make_full_relation(func_decl* pred, const relation_signature & sig, reg_idx & result, void make_full_relation(func_decl* pred, const relation_signature & sig, reg_idx & result,
instruction_block & acc); instruction_block & acc);

View file

@ -108,7 +108,7 @@ namespace datalog {
void relation_manager::store_relation(func_decl * pred, relation_base * rel) { void relation_manager::store_relation(func_decl * pred, relation_base * rel) {
SASSERT(rel); SASSERT(rel);
relation_map::entry * e = m_relations.insert_if_not_there2(pred, 0); relation_map::obj_map_entry * e = m_relations.insert_if_not_there2(pred, 0);
if (e->get_data().m_value) { if (e->get_data().m_value) {
e->get_data().m_value->deallocate(); e->get_data().m_value->deallocate();
} }

View file

@ -73,7 +73,7 @@ namespace datalog {
typedef map<const relation_plugin *, finite_product_relation_plugin *, ptr_hash<const relation_plugin>, typedef map<const relation_plugin *, finite_product_relation_plugin *, ptr_hash<const relation_plugin>,
ptr_eq<const relation_plugin> > rp2fprp_map; ptr_eq<const relation_plugin> > rp2fprp_map;
typedef map<func_decl *, relation_base *, ptr_hash<func_decl>, ptr_eq<func_decl> > relation_map; typedef obj_map<func_decl, relation_base *> relation_map;
typedef ptr_vector<table_plugin> table_plugin_vector; typedef ptr_vector<table_plugin> table_plugin_vector;
typedef ptr_vector<relation_plugin> relation_plugin_vector; typedef ptr_vector<relation_plugin> relation_plugin_vector;

View file

@ -323,12 +323,8 @@ private:
void display_statistics(cmd_context& ctx) { void display_statistics(cmd_context& ctx) {
statistics stats; statistics stats;
unsigned long long max_mem = memory::get_max_used_memory();
unsigned long long mem = memory::get_allocation_size();
stats.update("time", ctx.get_seconds());
stats.update("memory", static_cast<double>(mem)/static_cast<double>(1024*1024));
stats.update("max memory", static_cast<double>(max_mem)/static_cast<double>(1024*1024));
get_opt(ctx).collect_statistics(stats); get_opt(ctx).collect_statistics(stats);
stats.update("time", ctx.get_seconds());
stats.display_smt2(ctx.regular_stream()); stats.display_smt2(ctx.regular_stream());
} }
}; };

View file

@ -31,6 +31,7 @@ Notes:
#include "propagate_values_tactic.h" #include "propagate_values_tactic.h"
#include "solve_eqs_tactic.h" #include "solve_eqs_tactic.h"
#include "elim_uncnstr_tactic.h" #include "elim_uncnstr_tactic.h"
#include "elim_term_ite_tactic.h"
#include "tactical.h" #include "tactical.h"
#include "model_smt2_pp.h" #include "model_smt2_pp.h"
#include "card2bv_tactic.h" #include "card2bv_tactic.h"
@ -254,6 +255,12 @@ namespace opt {
} }
} }
bool context::print_model() const {
opt_params optp(m_params);
return optp.print_model();
}
void context::get_base_model(model_ref& mdl) { void context::get_base_model(model_ref& mdl) {
mdl = m_model; mdl = m_model;
} }
@ -644,17 +651,19 @@ namespace opt {
and_then(mk_simplify_tactic(m), and_then(mk_simplify_tactic(m),
mk_propagate_values_tactic(m), mk_propagate_values_tactic(m),
mk_solve_eqs_tactic(m), mk_solve_eqs_tactic(m),
mk_elim_term_ite_tactic(m),
// NB: mk_elim_uncstr_tactic(m) is not sound with soft constraints // NB: mk_elim_uncstr_tactic(m) is not sound with soft constraints
mk_simplify_tactic(m)); mk_simplify_tactic(m));
opt_params optp(m_params); opt_params optp(m_params);
tactic_ref tac2, tac3; tactic_ref tac2, tac3, tac4;
if (optp.elim_01()) { if (optp.elim_01()) {
tac2 = mk_elim01_tactic(m); tac2 = mk_elim01_tactic(m);
tac3 = mk_lia2card_tactic(m); tac3 = mk_lia2card_tactic(m);
tac4 = mk_elim_term_ite_tactic(m);
params_ref lia_p; params_ref lia_p;
lia_p.set_bool("compile_equality", optp.pb_compile_equality()); lia_p.set_bool("compile_equality", optp.pb_compile_equality());
tac3->updt_params(lia_p); tac3->updt_params(lia_p);
set_simplify(and_then(tac0.get(), tac2.get(), tac3.get())); set_simplify(and_then(tac0.get(), tac2.get(), tac3.get(), tac4.get()));
} }
else { else {
set_simplify(tac0.get()); set_simplify(tac0.get());
@ -1179,6 +1188,10 @@ namespace opt {
for (; it != end; ++it) { for (; it != end; ++it) {
it->m_value->collect_statistics(stats); it->m_value->collect_statistics(stats);
} }
unsigned long long max_mem = memory::get_max_used_memory();
unsigned long long mem = memory::get_allocation_size();
stats.update("memory", static_cast<double>(mem)/static_cast<double>(1024*1024));
stats.update("max memory", static_cast<double>(max_mem)/static_cast<double>(1024*1024));
} }
void context::collect_param_descrs(param_descrs & r) { void context::collect_param_descrs(param_descrs & r) {

View file

@ -180,6 +180,7 @@ namespace opt {
virtual void cancel() { set_cancel(true); } virtual void cancel() { set_cancel(true); }
virtual void set_hard_constraints(ptr_vector<expr> & hard); virtual void set_hard_constraints(ptr_vector<expr> & hard);
virtual lbool optimize(); virtual lbool optimize();
virtual bool print_model() const;
virtual void get_model(model_ref& _m); virtual void get_model(model_ref& _m);
virtual void set_model(model_ref& _m); virtual void set_model(model_ref& _m);
virtual void fix_model(model_ref& _m); virtual void fix_model(model_ref& _m);

View file

@ -42,7 +42,7 @@ namespace opt {
m_context(mgr, m_params), m_context(mgr, m_params),
m(mgr), m(mgr),
m_fm(fm), m_fm(fm),
m_objective_sorts(m), m_objective_terms(m),
m_dump_benchmarks(false), m_dump_benchmarks(false),
m_first(true) { m_first(true) {
m_params.updt_params(p); m_params.updt_params(p);
@ -216,8 +216,10 @@ namespace opt {
decrement_value(i, val); decrement_value(i, val);
} }
m_objective_values[i] = val; m_objective_values[i] = val;
TRACE("opt", { tout << val << "\n"; TRACE("opt", {
tout << blocker << "\n"; tout << "objective: " << mk_pp(m_objective_terms[i].get(), m) << "\n";
tout << "maximal value: " << val << "\n";
tout << "new condition: " << blocker << "\n";
model_smt2_pp(tout << "update model:\n", m, *m_models[i], 0); }); model_smt2_pp(tout << "update model:\n", m, *m_models[i], 0); });
} }
@ -240,7 +242,7 @@ namespace opt {
TRACE("opt", tout << is_sat << "\n";); TRACE("opt", tout << is_sat << "\n";);
if (is_sat != l_true) { if (is_sat != l_true) {
// cop-out approximation // cop-out approximation
if (arith_util(m).is_real(m_objective_sorts[i].get())) { if (arith_util(m).is_real(m_objective_terms[i].get())) {
val -= inf_eps(inf_rational(rational(0), true)); val -= inf_eps(inf_rational(rational(0), true));
} }
else { else {
@ -304,7 +306,7 @@ namespace opt {
smt::theory_var v = get_optimizer().add_objective(term); smt::theory_var v = get_optimizer().add_objective(term);
m_objective_vars.push_back(v); m_objective_vars.push_back(v);
m_objective_values.push_back(inf_eps(rational(-1), inf_rational())); m_objective_values.push_back(inf_eps(rational(-1), inf_rational()));
m_objective_sorts.push_back(m.get_sort(term)); m_objective_terms.push_back(term);
m_valid_objectives.push_back(true); m_valid_objectives.push_back(true);
m_models.push_back(0); m_models.push_back(0);
return v; return v;
@ -363,7 +365,7 @@ namespace opt {
void opt_solver::reset_objectives() { void opt_solver::reset_objectives() {
m_objective_vars.reset(); m_objective_vars.reset();
m_objective_values.reset(); m_objective_values.reset();
m_objective_sorts.reset(); m_objective_terms.reset();
m_valid_objectives.reset(); m_valid_objectives.reset();
} }

View file

@ -76,7 +76,7 @@ namespace opt {
svector<smt::theory_var> m_objective_vars; svector<smt::theory_var> m_objective_vars;
vector<inf_eps> m_objective_values; vector<inf_eps> m_objective_values;
sref_vector<model> m_models; sref_vector<model> m_models;
sort_ref_vector m_objective_sorts; expr_ref_vector m_objective_terms;
svector<bool> m_valid_objectives; svector<bool> m_valid_objectives;
bool m_dump_benchmarks; bool m_dump_benchmarks;
static unsigned m_dump_count; static unsigned m_dump_count;

View file

@ -141,6 +141,7 @@ namespace opt {
ors.push_back(m_s->mk_ge(i, m_upper[i])); ors.push_back(m_s->mk_ge(i, m_upper[i]));
} }
fml = m.mk_or(ors.size(), ors.c_ptr()); fml = m.mk_or(ors.size(), ors.c_ptr());
tmp = m.mk_fresh_const("b", m.mk_bool_sort()); tmp = m.mk_fresh_const("b", m.mk_bool_sort());
fml = m.mk_implies(tmp, fml); fml = m.mk_implies(tmp, fml);
@ -150,6 +151,7 @@ namespace opt {
solver::scoped_push _push(*m_s); solver::scoped_push _push(*m_s);
while (!m_cancel) { while (!m_cancel) {
m_s->assert_expr(fml); m_s->assert_expr(fml);
TRACE("opt", tout << fml << "\n";);
is_sat = m_s->check_sat(1,vars); is_sat = m_s->check_sat(1,vars);
if (is_sat == l_true) { if (is_sat == l_true) {
disj.reset(); disj.reset();
@ -343,6 +345,7 @@ namespace opt {
m_lower[i] = m_s->saved_objective_value(i); m_lower[i] = m_s->saved_objective_value(i);
} }
} }
TRACE("opt", tout << "strengthen bound: " << block << "\n";);
m_s->assert_expr(block); m_s->assert_expr(block);
// TBD: only works for simplex // TBD: only works for simplex

View file

@ -163,6 +163,9 @@ void parse_cmd_line_args(int argc, char ** argv) {
else if (strcmp(opt_name, "smt2") == 0) { else if (strcmp(opt_name, "smt2") == 0) {
g_input_kind = IN_SMTLIB_2; g_input_kind = IN_SMTLIB_2;
} }
else if (strcmp(opt_name, "dl") == 0) {
g_input_kind = IN_DATALOG;
}
else if (strcmp(opt_name, "in") == 0) { else if (strcmp(opt_name, "in") == 0) {
g_standard_input = true; g_standard_input = true;
} }

View file

@ -1411,6 +1411,10 @@ namespace smt {
void context::mk_th_axiom(theory_id tid, unsigned num_lits, literal * lits, unsigned num_params, parameter * params) { void context::mk_th_axiom(theory_id tid, unsigned num_lits, literal * lits, unsigned num_params, parameter * params) {
justification * js = 0; justification * js = 0;
TRACE("mk_th_axiom",
display_literals_verbose(tout, num_lits, lits);
tout << "\n";);
if (m_manager.proofs_enabled()) { if (m_manager.proofs_enabled()) {
js = mk_justification(theory_axiom_justification(tid, m_region, num_lits, lits, num_params, params)); js = mk_justification(theory_axiom_justification(tid, m_region, num_lits, lits, num_params, params));
} }
@ -1425,13 +1429,11 @@ namespace smt {
void context::mk_th_axiom(theory_id tid, literal l1, literal l2, unsigned num_params, parameter * params) { void context::mk_th_axiom(theory_id tid, literal l1, literal l2, unsigned num_params, parameter * params) {
literal ls[2] = { l1, l2 }; literal ls[2] = { l1, l2 };
TRACE("mk_th_axiom", display_literal(tout, l1); tout << " "; display_literal(tout, l2); tout << "\n";);
mk_th_axiom(tid, 2, ls, num_params, params); mk_th_axiom(tid, 2, ls, num_params, params);
} }
void context::mk_th_axiom(theory_id tid, literal l1, literal l2, literal l3, unsigned num_params, parameter * params) { void context::mk_th_axiom(theory_id tid, literal l1, literal l2, literal l3, unsigned num_params, parameter * params) {
literal ls[3] = { l1, l2, l3 }; literal ls[3] = { l1, l2, l3 };
TRACE("mk_th_axiom", display_literal(tout, l1); tout << " "; display_literal(tout, l2); tout << " "; display_literal(tout, l3); tout << "\n";);
mk_th_axiom(tid, 3, ls, num_params, params); mk_th_axiom(tid, 3, ls, num_params, params);
} }

View file

@ -116,7 +116,7 @@ namespace smt {
setup_LRA(); setup_LRA();
else if (m_logic == "QF_FP") else if (m_logic == "QF_FP")
setup_QF_FP(); setup_QF_FP();
else if (m_logic == "QF_FPBV") else if (m_logic == "QF_FPBV" || m_logic == "QF_BVFP")
setup_QF_FPBV(); setup_QF_FPBV();
else else
setup_unknown(); setup_unknown();

View file

@ -245,6 +245,8 @@ namespace smt {
parameter* params(char const* name); parameter* params(char const* name);
}; };
class gomory_cut_justification;
class bound { class bound {
protected: protected:
theory_var m_var; theory_var m_var;

View file

@ -439,6 +439,7 @@ namespace smt {
j += rational(1); j += rational(1);
} }
ctx.mk_th_axiom(get_id(), lits.size(), lits.begin()); ctx.mk_th_axiom(get_id(), lits.size(), lits.begin());
#else #else
// performs slightly worse. // performs slightly worse.
literal_buffer lits; literal_buffer lits;

View file

@ -460,13 +460,16 @@ namespace smt {
SASSERT(is_well_sorted(get_manager(), result)); SASSERT(is_well_sorted(get_manager(), result));
} }
class gomory_cut_justification : public ext_theory_propagation_justification { template<typename Ext>
class theory_arith<Ext>::gomory_cut_justification : public ext_theory_propagation_justification {
public: public:
gomory_cut_justification(family_id fid, region & r, gomory_cut_justification(family_id fid, region & r,
unsigned num_lits, literal const * lits, unsigned num_lits, literal const * lits,
unsigned num_eqs, enode_pair const * eqs, unsigned num_eqs, enode_pair const * eqs,
antecedents& bounds,
literal consequent): literal consequent):
ext_theory_propagation_justification(fid, r, num_lits, lits, num_eqs, eqs, consequent) { ext_theory_propagation_justification(fid, r, num_lits, lits, num_eqs, eqs, consequent,
bounds.num_params(), bounds.params("gomory-cut")) {
} }
// Remark: the assignment must be propagated back to arith // Remark: the assignment must be propagated back to arith
virtual theory_id get_from_theory() const { return null_theory_id; } virtual theory_id get_from_theory() const { return null_theory_id; }
@ -530,7 +533,7 @@ namespace smt {
} }
// k += new_a_ij * lower_bound(x_j).get_rational(); // k += new_a_ij * lower_bound(x_j).get_rational();
k.addmul(new_a_ij, lower_bound(x_j).get_rational()); k.addmul(new_a_ij, lower_bound(x_j).get_rational());
lower(x_j)->push_justification(ante, numeral::zero(), coeffs_enabled()); lower(x_j)->push_justification(ante, new_a_ij, coeffs_enabled());
} }
else { else {
SASSERT(at_upper(x_j)); SASSERT(at_upper(x_j));
@ -546,7 +549,7 @@ namespace smt {
} }
// k += new_a_ij * upper_bound(x_j).get_rational(); // k += new_a_ij * upper_bound(x_j).get_rational();
k.addmul(new_a_ij, upper_bound(x_j).get_rational()); k.addmul(new_a_ij, upper_bound(x_j).get_rational());
upper(x_j)->push_justification(ante, numeral::zero(), coeffs_enabled()); upper(x_j)->push_justification(ante, new_a_ij, coeffs_enabled());
} }
pol.push_back(row_entry(new_a_ij, x_j)); pol.push_back(row_entry(new_a_ij, x_j));
} }
@ -571,7 +574,7 @@ namespace smt {
} }
// k += new_a_ij * lower_bound(x_j).get_rational(); // k += new_a_ij * lower_bound(x_j).get_rational();
k.addmul(new_a_ij, lower_bound(x_j).get_rational()); k.addmul(new_a_ij, lower_bound(x_j).get_rational());
lower(x_j)->push_justification(ante, numeral::zero(), coeffs_enabled()); lower(x_j)->push_justification(ante, new_a_ij, coeffs_enabled());
} }
else { else {
SASSERT(at_upper(x_j)); SASSERT(at_upper(x_j));
@ -584,7 +587,7 @@ namespace smt {
new_a_ij.neg(); // the upper terms are inverted new_a_ij.neg(); // the upper terms are inverted
// k += new_a_ij * upper_bound(x_j).get_rational(); // k += new_a_ij * upper_bound(x_j).get_rational();
k.addmul(new_a_ij, upper_bound(x_j).get_rational()); k.addmul(new_a_ij, upper_bound(x_j).get_rational());
upper(x_j)->push_justification(ante, numeral::zero(), coeffs_enabled()); upper(x_j)->push_justification(ante, new_a_ij, coeffs_enabled());
} }
TRACE("gomory_cut_detail", tout << "new_a_ij: " << new_a_ij << "\n";); TRACE("gomory_cut_detail", tout << "new_a_ij: " << new_a_ij << "\n";);
pol.push_back(row_entry(new_a_ij, x_j)); pol.push_back(row_entry(new_a_ij, x_j));
@ -600,7 +603,7 @@ namespace smt {
if (pol.empty()) { if (pol.empty()) {
SASSERT(k.is_pos()); SASSERT(k.is_pos());
// conflict 0 >= k where k is positive // conflict 0 >= k where k is positive
set_conflict(ante.lits().size(), ante.lits().c_ptr(), ante.eqs().size(), ante.eqs().c_ptr(), ante, true, "gomory_cut"); set_conflict(ante.lits().size(), ante.lits().c_ptr(), ante.eqs().size(), ante.eqs().c_ptr(), ante, true, "gomory-cut");
return true; return true;
} }
else if (pol.size() == 1) { else if (pol.size() == 1) {
@ -652,7 +655,7 @@ namespace smt {
gomory_cut_justification( gomory_cut_justification(
get_id(), ctx.get_region(), get_id(), ctx.get_region(),
ante.lits().size(), ante.lits().c_ptr(), ante.lits().size(), ante.lits().c_ptr(),
ante.eqs().size(), ante.eqs().c_ptr(), l))); ante.eqs().size(), ante.eqs().c_ptr(), ante, l)));
return true; return true;
} }
@ -1061,6 +1064,7 @@ namespace smt {
} }
if (!failed) { if (!failed) {
m_solver.assert_eq(as.size(), as.c_ptr(), xs.c_ptr(), c, j); m_solver.assert_eq(as.size(), as.c_ptr(), xs.c_ptr(), c, j);
TRACE("euclidean_solver", tout << "add definition: v" << v << " := " << mk_ismt2_pp(n, t.get_manager()) << "\n";);
} }
else { else {
TRACE("euclidean_solver", tout << "failed for:\n" << mk_ismt2_pp(n, t.get_manager()) << "\n";); TRACE("euclidean_solver", tout << "failed for:\n" << mk_ismt2_pp(n, t.get_manager()) << "\n";);
@ -1191,7 +1195,8 @@ namespace smt {
if (l != 0) { if (l != 0) {
rational l_old = l->get_value().get_rational().to_rational(); rational l_old = l->get_value().get_rational().to_rational();
rational l_new = g*ceil((l_old - c2)/g) + c2; rational l_new = g*ceil((l_old - c2)/g) + c2;
TRACE("euclidean_solver_new", tout << "new lower: " << l_new << " old: " << l_old << "\n";); TRACE("euclidean_solver_new", tout << "new lower: " << l_new << " old: " << l_old << "\n";
tout << "c: " << c2 << " ceil((l_old - c2)/g): " << (ceil((l_old - c2)/g)) << "\n";);
if (l_new > l_old) { if (l_new > l_old) {
propagated = true; propagated = true;
mk_lower(v, l_new, l, m_js); mk_lower(v, l_new, l, m_js);

View file

@ -208,6 +208,8 @@ namespace smt {
theory_array::reset_eh(); theory_array::reset_eh();
std::for_each(m_var_data_full.begin(), m_var_data_full.end(), delete_proc<var_data_full>()); std::for_each(m_var_data_full.begin(), m_var_data_full.end(), delete_proc<var_data_full>());
m_var_data_full.reset(); m_var_data_full.reset();
m_eqs.reset();
m_eqsv.reset();
} }
void theory_array_full::display_var(std::ostream & out, theory_var v) const { void theory_array_full::display_var(std::ostream & out, theory_var v) const {
@ -223,7 +225,6 @@ namespace smt {
} }
theory_var theory_array_full::mk_var(enode * n) { theory_var theory_array_full::mk_var(enode * n) {
theory_var r = theory_array::mk_var(n); theory_var r = theory_array::mk_var(n);
SASSERT(r == static_cast<int>(m_var_data_full.size())); SASSERT(r == static_cast<int>(m_var_data_full.size()));
m_var_data_full.push_back(alloc(var_data_full)); m_var_data_full.push_back(alloc(var_data_full));
@ -760,37 +761,36 @@ namespace smt {
r = FC_CONTINUE; r = FC_CONTINUE;
} }
} }
while (!m_eqsv.empty()) {
literal eq = m_eqsv.back();
m_eqsv.pop_back();
get_context().mark_as_relevant(eq);
assert_axiom(eq);
r = FC_CONTINUE;
}
if (r == FC_DONE && m_found_unsupported_op) if (r == FC_DONE && m_found_unsupported_op)
r = FC_GIVEUP; r = FC_GIVEUP;
return r; return r;
} }
bool theory_array_full::try_assign_eq(expr* v1, expr* v2) { bool theory_array_full::try_assign_eq(expr* v1, expr* v2) {
context& ctx = get_context();
enode* n1 = ctx.get_enode(v1);
enode* n2 = ctx.get_enode(v2);
if (n1->get_root() == n2->get_root()) {
return false;
}
TRACE("array", TRACE("array",
tout << mk_bounded_pp(v1, get_manager()) << "\n==\n" tout << mk_bounded_pp(v1, get_manager()) << "\n==\n"
<< mk_bounded_pp(v2, get_manager()) << "\n";); << mk_bounded_pp(v2, get_manager()) << "\n";);
context& ctx = get_context();
#if 0 if (m_eqs.contains(v1, v2)) {
if (m.proofs_enabled()) { return false;
#endif
literal eq(mk_eq(v1,v2,true));
ctx.mark_as_relevant(eq);
assert_axiom(eq);
#if 0
} }
else { else {
ctx.mark_as_relevant(n1); m_eqs.insert(v1, v2, true);
ctx.mark_as_relevant(n2); literal eq(mk_eq(v1, v2, true));
ctx.assign_eq(n1, n2, eq_justification::mk_axiom()); get_context().mark_as_relevant(eq);
assert_axiom(eq);
// m_eqsv.push_back(eq);
return true;
} }
#endif
return true;
} }
void theory_array_full::pop_scope_eh(unsigned num_scopes) { void theory_array_full::pop_scope_eh(unsigned num_scopes) {
@ -798,6 +798,8 @@ namespace smt {
theory_array::pop_scope_eh(num_scopes); theory_array::pop_scope_eh(num_scopes);
std::for_each(m_var_data_full.begin() + num_old_vars, m_var_data_full.end(), delete_proc<var_data_full>()); std::for_each(m_var_data_full.begin() + num_old_vars, m_var_data_full.end(), delete_proc<var_data_full>());
m_var_data_full.shrink(num_old_vars); m_var_data_full.shrink(num_old_vars);
m_eqs.reset();
m_eqsv.reset();
} }
void theory_array_full::collect_statistics(::statistics & st) const { void theory_array_full::collect_statistics(::statistics & st) const {

View file

@ -38,12 +38,12 @@ namespace smt {
ast2ast_trailmap<sort,app> m_sort2epsilon; ast2ast_trailmap<sort,app> m_sort2epsilon;
simplifier* m_simp; simplifier* m_simp;
obj_pair_map<expr,expr,bool> m_eqs;
svector<literal> m_eqsv;
protected: protected:
#if 0 //virtual final_check_status final_check_eh();
virtual final_check_status final_check_eh();
#endif
virtual void reset_eh(); virtual void reset_eh();
virtual void set_prop_upward(theory_var v); virtual void set_prop_upward(theory_var v);
@ -84,6 +84,7 @@ namespace smt {
bool try_assign_eq(expr* n1, expr* n2); bool try_assign_eq(expr* n1, expr* n2);
void assign_eqs();
public: public:

View file

@ -34,8 +34,8 @@ struct arith_bounds_tactic : public tactic {
bounds_arith_subsumption(in, result); bounds_arith_subsumption(in, result);
} }
virtual tactic* translate(ast_manager& m) { virtual tactic* translate(ast_manager & mgr) {
return alloc(arith_bounds_tactic, m); return alloc(arith_bounds_tactic, mgr);
} }
void checkpoint() { void checkpoint() {

View file

@ -488,7 +488,7 @@ public:
unsigned size = g->size(); unsigned size = g->size();
expr_ref new_f1(m), new_f2(m); expr_ref new_f1(m), new_f2(m);
proof_ref new_pr1(m), new_pr2(m); proof_ref new_pr1(m), new_pr2(m);
for (unsigned idx = 0; idx < size; idx++) { for (unsigned idx = 0; !g->inconsistent() && idx < g->size(); idx++) {
m_rw1(g->form(idx), new_f1, new_pr1); m_rw1(g->form(idx), new_f1, new_pr1);
TRACE("card2bv", tout << "Rewriting " << mk_ismt2_pp(new_f1.get(), m) << std::endl;); TRACE("card2bv", tout << "Rewriting " << mk_ismt2_pp(new_f1.get(), m) << std::endl;);
m_rw2.rewrite(new_f1, new_f2); m_rw2.rewrite(new_f1, new_f2);

View file

@ -147,7 +147,6 @@ class fpa2bv_approx_tactic: public tactic {
while (to_traverse.size() > 0) { while (to_traverse.size() > 0) {
cur = to_app(to_traverse.front()); cur = to_app(to_traverse.front());
mpf_rounding_mode rm;
#ifdef Z3DEBUG #ifdef Z3DEBUG
std::cout<<"Analyze - traversing: "<<mk_ismt2_pp(cur,m)<<std::endl; std::cout<<"Analyze - traversing: "<<mk_ismt2_pp(cur,m)<<std::endl;
std::cout.flush(); std::cout.flush();
@ -273,8 +272,12 @@ class fpa2bv_approx_tactic: public tactic {
expr_ref arg_e[] = { expr_ref(m), expr_ref(m), expr_ref(m), expr_ref(m) }; expr_ref arg_e[] = { expr_ref(m), expr_ref(m), expr_ref(m), expr_ref(m) };
unsigned i=0; unsigned i=0;
//Set rounding mode //Set rounding mode
if (rhs->get_num_args() > 0 && m_float_util.is_rm(rhs->get_arg(0))) if (rhs->get_num_args() > 0 && m_float_util.is_rm(rhs->get_arg(0))) {
expr_ref rm_val(m);
mdl->eval(rhs->get_arg(0), rm_val, true);
m_float_util.is_rm_numeral(rm_val, rm);
i = 1; i = 1;
}
//Collect argument values //Collect argument values
for (; i < rhs->get_num_args(); i++) { for (; i < rhs->get_num_args(); i++) {
expr * arg = rhs->get_arg(i); expr * arg = rhs->get_arg(i);
@ -373,6 +376,12 @@ class fpa2bv_approx_tactic: public tactic {
mpf_mngr.set(est_rhs_value, ebits, sbits, rm, est_arg_val[1]); mpf_mngr.set(est_rhs_value, ebits, sbits, rm, est_arg_val[1]);
break; break;
} }
case OP_FPA_ABS:
{
mpf_mngr.abs(arg_val[0], rhs_value);
mpf_mngr.abs(est_arg_val[0], est_rhs_value);
break;
}
default: default:
NOT_IMPLEMENTED_YET(); NOT_IMPLEMENTED_YET();
break; break;
@ -700,7 +709,6 @@ class fpa2bv_approx_tactic: public tactic {
#ifdef Z3DEBUG #ifdef Z3DEBUG
std::cout<<"Increasing precision:"<<std::endl; std::cout<<"Increasing precision:"<<std::endl;
#endif #endif
mpf_rounding_mode rm;
for(std::list<struct pair *>::iterator itp = ranked_terms.begin(); for(std::list<struct pair *>::iterator itp = ranked_terms.begin();
itp != ranked_terms.end(); itp != ranked_terms.end();
itp++) { itp++) {

View file

@ -35,8 +35,8 @@ fpa2bv_converter_prec::fpa2bv_converter_prec(ast_manager & m, fpa_approximation_
void fpa2bv_converter_prec::fix_bits(unsigned prec, expr_ref rounded, unsigned sbits, unsigned ebits)//expr_ref& fixed, void fpa2bv_converter_prec::fix_bits(unsigned prec, expr_ref rounded, unsigned sbits, unsigned ebits)//expr_ref& fixed,
{ //AZ: TODO: revise! minimal number of legal bits is 3!!!! Remove magic numbers { //AZ: TODO: revise! minimal number of legal bits is 3!!!! Remove magic numbers
unsigned szeroes=((sbits-2)*(MAX_PRECISION - prec +0.0)/MAX_PRECISION);//3 bits are minimum for the significand unsigned szeroes = (unsigned) ((sbits-2)*(MAX_PRECISION - prec +0.0) / MAX_PRECISION);//3 bits are minimum for the significand
unsigned ezeroes=((ebits-2)*(MAX_PRECISION - prec+0.0)/MAX_PRECISION);//2 bits are minimum for the exponent unsigned ezeroes = (unsigned) ((ebits - 2)*(MAX_PRECISION - prec + 0.0) / MAX_PRECISION);//2 bits are minimum for the exponent
expr_ref fix_sig(m), fix_exp(m); expr_ref fix_sig(m), fix_exp(m);
expr * sgn, *sig, *expn; expr * sgn, *sig, *expn;
@ -226,8 +226,8 @@ void fpa2bv_converter_prec::mk_cast_small_to_big(unsigned sbits, unsigned ebits,
void fpa2bv_converter_prec::match_sorts(expr * a, expr * b, expr_ref & n_a, expr_ref & n_b) void fpa2bv_converter_prec::match_sorts(expr * a, expr * b, expr_ref & n_a, expr_ref & n_b)
{ {
//Check if the sorts of lhs and rhs match, otherwise cast them to appropriate size? //Check if the sorts of lhs and rhs match, otherwise cast them to appropriate size?
SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_TO_FP)); SASSERT(is_app_of(a, m_plugin->get_family_id(), OP_FPA_FP));
SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_TO_FP)); SASSERT(is_app_of(b, m_plugin->get_family_id(), OP_FPA_FP));
func_decl * a_decl = to_app(a)->get_decl(); func_decl * a_decl = to_app(a)->get_decl();
func_decl * b_decl = to_app(b)->get_decl(); func_decl * b_decl = to_app(b)->get_decl();

View file

@ -23,9 +23,47 @@ Notes:
#include"fpa2bv_tactic.h" #include"fpa2bv_tactic.h"
#include"smt_tactic.h" #include"smt_tactic.h"
#include"propagate_values_tactic.h" #include"propagate_values_tactic.h"
#include"probe_arith.h"
#include"qfnra_tactic.h"
#include"qffp_tactic.h" #include"qffp_tactic.h"
struct has_fp_to_real_predicate {
struct found {};
ast_manager & m;
bv_util bu;
fpa_util fu;
arith_util au;
has_fp_to_real_predicate(ast_manager & _m) : m(_m), bu(m), fu(m), au(m) {}
void operator()(var *) { throw found(); }
void operator()(quantifier *) { throw found(); }
void operator()(app * n) {
sort * s = get_sort(n);
if (au.is_real(s) && n->get_family_id() == fu.get_family_id() &&
is_app(n) && to_app(n)->get_decl_kind() == OP_FPA_TO_REAL)
throw found();
}
};
class has_fp_to_real_probe : public probe {
public:
virtual result operator()(goal const & g) {
return !test<has_fp_to_real_predicate>(g);
}
virtual ~has_fp_to_real_probe() {}
};
probe * mk_has_fp_to_real_probe() {
return alloc(has_fp_to_real_probe);
}
tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) { tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) {
params_ref simp_p = p; params_ref simp_p = p;
simp_p.set_bool("arith_lhs", true); simp_p.set_bool("arith_lhs", true);
@ -43,7 +81,10 @@ tactic * mk_qffp_tactic(ast_manager & m, params_ref const & p) {
using_params(mk_simplify_tactic(m, p), simp_p), using_params(mk_simplify_tactic(m, p), simp_p),
cond(mk_is_propositional_probe(), cond(mk_is_propositional_probe(),
mk_sat_tactic(m, p), mk_sat_tactic(m, p),
mk_smt_tactic(p)), cond(mk_has_fp_to_real_probe(),
mk_qfnra_tactic(m, p),
mk_smt_tactic(p))
),
mk_fail_if_undecided_tactic()))); mk_fail_if_undecided_tactic())));
st->updt_params(p); st->updt_params(p);

View file

@ -81,7 +81,7 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const
return mk_ufbv_tactic(m, p); return mk_ufbv_tactic(m, p);
else if (logic=="QF_FP") else if (logic=="QF_FP")
return mk_qffp_tactic(m, p); return mk_qffp_tactic(m, p);
else if (logic == "QF_FPBV") else if (logic == "QF_FPBV" || logic == "QF_BVFP")
return mk_qffpbv_tactic(m, p); return mk_qffpbv_tactic(m, p);
else if (logic=="HORN") else if (logic=="HORN")
return mk_horn_tactic(m, p); return mk_horn_tactic(m, p);

View file

@ -709,8 +709,6 @@ public:
tactic_ref_vector ts2; tactic_ref_vector ts2;
goal_ref_vector g_copies; goal_ref_vector g_copies;
ast_manager & m = in->m();
for (unsigned i = 0; i < r1_size; i++) { for (unsigned i = 0; i < r1_size; i++) {
ast_manager * new_m = alloc(ast_manager, m, !m.proof_mode()); ast_manager * new_m = alloc(ast_manager, m, !m.proof_mode());
managers.push_back(new_m); managers.push_back(new_m);

View file

@ -1229,7 +1229,11 @@ void mpf_manager::rem(mpf const & x, mpf const & y, mpf & o) {
} }
void mpf_manager::maximum(mpf const & x, mpf const & y, mpf & o) { void mpf_manager::maximum(mpf const & x, mpf const & y, mpf & o) {
if (is_nan(x) || (is_zero(x) && is_zero(y))) if (is_nan(x))
set(o, y);
else if (is_zero(x) && is_zero(y) && sgn(x) != sgn(y))
mk_pzero(x.ebits, x.sbits, o);
else if (is_zero(x) && is_zero(y))
set(o, y); set(o, y);
else if (is_nan(y)) else if (is_nan(y))
set(o, x); set(o, x);
@ -1240,7 +1244,11 @@ void mpf_manager::maximum(mpf const & x, mpf const & y, mpf & o) {
} }
void mpf_manager::minimum(mpf const & x, mpf const & y, mpf & o) { void mpf_manager::minimum(mpf const & x, mpf const & y, mpf & o) {
if (is_nan(x) || (is_zero(x) && is_zero(y))) if (is_nan(x))
set(o, y);
else if (is_zero(x) && is_zero(y) && sgn(x) != sgn(y))
mk_pzero(x.ebits, x.sbits, o);
else if (is_zero(x) && is_zero(y))
set(o, y); set(o, y);
else if (is_nan(y)) else if (is_nan(y))
set(o, x); set(o, x);