mirror of
https://github.com/Z3Prover/z3
synced 2025-04-12 04:03:39 +00:00
mbqi
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
34e0e26e3d
commit
1ee2ba2a9b
|
@ -590,32 +590,29 @@ public:
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
out << "[" << j << "]\t";
|
out << "[" << j << "] " << std::setw(6) << " := " << m_x[j];
|
||||||
|
if (m_basis_heading[j] >= 0)
|
||||||
|
out << " base\t";
|
||||||
|
else
|
||||||
|
out << " \t";
|
||||||
switch (m_column_types[j]) {
|
switch (m_column_types[j]) {
|
||||||
case column_type::fixed:
|
case column_type::fixed:
|
||||||
case column_type::boxed:
|
case column_type::boxed:
|
||||||
out << " [" << m_lower_bounds[j] << ", " << m_upper_bounds[j] << "]";
|
out << "[" << m_lower_bounds[j] << ", " << m_upper_bounds[j] << "]";
|
||||||
break;
|
break;
|
||||||
case column_type::lower_bound:
|
case column_type::lower_bound:
|
||||||
out << " [" << m_lower_bounds[j] << "," << "oo" << "]";
|
out << "[" << m_lower_bounds[j] << ", oo" << "]";
|
||||||
break;
|
break;
|
||||||
case column_type::upper_bound:
|
case column_type::upper_bound:
|
||||||
out << " [-oo, " << m_upper_bounds[j] << ']';
|
out << "[-oo, " << m_upper_bounds[j] << ']';
|
||||||
break;
|
break;
|
||||||
case column_type::free_column:
|
case column_type::free_column:
|
||||||
out << " [-oo, oo]";
|
out << "[-oo, oo]";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
lp_assert(false);
|
lp_assert(false);
|
||||||
}
|
}
|
||||||
// out << "basis heading = " << m_basis_heading[j] << std::endl;
|
return out << "\n";
|
||||||
out << "\tx = " << m_x[j];
|
|
||||||
if (m_basis_heading[j] >= 0)
|
|
||||||
out << " base\n";
|
|
||||||
else
|
|
||||||
out << " \n";
|
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool column_is_free(unsigned j) const { return this->m_column_types[j] == column_type::free_column; }
|
bool column_is_free(unsigned j) const { return this->m_column_types[j] == column_type::free_column; }
|
||||||
|
|
|
@ -215,6 +215,13 @@ void func_interp::insert_new_entry(expr * const * args, expr * r) {
|
||||||
m_entries.push_back(new_entry);
|
m_entries.push_back(new_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void func_interp::del_entry(unsigned idx) {
|
||||||
|
auto* e = m_entries[idx];
|
||||||
|
m_entries[idx] = m_entries.back();
|
||||||
|
m_entries.pop_back();
|
||||||
|
e->deallocate(m(), m_arity);
|
||||||
|
}
|
||||||
|
|
||||||
bool func_interp::eval_else(expr * const * args, expr_ref & result) const {
|
bool func_interp::eval_else(expr * const * args, expr_ref & result) const {
|
||||||
if (m_else == nullptr)
|
if (m_else == nullptr)
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -109,6 +109,7 @@ public:
|
||||||
ptr_vector<func_entry>::const_iterator end() const { return m_entries.end(); }
|
ptr_vector<func_entry>::const_iterator end() const { return m_entries.end(); }
|
||||||
func_entry const * const * get_entries() const { return m_entries.c_ptr(); }
|
func_entry const * const * get_entries() const { return m_entries.c_ptr(); }
|
||||||
func_entry const * get_entry(unsigned idx) const { return m_entries[idx]; }
|
func_entry const * get_entry(unsigned idx) const { return m_entries[idx]; }
|
||||||
|
void del_entry(unsigned idx);
|
||||||
|
|
||||||
expr * get_max_occ_result() const;
|
expr * get_max_occ_result() const;
|
||||||
void compress();
|
void compress();
|
||||||
|
|
|
@ -37,7 +37,14 @@ namespace mbp {
|
||||||
|
|
||||||
ast_manager& m;
|
ast_manager& m;
|
||||||
arith_util a;
|
arith_util a;
|
||||||
bool m_check_purified; // check that variables are properly pure
|
bool m_check_purified { true }; // check that variables are properly pure
|
||||||
|
bool m_apply_projection { false };
|
||||||
|
|
||||||
|
|
||||||
|
imp(ast_manager& m) :
|
||||||
|
m(m), a(m) {}
|
||||||
|
|
||||||
|
~imp() {}
|
||||||
|
|
||||||
void insert_mul(expr* x, rational const& v, obj_map<expr, rational>& ts) {
|
void insert_mul(expr* x, rational const& v, obj_map<expr, rational>& ts) {
|
||||||
// TRACE("qe", tout << "Adding variable " << mk_pp(x, m) << " " << v << "\n";);
|
// TRACE("qe", tout << "Adding variable " << mk_pp(x, m) << " " << v << "\n";);
|
||||||
|
@ -238,11 +245,6 @@ namespace mbp {
|
||||||
return rational(b.is_pos()?-1:1);
|
return rational(b.is_pos()?-1:1);
|
||||||
}
|
}
|
||||||
|
|
||||||
imp(ast_manager& m):
|
|
||||||
m(m), a(m), m_check_purified(true) {}
|
|
||||||
|
|
||||||
~imp() {}
|
|
||||||
|
|
||||||
bool operator()(model& model, app* v, app_ref_vector& vars, expr_ref_vector& lits) {
|
bool operator()(model& model, app* v, app_ref_vector& vars, expr_ref_vector& lits) {
|
||||||
app_ref_vector vs(m);
|
app_ref_vector vs(m);
|
||||||
vs.push_back(v);
|
vs.push_back(v);
|
||||||
|
@ -271,6 +273,7 @@ namespace mbp {
|
||||||
model_evaluator eval(model);
|
model_evaluator eval(model);
|
||||||
TRACE("qe", tout << model;);
|
TRACE("qe", tout << model;);
|
||||||
eval.set_model_completion(true);
|
eval.set_model_completion(true);
|
||||||
|
compute_def |= m_apply_projection;
|
||||||
|
|
||||||
opt::model_based_opt mbo;
|
opt::model_based_opt mbo;
|
||||||
obj_map<expr, unsigned> tids;
|
obj_map<expr, unsigned> tids;
|
||||||
|
@ -341,15 +344,19 @@ namespace mbp {
|
||||||
for (unsigned v : real_vars) tout << "v" << v << " " << mk_pp(index2expr[v], m) << "\n";
|
for (unsigned v : real_vars) tout << "v" << v << " " << mk_pp(index2expr[v], m) << "\n";
|
||||||
mbo.display(tout););
|
mbo.display(tout););
|
||||||
vector<opt::model_based_opt::def> defs = mbo.project(real_vars.size(), real_vars.c_ptr(), compute_def);
|
vector<opt::model_based_opt::def> defs = mbo.project(real_vars.size(), real_vars.c_ptr(), compute_def);
|
||||||
TRACE("qe", mbo.display(tout << "mbo result\n");
|
|
||||||
for (auto const& d : defs) tout << "def: " << d << "\n";);
|
|
||||||
vector<row> rows;
|
vector<row> rows;
|
||||||
mbo.get_live_rows(rows);
|
mbo.get_live_rows(rows);
|
||||||
rows2fmls(rows, index2expr, fmls);
|
rows2fmls(rows, index2expr, fmls);
|
||||||
|
TRACE("qe", mbo.display(tout << "mbo result\n");
|
||||||
|
for (auto const& d : defs) tout << "def: " << d << "\n";
|
||||||
|
tout << fmls << "\n";);
|
||||||
|
|
||||||
vector<def> result;
|
vector<def> result;
|
||||||
if (compute_def)
|
if (compute_def)
|
||||||
optdefs2mbpdef(defs, index2expr, real_vars, result);
|
optdefs2mbpdef(defs, index2expr, real_vars, result);
|
||||||
|
if (m_apply_projection)
|
||||||
|
apply_projection(result, fmls);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -523,6 +530,20 @@ namespace mbp {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void apply_projection(vector<def>& defs, expr_ref_vector& fmls) {
|
||||||
|
if (fmls.empty() || defs.empty())
|
||||||
|
return;
|
||||||
|
expr_safe_replace subst(m);
|
||||||
|
for (auto const& d : defs)
|
||||||
|
subst.insert(d.var, d.term);
|
||||||
|
unsigned j = 0;
|
||||||
|
expr_ref tmp(m);
|
||||||
|
for (expr* fml : fmls) {
|
||||||
|
subst(fml, tmp);
|
||||||
|
fmls[j++] = tmp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
arith_project_plugin::arith_project_plugin(ast_manager& m):project_plugin(m) {
|
arith_project_plugin::arith_project_plugin(ast_manager& m):project_plugin(m) {
|
||||||
|
@ -549,6 +570,10 @@ namespace mbp {
|
||||||
m_imp->m_check_purified = check_purified;
|
m_imp->m_check_purified = check_purified;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void arith_project_plugin::set_apply_projection(bool f) {
|
||||||
|
m_imp->m_apply_projection = f;
|
||||||
|
}
|
||||||
|
|
||||||
family_id arith_project_plugin::get_family_id() {
|
family_id arith_project_plugin::get_family_id() {
|
||||||
return m_imp->a.get_family_id();
|
return m_imp->a.get_family_id();
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,11 @@ namespace mbp {
|
||||||
*/
|
*/
|
||||||
void set_check_purified(bool check_purified);
|
void set_check_purified(bool check_purified);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief apply projection
|
||||||
|
*/
|
||||||
|
void set_apply_projection(bool apply_project);
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool arith_project(model& model, app* var, expr_ref_vector& lits);
|
bool arith_project(model& model, app* var, expr_ref_vector& lits);
|
||||||
|
|
|
@ -327,10 +327,10 @@ namespace mbp {
|
||||||
|
|
||||||
void project_plugin::purify(euf_inverter& inv, model& mdl, app_ref_vector const& vars, expr_ref_vector& lits) {
|
void project_plugin::purify(euf_inverter& inv, model& mdl, app_ref_vector const& vars, expr_ref_vector& lits) {
|
||||||
TRACE("mbp", tout << lits << "\n" << mdl << "\n";);
|
TRACE("mbp", tout << lits << "\n" << mdl << "\n";);
|
||||||
|
model_evaluator eval(mdl);
|
||||||
extract_literals(mdl, vars, lits);
|
extract_literals(mdl, vars, lits);
|
||||||
if (!m.inc())
|
if (!m.inc())
|
||||||
return;
|
return;
|
||||||
model_evaluator eval(mdl);
|
|
||||||
eval.set_expand_array_equalities(true);
|
eval.set_expand_array_equalities(true);
|
||||||
m_non_ground.reset();
|
m_non_ground.reset();
|
||||||
m_to_visit.reset();
|
m_to_visit.reset();
|
||||||
|
@ -341,7 +341,6 @@ namespace mbp {
|
||||||
m_non_ground.mark(v);
|
m_non_ground.mark(v);
|
||||||
for (unsigned i = 0; m.inc() && i < lits.size(); ++i)
|
for (unsigned i = 0; m.inc() && i < lits.size(); ++i)
|
||||||
lits[i] = purify(inv, eval, lits.get(i), lits);
|
lits[i] = purify(inv, eval, lits.get(i), lits);
|
||||||
std::cout << m_pure_eqs << "\n";
|
|
||||||
lits.append(m_pure_eqs);
|
lits.append(m_pure_eqs);
|
||||||
TRACE("mbp", tout << lits << "\n";);
|
TRACE("mbp", tout << lits << "\n";);
|
||||||
}
|
}
|
||||||
|
|
|
@ -296,21 +296,19 @@ namespace arith {
|
||||||
return lp::EQ;
|
return lp::EQ;
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::mk_eq_axiom(theory_var v1, theory_var v2) {
|
void solver::mk_eq_axiom(bool is_eq, theory_var v1, theory_var v2) {
|
||||||
if (is_bool(v1))
|
if (is_bool(v1))
|
||||||
return;
|
return;
|
||||||
expr* e1 = var2expr(v1);
|
expr* e1 = var2expr(v1);
|
||||||
expr* e2 = var2expr(v2);
|
expr* e2 = var2expr(v2);
|
||||||
if (e1 == e2)
|
if (is_eq && m.are_equal(e1, e2))
|
||||||
return;
|
return;
|
||||||
|
if (!is_eq && m.are_distinct(e1, e2))
|
||||||
|
return;
|
||||||
literal le, ge;
|
literal le, ge;
|
||||||
if (a.is_numeral(e1))
|
if (a.is_numeral(e1))
|
||||||
std::swap(e1, e2);
|
std::swap(e1, e2);
|
||||||
if (a.is_numeral(e1)) {
|
SASSERT(!a.is_numeral(e1));
|
||||||
add_unit(~mk_literal(m.mk_eq(e1, e2)));
|
|
||||||
std::cout << "two numerals\n";
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
literal eq = eq_internalize(e1, e2);
|
literal eq = eq_internalize(e1, e2);
|
||||||
if (a.is_numeral(e2)) {
|
if (a.is_numeral(e2)) {
|
||||||
le = mk_literal(a.mk_le(e1, e2));
|
le = mk_literal(a.mk_le(e1, e2));
|
||||||
|
@ -321,8 +319,11 @@ namespace arith {
|
||||||
expr_ref zero(a.mk_numeral(rational(0), a.is_int(e1)), m);
|
expr_ref zero(a.mk_numeral(rational(0), a.is_int(e1)), m);
|
||||||
rewrite(diff);
|
rewrite(diff);
|
||||||
if (a.is_numeral(diff)) {
|
if (a.is_numeral(diff)) {
|
||||||
std::cout << "diff " << diff << " " << mk_pp(e1, m) << " " << mk_pp(e2, m) << "\n";
|
if (is_eq && a.is_zero(diff))
|
||||||
if (zero == diff)
|
return;
|
||||||
|
if (!is_eq && !a.is_zero(diff))
|
||||||
|
return;
|
||||||
|
if (a.is_zero(diff))
|
||||||
add_unit(eq);
|
add_unit(eq);
|
||||||
else
|
else
|
||||||
add_unit(~eq);
|
add_unit(~eq);
|
||||||
|
@ -331,8 +332,8 @@ namespace arith {
|
||||||
le = mk_literal(a.mk_le(diff, zero));
|
le = mk_literal(a.mk_le(diff, zero));
|
||||||
ge = mk_literal(a.mk_ge(diff, zero));
|
ge = mk_literal(a.mk_ge(diff, zero));
|
||||||
}
|
}
|
||||||
std::cout << mk_pp(e1, m) << " " << mk_pp(e2, m) << " ";
|
// std::cout << "eq " << mk_pp(e1, m) << " " << mk_pp(e2, m) << " ";
|
||||||
std::cout << le << " " << ge << "\n";
|
// std::cout << le << " " << ge << "\n";
|
||||||
add_clause(~eq, le);
|
add_clause(~eq, le);
|
||||||
add_clause(~eq, ge);
|
add_clause(~eq, ge);
|
||||||
add_clause(~le, ~ge, eq);
|
add_clause(~le, ~ge, eq);
|
||||||
|
|
|
@ -21,6 +21,7 @@ Author:
|
||||||
namespace arith {
|
namespace arith {
|
||||||
|
|
||||||
sat::literal solver::internalize(expr* e, bool sign, bool root, bool learned) {
|
sat::literal solver::internalize(expr* e, bool sign, bool root, bool learned) {
|
||||||
|
force_push();
|
||||||
flet<bool> _is_learned(m_is_redundant, learned);
|
flet<bool> _is_learned(m_is_redundant, learned);
|
||||||
internalize_atom(e);
|
internalize_atom(e);
|
||||||
literal lit = ctx.expr2literal(e);
|
literal lit = ctx.expr2literal(e);
|
||||||
|
@ -30,6 +31,7 @@ namespace arith {
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::internalize(expr* e, bool redundant) {
|
void solver::internalize(expr* e, bool redundant) {
|
||||||
|
force_push();
|
||||||
flet<bool> _is_learned(m_is_redundant, redundant);
|
flet<bool> _is_learned(m_is_redundant, redundant);
|
||||||
if (m.is_bool(e))
|
if (m.is_bool(e))
|
||||||
internalize_atom(e);
|
internalize_atom(e);
|
||||||
|
|
|
@ -583,7 +583,7 @@ namespace arith {
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::push_core() {
|
void solver::push_core() {
|
||||||
TRACE("arith", tout << "push\n";);
|
TRACE("arith_verbose", tout << "push\n";);
|
||||||
m_scopes.push_back(scope());
|
m_scopes.push_back(scope());
|
||||||
scope& sc = m_scopes.back();
|
scope& sc = m_scopes.back();
|
||||||
sc.m_bounds_lim = m_bounds_trail.size();
|
sc.m_bounds_lim = m_bounds_trail.size();
|
||||||
|
@ -596,11 +596,11 @@ namespace arith {
|
||||||
if (m_nla)
|
if (m_nla)
|
||||||
m_nla->push();
|
m_nla->push();
|
||||||
th_euf_solver::push_core();
|
th_euf_solver::push_core();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::pop_core(unsigned num_scopes) {
|
void solver::pop_core(unsigned num_scopes) {
|
||||||
TRACE("arith", tout << "pop " << num_scopes << "\n";);
|
TRACE("arith", tout << "pop " << num_scopes << "\n";);
|
||||||
th_euf_solver::pop_core(num_scopes);
|
|
||||||
unsigned old_size = m_scopes.size() - num_scopes;
|
unsigned old_size = m_scopes.size() - num_scopes;
|
||||||
del_bounds(m_scopes[old_size].m_bounds_lim);
|
del_bounds(m_scopes[old_size].m_bounds_lim);
|
||||||
m_idiv_terms.shrink(m_scopes[old_size].m_idiv_lim);
|
m_idiv_terms.shrink(m_scopes[old_size].m_idiv_lim);
|
||||||
|
@ -613,7 +613,8 @@ namespace arith {
|
||||||
m_new_bounds.reset();
|
m_new_bounds.reset();
|
||||||
if (m_nla)
|
if (m_nla)
|
||||||
m_nla->pop(num_scopes);
|
m_nla->pop(num_scopes);
|
||||||
TRACE("arith", tout << "num scopes: " << num_scopes << " new scope level: " << m_scopes.size() << "\n";);
|
TRACE("arith_verbose", tout << "num scopes: " << num_scopes << " new scope level: " << m_scopes.size() << "\n";);
|
||||||
|
th_euf_solver::pop_core(num_scopes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void solver::del_bounds(unsigned old_size) {
|
void solver::del_bounds(unsigned old_size) {
|
||||||
|
@ -964,7 +965,7 @@ namespace arith {
|
||||||
return sat::check_result::CR_CONTINUE;
|
return sat::check_result::CR_CONTINUE;
|
||||||
case l_undef:
|
case l_undef:
|
||||||
TRACE("arith", tout << "check feasible is undef\n";);
|
TRACE("arith", tout << "check feasible is undef\n";);
|
||||||
return m.inc() ? sat::check_result::CR_CONTINUE : sat::check_result::CR_GIVEUP;
|
return sat::check_result::CR_CONTINUE;
|
||||||
case l_true:
|
case l_true:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -303,7 +303,7 @@ namespace arith {
|
||||||
void refine_bound(theory_var v, const lp::implied_bound& be);
|
void refine_bound(theory_var v, const lp::implied_bound& be);
|
||||||
literal is_bound_implied(lp::lconstraint_kind k, rational const& value, api_bound const& b) const;
|
literal is_bound_implied(lp::lconstraint_kind k, rational const& value, api_bound const& b) const;
|
||||||
void assert_bound(bool is_true, api_bound& b);
|
void assert_bound(bool is_true, api_bound& b);
|
||||||
void mk_eq_axiom(theory_var v1, theory_var v2);
|
void mk_eq_axiom(bool is_eq, theory_var v1, theory_var v2);
|
||||||
void assert_idiv_mod_axioms(theory_var u, theory_var v, theory_var w, rational const& r);
|
void assert_idiv_mod_axioms(theory_var u, theory_var v, theory_var w, rational const& r);
|
||||||
api_bound* mk_var_bound(sat::literal lit, theory_var v, lp_api::bound_kind bk, rational const& bound);
|
api_bound* mk_var_bound(sat::literal lit, theory_var v, lp_api::bound_kind bk, rational const& bound);
|
||||||
lp::lconstraint_kind bound2constraint_kind(bool is_int, lp_api::bound_kind bk, bool is_true);
|
lp::lconstraint_kind bound2constraint_kind(bool is_int, lp_api::bound_kind bk, bool is_true);
|
||||||
|
@ -423,8 +423,8 @@ namespace arith {
|
||||||
void collect_statistics(statistics& st) const override;
|
void collect_statistics(statistics& st) const override;
|
||||||
euf::th_solver* clone(euf::solver& ctx) override;
|
euf::th_solver* clone(euf::solver& ctx) override;
|
||||||
bool use_diseqs() const override { return true; }
|
bool use_diseqs() const override { return true; }
|
||||||
void new_eq_eh(euf::th_eq const& eq) override { mk_eq_axiom(eq.v1(), eq.v2()); }
|
void new_eq_eh(euf::th_eq const& eq) override { mk_eq_axiom(true, eq.v1(), eq.v2()); }
|
||||||
void new_diseq_eh(euf::th_eq const& de) override { mk_eq_axiom(de.v1(), de.v2()); }
|
void new_diseq_eh(euf::th_eq const& de) override { mk_eq_axiom(false, de.v1(), de.v2()); }
|
||||||
bool unit_propagate() override;
|
bool unit_propagate() override;
|
||||||
void init_model() override;
|
void init_model() override;
|
||||||
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
void add_value(euf::enode* n, model& mdl, expr_ref_vector& values) override;
|
||||||
|
|
|
@ -402,12 +402,15 @@ namespace euf {
|
||||||
if (!init_relevancy())
|
if (!init_relevancy())
|
||||||
give_up = true;
|
give_up = true;
|
||||||
|
|
||||||
for (auto* e : m_solvers)
|
for (auto* e : m_solvers) {
|
||||||
|
if (!m.inc())
|
||||||
|
return sat::check_result::CR_GIVEUP;
|
||||||
switch (e->check()) {
|
switch (e->check()) {
|
||||||
case sat::check_result::CR_CONTINUE: cont = true; break;
|
case sat::check_result::CR_CONTINUE: cont = true; break;
|
||||||
case sat::check_result::CR_GIVEUP: give_up = true; break;
|
case sat::check_result::CR_GIVEUP: give_up = true; break;
|
||||||
default: break;
|
default: break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (cont)
|
if (cont)
|
||||||
return sat::check_result::CR_CONTINUE;
|
return sat::check_result::CR_CONTINUE;
|
||||||
if (give_up)
|
if (give_up)
|
||||||
|
|
|
@ -39,6 +39,7 @@ namespace q {
|
||||||
{
|
{
|
||||||
auto* ap = alloc(mbp::arith_project_plugin, m);
|
auto* ap = alloc(mbp::arith_project_plugin, m);
|
||||||
ap->set_check_purified(false);
|
ap->set_check_purified(false);
|
||||||
|
ap->set_apply_projection(true);
|
||||||
add_plugin(ap);
|
add_plugin(ap);
|
||||||
add_plugin(alloc(mbp::datatype_project_plugin, m));
|
add_plugin(alloc(mbp::datatype_project_plugin, m));
|
||||||
add_plugin(alloc(mbp::array_project_plugin, m));
|
add_plugin(alloc(mbp::array_project_plugin, m));
|
||||||
|
@ -186,11 +187,13 @@ namespace q {
|
||||||
expr_ref mbqi::solver_project(model& mdl, q_body& qb) {
|
expr_ref mbqi::solver_project(model& mdl, q_body& qb) {
|
||||||
for (app* v : qb.vars)
|
for (app* v : qb.vars)
|
||||||
m_model->register_decl(v->get_decl(), mdl(v));
|
m_model->register_decl(v->get_decl(), mdl(v));
|
||||||
|
std::cout << "Project\n";
|
||||||
|
std::cout << *m_model << "\n";
|
||||||
|
std::cout << qb.vbody << "\n";
|
||||||
expr_ref_vector fmls(qb.vbody);
|
expr_ref_vector fmls(qb.vbody);
|
||||||
app_ref_vector vars(qb.vars);
|
app_ref_vector vars(qb.vars);
|
||||||
mbp::project_plugin proj(m);
|
mbp::project_plugin proj(m);
|
||||||
proj.purify(m_model_fixer, *m_model, vars, fmls);
|
proj.purify(m_model_fixer, *m_model, vars, fmls);
|
||||||
std::cout << "fmls\n" << fmls << "\n";
|
|
||||||
for (unsigned i = 0; i < vars.size(); ++i) {
|
for (unsigned i = 0; i < vars.size(); ++i) {
|
||||||
app* v = vars.get(i);
|
app* v = vars.get(i);
|
||||||
auto* p = get_plugin(v);
|
auto* p = get_plugin(v);
|
||||||
|
|
|
@ -103,15 +103,17 @@ namespace q {
|
||||||
|
|
||||||
void model_fixer::add_projection_functions(model& mdl, ptr_vector<quantifier> const& qs) {
|
void model_fixer::add_projection_functions(model& mdl, ptr_vector<quantifier> const& qs) {
|
||||||
func_decl_set fns;
|
func_decl_set fns;
|
||||||
|
TRACE("q", tout << mdl << "\n";);
|
||||||
collect_partial_functions(qs, fns);
|
collect_partial_functions(qs, fns);
|
||||||
for (func_decl* f : fns)
|
for (func_decl* f : fns)
|
||||||
add_projection_functions(mdl, f);
|
add_projection_functions(mdl, f);
|
||||||
|
TRACE("q", tout << mdl << "\n";);
|
||||||
}
|
}
|
||||||
|
|
||||||
void model_fixer::add_projection_functions(model& mdl, func_decl* f) {
|
void model_fixer::add_projection_functions(model& mdl, func_decl* f) {
|
||||||
// update interpretation of f so that the graph of f is fully determined by the
|
// update interpretation of f so that the graph of f is fully determined by the
|
||||||
// ground values of its arguments.
|
// ground values of its arguments.
|
||||||
TRACE("q", tout << mdl << "\n";);
|
|
||||||
func_interp* fi = mdl.get_func_interp(f);
|
func_interp* fi = mdl.get_func_interp(f);
|
||||||
if (!fi)
|
if (!fi)
|
||||||
return;
|
return;
|
||||||
|
@ -120,8 +122,12 @@ namespace q {
|
||||||
expr_ref_vector args(m);
|
expr_ref_vector args(m);
|
||||||
for (unsigned i = 0; i < f->get_arity(); ++i)
|
for (unsigned i = 0; i < f->get_arity(); ++i)
|
||||||
args.push_back(add_projection_function(mdl, f, i));
|
args.push_back(add_projection_function(mdl, f, i));
|
||||||
if (!fi->get_else() && fi->num_entries() > 0)
|
if (!fi->get_else() && fi->num_entries() > 0) {
|
||||||
fi->set_else(fi->get_entry(ctx.s().rand()(fi->num_entries()))->get_result());
|
unsigned idx = ctx.s().rand()(fi->num_entries());
|
||||||
|
func_entry const* e = fi->get_entry(idx);
|
||||||
|
fi->set_else(e->get_result());
|
||||||
|
fi->del_entry(idx);
|
||||||
|
}
|
||||||
bool has_projection = false;
|
bool has_projection = false;
|
||||||
for (expr* arg : args)
|
for (expr* arg : args)
|
||||||
has_projection |= !is_var(arg);
|
has_projection |= !is_var(arg);
|
||||||
|
@ -132,7 +138,6 @@ namespace q {
|
||||||
new_fi->set_else(m.mk_app(f_new, args));
|
new_fi->set_else(m.mk_app(f_new, args));
|
||||||
mdl.update_func_interp(f, new_fi);
|
mdl.update_func_interp(f, new_fi);
|
||||||
mdl.register_decl(f_new, fi);
|
mdl.register_decl(f_new, fi);
|
||||||
TRACE("q", tout << mdl << "\n";);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref model_fixer::add_projection_function(model& mdl, func_decl* f, unsigned idx) {
|
expr_ref model_fixer::add_projection_function(model& mdl, func_decl* f, unsigned idx) {
|
||||||
|
|
|
@ -217,8 +217,8 @@ namespace euf {
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned th_propagation::get_obj_size(unsigned num_lits, unsigned num_eqs) {
|
size_t th_propagation::get_obj_size(unsigned num_lits, unsigned num_eqs) {
|
||||||
return sizeof(th_propagation) + sizeof(sat::literal) * num_lits + sizeof(enode_pair) * num_eqs;
|
return sat::constraint_base::obj_size(sizeof(th_propagation) + sizeof(sat::literal) * num_lits + sizeof(enode_pair) * num_eqs);
|
||||||
}
|
}
|
||||||
|
|
||||||
th_propagation::th_propagation(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs) {
|
th_propagation::th_propagation(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs) {
|
||||||
|
|
|
@ -161,7 +161,7 @@ namespace euf {
|
||||||
virtual void push_core();
|
virtual void push_core();
|
||||||
virtual void pop_core(unsigned n);
|
virtual void pop_core(unsigned n);
|
||||||
void force_push() {
|
void force_push() {
|
||||||
CTRACE("euf", m_num_scopes > 0, tout << "push-core " << m_num_scopes << "\n";);
|
CTRACE("euf_verbose", m_num_scopes > 0, tout << "push-core " << m_num_scopes << "\n";);
|
||||||
for (; m_num_scopes > 0; --m_num_scopes) push_core();
|
for (; m_num_scopes > 0; --m_num_scopes) push_core();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -194,7 +194,7 @@ namespace euf {
|
||||||
unsigned m_num_eqs;
|
unsigned m_num_eqs;
|
||||||
sat::literal* m_literals;
|
sat::literal* m_literals;
|
||||||
enode_pair* m_eqs;
|
enode_pair* m_eqs;
|
||||||
static unsigned get_obj_size(unsigned num_lits, unsigned num_eqs);
|
static size_t get_obj_size(unsigned num_lits, unsigned num_eqs);
|
||||||
th_propagation(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs);
|
th_propagation(unsigned n_lits, sat::literal const* lits, unsigned n_eqs, enode_pair const* eqs);
|
||||||
public:
|
public:
|
||||||
static th_propagation* mk(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs);
|
static th_propagation* mk(th_euf_solver& th, sat::literal_vector const& lits, enode_pair_vector const& eqs);
|
||||||
|
|
|
@ -21,9 +21,33 @@ Revision History:
|
||||||
#ifdef Z3DEBUG
|
#ifdef Z3DEBUG
|
||||||
|
|
||||||
void region::display_mem_stats(std::ostream & out) const {
|
void region::display_mem_stats(std::ostream & out) const {
|
||||||
out << "num. objects: " << m_chuncks.size() << "\n";
|
out << "num. objects: " << m_chunks.size() << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void * region::allocate(size_t size) {
|
||||||
|
char * r = alloc_svect(char, size);
|
||||||
|
m_chunks.push_back(r);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void region::reset() {
|
||||||
|
for (auto* c : m_chunks)
|
||||||
|
dealloc_svect(c);
|
||||||
|
m_chunks.reset();
|
||||||
|
m_scopes.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
void region::pop_scope() {
|
||||||
|
unsigned old_size = m_scopes.back();
|
||||||
|
m_scopes.pop_back();
|
||||||
|
ptr_vector<char>::iterator it = m_chunks.begin() + old_size;
|
||||||
|
ptr_vector<char>::iterator end = m_chunks.end();
|
||||||
|
for (; it != end; ++it)
|
||||||
|
dealloc_svect(*it);
|
||||||
|
m_chunks.shrink(old_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#include "util/tptr.h"
|
#include "util/tptr.h"
|
||||||
|
|
|
@ -25,44 +25,23 @@ Revision History:
|
||||||
#include "util/vector.h"
|
#include "util/vector.h"
|
||||||
|
|
||||||
class region {
|
class region {
|
||||||
ptr_vector<char> m_chuncks;
|
ptr_vector<char> m_chunks;
|
||||||
unsigned_vector m_scopes;
|
unsigned_vector m_scopes;
|
||||||
public:
|
public:
|
||||||
~region() {
|
~region() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void * allocate(size_t size) {
|
|
||||||
char * r = alloc_svect(char, size);
|
|
||||||
m_chuncks.push_back(r);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset() {
|
void * allocate(size_t size);
|
||||||
ptr_vector<char>::iterator it = m_chuncks.begin();
|
|
||||||
ptr_vector<char>::iterator end = m_chuncks.end();
|
void reset();
|
||||||
for (; it != end; ++it) {
|
|
||||||
dealloc_svect(*it);
|
|
||||||
}
|
|
||||||
m_chuncks.reset();
|
|
||||||
m_scopes.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
void push_scope() {
|
void push_scope() {
|
||||||
m_scopes.push_back(m_chuncks.size());
|
m_scopes.push_back(m_chunks.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pop_scope();
|
||||||
void pop_scope() {
|
|
||||||
unsigned old_size = m_scopes.back();
|
|
||||||
m_scopes.pop_back();
|
|
||||||
ptr_vector<char>::iterator it = m_chuncks.begin() + old_size;
|
|
||||||
ptr_vector<char>::iterator end = m_chuncks.end();
|
|
||||||
for (; it != end; ++it) {
|
|
||||||
dealloc_svect(*it);
|
|
||||||
}
|
|
||||||
m_chuncks.shrink(old_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void pop_scope(unsigned num_scopes) {
|
void pop_scope(unsigned num_scopes) {
|
||||||
for (unsigned i = 0; i < num_scopes; i++) {
|
for (unsigned i = 0; i < num_scopes; i++) {
|
||||||
|
|
Loading…
Reference in a new issue