diff --git a/src/cmd_context/extra_cmds/dbg_cmds.cpp b/src/cmd_context/extra_cmds/dbg_cmds.cpp index ceb979761..1b378f430 100644 --- a/src/cmd_context/extra_cmds/dbg_cmds.cpp +++ b/src/cmd_context/extra_cmds/dbg_cmds.cpp @@ -369,7 +369,7 @@ public: void set_next_arg(cmd_context & ctx, unsigned num, expr * const * ts) override { m_vars.append(num, ts); } - void prepare(cmd_context & ctx) override { m_fml = nullptr; m_vars.reset(); } + void prepare(cmd_context & ctx) override { m_fml = nullptr; } void execute(cmd_context & ctx) override { ast_manager& m = ctx.m(); app_ref_vector vars(m); diff --git a/src/qe/qe_arrays.cpp b/src/qe/qe_arrays.cpp index df5c7f44e..e582676a8 100644 --- a/src/qe/qe_arrays.cpp +++ b/src/qe/qe_arrays.cpp @@ -631,13 +631,13 @@ namespace qe { m_v = arr_vars.get (i); if (!m_arr_u.is_array (m_v)) { TRACE ("qe", - tout << "not an array variable: " << mk_pp (m_v, m) << "\n"; + tout << "not an array variable: " << m_v << "\n"; ); aux_vars.push_back (m_v); continue; } TRACE ("qe", - tout << "projecting equalities on variable: " << mk_pp (m_v, m) << "\n"; + tout << "projecting equalities on variable: " << m_v << "\n"; ); if (project (fml)) { @@ -653,8 +653,8 @@ namespace qe { ); } else { - IF_VERBOSE(2, verbose_stream() << "can't project:" << mk_pp(m_v, m) << "\n";); - TRACE ("qe", tout << "Failed to project: " << mk_pp (m_v, m) << "\n";); + IF_VERBOSE(2, verbose_stream() << "can't project:" << m_v << "\n";); + TRACE ("qe", tout << "Failed to project: " << m_v << "\n";); arr_vars[j++] = m_v; } } @@ -1196,67 +1196,6 @@ namespace qe { return false; } - bool operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { - - TRACE("qe", tout << mk_pp(var, m) << "\n" << lits;); - m_var = alloc(contains_app, m, var); - - // reduce select-store redeces based on model. - // rw_cfg rw(m); - // rw(lits); - - // try first to solve for var. - if (solve_eq(model, vars, lits)) { - return true; - } - - app_ref_vector selects(m); - - // check that only non-select occurrences are in disequalities. - if (!check_diseqs(lits, selects)) { - TRACE("qe", tout << "Could not project " << mk_pp(var, m) << " for:\n" << lits << "\n";); - return false; - } - - // remove disequalities. - elim_diseqs(lits); - - // Ackerman reduction on remaining select occurrences - // either replace occurrences by model value or other node - // that is congruent to model value. - - ackermanize_select(model, selects, vars, lits); - - TRACE("qe", tout << selects << "\n" << lits << "\n";); - return true; - } - - void ackermanize_select(model& model, app_ref_vector const& selects, app_ref_vector& vars, expr_ref_vector& lits) { - expr_ref_vector vals(m), reps(m); - expr_ref val(m); - expr_safe_replace sub(m); - - if (selects.empty()) { - return; - } - - app_ref sel(m); - for (unsigned i = 0; i < selects.size(); ++i) { - sel = m.mk_fresh_const("sel", m.get_sort(selects[i])); - VERIFY (model.eval(selects[i], val)); - model.register_decl(sel->get_decl(), val); - vals.push_back(to_app(val)); - reps.push_back(val); // TODO: direct pass could handle nested selects. - vars.push_back(sel); - sub.insert(selects[i], val); - } - - sub(lits); - remove_true(lits); - project_plugin::partition_args(model, selects, lits); - project_plugin::partition_values(model, reps, lits); - } - void remove_true(expr_ref_vector& lits) { for (unsigned i = 0; i < lits.size(); ++i) { if (m.is_true(lits[i].get())) { @@ -1275,113 +1214,7 @@ namespace qe { for (unsigned j = 0; j < n; ++j) { lits.push_back(m.mk_eq(x.m_vars[j], y.m_vars[j])); } - } - - // check that x occurs only under selects or in disequalities. - bool check_diseqs(expr_ref_vector const& lits, app_ref_vector& selects) { - expr_mark mark; - ptr_vector todo; - app* e; - for (unsigned i = 0; i < lits.size(); ++i) { - e = to_app(lits[i]); - if (is_diseq_x(e)) { - continue; - } - if (contains_x(e)) { - todo.push_back(e); - } - } - while (!todo.empty()) { - e = todo.back(); - todo.pop_back(); - if (mark.is_marked(e)) { - continue; - } - mark.mark(e); - if (m_var->x() == e) { - return false; - } - unsigned start = 0; - if (a.is_select(e)) { - if (e->get_arg(0) == m_var->x()) { - start = 1; - selects.push_back(e); - } - } - for (unsigned i = start; i < e->get_num_args(); ++i) { - todo.push_back(to_app(e->get_arg(i))); - } - } - return true; - } - - void elim_diseqs(expr_ref_vector& lits) { - for (unsigned i = 0; i < lits.size(); ++i) { - if (is_diseq_x(lits[i].get())) { - project_plugin::erase(lits, i); - } - } - } - - bool is_update_x(app* e) { - do { - if (m_var->x() == e) { - return true; - } - if (a.is_store(e) && contains_x(e->get_arg(0))) { - for (unsigned i = 1; i < e->get_num_args(); ++i) { - if (contains_x(e->get_arg(i))) { - return false; - } - } - e = to_app(e->get_arg(0)); - continue; - } - } - while (false); - return false; - } - - bool is_diseq_x(expr* e) { - expr *f, * s, *t; - if (m.is_not(e, f) && m.is_eq(f, s, t)) { - if (contains_x(s) && !contains_x(t) && is_update_x(to_app(s))) return true; - if (contains_x(t) && !contains_x(s) && is_update_x(to_app(t))) return true; - } - return false; - } - - bool solve_eq(model& model, app_ref_vector& vars, expr_ref_vector& lits) { - // find an equality to solve for. - expr* s, *t; - for (unsigned i = 0; i < lits.size(); ++i) { - if (m.is_eq(lits[i].get(), s, t)) { - vector idxs; - expr_ref save(m), back(m); - save = lits[i].get(); - back = lits.back(); - lits[i] = back; - lits.pop_back(); - unsigned sz = lits.size(); - if (contains_x(s) && !contains_x(t) && is_app(s)) { - if (solve(model, to_app(s), t, idxs, vars, lits)) { - return true; - } - } - else if (contains_x(t) && !contains_x(s) && is_app(t)) { - if (solve(model, to_app(t), s, idxs, vars, lits)) { - return true; - } - } - // put back the equality literal. - lits.resize(sz); - lits.push_back(back); - lits[i] = save; - } - // TBD: not distinct? - } - return false; - } + } bool solve(model& model, app* s, expr* t, vector& idxs, app_ref_vector& vars, expr_ref_vector& lits) { SASSERT(contains_x(s)); @@ -1502,7 +1335,13 @@ namespace qe { } bool array_project_plugin::operator()(model& model, app* var, app_ref_vector& vars, expr_ref_vector& lits) { - return (*m_imp)(model, var, vars, lits); + ast_manager& m = vars.get_manager(); + app_ref_vector vvars(m, 1, &var); + expr_ref fml = mk_and(lits); + (*this)(model, vvars, fml, vars, false); + lits.reset(); + flatten_and(fml, lits); + return true; } bool array_project_plugin::solve(model& model, app_ref_vector& vars, expr_ref_vector& lits) { diff --git a/src/qe/qe_mbp.cpp b/src/qe/qe_mbp.cpp index b07e9904c..58eb77bb4 100644 --- a/src/qe/qe_mbp.cpp +++ b/src/qe/qe_mbp.cpp @@ -99,6 +99,7 @@ void project_plugin::partition_values(model& model, expr_ref_vector const& vals, } } +#if 0 void project_plugin::partition_args(model& model, app_ref_vector const& selects, expr_ref_vector& lits) { ast_manager& m = selects.get_manager(); if (selects.empty()) return; @@ -111,6 +112,7 @@ void project_plugin::partition_args(model& model, app_ref_vector const& selects, project_plugin::partition_values(model, args, lits); } } +#endif void project_plugin::erase(expr_ref_vector& lits, unsigned& i) { lits[i] = lits.back(); diff --git a/src/qe/qe_mbp.h b/src/qe/qe_mbp.h index 25a95e885..665e25d48 100644 --- a/src/qe/qe_mbp.h +++ b/src/qe/qe_mbp.h @@ -40,6 +40,8 @@ namespace qe { virtual void operator()(model& model, app_ref_vector& vars, expr_ref_vector& lits) { }; 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); + //static void partition_args(model& model, app_ref_vector const& sels, expr_ref_vector& lits); static void erase(expr_ref_vector& lits, unsigned& i); static void push_back(expr_ref_vector& lits, expr* lit); static void mark_rec(expr_mark& visited, expr* e);