3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-06-28 08:58:44 +00:00

add options to substitute vars in Horner and Grobner

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2020-01-02 15:53:56 -08:00
parent 8596fb2ae6
commit 20af3dd675
7 changed files with 27 additions and 40 deletions

View file

@ -78,7 +78,7 @@ bool horner::lemmas_on_row(const T& row) {
SASSERT (row_is_interesting(row)); SASSERT (row_is_interesting(row));
c().clear_and_resize_active_var_set(); c().clear_and_resize_active_var_set();
create_sum_from_row(row, cn.get_nex_creator(), m_row_sum, nullptr); create_sum_from_row(row, cn.get_nex_creator(), m_row_sum);
c().set_active_vars_weights(m_nex_creator); // without this call the comparisons will be incorrect c().set_active_vars_weights(m_nex_creator); // without this call the comparisons will be incorrect
nex* e = m_nex_creator.simplify(m_row_sum.mk()); nex* e = m_nex_creator.simplify(m_row_sum.mk());
TRACE("nla_horner", tout << "e = " << * e << "\n";); TRACE("nla_horner", tout << "e = " << * e << "\n";);

View file

@ -123,17 +123,9 @@ unsigned common::random() {
} }
// creates a nex expression for the coeff and var, // creates a nex expression for the coeff and var,
nex * common::nexvar(const rational & coeff, lpvar j, nex_creator& cn, nex * common::nexvar(const rational & coeff, lpvar j, nex_creator& cn) {
u_dependency*& dep,
u_dependency_manager* dep_manager) {
SASSERT(!coeff.is_zero()); SASSERT(!coeff.is_zero());
unsigned lc, uc; if (c().m_nla_settings.horner_subs_fixed() && c().var_is_fixed(j)) {
if (c().var_is_fixed(j)) {
if (dep_manager) {
c().m_lar_solver.get_bound_constraint_witnesses_for_column(j, lc, uc);
dep = dep_manager->mk_join(dep, dep_manager->mk_leaf(lc));
dep = dep_manager->mk_join(dep, dep_manager->mk_leaf(uc));
}
return cn.mk_scalar(coeff * c().m_lar_solver.column_lower_bound(j).x); return cn.mk_scalar(coeff * c().m_lar_solver.column_lower_bound(j).x);
} }
if (!c().is_monic_var(j)) { if (!c().is_monic_var(j)) {
@ -144,12 +136,7 @@ nex * common::nexvar(const rational & coeff, lpvar j, nex_creator& cn,
nex_creator::mul_factory mf(cn); nex_creator::mul_factory mf(cn);
mf *= coeff; mf *= coeff;
for (lpvar k : m.vars()) { for (lpvar k : m.vars()) {
if (c().var_is_fixed(k)) { if (c().m_nla_settings.horner_subs_fixed() && c().var_is_fixed(k)) {
if (dep_manager) {
c().m_lar_solver.get_bound_constraint_witnesses_for_column(k, lc, uc);
dep = dep_manager->mk_join(dep, dep_manager->mk_leaf(lc));
dep = dep_manager->mk_join(dep, dep_manager->mk_leaf(uc));
}
mf *= c().m_lar_solver.column_lower_bound(k).x; mf *= c().m_lar_solver.column_lower_bound(k).x;
} else { } else {
c().insert_to_active_var_set(k); c().insert_to_active_var_set(k);
@ -163,31 +150,20 @@ nex * common::nexvar(const rational & coeff, lpvar j, nex_creator& cn,
} }
template <typename T> u_dependency* common::create_sum_from_row(const T& row, template <typename T> void common::create_sum_from_row(const T& row,
nex_creator& cn, nex_creator& cn,
nex_creator::sum_factory& sum, nex_creator::sum_factory& sum
u_dependency_manager* dep_manager
) { ) {
TRACE("nla_horner", tout << "row="; m_core->print_row(row, tout) << "\n";); TRACE("nla_horner", tout << "row="; m_core->print_row(row, tout) << "\n";);
u_dependency * dep = nullptr;
SASSERT(row.size() > 1); SASSERT(row.size() > 1);
sum.reset(); sum.reset();
for (const auto &p : row) { for (const auto &p : row) {
nex* e = nexvar(p.coeff(), p.var(), cn, dep, dep_manager); nex* e = nexvar(p.coeff(), p.var(), cn);
if (!e) if (!e)
continue; continue;
unsigned lc, uc;
if (dep_manager) {
c().m_lar_solver.get_bound_constraint_witnesses_for_column(p.var(), lc, uc);
if (lc + 1)
dep = dep_manager->mk_join(dep, dep_manager->mk_leaf(lc));
if (uc + 1)
dep = dep_manager->mk_join(dep, dep_manager->mk_leaf(uc));
}
sum += e; sum += e;
} }
return dep;
} }
template <typename T> template <typename T>
@ -223,4 +199,4 @@ u_dependency* common::get_fixed_vars_dep_from_row(const T& row, u_dependency_man
} }
template u_dependency* 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_creator::sum_factory&, u_dependency_manager*); 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_creator::sum_factory&);

View file

@ -116,9 +116,9 @@ struct common {
typedef lp::constraint_index value; typedef lp::constraint_index value;
}; };
nex* nexvar(const rational& coeff, lpvar j, nex_creator&, u_dependency*&, u_dependency_manager*); nex* nexvar(const rational& coeff, lpvar j, nex_creator&);
template <typename T> template <typename T>
u_dependency* create_sum_from_row(const T&, nex_creator&, nex_creator::sum_factory&, u_dependency_manager*); void create_sum_from_row(const T&, nex_creator&, nex_creator::sum_factory&);
template <typename T> template <typename T>
u_dependency* get_fixed_vars_dep_from_row(const T&, u_dependency_manager& dep_manager); u_dependency* get_fixed_vars_dep_from_row(const T&, u_dependency_manager& dep_manager);
}; };

View file

@ -1545,7 +1545,7 @@ const rational& core::val_of_fixed_var_with_deps(lpvar j, u_dependency*& dep) {
} }
dd::pdd core::pdd_expr(const rational& c, lpvar j, u_dependency*& dep) { dd::pdd core::pdd_expr(const rational& c, lpvar j, u_dependency*& dep) {
if (var_is_fixed(j)) { if (m_nla_settings.grobner_subs_fixed() && var_is_fixed(j)) {
return m_pdd_manager.mk_val(c * val_of_fixed_var_with_deps(j, dep)); return m_pdd_manager.mk_val(c * val_of_fixed_var_with_deps(j, dep));
} }
@ -1556,7 +1556,7 @@ dd::pdd core::pdd_expr(const rational& c, lpvar j, u_dependency*& dep) {
dd::pdd r = m_pdd_manager.mk_val(c); dd::pdd r = m_pdd_manager.mk_val(c);
const monic& m = emons()[j]; const monic& m = emons()[j];
for (lpvar k : m.vars()) { for (lpvar k : m.vars()) {
if (var_is_fixed(k)) { if (m_nla_settings.grobner_subs_fixed() && var_is_fixed(k)) {
r *= m_pdd_manager.mk_val(val_of_fixed_var_with_deps(k, dep)); r *= m_pdd_manager.mk_val(val_of_fixed_var_with_deps(k, dep));
} else { } else {
r *= m_pdd_manager.mk_var(k); r *= m_pdd_manager.mk_var(k);

View file

@ -4,11 +4,12 @@ def_module_params('nla',
('order', BOOL, True, 'run order lemmas'), ('order', BOOL, True, 'run order lemmas'),
('tangents', BOOL, True, 'run tangent lemmas'), ('tangents', BOOL, True, 'run tangent lemmas'),
('horner', BOOL, True, 'run horner\'s heuristic'), ('horner', BOOL, True, 'run horner\'s heuristic'),
('horner_subs_fixed', BOOL, True, 'substitute fixed variables by constants'),
('horner_frequency', UINT, 4, 'horner\'s call frequency'), ('horner_frequency', UINT, 4, 'horner\'s call frequency'),
('horner_row_length_limit', UINT, 10, 'row is disregarded by the heuristic if its length is longer than the value'), ('horner_row_length_limit', UINT, 10, 'row is disregarded by the heuristic if its length is longer than the value'),
('grobner', BOOL, True, 'run grobner\'s basis heuristic'), ('grobner', BOOL, True, 'run grobner\'s basis heuristic'),
('grobner_frequency', UINT, 5, 'grobner\'s call frequency'), ('grobner_eqs_threshold', UINT, 512, 'grobner\'s maximum number of equalities'),
('grobner_eqs_threshold', UINT, 512, 'grobner\'s maximum number of equalities') ('grobner_subs_fixed', BOOL, False, 'substitute fixed variables by constants')
)) ))

View file

@ -27,18 +27,21 @@ class nla_settings {
// how often to call the horner heuristic // how often to call the horner heuristic
unsigned m_horner_frequency; unsigned m_horner_frequency;
unsigned m_horner_row_length_limit; unsigned m_horner_row_length_limit;
bool m_horner_subs_fixed;
// grobner fields // grobner fields
bool m_run_grobner; bool m_run_grobner;
unsigned m_grobner_row_length_limit; unsigned m_grobner_row_length_limit;
bool m_grobner_subs_fixed;
public: public:
nla_settings() : m_run_order(true), nla_settings() : m_run_order(true),
m_run_tangents(true), m_run_tangents(true),
m_run_horner(true), m_run_horner(true),
m_horner_frequency(4), m_horner_frequency(4),
m_horner_row_length_limit(10), m_horner_row_length_limit(10),
m_horner_subs_fixed(true),
m_run_grobner(true), m_run_grobner(true),
m_grobner_row_length_limit(50) m_grobner_row_length_limit(50),
m_grobner_subs_fixed(false)
{} {}
bool run_order() const { return m_run_order; } bool run_order() const { return m_run_order; }
@ -54,11 +57,15 @@ public:
unsigned& horner_frequency() { return m_horner_frequency; } unsigned& horner_frequency() { return m_horner_frequency; }
unsigned horner_row_length_limit() const { return m_horner_row_length_limit; } unsigned horner_row_length_limit() const { return m_horner_row_length_limit; }
unsigned& horner_row_length_limit() { return m_horner_row_length_limit; } unsigned& horner_row_length_limit() { return m_horner_row_length_limit; }
bool horner_subs_fixed() const { return m_horner_subs_fixed; }
bool& horner_subs_fixed() { return m_horner_subs_fixed; }
bool run_grobner() const { return m_run_grobner; } bool run_grobner() const { return m_run_grobner; }
bool& run_grobner() { return m_run_grobner; } bool& run_grobner() { return m_run_grobner; }
unsigned grobner_row_length_limit() const { return m_grobner_row_length_limit; } unsigned grobner_row_length_limit() const { return m_grobner_row_length_limit; }
unsigned& grobner_row_length_limit() { return m_grobner_row_length_limit; } unsigned& grobner_row_length_limit() { return m_grobner_row_length_limit; }
bool grobner_subs_fixed() const { return m_grobner_subs_fixed; }
bool& grobner_subs_fixed() { return m_grobner_subs_fixed; }
}; };
} }

View file

@ -450,9 +450,12 @@ class theory_lra::imp {
m_nla->get_core()->m_nla_settings.run_order() = nla.order(); m_nla->get_core()->m_nla_settings.run_order() = nla.order();
m_nla->get_core()->m_nla_settings.run_tangents() = nla.tangents(); m_nla->get_core()->m_nla_settings.run_tangents() = nla.tangents();
m_nla->get_core()->m_nla_settings.run_horner() = nla.horner(); m_nla->get_core()->m_nla_settings.run_horner() = nla.horner();
m_nla->get_core()->m_nla_settings.horner_subs_fixed() = nla.horner_subs_fixed();
m_nla->get_core()->m_nla_settings.horner_frequency() = nla.horner_frequency(); m_nla->get_core()->m_nla_settings.horner_frequency() = nla.horner_frequency();
m_nla->get_core()->m_nla_settings.horner_row_length_limit() = nla.horner_row_length_limit(); m_nla->get_core()->m_nla_settings.horner_row_length_limit() = nla.horner_row_length_limit();
m_nla->get_core()->m_nla_settings.run_grobner() = nla.grobner(); m_nla->get_core()->m_nla_settings.run_grobner() = nla.grobner();
m_nla->get_core()->m_nla_settings.grobner_subs_fixed() = nla.grobner_subs_fixed();
} }
} }