mirror of
https://github.com/Z3Prover/z3
synced 2025-06-25 15:23:41 +00:00
fix nex simplification
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
13434a2589
commit
43294cea16
3 changed files with 70 additions and 39 deletions
|
@ -327,6 +327,8 @@ nex* nex_creator::simplify_sum(nex_sum *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool nex_creator::sum_is_simplified(const nex_sum* e) const {
|
bool nex_creator::sum_is_simplified(const nex_sum* e) const {
|
||||||
|
TRACE("nla_cn_details", tout << ++ lp::lp_settings::ddd << std::endl;);
|
||||||
|
|
||||||
if (e->size() < 2) return false;
|
if (e->size() < 2) return false;
|
||||||
for (nex * ee : e->children()) {
|
for (nex * ee : e->children()) {
|
||||||
if (ee->is_sum())
|
if (ee->is_sum())
|
||||||
|
@ -395,80 +397,110 @@ nex* nex_creator::create_child_from_nex_and_coeff(nex *e,
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
// returns true if new
|
// returns true if the key exists already
|
||||||
bool nex_creator::register_in_join_map(std::map<nex*, rational, nex_lt>& map, nex* e, const rational& r) const{
|
bool nex_creator::register_in_join_map(std::map<nex*, rational, nex_lt>& map, nex* e, const rational& r) const{
|
||||||
TRACE("nla_cn_details", tout << *e << ", r = " << r << std::endl;);
|
TRACE("nla_cn_details", tout << *e << ", r = " << r << std::endl;);
|
||||||
auto map_it = map.find(e);
|
auto map_it = map.find(e);
|
||||||
if (map_it == map.end()) {
|
if (map_it == map.end()) {
|
||||||
map[e] = r;
|
map[e] = r;
|
||||||
return true;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
map_it->second += r;
|
map_it->second += r;
|
||||||
return false;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void nex_creator::process_mul_in_simplify_sum(nex_mul* em, std::map<nex*, rational, nex_lt> &map, vector<nex_mul> & tmp) {
|
// returns true if a simplificatian happens
|
||||||
|
bool nex_creator::process_mul_in_simplify_sum(nex_mul* em, std::map<nex*, rational, nex_lt> &map) {
|
||||||
|
bool found = false;
|
||||||
auto it = em->children().begin();
|
auto it = em->children().begin();
|
||||||
if (it->e()->is_scalar()) {
|
if (it->e()->is_scalar()) {
|
||||||
SASSERT(it->pow() == 1);
|
SASSERT(it->pow() == 1);
|
||||||
rational r = to_scalar(it->e())->value();
|
rational r = to_scalar(it->e())->value();
|
||||||
auto end = em->children().end();
|
auto end = em->children().end();
|
||||||
if (em->children().size() == 2 && em->children()[1].pow() == 1) {
|
if (em->children().size() == 2 && em->children()[1].pow() == 1) {
|
||||||
register_in_join_map(map, em->children()[1].e(), r);
|
found = register_in_join_map(map, em->children()[1].e(), r);
|
||||||
} else {
|
} else {
|
||||||
tmp.push_back(nex_mul());
|
nex_mul * m = new nex_mul();
|
||||||
nex_mul * m = &tmp[tmp.size()-1];
|
|
||||||
for (it++; it != end; it++) {
|
for (it++; it != end; it++) {
|
||||||
m->add_child_in_power(it->e(), it->pow());
|
m->add_child_in_power(it->e(), it->pow());
|
||||||
}
|
}
|
||||||
if (!register_in_join_map(map, m, r))
|
found = register_in_join_map(map, m, r);
|
||||||
tmp.pop_back();
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
register_in_join_map(map, em, rational(1));
|
found = register_in_join_map(map, em, rational(1));
|
||||||
}
|
}
|
||||||
|
return found;
|
||||||
}
|
}
|
||||||
|
|
||||||
// a + 3bc + 2bc => a + 5bc
|
// a + 3bc + 2bc => a + 5bc
|
||||||
void nex_creator::sort_join_sum(ptr_vector<nex> & children) {
|
void nex_creator::sort_join_sum(ptr_vector<nex> & children) {
|
||||||
|
TRACE("nla_cn_details", print_vector_of_ptrs(children, tout););
|
||||||
std::map<nex*, rational, nex_lt> map([this](const nex *a , const nex *b)
|
std::map<nex*, rational, nex_lt> map([this](const nex *a , const nex *b)
|
||||||
{ return lt(a, b); });
|
{ return lt(a, b); });
|
||||||
TRACE("nla_cn_details", print_vector_of_ptrs(children, tout););
|
std::unordered_set<nex*> existing_nex; // handling (nex*) as numbers
|
||||||
vector<nex_mul> tmp;
|
nex_scalar * common_scalar = nullptr;
|
||||||
nex_scalar * s = nullptr;
|
bool simplified = false;
|
||||||
for (auto e : children) {
|
for (auto e : children) {
|
||||||
if (e->is_mul()) {
|
if (e->is_scalar()) {
|
||||||
process_mul_in_simplify_sum(to_mul(e), map, tmp);
|
|
||||||
} else if (e->is_scalar()) {
|
|
||||||
nex_scalar * es = to_scalar(e);
|
nex_scalar * es = to_scalar(e);
|
||||||
if (s == nullptr)
|
if (common_scalar == nullptr) {
|
||||||
s = es;
|
common_scalar = es;
|
||||||
else
|
} else {
|
||||||
s->value() += es->value();
|
simplified = true;
|
||||||
|
common_scalar->value() += es->value();
|
||||||
}
|
}
|
||||||
else {
|
continue;
|
||||||
register_in_join_map(map, e, rational(1));
|
}
|
||||||
|
existing_nex.insert(e);
|
||||||
|
if (e->is_mul()) {
|
||||||
|
simplified |= process_mul_in_simplify_sum(to_mul(e), map);
|
||||||
|
} else {
|
||||||
|
SASSERT(e->is_var());
|
||||||
|
simplified |= register_in_join_map(map, e, rational(1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool simplified;
|
|
||||||
for (auto& p : map) {
|
|
||||||
if (!p.second.is_one()) {
|
|
||||||
simplified = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!simplified)
|
if (!simplified)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
TRACE("nla_cn_details", for (auto & p : map ) { tout << "(" << *p.first << ", " << p.second << ") ";});
|
TRACE("nla_cn_details", for (auto & p : map ) { tout << "(" << *p.first << ", " << p.second << ") ";});
|
||||||
children.clear();
|
children.clear();
|
||||||
if (s) {
|
if (common_scalar) {
|
||||||
children.push_back(s);
|
children.push_back(common_scalar);
|
||||||
}
|
}
|
||||||
for (auto& p : map) {
|
for (auto& p : map) {
|
||||||
if (p.second.is_zero() == false)
|
nex *e = p.first;
|
||||||
children.push_back(create_child_from_nex_and_coeff(p.first, p.second));
|
const rational & coeff = p.second;
|
||||||
|
if (coeff.is_zero())
|
||||||
|
continue;
|
||||||
|
bool e_is_old = existing_nex.find(e) != existing_nex.end();
|
||||||
|
if (e_is_old) {
|
||||||
|
if (coeff.is_one()) {
|
||||||
|
children.push_back(e);
|
||||||
|
} else {
|
||||||
|
if (e->is_var()) {
|
||||||
|
children.push_back(mk_mul(mk_scalar(coeff), e));
|
||||||
|
} else {
|
||||||
|
SASSERT(e->is_mul());
|
||||||
|
nex* first = to_mul(e)->children()[0].e();
|
||||||
|
if (first->is_scalar()) {
|
||||||
|
to_scalar(first)->value() = coeff;
|
||||||
|
children.push_back(e);
|
||||||
|
} else {
|
||||||
|
e = simplify(mk_mul(mk_scalar(coeff), e));
|
||||||
|
children.push_back(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { // e is new
|
||||||
|
if (coeff.is_one()) {
|
||||||
|
m_allocated.push_back(e);
|
||||||
|
children.push_back(e);
|
||||||
|
} else {
|
||||||
|
children.push_back(simplify(mk_mul(mk_scalar(coeff), e)));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -208,7 +208,7 @@ public:
|
||||||
bool is_sorted(const nex_mul * e) const;
|
bool is_sorted(const nex_mul * e) const;
|
||||||
|
|
||||||
nex* simplify_sum(nex_sum *e);
|
nex* simplify_sum(nex_sum *e);
|
||||||
void process_mul_in_simplify_sum(nex_mul* e, std::map<nex*, rational, nex_lt> &, vector<nex_mul> &);
|
bool process_mul_in_simplify_sum(nex_mul* e, std::map<nex*, rational, nex_lt> &);
|
||||||
|
|
||||||
bool is_simplified(const nex *e) const;
|
bool is_simplified(const nex *e) const;
|
||||||
bool sum_is_simplified(const nex_sum* e) const;
|
bool sum_is_simplified(const nex_sum* e) const;
|
||||||
|
|
|
@ -83,9 +83,9 @@ void test_simplify() {
|
||||||
[](unsigned) { return false; },
|
[](unsigned) { return false; },
|
||||||
[]() { return 1; } // for random
|
[]() { return 1; } // for random
|
||||||
);
|
);
|
||||||
enable_trace("nla_cn");
|
// enable_trace("nla_cn");
|
||||||
enable_trace("nla_cn_details");
|
// enable_trace("nla_cn_details");
|
||||||
enable_trace("nla_cn_details_");
|
// enable_trace("nla_cn_details_");
|
||||||
enable_trace("nla_test");
|
enable_trace("nla_test");
|
||||||
|
|
||||||
nex_creator & r = cn.get_nex_creator();
|
nex_creator & r = cn.get_nex_creator();
|
||||||
|
@ -99,7 +99,6 @@ void test_simplify() {
|
||||||
auto a_plus_bc = r.mk_sum(a, bc);
|
auto a_plus_bc = r.mk_sum(a, bc);
|
||||||
auto simp_a_plus_bc = r.simplify(a_plus_bc);
|
auto simp_a_plus_bc = r.simplify(a_plus_bc);
|
||||||
SASSERT(to_sum(simp_a_plus_bc)->size() > 1);
|
SASSERT(to_sum(simp_a_plus_bc)->size() > 1);
|
||||||
return;
|
|
||||||
auto m = r.mk_mul(); m->add_child_in_power(c, 2);
|
auto m = r.mk_mul(); m->add_child_in_power(c, 2);
|
||||||
TRACE("nla_test_", tout << "m = " << *m << "\n";);
|
TRACE("nla_test_", tout << "m = " << *m << "\n";);
|
||||||
auto n = r.mk_mul(a);
|
auto n = r.mk_mul(a);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue