mirror of
https://github.com/Z3Prover/z3
synced 2025-07-19 19:02:02 +00:00
updates to mbqi
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
e8cabdc620
commit
402234757e
2 changed files with 114 additions and 114 deletions
|
@ -90,33 +90,33 @@ namespace spacer {
|
||||||
if (!m_model) { return; }
|
if (!m_model) { return; }
|
||||||
m_mev = alloc(model_evaluator, *m_model);
|
m_mev = alloc(model_evaluator, *m_model);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool model_evaluator_util::eval(expr *e, expr_ref &result, bool model_completion) {
|
bool model_evaluator_util::eval(expr *e, expr_ref &result, bool model_completion) {
|
||||||
m_mev->set_model_completion (model_completion);
|
m_mev->set_model_completion (model_completion);
|
||||||
try {
|
try {
|
||||||
m_mev->operator() (e, result);
|
m_mev->operator() (e, result);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (model_evaluator_exception &ex) {
|
catch (model_evaluator_exception &ex) {
|
||||||
(void)ex;
|
(void)ex;
|
||||||
TRACE("spacer_model_evaluator", tout << ex.msg () << "\n";);
|
TRACE("spacer_model_evaluator", tout << ex.msg () << "\n";);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool model_evaluator_util::eval(const expr_ref_vector &v,
|
bool model_evaluator_util::eval(const expr_ref_vector &v,
|
||||||
expr_ref& res, bool model_completion) {
|
expr_ref& res, bool model_completion) {
|
||||||
expr_ref e(m);
|
expr_ref e(m);
|
||||||
e = mk_and (v);
|
e = mk_and (v);
|
||||||
return eval(e, res, model_completion);
|
return eval(e, res, model_completion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool model_evaluator_util::is_true(const expr_ref_vector &v) {
|
bool model_evaluator_util::is_true(const expr_ref_vector &v) {
|
||||||
expr_ref res(m);
|
expr_ref res(m);
|
||||||
return eval (v, res, false) && m.is_true (res);
|
return eval (v, res, false) && m.is_true (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool model_evaluator_util::is_false(expr *x) {
|
bool model_evaluator_util::is_false(expr *x) {
|
||||||
expr_ref res(m);
|
expr_ref res(m);
|
||||||
return eval(x, res, false) && m.is_false (res);
|
return eval(x, res, false) && m.is_false (res);
|
||||||
|
@ -126,7 +126,7 @@ namespace spacer {
|
||||||
expr_ref res(m);
|
expr_ref res(m);
|
||||||
return eval(x, res, false) && m.is_true (res);
|
return eval(x, res, false) && m.is_true (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) {
|
void reduce_disequalities(model& model, unsigned threshold, expr_ref& fml) {
|
||||||
ast_manager& m = fml.get_manager();
|
ast_manager& m = fml.get_manager();
|
||||||
expr_ref_vector conjs(m);
|
expr_ref_vector conjs(m);
|
||||||
|
@ -172,16 +172,16 @@ namespace spacer {
|
||||||
SASSERT(orig_size <= 1 + conjs.size());
|
SASSERT(orig_size <= 1 + conjs.size());
|
||||||
if (i + 1 == orig_size) {
|
if (i + 1 == orig_size) {
|
||||||
// no-op.
|
// no-op.
|
||||||
}
|
}
|
||||||
else if (orig_size <= conjs.size()) {
|
else if (orig_size <= conjs.size()) {
|
||||||
// no-op
|
// no-op
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
SASSERT(orig_size == 1 + conjs.size());
|
SASSERT(orig_size == 1 + conjs.size());
|
||||||
--orig_size;
|
--orig_size;
|
||||||
--i;
|
--i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
conjs[i] = tmp;
|
conjs[i] = tmp;
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ namespace spacer {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
public:
|
public:
|
||||||
ite_hoister(ast_manager& m): m(m) {}
|
ite_hoister(ast_manager& m): m(m) {}
|
||||||
|
|
||||||
br_status mk_app_core(func_decl* f, unsigned num_args, expr* const* args, expr_ref& result) {
|
br_status mk_app_core(func_decl* f, unsigned num_args, expr* const* args, expr_ref& result) {
|
||||||
if (m.is_ite(f)) {
|
if (m.is_ite(f)) {
|
||||||
return BR_FAILED;
|
return BR_FAILED;
|
||||||
|
@ -234,7 +234,7 @@ namespace spacer {
|
||||||
}
|
}
|
||||||
ite_hoister_cfg(ast_manager & m, params_ref const & p):m_r(m) {}
|
ite_hoister_cfg(ast_manager & m, params_ref const & p):m_r(m) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
class ite_hoister_star : public rewriter_tpl<ite_hoister_cfg> {
|
class ite_hoister_star : public rewriter_tpl<ite_hoister_cfg> {
|
||||||
ite_hoister_cfg m_cfg;
|
ite_hoister_cfg m_cfg;
|
||||||
public:
|
public:
|
||||||
|
@ -242,7 +242,7 @@ namespace spacer {
|
||||||
rewriter_tpl<ite_hoister_cfg>(m, false, m_cfg),
|
rewriter_tpl<ite_hoister_cfg>(m, false, m_cfg),
|
||||||
m_cfg(m, p) {}
|
m_cfg(m, p) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
void hoist_non_bool_if(expr_ref& fml) {
|
void hoist_non_bool_if(expr_ref& fml) {
|
||||||
ast_manager& m = fml.get_manager();
|
ast_manager& m = fml.get_manager();
|
||||||
scoped_no_proof _sp(m);
|
scoped_no_proof _sp(m);
|
||||||
|
@ -274,7 +274,7 @@ namespace spacer {
|
||||||
bool is_arith_expr(expr *e) const {
|
bool is_arith_expr(expr *e) const {
|
||||||
return is_app(e) && a.get_family_id() == to_app(e)->get_family_id();
|
return is_app(e) && a.get_family_id() == to_app(e)->get_family_id();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_offset(expr* e) const {
|
bool is_offset(expr* e) const {
|
||||||
if (a.is_numeral(e)) {
|
if (a.is_numeral(e)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -358,7 +358,7 @@ namespace spacer {
|
||||||
!a.is_mul(lhs) &&
|
!a.is_mul(lhs) &&
|
||||||
!a.is_mul(rhs);
|
!a.is_mul(rhs);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool test_term(expr* e) const {
|
bool test_term(expr* e) const {
|
||||||
if (m.is_bool(e)) {
|
if (m.is_bool(e)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -403,9 +403,9 @@ namespace spacer {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
test_diff_logic(ast_manager& m): m(m), a(m), bv(m), m_is_dl(true), m_test_for_utvpi(false) {}
|
test_diff_logic(ast_manager& m): m(m), a(m), bv(m), m_is_dl(true), m_test_for_utvpi(false) {}
|
||||||
|
|
||||||
void test_for_utvpi() { m_test_for_utvpi = true; }
|
void test_for_utvpi() { m_test_for_utvpi = true; }
|
||||||
|
|
||||||
void operator()(expr* e) {
|
void operator()(expr* e) {
|
||||||
if (!m_is_dl) {
|
if (!m_is_dl) {
|
||||||
return;
|
return;
|
||||||
|
@ -422,7 +422,7 @@ namespace spacer {
|
||||||
m_is_dl = test_term(a->get_arg(i));
|
m_is_dl = test_term(a->get_arg(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_is_dl) {
|
if (!m_is_dl) {
|
||||||
char const* msg = "non-diff: ";
|
char const* msg = "non-diff: ";
|
||||||
if (m_test_for_utvpi) {
|
if (m_test_for_utvpi) {
|
||||||
|
@ -431,10 +431,10 @@ namespace spacer {
|
||||||
IF_VERBOSE(1, verbose_stream() << msg << mk_pp(e, m) << "\n";);
|
IF_VERBOSE(1, verbose_stream() << msg << mk_pp(e, m) << "\n";);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_dl() const { return m_is_dl; }
|
bool is_dl() const { return m_is_dl; }
|
||||||
};
|
};
|
||||||
|
|
||||||
bool is_difference_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls) {
|
bool is_difference_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls) {
|
||||||
test_diff_logic test(m);
|
test_diff_logic test(m);
|
||||||
expr_fast_mark1 mark;
|
expr_fast_mark1 mark;
|
||||||
|
@ -443,7 +443,7 @@ namespace spacer {
|
||||||
}
|
}
|
||||||
return test.is_dl();
|
return test.is_dl();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool is_utvpi_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls) {
|
bool is_utvpi_logic(ast_manager& m, unsigned num_fmls, expr* const* fmls) {
|
||||||
test_diff_logic test(m);
|
test_diff_logic test(m);
|
||||||
test.test_for_utvpi();
|
test.test_for_utvpi();
|
||||||
|
@ -455,7 +455,7 @@ namespace spacer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void subst_vars(ast_manager& m,
|
void subst_vars(ast_manager& m,
|
||||||
app_ref_vector const& vars,
|
app_ref_vector const& vars,
|
||||||
model* M, expr_ref& fml) {
|
model* M, expr_ref& fml) {
|
||||||
expr_safe_replace sub (m);
|
expr_safe_replace sub (m);
|
||||||
|
@ -488,7 +488,7 @@ namespace spacer {
|
||||||
flatten_and (fml, flat);
|
flatten_and (fml, flat);
|
||||||
fml = mk_and(flat);
|
fml = mk_and(flat);
|
||||||
}
|
}
|
||||||
|
|
||||||
app_ref_vector arith_vars (m);
|
app_ref_vector arith_vars (m);
|
||||||
app_ref_vector array_vars (m);
|
app_ref_vector array_vars (m);
|
||||||
array_util arr_u (m);
|
array_util arr_u (m);
|
||||||
|
@ -497,19 +497,19 @@ namespace spacer {
|
||||||
expr_ref bval (m);
|
expr_ref bval (m);
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
params_ref p;
|
params_ref p;
|
||||||
qe_lite qe(m, p, false);
|
qe_lite qe(m, p, false);
|
||||||
qe (vars, fml);
|
qe (vars, fml);
|
||||||
rw (fml);
|
rw (fml);
|
||||||
|
|
||||||
TRACE ("spacer_mbp",
|
TRACE ("spacer_mbp",
|
||||||
tout << "After qe_lite:\n";
|
tout << "After qe_lite:\n";
|
||||||
tout << mk_pp (fml, m) << "\n";
|
tout << mk_pp (fml, m) << "\n";
|
||||||
tout << "Vars:\n" << vars;);
|
tout << "Vars:\n" << vars;);
|
||||||
|
|
||||||
SASSERT (!m.is_false (fml));
|
SASSERT (!m.is_false (fml));
|
||||||
|
|
||||||
|
|
||||||
// sort out vars into bools, arith (int/real), and arrays
|
// sort out vars into bools, arith (int/real), and arrays
|
||||||
for (app* v : vars) {
|
for (app* v : vars) {
|
||||||
if (m.is_bool (v)) {
|
if (m.is_bool (v)) {
|
||||||
|
@ -523,7 +523,7 @@ namespace spacer {
|
||||||
arith_vars.push_back (v);
|
arith_vars.push_back (v);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// substitute Booleans
|
// substitute Booleans
|
||||||
if (!bool_sub.empty()) {
|
if (!bool_sub.empty()) {
|
||||||
bool_sub (fml);
|
bool_sub (fml);
|
||||||
|
@ -533,13 +533,13 @@ namespace spacer {
|
||||||
TRACE ("spacer_mbp", tout << "Projected Booleans:\n" << fml << "\n"; );
|
TRACE ("spacer_mbp", tout << "Projected Booleans:\n" << fml << "\n"; );
|
||||||
bool_sub.reset ();
|
bool_sub.reset ();
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE ("spacer_mbp",
|
TRACE ("spacer_mbp",
|
||||||
tout << "Array vars:\n";
|
tout << "Array vars:\n";
|
||||||
tout << array_vars;);
|
tout << array_vars;);
|
||||||
|
|
||||||
vars.reset ();
|
vars.reset ();
|
||||||
|
|
||||||
// project arrays
|
// project arrays
|
||||||
{
|
{
|
||||||
scoped_no_proof _sp (m);
|
scoped_no_proof _sp (m);
|
||||||
|
@ -550,14 +550,14 @@ namespace spacer {
|
||||||
srw (fml);
|
srw (fml);
|
||||||
SASSERT (!m.is_false (fml));
|
SASSERT (!m.is_false (fml));
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE ("spacer_mbp",
|
TRACE ("spacer_mbp",
|
||||||
tout << "extended model:\n";
|
tout << "extended model:\n";
|
||||||
model_pp (tout, *M);
|
model_pp (tout, *M);
|
||||||
tout << "Auxiliary variables of index and value sorts:\n";
|
tout << "Auxiliary variables of index and value sorts:\n";
|
||||||
tout << vars;
|
tout << vars;
|
||||||
);
|
);
|
||||||
|
|
||||||
if (vars.empty()) { break; }
|
if (vars.empty()) { break; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,21 +572,21 @@ namespace spacer {
|
||||||
// tout << "After second qelite: " <<
|
// tout << "After second qelite: " <<
|
||||||
// mk_pp (fml, m) << "\n";);
|
// mk_pp (fml, m) << "\n";);
|
||||||
|
|
||||||
if (use_native_mbp) {
|
if (use_native_mbp) {
|
||||||
qe::mbp mbp (m);
|
qe::mbp mbp (m);
|
||||||
expr_ref_vector fmls(m);
|
expr_ref_vector fmls(m);
|
||||||
flatten_and (fml, fmls);
|
flatten_and (fml, fmls);
|
||||||
|
|
||||||
mbp (true, arith_vars, *M.get (), fmls);
|
mbp (true, arith_vars, *M.get (), fmls);
|
||||||
fml = mk_and (fmls);
|
fml = mk_and (fmls);
|
||||||
SASSERT (arith_vars.empty ());
|
SASSERT (arith_vars.empty ());
|
||||||
} else {
|
} else {
|
||||||
scoped_no_proof _sp (m);
|
scoped_no_proof _sp (m);
|
||||||
spacer_qe::arith_project (*M.get (), arith_vars, fml);
|
spacer_qe::arith_project (*M.get (), arith_vars, fml);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE ("spacer_mbp",
|
TRACE ("spacer_mbp",
|
||||||
tout << "Projected arith vars:\n" << mk_pp (fml, m) << "\n";
|
tout << "Projected arith vars:\n" << mk_pp (fml, m) << "\n";
|
||||||
tout << "Remaining arith vars:\n" << arith_vars << "\n";);
|
tout << "Remaining arith vars:\n" << arith_vars << "\n";);
|
||||||
SASSERT (!m.is_false (fml));
|
SASSERT (!m.is_false (fml));
|
||||||
}
|
}
|
||||||
|
@ -697,7 +697,7 @@ void expand_literals(ast_manager &m, expr_ref_vector& conjs)
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
class implicant_picker {
|
class implicant_picker {
|
||||||
model_evaluator_util &m_mev;
|
model_evaluator_util &m_mev;
|
||||||
ast_manager &m;
|
ast_manager &m;
|
||||||
arith_util m_arith;
|
arith_util m_arith;
|
||||||
|
@ -747,37 +747,37 @@ namespace {
|
||||||
out.push_back (res);
|
out.push_back (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
void process_app(app *a, expr_ref_vector &out)
|
void process_app(app *a, expr_ref_vector &out)
|
||||||
{
|
{
|
||||||
if (m_visited.is_marked(a)) { return; }
|
if (m_visited.is_marked(a)) { return; }
|
||||||
SASSERT (m.is_bool (a));
|
SASSERT (m.is_bool (a));
|
||||||
expr_ref v(m);
|
expr_ref v(m);
|
||||||
m_mev.eval (a, v, false);
|
m_mev.eval (a, v, false);
|
||||||
|
|
||||||
if (!m.is_true(v) && !m.is_false(v)) { return; }
|
if (!m.is_true(v) && !m.is_false(v)) { return; }
|
||||||
|
|
||||||
expr *na, *f1, *f2, *f3;
|
expr *na, *f1, *f2, *f3;
|
||||||
|
|
||||||
if (a->get_family_id() != m.get_basic_family_id())
|
if (a->get_family_id() != m.get_basic_family_id())
|
||||||
{ add_literal(a, out); }
|
{ add_literal(a, out); }
|
||||||
else if (is_uninterp_const(a))
|
else if (is_uninterp_const(a))
|
||||||
{ add_literal(a, out); }
|
{ add_literal(a, out); }
|
||||||
else if (m.is_not(a, na) && m.is_not(na, na))
|
else if (m.is_not(a, na) && m.is_not(na, na))
|
||||||
{ m_todo.push_back(na); }
|
{ m_todo.push_back(na); }
|
||||||
else if (m.is_not(a, na))
|
else if (m.is_not(a, na))
|
||||||
{ m_todo.push_back(na); }
|
{ m_todo.push_back(na); }
|
||||||
else if (m.is_distinct(a)) {
|
else if (m.is_distinct(a)) {
|
||||||
if (m.is_false(v))
|
if (m.is_false(v))
|
||||||
m_todo.push_back
|
m_todo.push_back
|
||||||
(qe::project_plugin::pick_equality(m, *m_mev.get_model(), a));
|
(qe::project_plugin::pick_equality(m, *m_mev.get_model(), a));
|
||||||
else if (a->get_num_args() == 2)
|
else if (a->get_num_args() == 2)
|
||||||
{ add_literal(a, out); }
|
{ add_literal(a, out); }
|
||||||
else
|
else
|
||||||
m_todo.push_back(m.mk_distinct_expanded(a->get_num_args(),
|
m_todo.push_back(m.mk_distinct_expanded(a->get_num_args(),
|
||||||
a->get_args()));
|
a->get_args()));
|
||||||
} else if (m.is_and(a)) {
|
} else if (m.is_and(a)) {
|
||||||
if (m.is_true(v))
|
if (m.is_true(v))
|
||||||
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
||||||
else if (m.is_false(v)) {
|
else if (m.is_false(v)) {
|
||||||
for (unsigned i = 0, sz = a->get_num_args (); i < sz; ++i) {
|
for (unsigned i = 0, sz = a->get_num_args (); i < sz; ++i) {
|
||||||
if (m_mev.is_false(a->get_arg(i))) {
|
if (m_mev.is_false(a->get_arg(i))) {
|
||||||
|
@ -786,9 +786,9 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (m.is_or(a)) {
|
} else if (m.is_or(a)) {
|
||||||
if (m.is_false(v))
|
if (m.is_false(v))
|
||||||
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
||||||
else if (m.is_true(v)) {
|
else if (m.is_true(v)) {
|
||||||
for (unsigned i = 0, sz = a->get_num_args(); i < sz; ++i) {
|
for (unsigned i = 0, sz = a->get_num_args(); i < sz; ++i) {
|
||||||
if (m_mev.is_true(a->get_arg(i))) {
|
if (m_mev.is_true(a->get_arg(i))) {
|
||||||
|
@ -797,39 +797,39 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (m.is_iff(a, f1, f2) || m.is_eq(a, f1, f2) ||
|
} else if (m.is_iff(a, f1, f2) || m.is_eq(a, f1, f2) ||
|
||||||
(m.is_true(v) && m.is_not(a, na) && m.is_xor (na, f1, f2))) {
|
(m.is_true(v) && m.is_not(a, na) && m.is_xor (na, f1, f2))) {
|
||||||
if (!m.are_equal(f1, f2) && !m.are_distinct(f1, f2)) {
|
if (!m.are_equal(f1, f2) && !m.are_distinct(f1, f2)) {
|
||||||
if (m.is_bool(f1) &&
|
if (m.is_bool(f1) &&
|
||||||
(!is_uninterp_const(f1) || !is_uninterp_const(f2)))
|
(!is_uninterp_const(f1) || !is_uninterp_const(f2)))
|
||||||
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
|
||||||
else
|
|
||||||
{ add_literal(a, out); }
|
|
||||||
}
|
|
||||||
} else if (m.is_ite(a, f1, f2, f3)) {
|
|
||||||
if (m.are_equal(f2, f3)) { m_todo.push_back(f2); }
|
|
||||||
else if (m_mev.is_true (f2) && m_mev.is_true (f3)) {
|
|
||||||
m_todo.push_back(f2);
|
|
||||||
m_todo.push_back(f3);
|
|
||||||
} else if (m_mev.is_false(f2) && m_mev.is_false(f3)) {
|
|
||||||
m_todo.push_back(f2);
|
|
||||||
m_todo.push_back(f3);
|
|
||||||
} else if (m_mev.is_true(f1)) {
|
|
||||||
m_todo.push_back(f1);
|
|
||||||
m_todo.push_back(f2);
|
|
||||||
} else if (m_mev.is_false(f1)) {
|
|
||||||
m_todo.push_back(f1);
|
|
||||||
m_todo.push_back(f3);
|
|
||||||
}
|
|
||||||
} else if (m.is_xor(a, f1, f2))
|
|
||||||
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
||||||
|
else
|
||||||
|
{ add_literal(a, out); }
|
||||||
|
}
|
||||||
|
} else if (m.is_ite(a, f1, f2, f3)) {
|
||||||
|
if (m.are_equal(f2, f3)) { m_todo.push_back(f2); }
|
||||||
|
else if (m_mev.is_true (f2) && m_mev.is_true (f3)) {
|
||||||
|
m_todo.push_back(f2);
|
||||||
|
m_todo.push_back(f3);
|
||||||
|
} else if (m_mev.is_false(f2) && m_mev.is_false(f3)) {
|
||||||
|
m_todo.push_back(f2);
|
||||||
|
m_todo.push_back(f3);
|
||||||
|
} else if (m_mev.is_true(f1)) {
|
||||||
|
m_todo.push_back(f1);
|
||||||
|
m_todo.push_back(f2);
|
||||||
|
} else if (m_mev.is_false(f1)) {
|
||||||
|
m_todo.push_back(f1);
|
||||||
|
m_todo.push_back(f3);
|
||||||
|
}
|
||||||
|
} else if (m.is_xor(a, f1, f2))
|
||||||
|
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
||||||
else if (m.is_implies(a, f1, f2)) {
|
else if (m.is_implies(a, f1, f2)) {
|
||||||
if (m.is_true (v)) {
|
if (m.is_true (v)) {
|
||||||
if (m_mev.is_true(f2)) { m_todo.push_back(f2); }
|
if (m_mev.is_true(f2)) { m_todo.push_back(f2); }
|
||||||
else if (m_mev.is_false(f1)) { m_todo.push_back(f1); }
|
else if (m_mev.is_false(f1)) { m_todo.push_back(f1); }
|
||||||
} else if (m.is_false(v))
|
} else if (m.is_false(v))
|
||||||
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
{ m_todo.append(a->get_num_args(), a->get_args()); }
|
||||||
} else if (m.is_true(a) || m.is_false(a)) { /* nothing */ }
|
} else if (m.is_true(a) || m.is_false(a)) { /* nothing */ }
|
||||||
else {
|
else {
|
||||||
verbose_stream () << "Unexpected expression: "
|
verbose_stream () << "Unexpected expression: "
|
||||||
<< mk_pp(a, m) << "\n";
|
<< mk_pp(a, m) << "\n";
|
||||||
|
@ -837,10 +837,10 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pick_literals(expr *e, expr_ref_vector &out)
|
void pick_literals(expr *e, expr_ref_vector &out)
|
||||||
{
|
{
|
||||||
SASSERT(m_todo.empty());
|
SASSERT(m_todo.empty());
|
||||||
if (m_visited.is_marked(e)) { return; }
|
if (m_visited.is_marked(e)) { return; }
|
||||||
SASSERT(is_app(e));
|
SASSERT(is_app(e));
|
||||||
|
|
||||||
m_todo.push_back(e);
|
m_todo.push_back(e);
|
||||||
|
@ -852,8 +852,8 @@ namespace {
|
||||||
} while (!m_todo.empty());
|
} while (!m_todo.empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool pick_implicant(const expr_ref_vector &in, expr_ref_vector &out)
|
bool pick_implicant(const expr_ref_vector &in, expr_ref_vector &out)
|
||||||
{
|
{
|
||||||
m_visited.reset();
|
m_visited.reset();
|
||||||
expr_ref e(m);
|
expr_ref e(m);
|
||||||
e = mk_and (in);
|
e = mk_and (in);
|
||||||
|
@ -861,7 +861,7 @@ namespace {
|
||||||
|
|
||||||
for (unsigned i = 0, sz = in.size (); i < sz; ++i) {
|
for (unsigned i = 0, sz = in.size (); i < sz; ++i) {
|
||||||
if (is_true || m_mev.is_true(in.get(i)))
|
if (is_true || m_mev.is_true(in.get(i)))
|
||||||
{ pick_literals(in.get(i), out); }
|
{ pick_literals(in.get(i), out); }
|
||||||
}
|
}
|
||||||
|
|
||||||
m_visited.reset ();
|
m_visited.reset ();
|
||||||
|
@ -875,7 +875,7 @@ namespace {
|
||||||
void operator() (expr_ref_vector &in, expr_ref_vector& out)
|
void operator() (expr_ref_vector &in, expr_ref_vector& out)
|
||||||
{pick_implicant (in, out);}
|
{pick_implicant (in, out);}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void compute_implicant_literals (model_evaluator_util &mev, expr_ref_vector &formula,
|
void compute_implicant_literals (model_evaluator_util &mev, expr_ref_vector &formula,
|
||||||
expr_ref_vector &res)
|
expr_ref_vector &res)
|
||||||
|
@ -1178,9 +1178,9 @@ void ground_expr(expr *e, expr_ref &out, app_ref_vector &vars) {
|
||||||
expr *e1, *e2;
|
expr *e1, *e2;
|
||||||
if (m_array.is_select (n) && n->get_arg (1) != m_var) {
|
if (m_array.is_select (n) && n->get_arg (1) != m_var) {
|
||||||
m_res.push_back (n->get_arg (1));
|
m_res.push_back (n->get_arg (1));
|
||||||
} else if (m.is_eq(n, e1, e2)) {
|
} else if (m.is_eq(n, e1, e2)) {
|
||||||
if (e1 == m_var) { m_res.push_back(e2); }
|
if (e1 == m_var) { m_res.push_back(e2); }
|
||||||
else if (e2 == m_var) { m_res.push_back(e1); }
|
else if (e2 == m_var) { m_res.push_back(e1); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1206,7 +1206,7 @@ void ground_expr(expr *e, expr_ref &out, app_ref_vector &vars) {
|
||||||
tout << i << ": " << mk_pp (terms.get (i), m) << "\n";
|
tout << i << ": " << mk_pp (terms.get (i), m) << "\n";
|
||||||
);
|
);
|
||||||
|
|
||||||
for (unsigned i = 0, e = terms.size(); i < e; ++i) {
|
for (unsigned i = 0, e = terms.size(); i < e; ++i) {
|
||||||
expr* term = terms.get (i);
|
expr* term = terms.get (i);
|
||||||
expr_ref tval (m);
|
expr_ref tval (m);
|
||||||
mev.eval (term, tval, false);
|
mev.eval (term, tval, false);
|
||||||
|
|
|
@ -125,13 +125,13 @@ void project_plugin::push_back(expr_ref_vector& lits, expr* e) {
|
||||||
|
|
||||||
|
|
||||||
class mbp::impl {
|
class mbp::impl {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
params_ref m_params;
|
params_ref m_params;
|
||||||
th_rewriter m_rw;
|
th_rewriter m_rw;
|
||||||
ptr_vector<project_plugin> m_plugins;
|
ptr_vector<project_plugin> m_plugins;
|
||||||
expr_mark m_visited;
|
expr_mark m_visited;
|
||||||
expr_mark m_bool_visited;
|
expr_mark m_bool_visited;
|
||||||
|
|
||||||
// parameters
|
// parameters
|
||||||
bool m_reduce_all_selects;
|
bool m_reduce_all_selects;
|
||||||
bool m_native_mbp;
|
bool m_native_mbp;
|
||||||
|
@ -280,33 +280,33 @@ class mbp::impl {
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vars[j++] = var;
|
vars[j++] = var;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (j == vars.size()) {
|
if (j == vars.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
vars.shrink(j);
|
vars.shrink(j);
|
||||||
j = 0;
|
j = 0;
|
||||||
for (unsigned i = 0; i < fmls.size(); ++i) {
|
for (unsigned i = 0; i < fmls.size(); ++i) {
|
||||||
expr* fml = fmls[i].get();
|
expr* fml = fmls[i].get();
|
||||||
sub(fml, val);
|
sub(fml, val);
|
||||||
m_rw(val);
|
m_rw(val);
|
||||||
if (!m.is_true(val)) {
|
if (!m.is_true(val)) {
|
||||||
TRACE("qe", tout << mk_pp(fml, m) << " -> " << val << "\n";);
|
TRACE("qe", tout << mk_pp(fml, m) << " -> " << val << "\n";);
|
||||||
fmls[j++] = val;
|
fmls[j++] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fmls.shrink(j);
|
fmls.shrink(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void subst_vars(model_evaluator& eval, app_ref_vector const& vars, expr_ref& fml) {
|
void subst_vars(model_evaluator& eval, app_ref_vector const& vars, expr_ref& fml) {
|
||||||
expr_safe_replace sub (m);
|
expr_safe_replace sub (m);
|
||||||
for (app * v : vars) {
|
for (app * v : vars) {
|
||||||
sub.insert(v, eval(v));
|
sub.insert(v, eval(v));
|
||||||
}
|
}
|
||||||
sub(fml);
|
sub(fml);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct index_term_finder {
|
struct index_term_finder {
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
|
@ -731,7 +731,7 @@ mbp::mbp(ast_manager& m, params_ref const& p) {
|
||||||
mbp::~mbp() {
|
mbp::~mbp() {
|
||||||
dealloc(m_impl);
|
dealloc(m_impl);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mbp::updt_params(params_ref const& p) {
|
void mbp::updt_params(params_ref const& p) {
|
||||||
m_impl->updt_params(p);
|
m_impl->updt_params(p);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue