mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 00:55:31 +00:00
mbo
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
d12efb6097
commit
339cd6e537
8 changed files with 317 additions and 19 deletions
|
@ -29,6 +29,7 @@ Revision History:
|
|||
#include "expr_functors.h"
|
||||
#include "expr_safe_replace.h"
|
||||
#include "model_based_opt.h"
|
||||
#include "model_evaluator.h"
|
||||
|
||||
namespace qe {
|
||||
|
||||
|
@ -658,6 +659,9 @@ namespace qe {
|
|||
bool new_max = true;
|
||||
rational max_r, r;
|
||||
expr_ref val(m);
|
||||
model_evaluator eval(mdl);
|
||||
eval.set_model_completion(true);
|
||||
|
||||
bool is_int = a.is_int(m_var->x());
|
||||
for (unsigned i = 0; i < num_ineqs(); ++i) {
|
||||
rational const& ac = m_ineq_coeffs[i];
|
||||
|
@ -669,7 +673,7 @@ namespace qe {
|
|||
// ac < 0: x + t/ac > 0 <=> x > max { - t/ac | ac < 0 } = max { t/|ac| | ac < 0 }
|
||||
//
|
||||
if (ac.is_pos() == do_pos) {
|
||||
VERIFY(mdl.eval(ineq_term(i), val));
|
||||
eval(ineq_term(i), val);
|
||||
VERIFY(a.is_numeral(val, r));
|
||||
r /= abs(ac);
|
||||
new_max =
|
||||
|
|
|
@ -28,10 +28,15 @@ Revision History:
|
|||
#include "th_rewriter.h"
|
||||
#include "model_v2_pp.h"
|
||||
#include "expr_functors.h"
|
||||
#include "for_each_expr.h"
|
||||
|
||||
|
||||
using namespace qe;
|
||||
|
||||
struct noop_op_proc {
|
||||
void operator()(expr*) {}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
\brief return two terms that are equal in the model.
|
||||
|
@ -106,6 +111,7 @@ void project_plugin::push_back(expr_ref_vector& lits, expr* e) {
|
|||
|
||||
class mbp::impl {
|
||||
ast_manager& m;
|
||||
th_rewriter m_rw;
|
||||
ptr_vector<project_plugin> m_plugins;
|
||||
expr_mark m_visited;
|
||||
|
||||
|
@ -130,7 +136,6 @@ class mbp::impl {
|
|||
is_var.mark(vars[i].get());
|
||||
}
|
||||
expr_ref tmp(m), t(m), v(m);
|
||||
th_rewriter rw(m);
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
expr* e = lits[i].get(), *l, *r;
|
||||
if (m.is_eq(e, l, r) && reduce_eq(is_var, l, r, v, t)) {
|
||||
|
@ -141,7 +146,7 @@ class mbp::impl {
|
|||
is_rem.mark(v);
|
||||
for (unsigned j = 0; j < lits.size(); ++j) {
|
||||
sub(lits[j].get(), tmp);
|
||||
rw(tmp);
|
||||
m_rw(tmp);
|
||||
lits[j] = tmp;
|
||||
}
|
||||
}
|
||||
|
@ -177,6 +182,29 @@ class mbp::impl {
|
|||
}
|
||||
|
||||
|
||||
void filter_variables(model& model, app_ref_vector& vars, expr_ref_vector& lits, expr_ref_vector& unused_lits) {
|
||||
ast_manager& m = vars.get_manager();
|
||||
expr_mark lit_visited;
|
||||
for_each_expr_proc<noop_op_proc> fe;
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
for_each_expr(fe, lit_visited, lits[i].get());
|
||||
}
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
||||
app* var = vars[i].get();
|
||||
if (lit_visited.is_marked(var)) {
|
||||
if (i != j) {
|
||||
vars[j] = vars[i].get();
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
if (vars.size() != j) {
|
||||
vars.resize(j);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void extract_bools(model& model, expr_ref_vector& fmls, expr* fml) {
|
||||
TRACE("qe", tout << "extract bools: " << mk_pp(fml, m) << "\n";);
|
||||
ptr_vector<expr> todo;
|
||||
|
@ -210,6 +238,42 @@ class mbp::impl {
|
|||
}
|
||||
}
|
||||
|
||||
void project_bools(model& model, app_ref_vector& vars, expr_ref_vector& fmls) {
|
||||
expr_safe_replace sub(m);
|
||||
expr_ref val(m);
|
||||
unsigned j = 0;
|
||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
||||
app* var = vars[i].get();
|
||||
if (m.is_bool(var)) {
|
||||
VERIFY(model.eval(var, val));
|
||||
sub.insert(var, val);
|
||||
}
|
||||
else {
|
||||
if (j != i) {
|
||||
vars[j] = vars[i].get();
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
if (j != vars.size()) {
|
||||
vars.resize(j);
|
||||
j = 0;
|
||||
for (unsigned i = 0; i < fmls.size(); ++i) {
|
||||
sub(fmls[i].get(), val);
|
||||
m_rw(val);
|
||||
if (!m.is_true(val)) {
|
||||
if (j != i) {
|
||||
fmls[j] = fmls[i].get();
|
||||
}
|
||||
++j;
|
||||
}
|
||||
}
|
||||
if (j != fmls.size()) {
|
||||
fmls.resize(j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
|
||||
|
@ -333,7 +397,7 @@ public:
|
|||
m_visited.reset();
|
||||
}
|
||||
|
||||
impl(ast_manager& m):m(m) {
|
||||
impl(ast_manager& m):m(m), m_rw(m) {
|
||||
add_plugin(alloc(arith_project_plugin, m));
|
||||
add_plugin(alloc(datatype_project_plugin, m));
|
||||
add_plugin(alloc(array_project_plugin, m));
|
||||
|
@ -359,14 +423,16 @@ public:
|
|||
void operator()(bool force_elim, app_ref_vector& vars, model& model, expr_ref_vector& fmls) {
|
||||
expr_ref val(m), tmp(m);
|
||||
app_ref var(m);
|
||||
th_rewriter rw(m);
|
||||
expr_ref_vector unused_fmls(m);
|
||||
bool progress = true;
|
||||
TRACE("qe", tout << vars << " " << fmls << "\n";);
|
||||
while (progress && !vars.empty()) {
|
||||
preprocess_solve(model, vars, fmls);
|
||||
preprocess_solve(model, vars, fmls);
|
||||
filter_variables(model, vars, fmls, unused_fmls);
|
||||
project_bools(model, vars, fmls);
|
||||
while (progress && !vars.empty() && !fmls.empty()) {
|
||||
app_ref_vector new_vars(m);
|
||||
progress = false;
|
||||
while (!vars.empty()) {
|
||||
while (!vars.empty() && !fmls.empty()) {
|
||||
var = vars.back();
|
||||
vars.pop_back();
|
||||
project_plugin* p = get_plugin(var);
|
||||
|
@ -377,7 +443,7 @@ public:
|
|||
new_vars.push_back(var);
|
||||
}
|
||||
}
|
||||
if (!progress && !new_vars.empty() && force_elim) {
|
||||
if (!progress && !new_vars.empty() && !fmls.empty() && force_elim) {
|
||||
var = new_vars.back();
|
||||
new_vars.pop_back();
|
||||
expr_safe_replace sub(m);
|
||||
|
@ -385,7 +451,7 @@ public:
|
|||
sub.insert(var, val);
|
||||
for (unsigned i = 0; i < fmls.size(); ++i) {
|
||||
sub(fmls[i].get(), tmp);
|
||||
rw(tmp);
|
||||
m_rw(tmp);
|
||||
if (m.is_true(tmp)) {
|
||||
project_plugin::erase(fmls, i);
|
||||
}
|
||||
|
@ -396,9 +462,17 @@ public:
|
|||
progress = true;
|
||||
}
|
||||
vars.append(new_vars);
|
||||
if (progress) {
|
||||
preprocess_solve(model, vars, fmls);
|
||||
}
|
||||
}
|
||||
if (fmls.empty()) {
|
||||
vars.reset();
|
||||
}
|
||||
fmls.append(unused_fmls);
|
||||
TRACE("qe", tout << vars << " " << fmls << "\n";);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
mbp::mbp(ast_manager& m) {
|
||||
|
|
|
@ -37,6 +37,7 @@ namespace qe {
|
|||
virtual bool operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) = 0;
|
||||
virtual bool solve(model& model, app_ref_vector& vars, expr_ref_vector& lits) = 0;
|
||||
virtual family_id get_family_id() = 0;
|
||||
virtual bool operator()(model& model, app_ref_vector& vars, expr_ref_vector& lits) { return false; };
|
||||
|
||||
static expr_ref pick_equality(ast_manager& m, model& model, expr* t);
|
||||
static void partition_values(model& model, expr_ref_vector const& vals, expr_ref_vector& lits);
|
||||
|
|
|
@ -575,6 +575,7 @@ namespace qe {
|
|||
lbool check_sat() {
|
||||
while (true) {
|
||||
++m_stats.m_num_rounds;
|
||||
IF_VERBOSE(3, verbose_stream() << "(check-qsat level: " << m_level << " round: " << m_stats.m_num_rounds << ")\n";);
|
||||
check_cancel();
|
||||
expr_ref_vector asms(m_asms);
|
||||
m_pred_abs.get_assumptions(m_model.get(), asms);
|
||||
|
@ -1191,7 +1192,7 @@ namespace qe {
|
|||
|
||||
lbool maximize(expr_ref_vector const& fmls, app* t, model_ref& mdl, opt::inf_eps& value) {
|
||||
expr_ref_vector defs(m);
|
||||
expr_ref fml = negate_core(fmls);
|
||||
expr_ref fml = mk_and(fmls);
|
||||
hoist(fml);
|
||||
m_objective = t;
|
||||
m_value = opt::inf_eps();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue