3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-15 10:26:16 +00:00
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2019-07-12 11:53:25 -07:00
parent 92769469df
commit 24d70abfd8
2 changed files with 180 additions and 164 deletions

View file

@ -23,47 +23,63 @@
namespace nla {
class cross_nested {
typedef nla_expr<rational> nex;
std::function<void (unsigned)> m_call_on_result;
nex& m_e;
std::function<void (const nex&)> m_call_on_result;
public:
cross_nested(std::function<void (unsigned)> call_on_result): m_call_on_result(call_on_result) {}
cross_nested(nex &e, std::function<void (const nex&)> call_on_result): m_e(e), m_call_on_result(call_on_result) {}
void cross_nested_of_expr_on_front_elem(nex& e, nex* c, vector<nex*>& front) {
void run() {
vector<nex*> front;
cross_nested_of_expr_on_front_elem(&m_e, front);
}
static nex* pop_back(vector<nex*>& front) {
nex* c = front.back();
front.pop_back();
return c;
}
void cross_nested_of_expr_on_front_elem(nex* c, vector<nex*>& front) {
SASSERT(c->is_sum());
vector<lpvar> occurences = get_mult_occurences(*c);
TRACE("nla_cn", tout << "e=" << e << "\nc=" << *c << "\noccurences="; print_vector(occurences, tout) << "\nfront:"; print_vector_of_ptrs(front, tout) << "\n";);
TRACE("nla_cn", tout << "m_e=" << m_e << "\nc=" << *c << "\noccurences="; print_vector(occurences, tout) << "\nfront:"; print_vector_of_ptrs(front, tout) << "\n";);
if (occurences.empty()) {
if(front.empty()) {
TRACE("nla_cn_cn", tout << "got the cn form: e=" << e << "\n";);
SASSERT(!can_be_cross_nested_more(e));
auto i = interval_of_expr(e);
m_intervals.check_interval_for_conflict_on_zero(i);
TRACE("nla_cn_cn", tout << "got the cn form: m_e=" << m_e << "\n";);
SASSERT(!can_be_cross_nested_more(m_e));
m_call_on_result(m_e);
} else {
nex* c = pop_back(front);
cross_nested_of_expr_on_front_elem(e, c, front);
cross_nested_of_expr_on_front_elem(c, front);
}
} else {
TRACE("nla_cn", tout << "save c=" << *c << "front:"; print_vector_of_ptrs(front, tout) << "\n";);
nex copy_of_c = *c;
vector<nex> copy_of_front;
for (nex* n: front)
copy_of_front.push_back(*n);
for(lpvar j : occurences) {
cross_nested_of_expr_on_sum_and_var(e, c, j, front);
cross_nested_of_expr_on_sum_and_var(c, j, front);
*c = copy_of_c;
TRACE("nla_cn", tout << "restore c=" << *c << ", e=" << e << "\n";);
TRACE("nla_cn", tout << "restore c=" << *c << ", m_e=" << m_e << "\n";);
for (unsigned i = 0; i < front.size(); i++)
*(front[i]) = copy_of_front[i];
}
}
TRACE("nla_cn", tout << "exit\n";);
}
// e is the global expression, c is the sub expressiond which is going to changed from sum to the cross nested form
void horner::cross_nested_of_expr_on_sum_and_var(nex& e, nex* c, lpvar j, vector<nex*>& front) {
TRACE("nla_cn", tout << "e=" << e << "\nc=" << *c << "\nj = v" << j << "\nfront="; print_vector_of_ptrs(front, tout) << "\n";);
void cross_nested_of_expr_on_sum_and_var(nex* c, lpvar j, vector<nex*> front) {
TRACE("nla_cn", tout << "m_e=" << m_e << "\nc=" << *c << "\nj = v" << j << "\nfront="; print_vector_of_ptrs(front, tout) << "\n";);
split_with_var(*c, j, front);
TRACE("nla_cn", tout << "after split c=" << *c << "\nfront="; print_vector_of_ptrs(front, tout) << "\n";);
do {
nex* n = pop_back(front);
cross_nested_of_expr_on_front_elem(e, n, front);
cross_nested_of_expr_on_front_elem(n, front);
} while (!front.empty());
}
void process_var_occurences(lpvar j, std::unordered_set<lpvar>& seen, std::unordered_map<lpvar, unsigned>& occurences) {
void process_var_occurences(lpvar j, std::unordered_set<lpvar>& seen, std::unordered_map<lpvar, unsigned>& occurences) const {
if (seen.find(j) != seen.end()) return;
seen.insert(j);
auto it = occurences.find(j);
@ -73,7 +89,7 @@ void process_var_occurences(lpvar j, std::unordered_set<lpvar>& seen, std::unord
it->second ++;
}
void process_mul_occurences(const nex& e, std::unordered_set<lpvar>& seen, std::unordered_map<lpvar, unsigned>& occurences) {
void process_mul_occurences(const nex& e, std::unordered_set<lpvar>& seen, std::unordered_map<lpvar, unsigned>& occurences) const {
SASSERT(e.type() == expr_type::MUL);
for (const auto & ce : e.children()) {
if (ce.type() == expr_type::VAR) {
@ -86,7 +102,7 @@ void process_mul_occurences(const nex& e, std::unordered_set<lpvar>& seen, std::
// j -> the number of expressions j appears in as a multiplier
vector<lpvar> horner::get_mult_occurences(const nex& e) const {
vector<lpvar> get_mult_occurences(const nex& e) const {
std::unordered_map<lpvar, unsigned> occurences;
SASSERT(e.type() == expr_type::SUM);
for (const auto & ce : e.children()) {
@ -118,7 +134,7 @@ vector<lpvar> horner::get_mult_occurences(const nex& e) const {
}
return r;
}
bool horner::can_be_cross_nested_more(const nex& e) const {
bool can_be_cross_nested_more(const nex& e) const {
switch (e.type()) {
case expr_type::SCALAR:
return false;
@ -141,7 +157,7 @@ bool horner::can_be_cross_nested_more(const nex& e) const {
return false;
}
}
void horner::split_with_var(nex& e, lpvar j, vector<nex*> & front) {
void split_with_var(nex& e, lpvar j, vector<nex*> & front) {
TRACE("nla_cn_details", tout << "e = " << e << ", j = v" << j << "\n";);
if (!e.is_sum())
return;
@ -187,7 +203,7 @@ void horner::split_with_var(nex& e, lpvar j, vector<nex*> & front) {
}
}
}
std::set<lpvar> horner::get_vars_of_expr(const nex &e ) const {
std::set<lpvar> get_vars_of_expr(const nex &e ) const {
std::set<lpvar> r;
switch (e.type()) {
case expr_type::SCALAR:

View file

@ -41,15 +41,12 @@ bool horner::row_is_interesting(const T& row) const {
void horner::lemmas_on_expr(nex& e) {
TRACE("nla_cn", tout << "e = " << e << "\n";);
TRACE("nla_cn_cn", tout << "e = " << e << "\n";);
vector<nex*> front;
cross_nested_of_expr_on_front_elem(e, &e, front);
cross_nested cn(e, [this](const nex& n) {
auto i = interval_of_expr(n);
m_intervals.check_interval_for_conflict_on_zero(i);} );
}
nex* pop_back(vector<nex*>& front) {
nex* c = front.back();
front.pop_back();
return c;
}
template <typename T>
void horner::lemmas_on_row(const T& row) {
@ -71,6 +68,8 @@ void horner::horner_lemmas() {
}
}
typedef nla_expr<rational> nex;
nex horner::nexvar(lpvar j) const {
// todo: consider deepen the recursion
if (!c().is_monomial_var(j))
@ -83,7 +82,6 @@ nex horner::nexvar(lpvar j) const {
return e;
}
template <typename T> nex horner::create_sum_from_row(const T& row) {
TRACE("nla_cn", tout << "row="; m_core->print_term(row, tout) << "\n";);
SASSERT(row.size() > 1);
@ -191,3 +189,5 @@ void horner::set_var_interval(lpvar v, interv& b) {
}
}
auto i = interval_of_expr(e);
m_intervals.check_interval_for_conflict_on_zero(i);