3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-09 12:50:32 +00:00

convert def into expression tree

prior data-structure could not represent
((1 + x) div 2) * 2
It is possible to have nested expressions with div.
To deal with this, replace original def by an expression tree data-structure.
This commit is contained in:
Nikolaj Bjorner 2025-02-17 18:47:00 -08:00
parent f977b48161
commit f8f26788ad
3 changed files with 1849 additions and 1787 deletions

View file

@ -258,7 +258,7 @@ namespace mbp {
rational c0 = add_def(t1, mul1, coeffs);
tids.insert(t, mbo.add_div(coeffs, c0, mul1));
}
else if (a.is_mod(t, t1, t2) && is_numeral(t2, mul1) && !mul1.is_zero()) {
else if (a.is_mod(t, t1, t2) && is_numeral(t2, mul1) && mul1 > 0) {
rational r;
val = eval(t);
if (!a.is_numeral(val, r)) {
@ -417,7 +417,7 @@ namespace mbp {
TRACE("qe", tout << "remaining vars: " << vars << "\n";
for (unsigned v : real_vars) tout << "v" << v << " " << mk_pp(index2expr[v], m) << "\n";
mbo.display(tout););
vector<opt::model_based_opt::def> defs = mbo.project(real_vars.size(), real_vars.data(), compute_def);
vector<opt::model_based_opt::def_ref> defs = mbo.project(real_vars.size(), real_vars.data(), compute_def);
vector<row> rows;
@ -431,7 +431,7 @@ namespace mbp {
}
rows2fmls(def_vars, rows, index2expr, fmls);
TRACE("qe", mbo.display(tout << "mbo result\n");
for (auto const& d : defs) tout << "def: " << d << "\n";
for (auto const& d : defs) if (d) tout << "def: " << *d << "\n";
tout << fmls << "\n";);
if (compute_def)
@ -448,29 +448,45 @@ namespace mbp {
return true;
}
void optdefs2mbpdef(u_map<row> const& def_vars, vector<opt::model_based_opt::def> const& defs, ptr_vector<expr> const& index2expr, unsigned_vector const& real_vars, vector<def>& result) {
expr_ref from_def(u_map<row> const& def_vars, opt::model_based_opt::def const& d, bool is_int, ptr_vector<expr> const& index2expr) {
if (d.is_add()) {
return expr_ref(
a.mk_add(from_def(def_vars, *d.to_add().x, is_int, index2expr),
from_def(def_vars, *d.to_add().y, is_int, index2expr)), m);
}
if (d.is_mul()) {
return expr_ref(
a.mk_mul(from_def(def_vars, *d.to_mul().x, is_int, index2expr),
from_def(def_vars, *d.to_mul().y, is_int, index2expr)), m);
}
if (d.is_const())
return expr_ref(a.mk_numeral(d.to_const().c, is_int), m);
if (d.is_var()) {
auto t = id2expr(def_vars, index2expr, d.to_var().v.m_id);
if (d.to_var().v.m_coeff != 1)
t = a.mk_mul(a.mk_numeral(d.to_var().v.m_coeff, is_int), t);
return expr_ref(t, m);
}
if (d.is_div()) {
auto t = from_def(def_vars, *d.to_div().x, is_int, index2expr);
if (is_int)
t = a.mk_idiv(t, a.mk_numeral(d.to_div().m_div, is_int));
else
t = a.mk_div(t, a.mk_numeral(d.to_div().m_div, is_int));
return expr_ref(t, m);
}
UNREACHABLE();
return expr_ref(nullptr, m);
}
void optdefs2mbpdef(u_map<row> const& def_vars, vector<opt::model_based_opt::def_ref> const& defs, ptr_vector<expr> const& index2expr, unsigned_vector const& real_vars, vector<def>& result) {
SASSERT(defs.size() == real_vars.size());
for (unsigned i = 0; i < defs.size(); ++i) {
auto const& d = defs[i];
expr* x = index2expr[real_vars[i]];
bool is_int = a.is_int(x);
expr_ref_vector ts(m);
expr_ref t(m);
for (var const& v : d.m_vars) {
t = id2expr(def_vars, index2expr, v.m_id);
if (v.m_coeff != 1)
t = a.mk_mul(a.mk_numeral(v.m_coeff, a.is_int(t)), t);
ts.push_back(t);
}
if (!d.m_coeff.is_zero())
ts.push_back(a.mk_numeral(d.m_coeff, is_int));
if (ts.empty())
ts.push_back(a.mk_numeral(rational(0), is_int));
t = mk_add(ts);
if (!d.m_div.is_one() && is_int)
t = a.mk_idiv(t, a.mk_numeral(d.m_div, is_int));
else if (!d.m_div.is_one() && !is_int)
t = a.mk_div(t, a.mk_numeral(d.m_div, is_int));
auto t = from_def(def_vars, *d, is_int, index2expr);
result.push_back({ expr_ref(x, m), t });
}
}