mirror of
https://github.com/Z3Prover/z3
synced 2025-04-13 04:28:17 +00:00
working on revising project0 to project
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
9379ec3a68
commit
076cfa5813
|
@ -30,6 +30,7 @@ Notes:
|
|||
|
||||
#include "ast/ast_util.h"
|
||||
#include "ast/for_each_expr.h"
|
||||
#include "ast/rewriter/expr_safe_replace.h"
|
||||
#include "ast/rewriter/bool_rewriter.h"
|
||||
#include "ast/arith_decl_plugin.h"
|
||||
#include "model/model_evaluator.h"
|
||||
|
@ -329,7 +330,108 @@ namespace qe {
|
|||
if (!get_literals(mdl, lits)) {
|
||||
return mbi_undef;
|
||||
}
|
||||
TRACE("qe", tout << lits << "\n";);
|
||||
project0(mdl, lits);
|
||||
return mbi_sat;
|
||||
}
|
||||
default:
|
||||
// TBD: if not running solver to completion, then:
|
||||
// 1. extract unit literals from m_solver.
|
||||
// 2. run a cc over the units
|
||||
// 3. extract equalities or other assignments over the congruence classes
|
||||
// 4. ensure that at least some progress is made over original lits.
|
||||
return mbi_undef;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
1. extract arithmetical variables, purify.
|
||||
2. project private variables from lits
|
||||
3. Order arithmetical variables.
|
||||
4. Perform arithmetical projection.
|
||||
5. Substitute solution into lits
|
||||
*/
|
||||
void euf_arith_mbi_plugin::project(model_ref& mdl, expr_ref_vector& lits) {
|
||||
TRACE("qe", tout << lits << "\n" << *mdl << "\n";);
|
||||
|
||||
// 1. arithmetical variables
|
||||
app_ref_vector avars = get_arith_vars(mdl, lits);
|
||||
TRACE("qe", tout << "vars: " << avars << " lits: " << lits << "\n";);
|
||||
|
||||
|
||||
// 2. project private variables from lits
|
||||
{
|
||||
term_graph tg(m);
|
||||
func_decl_ref_vector shared(m_shared);
|
||||
for (app* a : avars) shared.push_back(a->get_decl());
|
||||
tg.set_vars(shared, false);
|
||||
tg.add_lits(lits);
|
||||
lits.reset();
|
||||
lits.append(tg.project(*mdl.get()));
|
||||
TRACE("qe", tout << "project: " << lits << "\n";);
|
||||
}
|
||||
|
||||
// 3. Order arithmetical variables
|
||||
order_avars(mdl, lits, avars);
|
||||
|
||||
// 4. Arithmetical projection
|
||||
arith_project_plugin ap(m);
|
||||
ap.set_check_purified(false);
|
||||
auto defs = ap.project(*mdl.get(), avars, lits);
|
||||
|
||||
// 5. Substitute solution
|
||||
for (auto const& def : defs) {
|
||||
expr_safe_replace rep(m);
|
||||
rep.insert(def.var, def.term);
|
||||
for (unsigned i = 0; i < lits.size(); ++i) {
|
||||
expr_ref tmp(m);
|
||||
rep(lits.get(i), tmp);
|
||||
lits[i] = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void euf_arith_mbi_plugin::order_avars(model_ref& mdl, expr_ref_vector& lits, app_ref_vector& avars) {
|
||||
arith_util a(m);
|
||||
model_evaluator mev(*mdl.get());
|
||||
vector<std::pair<rational, app*>> vals;
|
||||
for (app* v : avars) {
|
||||
rational val;
|
||||
expr_ref tmp = mev(v);
|
||||
VERIFY(a.is_numeral(tmp, val));
|
||||
vals.push_back(std::make_pair(val, v));
|
||||
}
|
||||
struct compare_first {
|
||||
bool operator()(std::pair<rational, app*> const& x,
|
||||
std::pair<rational, app*> const& y) const {
|
||||
return x.first < y.first;
|
||||
}
|
||||
};
|
||||
// add linear order between avars
|
||||
compare_first cmp;
|
||||
std::sort(vals.begin(), vals.end(), cmp);
|
||||
for (unsigned i = 1; i < vals.size(); ++i) {
|
||||
if (vals[i-1].first == vals[i].first) {
|
||||
lits.push_back(m.mk_eq(vals[i-1].second, vals[i].second));
|
||||
}
|
||||
else {
|
||||
lits.push_back(a.mk_lt(vals[i-1].second, vals[i].second));
|
||||
}
|
||||
}
|
||||
// sort avars based on depth
|
||||
struct compare_depth {
|
||||
bool operator()(app* x, app* y) const {
|
||||
return x->get_depth() > y->get_depth();
|
||||
}
|
||||
};
|
||||
compare_depth cmpd;
|
||||
std::sort(avars.c_ptr(), avars.c_ptr() + avars.size(), cmpd);
|
||||
TRACE("qe", tout << lits << "\navars:" << avars << "\n" << *mdl << "\n";);
|
||||
}
|
||||
|
||||
|
||||
void euf_arith_mbi_plugin::project0(model_ref& mdl, expr_ref_vector& lits) {
|
||||
TRACE("qe", tout << lits << "\n" << *mdl << "\n";);
|
||||
|
||||
|
||||
// 1. Extract projected variables, add inequalities between
|
||||
// projected variables and non-projected terms according to model.
|
||||
|
@ -409,16 +511,6 @@ namespace qe {
|
|||
lits.reset();
|
||||
lits.append(tg2.project());
|
||||
TRACE("qe", tout << "project: " << lits << "\n";);
|
||||
return mbi_sat;
|
||||
}
|
||||
default:
|
||||
// TBD: if not running solver to completion, then:
|
||||
// 1. extract unit literals from m_solver.
|
||||
// 2. run a cc over the units
|
||||
// 3. extract equalities or other assignments over the congruence classes
|
||||
// 4. ensure that at least some progress is made over original lits.
|
||||
return mbi_undef;
|
||||
}
|
||||
}
|
||||
|
||||
void euf_arith_mbi_plugin::block(expr_ref_vector const& lits) {
|
||||
|
|
|
@ -115,6 +115,9 @@ namespace qe {
|
|||
app_ref_vector get_arith_vars(model_ref& mdl, expr_ref_vector& lits);
|
||||
bool get_literals(model_ref& mdl, expr_ref_vector& lits);
|
||||
void collect_atoms(expr_ref_vector const& fmls);
|
||||
void project0(model_ref& mdl, expr_ref_vector& lits);
|
||||
void project(model_ref& mdl, expr_ref_vector& lits);
|
||||
void order_avars(model_ref& mdl, expr_ref_vector& lits, app_ref_vector& avars);
|
||||
public:
|
||||
euf_arith_mbi_plugin(solver* s, solver* emptySolver);
|
||||
~euf_arith_mbi_plugin() override {}
|
||||
|
|
|
@ -815,6 +815,7 @@ namespace qe {
|
|||
for (expr* r : roots) {
|
||||
args.push_back(r);
|
||||
}
|
||||
TRACE("qe", tout << "function: " << d->get_name() << "\n";);
|
||||
res.push_back(m.mk_distinct(args.size(), args.c_ptr()));
|
||||
}
|
||||
}
|
||||
|
@ -965,6 +966,7 @@ namespace qe {
|
|||
m_pinned.reset();
|
||||
m_model.reset();
|
||||
}
|
||||
|
||||
expr_ref_vector project() {
|
||||
expr_ref_vector res(m);
|
||||
purify();
|
||||
|
|
Loading…
Reference in a new issue