mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +00:00
additional robustness check for incremental sat solver core when it recieves interpreted constants, added PB equality to interface and special handling of equalities to adddress performance gap documented in #755
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
fefd00aa49
commit
461e88e34c
21 changed files with 430 additions and 84 deletions
|
@ -79,12 +79,23 @@ static bool is_strict(decl_kind k) {
|
|||
return k == OP_LT || k == OP_GT;
|
||||
}
|
||||
|
||||
bool bound_manager::is_numeral(expr* v, numeral& n, bool& is_int) {
|
||||
expr* w;
|
||||
if (m_util.is_uminus(v, w) && is_numeral(w, n, is_int)) {
|
||||
n.neg();
|
||||
return true;
|
||||
}
|
||||
return m_util.is_numeral(v, n, is_int);
|
||||
}
|
||||
|
||||
void bound_manager::operator()(expr * f, expr_dependency * d) {
|
||||
TRACE("bound_manager", tout << "processing:\n" << mk_ismt2_pp(f, m()) << "\n";);
|
||||
expr * v;
|
||||
numeral n;
|
||||
if (is_disjunctive_bound(f, d))
|
||||
return;
|
||||
if (is_equality_bound(f, d))
|
||||
return;
|
||||
bool pos = true;
|
||||
while (m().is_not(f, f))
|
||||
pos = !pos;
|
||||
|
@ -99,10 +110,10 @@ void bound_manager::operator()(expr * f, expr_dependency * d) {
|
|||
expr * lhs = t->get_arg(0);
|
||||
expr * rhs = t->get_arg(1);
|
||||
bool is_int;
|
||||
if (is_uninterp_const(lhs) && m_util.is_numeral(rhs, n, is_int)) {
|
||||
if (is_uninterp_const(lhs) && is_numeral(rhs, n, is_int)) {
|
||||
v = lhs;
|
||||
}
|
||||
else if (is_uninterp_const(rhs) && m_util.is_numeral(lhs, n, is_int)) {
|
||||
else if (is_uninterp_const(rhs) && is_numeral(lhs, n, is_int)) {
|
||||
v = rhs;
|
||||
k = swap_decl(k);
|
||||
}
|
||||
|
@ -165,6 +176,26 @@ void bound_manager::insert_lower(expr * v, bool strict, numeral const & n, expr_
|
|||
}
|
||||
}
|
||||
|
||||
bool bound_manager::is_equality_bound(expr * f, expr_dependency * d) {
|
||||
expr* x, *y;
|
||||
if (!m().is_eq(f, x, y)) {
|
||||
return false;
|
||||
}
|
||||
if (!is_uninterp_const(x)) {
|
||||
std::swap(x, y);
|
||||
}
|
||||
numeral n;
|
||||
bool is_int;
|
||||
if (is_uninterp_const(x) && is_numeral(y, n, is_int)) {
|
||||
insert_lower(x, false, n, d);
|
||||
insert_upper(x, false, n, d);
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool bound_manager::is_disjunctive_bound(expr * f, expr_dependency * d) {
|
||||
numeral lo, hi, n;
|
||||
if (!m().is_or(f)) return false;
|
||||
|
@ -176,14 +207,14 @@ bool bound_manager::is_disjunctive_bound(expr * f, expr_dependency * d) {
|
|||
expr * e = to_app(f)->get_arg(i);
|
||||
if (!m().is_eq(e, x, y)) return false;
|
||||
if (is_uninterp_const(x) &&
|
||||
m_util.is_numeral(y, n, is_int) && is_int &&
|
||||
is_numeral(y, n, is_int) && is_int &&
|
||||
(x == v || v == 0)) {
|
||||
if (v == 0) { v = x; lo = hi = n; }
|
||||
if (n < lo) lo = n;
|
||||
if (n > hi) hi = n;
|
||||
}
|
||||
else if (is_uninterp_const(y) &&
|
||||
m_util.is_numeral(x, n, is_int) && is_int &&
|
||||
is_numeral(x, n, is_int) && is_int &&
|
||||
(y == v || v == 0)) {
|
||||
if (v == 0) { v = y; lo = hi = n; }
|
||||
if (n < lo) lo = n;
|
||||
|
|
|
@ -36,6 +36,8 @@ private:
|
|||
obj_map<expr, expr_dependency*> m_upper_deps;
|
||||
ptr_vector<expr> m_bounded_vars;
|
||||
bool is_disjunctive_bound(expr * f, expr_dependency * d);
|
||||
bool is_equality_bound(expr * f, expr_dependency * d);
|
||||
bool is_numeral(expr* v, rational& n, bool& is_int);
|
||||
void insert_lower(expr * v, bool strict, numeral const & n, expr_dependency * d);
|
||||
void insert_upper(expr * v, bool strict, numeral const & n, expr_dependency * d);
|
||||
public:
|
||||
|
|
|
@ -59,6 +59,7 @@ Revision History:
|
|||
#include "model_smt2_pp.h"
|
||||
#include "expr_safe_replace.h"
|
||||
#include "ast_util.h"
|
||||
#include "solver2tactic.h"
|
||||
|
||||
class nl_purify_tactic : public tactic {
|
||||
|
||||
|
|
|
@ -251,6 +251,16 @@ private:
|
|||
}
|
||||
sub.insert(e, t);
|
||||
}
|
||||
else {
|
||||
IF_VERBOSE(1,
|
||||
verbose_stream() << "unprocessed entry: " << mk_pp(e, m) << "\n";
|
||||
if (bm.has_lower(e, lo, s1)) {
|
||||
verbose_stream() << "lower: " << lo << " " << s1 << "\n";
|
||||
}
|
||||
if (bm.has_upper(e, hi, s2)) {
|
||||
verbose_stream() << "upper: " << hi << " " << s2 << "\n";
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ Notes:
|
|||
#include"inc_sat_solver.h"
|
||||
#include"fd_solver.h"
|
||||
#include"bv_rewriter.h"
|
||||
#include"solver2tactic.h"
|
||||
|
||||
|
||||
tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const & logic) {
|
||||
|
@ -89,6 +90,8 @@ tactic * mk_tactic_for_logic(ast_manager & m, params_ref const & p, symbol const
|
|||
return mk_qffpbv_tactic(m, p);
|
||||
else if (logic=="HORN")
|
||||
return mk_horn_tactic(m, p);
|
||||
else if (logic == "QF_FD")
|
||||
return mk_solver2tactic(mk_fd_solver(m, p));
|
||||
//else if (logic=="QF_UFNRA")
|
||||
// return mk_qfufnra_tactic(m, p);
|
||||
else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue