mirror of
https://github.com/Z3Prover/z3
synced 2025-04-13 12:28:44 +00:00
init of m_active_vars_weights and fixes in is_simplified
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
b2d1bcc8cd
commit
0c126031b0
|
@ -34,8 +34,8 @@ class cross_nested {
|
|||
ptr_vector<nex> m_b_split_vec;
|
||||
int m_reported;
|
||||
bool m_random_bit;
|
||||
nex_creator m_nex_creator;
|
||||
std::function<nex_scalar*()> m_mk_scalar;
|
||||
nex_creator& m_nex_creator;
|
||||
#ifdef Z3DEBUG
|
||||
nex* m_e_clone;
|
||||
#endif
|
||||
|
@ -45,13 +45,15 @@ public:
|
|||
|
||||
cross_nested(std::function<bool (const nex*)> call_on_result,
|
||||
std::function<bool (unsigned)> var_is_fixed,
|
||||
std::function<unsigned ()> random) :
|
||||
std::function<unsigned ()> random,
|
||||
nex_creator& nex_cr) :
|
||||
m_call_on_result(call_on_result),
|
||||
m_var_is_fixed(var_is_fixed),
|
||||
m_random(random),
|
||||
m_done(false),
|
||||
m_reported(0),
|
||||
m_mk_scalar([this]{return m_nex_creator.mk_scalar(rational(1));})
|
||||
m_mk_scalar([this]{return m_nex_creator.mk_scalar(rational(1));}),
|
||||
m_nex_creator(nex_cr)
|
||||
{}
|
||||
|
||||
|
||||
|
@ -369,15 +371,15 @@ public:
|
|||
// all factors of j go to a, the rest to b
|
||||
void pre_split(nex_sum * e, lpvar j, nex_sum*& a, nex*& b) {
|
||||
TRACE("nla_cn_details", tout << "e = " << * e << ", j = " << m_nex_creator.ch(j) << std::endl;);
|
||||
SASSERT(m_nex_creator.is_simplified(e));
|
||||
a = m_nex_creator.mk_sum();
|
||||
m_b_split_vec.clear();
|
||||
for (nex * ce: *e) {
|
||||
TRACE("nla_cn_details", tout << "ce = " << *ce << "\n";);
|
||||
if (is_divisible_by_var(ce, j)) {
|
||||
a->add_child(m_nex_creator.mk_div(ce , j));
|
||||
} else {
|
||||
m_b_split_vec.push_back(ce);
|
||||
TRACE("nla_cn_details", tout << "ce = " << *ce << "\n";);
|
||||
|
||||
}
|
||||
}
|
||||
TRACE("nla_cn_details", tout << "a = " << *a << "\n";);
|
||||
|
|
|
@ -45,7 +45,7 @@ bool horner::row_is_interesting(const T& row) const {
|
|||
return false;
|
||||
}
|
||||
SASSERT(row_has_monomial_to_refine(row));
|
||||
c().clear_row_var_set();
|
||||
c().clear_active_var_set();
|
||||
for (const auto& p : row) {
|
||||
lpvar j = p.var();
|
||||
if (!c().is_monic_var(j))
|
||||
|
@ -53,19 +53,19 @@ bool horner::row_is_interesting(const T& row) const {
|
|||
auto & m = c().emons()[j];
|
||||
|
||||
for (lpvar k : m.vars()) {
|
||||
if (c().row_var_set_contains(k))
|
||||
if (c().active_var_set_contains(k))
|
||||
return true;
|
||||
}
|
||||
for (lpvar k : m.vars()) {
|
||||
c().insert_to_row_var_set(k);
|
||||
c().insert_to_active_var_set(k);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool horner::lemmas_on_expr(cross_nested& cn) {
|
||||
TRACE("nla_horner", tout << "m_row_sum = " << m_row_sum << "\n";);
|
||||
cn.run(&m_row_sum);
|
||||
bool horner::lemmas_on_expr(cross_nested& cn, nex_sum* e) {
|
||||
TRACE("nla_horner", tout << "e = " << *e << "\n";);
|
||||
cn.run(e);
|
||||
return cn.done();
|
||||
}
|
||||
|
||||
|
@ -92,11 +92,15 @@ bool horner::lemmas_on_row(const T& row) {
|
|||
cross_nested cn(
|
||||
[this](const nex* n) { return check_cross_nested_expr(n); },
|
||||
[this](unsigned j) { return c().var_is_fixed(j); },
|
||||
[this]() { return c().random(); });
|
||||
[this]() { return c().random(); }, m_nex_creator);
|
||||
|
||||
SASSERT (row_is_interesting(row));
|
||||
create_sum_from_row(row, cn.get_nex_creator(), m_row_sum);
|
||||
return lemmas_on_expr(cn);
|
||||
nex* e = m_nex_creator.simplify(&m_row_sum);
|
||||
if (!e->is_sum())
|
||||
return false;
|
||||
|
||||
return lemmas_on_expr(cn, to_sum(e));
|
||||
}
|
||||
|
||||
void horner::horner_lemmas() {
|
||||
|
@ -112,7 +116,7 @@ void horner::horner_lemmas() {
|
|||
for (auto & s : matrix.m_columns[j])
|
||||
rows_to_check.insert(s.var());
|
||||
}
|
||||
c().prepare_row_var_set();
|
||||
c().prepare_active_var_set();
|
||||
svector<unsigned> rows;
|
||||
for (unsigned i : rows_to_check) {
|
||||
if (row_is_interesting(matrix.m_rows[i]))
|
||||
|
|
|
@ -53,7 +53,7 @@ public:
|
|||
intervals::interval interval_of_sum_no_term_with_deps(const nex_sum*);
|
||||
intervals::interval interval_of_mul_with_deps(const nex_mul*);
|
||||
void set_var_interval_with_deps(lpvar j, intervals::interval&) const;
|
||||
bool lemmas_on_expr(cross_nested&);
|
||||
bool lemmas_on_expr(cross_nested&, nex_sum*);
|
||||
|
||||
template <typename T> // T has an iterator of (coeff(), var())
|
||||
bool row_has_monomial_to_refine(const T&) const;
|
||||
|
|
|
@ -97,7 +97,8 @@ public:
|
|||
lpvar var() const { return m_j; }
|
||||
lpvar& var() { return m_j; } // the setter
|
||||
std::ostream & print(std::ostream& out) const {
|
||||
out << (char)('a' + m_j);
|
||||
// out << (char)('a' + m_j);
|
||||
out << "v" << m_j;
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -288,8 +288,12 @@ bool nex_creator::lt(const nex* a, const nex* b) const {
|
|||
|
||||
bool nex_creator::is_sorted(const nex_mul* e) const {
|
||||
for (unsigned j = 0; j < e->size() - 1; j++) {
|
||||
if (!(less_than_on_nex_pow((*e)[j], (*e)[j+1])))
|
||||
if (!(less_than_on_nex_pow((*e)[j], (*e)[j+1]))) {
|
||||
TRACE("nla_cn_details", tout << "not sorted e " << * e << "\norder is incorrect " <<
|
||||
(*e)[j] << " >= " << (*e)[j + 1]<< "\n";);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -298,22 +302,29 @@ bool nex_creator::is_sorted(const nex_mul* e) const {
|
|||
|
||||
|
||||
bool nex_creator::mul_is_simplified(const nex_mul* e) const {
|
||||
TRACE("nla_cn_details", tout << "e = " << *e << "\n";);
|
||||
if (e->size() == 1 && e->begin()->pow() == 1)
|
||||
return false;
|
||||
std::set<const nex*, nex_lt> s([this](const nex* a, const nex* b) {return lt(a, b); });
|
||||
for (const auto &p : *e) {
|
||||
const nex* ee = p.e();
|
||||
if (p.pow() == 0)
|
||||
if (p.pow() == 0) {
|
||||
TRACE("nla_cn_details", tout << "not simplified " << *ee << "\n";);
|
||||
return false;
|
||||
if (ee->is_mul())
|
||||
}
|
||||
if (ee->is_mul()) {
|
||||
TRACE("nla_cn_details", tout << "not simplified " << *ee << "\n";);
|
||||
return false;
|
||||
if (ee->is_scalar() && to_scalar(ee)->value().is_one())
|
||||
}
|
||||
if (ee->is_scalar() && to_scalar(ee)->value().is_one()) {
|
||||
TRACE("nla_cn_details", tout << "not simplified " << *ee << "\n";);
|
||||
return false;
|
||||
}
|
||||
|
||||
auto it = s.find(ee);
|
||||
if (it == s.end()) {
|
||||
s.insert(ee);
|
||||
} else {
|
||||
} else {
|
||||
TRACE("nla_cn_details", tout << "not simplified " << *ee << "\n";);
|
||||
return false;
|
||||
}
|
||||
|
@ -340,20 +351,29 @@ nex* nex_creator::simplify_sum(nex_sum *e) {
|
|||
}
|
||||
|
||||
bool nex_creator::sum_is_simplified(const nex_sum* e) const {
|
||||
|
||||
if (e->size() < 2) return false;
|
||||
bool scalar = false;
|
||||
for (nex * ee : *e) {
|
||||
if (ee->is_sum())
|
||||
if (ee->is_sum()) {
|
||||
TRACE("nla_cn", tout << "not simplified e = " << *e << "\n"
|
||||
<< " has a child which is a sum " << *ee << "\n";);
|
||||
return false;
|
||||
}
|
||||
if (ee->is_scalar()) {
|
||||
if (scalar) {
|
||||
TRACE("nla_cn", tout << "not simplified e = " << *e << "\n"
|
||||
<< " have more than one scalar " << *ee << "\n";);
|
||||
|
||||
return false;
|
||||
}
|
||||
if (to_scalar(ee)->value().is_zero()) {
|
||||
return false;
|
||||
if (scalar) {
|
||||
TRACE("nla_cn", tout << "have a zero scalar " << *ee << "\n";);
|
||||
|
||||
return false;
|
||||
}
|
||||
scalar = true;
|
||||
}
|
||||
scalar = true;
|
||||
}
|
||||
if (!is_simplified(ee))
|
||||
return false;
|
||||
|
|
|
@ -57,11 +57,11 @@ class nex_creator {
|
|||
svector<unsigned> m_active_vars_weights;
|
||||
|
||||
public:
|
||||
static char ch(unsigned j) {
|
||||
// std::stringstream s;
|
||||
// s << "v" << j;
|
||||
// return s.str();
|
||||
return (char)('a'+j);
|
||||
static std::string ch(unsigned j) {
|
||||
std::stringstream s;
|
||||
s << "v" << j;
|
||||
return s.str();
|
||||
// return (char)('a'+j);
|
||||
}
|
||||
|
||||
// assuming that every lpvar is less than this number
|
||||
|
|
|
@ -122,26 +122,32 @@ unsigned common::random() {
|
|||
return c().random();
|
||||
}
|
||||
|
||||
nex * common::nexvar(lpvar j, nex_creator& cn) const {
|
||||
nex * common::nexvar(lpvar j, nex_creator& cn) {
|
||||
// todo: consider deepen the recursion
|
||||
if (!c().is_monic_var(j))
|
||||
if (!c().is_monic_var(j)) {
|
||||
c().insert_to_active_var_set(j);
|
||||
return cn.mk_var(j);
|
||||
}
|
||||
const monic& m = c().emons()[j];
|
||||
nex_mul * e = cn.mk_mul();
|
||||
for (lpvar k : m.vars()) {
|
||||
c().insert_to_active_var_set(k);
|
||||
e->add_child(cn.mk_var(k));
|
||||
CTRACE("nla_horner", c().is_monic_var(k), c().print_var(k, tout) << "\n";);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
nex * common::nexvar(const rational & coeff, lpvar j, nex_creator& cn) const {
|
||||
nex * common::nexvar(const rational & coeff, lpvar j, nex_creator& cn) {
|
||||
// todo: consider deepen the recursion
|
||||
if (!c().is_monic_var(j))
|
||||
if (!c().is_monic_var(j)) {
|
||||
c().insert_to_active_var_set(j);
|
||||
return cn.mk_mul(cn.mk_scalar(coeff), cn.mk_var(j));
|
||||
}
|
||||
const monic& m = c().emons()[j];
|
||||
nex_mul * e = cn.mk_mul(cn.mk_scalar(coeff));
|
||||
for (lpvar k : m.vars()) {
|
||||
c().insert_to_active_var_set(j);
|
||||
e->add_child(cn.mk_var(k));
|
||||
CTRACE("nla_horner", c().is_monic_var(k), c().print_var(k, tout) << "\n";);
|
||||
}
|
||||
|
@ -151,6 +157,7 @@ nex * common::nexvar(const rational & coeff, lpvar j, nex_creator& cn) const {
|
|||
|
||||
template <typename T> void common::create_sum_from_row(const T& row, nex_creator& cn, nex_sum& sum) {
|
||||
TRACE("nla_horner", tout << "row="; m_core->print_term(row, tout) << "\n";);
|
||||
c().prepare_active_var_set();
|
||||
SASSERT(row.size() > 1);
|
||||
sum.children().clear();
|
||||
for (const auto &p : row) {
|
||||
|
@ -160,7 +167,43 @@ template <typename T> void common::create_sum_from_row(const T& row, nex_creator
|
|||
sum.add_child(nexvar(p.coeff(), p.var(), cn));
|
||||
}
|
||||
}
|
||||
set_active_vars_weights();
|
||||
}
|
||||
|
||||
void common::set_active_vars_weights() {
|
||||
m_nex_creator.set_number_of_vars(c().m_lar_solver.column_count());
|
||||
for (lpvar j : c().active_var_set()) {
|
||||
m_nex_creator.set_var_weight(j, static_cast<unsigned>(get_var_weight(j)));
|
||||
}
|
||||
}
|
||||
|
||||
var_weight common::get_var_weight(lpvar j) const {
|
||||
var_weight k;
|
||||
switch (c().m_lar_solver.get_column_type(j)) {
|
||||
|
||||
case lp::column_type::fixed:
|
||||
k = var_weight::FIXED;
|
||||
break;
|
||||
case lp::column_type::boxed:
|
||||
k = var_weight::BOUNDED;
|
||||
break;
|
||||
case lp::column_type::lower_bound:
|
||||
case lp::column_type::upper_bound:
|
||||
k = var_weight::NOT_FREE;
|
||||
case lp::column_type::free_column:
|
||||
k = var_weight::FREE;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
if (c().is_monic_var(j)) {
|
||||
return (var_weight)((int)k + 1);
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
template void nla::common::create_sum_from_row<old_vector<lp::row_cell<rational>, true, unsigned int> >(old_vector<lp::row_cell<rational>, true, unsigned int> const&, nla::nex_creator&, nla::nex_sum&);
|
||||
|
||||
|
|
|
@ -45,7 +45,9 @@ inline llc negate(llc cmp) {
|
|||
|
||||
class core;
|
||||
struct common {
|
||||
core* m_core;
|
||||
core* m_core;
|
||||
nex_creator m_nex_creator;
|
||||
|
||||
common(core* c): m_core(c) {}
|
||||
core& c() { return *m_core; }
|
||||
const core& c() const { return *m_core; }
|
||||
|
@ -115,10 +117,11 @@ struct common {
|
|||
typedef dependency_manager<ci_dependency_config> ci_dependency_manager;
|
||||
|
||||
typedef ci_dependency_manager::dependency ci_dependency;
|
||||
nex* nexvar(lpvar j, nex_creator& ) const;
|
||||
nex* nexvar(const rational& coeff, lpvar j, nex_creator&) const;
|
||||
nex* nexvar(lpvar j, nex_creator& );
|
||||
nex* nexvar(const rational& coeff, lpvar j, nex_creator&);
|
||||
template <typename T>
|
||||
void create_sum_from_row(const T&, nex_creator&, nex_sum&);
|
||||
|
||||
void set_active_vars_weights();
|
||||
var_weight get_var_weight(lpvar) const;
|
||||
};
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ public:
|
|||
|
||||
class core {
|
||||
public:
|
||||
var_eqs<emonics> m_evars;
|
||||
var_eqs<emonics> m_evars;
|
||||
lp::lar_solver& m_lar_solver;
|
||||
vector<lemma> * m_lemma_vec;
|
||||
lp::int_set m_to_refine;
|
||||
|
@ -91,25 +91,25 @@ public:
|
|||
nla_settings m_nla_settings;
|
||||
nla_grobner m_grobner;
|
||||
private:
|
||||
emonics m_emons;
|
||||
emonics m_emons;
|
||||
svector<lpvar> m_add_buffer;
|
||||
mutable lp::int_set m_row_var_set;
|
||||
mutable lp::int_set m_active_var_set;
|
||||
public:
|
||||
reslimit m_reslim;
|
||||
|
||||
|
||||
const lp::int_set& row_var_set () const { return m_row_var_set;}
|
||||
bool row_var_set_contains(unsigned j) const { return m_row_var_set.contains(j); }
|
||||
const lp::int_set& active_var_set () const { return m_active_var_set;}
|
||||
bool active_var_set_contains(unsigned j) const { return m_active_var_set.contains(j); }
|
||||
|
||||
void insert_to_row_var_set(unsigned j) const { m_row_var_set.insert(j); }
|
||||
void insert_to_active_var_set(unsigned j) const { m_active_var_set.insert(j); }
|
||||
|
||||
void clear_row_var_set() const {
|
||||
m_row_var_set.clear();
|
||||
void clear_active_var_set() const {
|
||||
m_active_var_set.clear();
|
||||
}
|
||||
|
||||
void prepare_row_var_set() const {
|
||||
m_row_var_set.clear();
|
||||
m_row_var_set.resize(m_lar_solver.number_of_vars());
|
||||
void prepare_active_var_set() const {
|
||||
m_active_var_set.clear();
|
||||
m_active_var_set.resize(m_lar_solver.number_of_vars());
|
||||
}
|
||||
|
||||
reslimit & reslim() { return m_reslim; }
|
||||
|
|
|
@ -75,39 +75,6 @@ void nla_grobner::add_var_and_its_factors_to_q_and_collect_new_rows(lpvar j, std
|
|||
}
|
||||
}
|
||||
|
||||
var_weight nla_grobner::get_var_weight(lpvar j) const {
|
||||
var_weight k;
|
||||
switch (c().m_lar_solver.get_column_type(j)) {
|
||||
|
||||
case lp::column_type::fixed:
|
||||
k = var_weight::FIXED;
|
||||
break;
|
||||
case lp::column_type::boxed:
|
||||
k = var_weight::BOUNDED;
|
||||
break;
|
||||
case lp::column_type::lower_bound:
|
||||
case lp::column_type::upper_bound:
|
||||
k = var_weight::NOT_FREE;
|
||||
case lp::column_type::free_column:
|
||||
k = var_weight::FREE;
|
||||
break;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
if (c().is_monic_var(j)) {
|
||||
return (var_weight)((int)k + 1);
|
||||
}
|
||||
return k;
|
||||
}
|
||||
|
||||
void nla_grobner::set_active_vars_weights() {
|
||||
m_nex_creator.set_number_of_vars(c().m_lar_solver.column_count());
|
||||
for (lpvar j : m_active_vars) {
|
||||
m_nex_creator.set_var_weight(j, static_cast<unsigned>(get_var_weight(j)));
|
||||
}
|
||||
}
|
||||
|
||||
void nla_grobner::find_nl_cluster() {
|
||||
prepare_rows_and_active_vars();
|
||||
std::queue<lpvar> q;
|
||||
|
|
|
@ -89,7 +89,6 @@ class nla_grobner : common {
|
|||
region m_alloc;
|
||||
ci_value_manager m_val_manager;
|
||||
ci_dependency_manager m_dep_manager;
|
||||
nex_creator m_nex_creator;
|
||||
nex_lt m_lt;
|
||||
public:
|
||||
nla_grobner(core *core);
|
||||
|
@ -100,9 +99,7 @@ private:
|
|||
void prepare_rows_and_active_vars();
|
||||
void add_var_and_its_factors_to_q_and_collect_new_rows(lpvar j, std::queue<lpvar>& q);
|
||||
void display(std::ostream&);
|
||||
void set_active_vars_weights();
|
||||
void init();
|
||||
var_weight get_var_weight(lpvar) const;
|
||||
void compute_basis();
|
||||
void update_statistics();
|
||||
bool find_conflict(ptr_vector<equation>& eqs);
|
||||
|
|
|
@ -76,20 +76,20 @@ void test_cn_on_expr(nex_sum *t, cross_nested& cn) {
|
|||
|
||||
void test_simplify() {
|
||||
#ifdef Z3DEBUG
|
||||
nex_creator r;
|
||||
cross_nested cn(
|
||||
[](const nex* n) {
|
||||
TRACE("nla_cn_test", tout << *n << "\n";);
|
||||
return false;
|
||||
} ,
|
||||
[](unsigned) { return false; },
|
||||
[]() { return 1; } // for random
|
||||
);
|
||||
[]() { return 1; }, // for random
|
||||
r);
|
||||
// enable_trace("nla_cn");
|
||||
// enable_trace("nla_cn_details");
|
||||
// enable_trace("nla_cn_details_");
|
||||
enable_trace("nla_test");
|
||||
|
||||
nex_creator & r = cn.get_nex_creator();
|
||||
r.set_number_of_vars(3);
|
||||
for (unsigned j = 0; j < r.get_number_of_vars(); j++)
|
||||
r.set_var_weight(j, j);
|
||||
|
@ -147,6 +147,7 @@ void test_simplify() {
|
|||
|
||||
void test_cn_shorter() {
|
||||
nex_sum *clone;
|
||||
nex_creator cr;
|
||||
cross_nested cn(
|
||||
[](const nex* n) {
|
||||
TRACE("nla_test", tout <<"cn form = " << *n << "\n";
|
||||
|
@ -155,13 +156,12 @@ void test_cn_shorter() {
|
|||
return false;
|
||||
} ,
|
||||
[](unsigned) { return false; },
|
||||
[]{ return 1; });
|
||||
[]{ return 1; }, cr);
|
||||
enable_trace("nla_test");
|
||||
enable_trace("nla_cn");
|
||||
enable_trace("nla_cn_test");
|
||||
enable_trace("nla_cn_details");
|
||||
enable_trace("nla_test_details");
|
||||
auto & cr = cn.get_nex_creator();
|
||||
cr.set_number_of_vars(20);
|
||||
for (unsigned j = 0; j < cr.get_number_of_vars(); j++)
|
||||
cr.set_var_weight(j,j);
|
||||
|
@ -191,18 +191,18 @@ void test_cn_shorter() {
|
|||
void test_cn() {
|
||||
#ifdef Z3DEBUG
|
||||
test_cn_shorter();
|
||||
nex_creator cr;
|
||||
cross_nested cn(
|
||||
[](const nex* n) {
|
||||
TRACE("nla_test", tout <<"cn form = " << *n << "\n";);
|
||||
return false;
|
||||
} ,
|
||||
[](unsigned) { return false; },
|
||||
[]{ return 1; });
|
||||
[]{ return 1; }, cr);
|
||||
enable_trace("nla_test");
|
||||
enable_trace("nla_cn_test");
|
||||
// enable_trace("nla_cn");
|
||||
// enable_trace("nla_test_details");
|
||||
auto & cr = cn.get_nex_creator();
|
||||
cr.set_number_of_vars(20);
|
||||
for (unsigned j = 0; j < cr.get_number_of_vars(); j++)
|
||||
cr.set_var_weight(j, j);
|
||||
|
|
Loading…
Reference in a new issue