3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-29 03:45:51 +00:00

fix handing of ite conditions that have to be included in projection, thanks to bug report by Zak

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2016-04-10 01:48:35 +02:00
parent 493b86eca7
commit cc6f72aba7
4 changed files with 167 additions and 9 deletions

View file

@ -107,6 +107,7 @@ void project_plugin::push_back(expr_ref_vector& lits, expr* e) {
class mbp::impl {
ast_manager& m;
ptr_vector<project_plugin> m_plugins;
expr_mark m_visited;
void add_plugin(project_plugin* p) {
family_id fid = p->get_family_id();
@ -175,12 +176,48 @@ class mbp::impl {
return false;
}
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;
if (is_app(fml)) {
todo.append(to_app(fml)->get_num_args(), to_app(fml)->get_args());
}
while (!todo.empty()) {
expr* e = todo.back();
todo.pop_back();
if (m_visited.is_marked(e)) {
continue;
}
m_visited.mark(e);
if (m.is_bool(e)) {
expr_ref val(m);
VERIFY(model.eval(e, val));
TRACE("qe", tout << "found: " << mk_pp(e, m) << "\n";);
if (m.is_true(val)) {
fmls.push_back(e);
}
else {
fmls.push_back(mk_not(m, e));
}
}
else if (is_app(e)) {
todo.append(to_app(e)->get_num_args(), to_app(e)->get_args());
}
else {
TRACE("qe", tout << "expression not handled " << mk_pp(e, m) << "\n";);
}
}
}
public:
void extract_literals(model& model, expr_ref_vector& fmls) {
expr_ref val(m);
for (unsigned i = 0; i < fmls.size(); ++i) {
expr* fml = fmls[i].get(), *nfml, *f1, *f2, *f3;
SASSERT(m.is_bool(fml));
if (m.is_not(fml, nfml) && m.is_distinct(nfml)) {
fmls[i] = project_plugin::pick_equality(m, model, nfml);
--i;
@ -205,26 +242,28 @@ public:
f1 = mk_not(m, f1);
f2 = mk_not(m, f2);
}
project_plugin::push_back(fmls, f1);
fmls[i] = f1;
project_plugin::push_back(fmls, f2);
project_plugin::erase(fmls, i);
--i;
}
else if (m.is_implies(fml, f1, f2)) {
VERIFY (model.eval(f2, val));
if (m.is_true(val)) {
project_plugin::push_back(fmls, f2);
fmls[i] = f2;
}
else {
project_plugin::push_back(fmls, mk_not(m, f1));
fmls[i] = mk_not(m, f1);
}
project_plugin::erase(fmls, i);
--i;
}
else if (m.is_ite(fml, f1, f2, f3)) {
VERIFY (model.eval(f1, val));
if (m.is_true(val)) {
project_plugin::push_back(fmls, f1);
project_plugin::push_back(fmls, f2);
}
else {
project_plugin::push_back(fmls, mk_not(m, f1));
project_plugin::push_back(fmls, f3);
}
project_plugin::erase(fmls, i);
@ -269,17 +308,24 @@ public:
else if (m.is_not(fml, nfml) && m.is_ite(nfml, f1, f2, f3)) {
VERIFY (model.eval(f1, val));
if (m.is_true(val)) {
project_plugin::push_back(fmls, f1);
project_plugin::push_back(fmls, mk_not(m, f2));
}
else {
project_plugin::push_back(fmls, mk_not(m, f1));
project_plugin::push_back(fmls, mk_not(m, f3));
}
project_plugin::erase(fmls, i);
}
else if (m.is_not(fml, nfml)) {
extract_bools(model, fmls, nfml);
}
else {
extract_bools(model, fmls, fml);
// TBD other Boolean operations.
}
}
m_visited.reset();
}
impl(ast_manager& m):m(m) {
@ -310,6 +356,7 @@ public:
app_ref var(m);
th_rewriter rw(m);
bool progress = true;
TRACE("qe", tout << vars << " " << fmls << "\n";);
while (progress && !vars.empty()) {
preprocess_solve(model, vars, fmls);
app_ref_vector new_vars(m);
@ -345,6 +392,7 @@ public:
}
vars.append(new_vars);
}
TRACE("qe", tout << vars << " " << fmls << "\n";);
}
};