3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-29 03:45:51 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2016-05-20 13:45:50 -07:00
parent d12efb6097
commit 339cd6e537
8 changed files with 317 additions and 19 deletions

View file

@ -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) {