mirror of
https://github.com/Z3Prover/z3
synced 2025-04-08 18:31:49 +00:00
add parameters to control grobner's explosure
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
7a2dc6e69e
commit
bb6511b425
|
@ -152,7 +152,7 @@ namespace dd {
|
|||
s.push_equation(solver::to_simplify, dst);
|
||||
}
|
||||
// v has been eliminated.
|
||||
SASSERT(!dst->poly().free_vars().contains(v));
|
||||
// SASSERT(!dst->poly().free_vars().contains(v));
|
||||
add_to_use(dst, use_list);
|
||||
}
|
||||
if (all_reduced) {
|
||||
|
|
|
@ -70,26 +70,22 @@ namespace dd {
|
|||
}
|
||||
|
||||
|
||||
void solver::set_thresholds() {
|
||||
void solver::set_thresholds(unsigned eqs_growth, unsigned expr_size_growth, unsigned expr_degree_growth) {
|
||||
IF_VERBOSE(3, verbose_stream() << "start saturate\n"; display_statistics(verbose_stream()));
|
||||
if (m_to_simplify.size() == 0)
|
||||
return;
|
||||
m_config.m_eqs_threshold = static_cast<unsigned>(10 * ceil(log(m_to_simplify.size()))*m_to_simplify.size());
|
||||
m_config.m_eqs_threshold = static_cast<unsigned>(eqs_growth * ceil(log(1 + m_to_simplify.size()))* m_to_simplify.size());
|
||||
m_config.m_expr_size_limit = 0;
|
||||
m_config.m_expr_degree_limit = 0;
|
||||
for (equation* e: m_to_simplify) {
|
||||
m_config.m_expr_size_limit = std::max(m_config.m_expr_size_limit, (unsigned)e->poly().tree_size());
|
||||
m_config.m_expr_degree_limit = std::max(m_config.m_expr_degree_limit, e->poly().degree());
|
||||
}
|
||||
m_config.m_expr_size_limit *= 2;
|
||||
m_config.m_expr_degree_limit *= 2;
|
||||
m_config.m_expr_size_limit *= expr_size_growth;
|
||||
m_config.m_expr_degree_limit *= expr_degree_growth;;
|
||||
|
||||
IF_VERBOSE(3, verbose_stream() << "set m_config.m_eqs_threshold to 10 * " << 10 * ceil(log(m_to_simplify.size())) << "* " << m_to_simplify.size() << " = " << m_config.m_eqs_threshold << "\n";
|
||||
verbose_stream() << "set m_config.m_expr_size_limit to " << m_config.m_expr_size_limit << "\n";
|
||||
verbose_stream() << "set m_config.m_expr_degree_limit to " << m_config.m_expr_degree_limit << "\n";
|
||||
);
|
||||
m_config.m_max_steps = 700;
|
||||
m_config.m_max_simplified = 7000;
|
||||
|
||||
}
|
||||
void solver::saturate() {
|
||||
|
|
|
@ -138,7 +138,7 @@ public:
|
|||
std::ostream& display_statistics(std::ostream& out) const;
|
||||
const stats& get_stats() const { return m_stats; }
|
||||
stats& get_stats() { return m_stats; }
|
||||
void set_thresholds();
|
||||
void set_thresholds(unsigned eqs_growth, unsigned expr_size_growth, unsigned expr_degree_growth);
|
||||
|
||||
private:
|
||||
bool step();
|
||||
|
|
|
@ -1289,7 +1289,7 @@ lbool core::inner_check(bool constraint_derived) {
|
|||
clear_and_resize_active_var_set();
|
||||
if (m_nla_settings.run_grobner()) {
|
||||
find_nl_cluster();
|
||||
run_pdd_grobner();
|
||||
run_grobner();
|
||||
}
|
||||
}
|
||||
if (done()) {
|
||||
|
@ -1396,13 +1396,32 @@ std::ostream& core::print_term( const lp::lar_term& t, std::ostream& out) const
|
|||
}
|
||||
|
||||
|
||||
void core::run_pdd_grobner() {
|
||||
void core::run_grobner() {
|
||||
lp_settings().stats().m_grobner_calls++;
|
||||
configure_grobner();
|
||||
m_pdd_grobner.saturate();
|
||||
bool conflict = false;
|
||||
for (auto eq : m_pdd_grobner.equations()) {
|
||||
if (check_pdd_eq(eq)) {
|
||||
conflict = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (conflict) {
|
||||
IF_VERBOSE(2, verbose_stream() << "grobner conflict\n");
|
||||
}
|
||||
else {
|
||||
IF_VERBOSE(2, verbose_stream() << "grobner miss\n");
|
||||
IF_VERBOSE(4, diagnose_pdd_miss(verbose_stream()));
|
||||
}
|
||||
}
|
||||
|
||||
void core::configure_grobner() {
|
||||
m_pdd_grobner.reset();
|
||||
try {
|
||||
set_level2var_for_pdd_grobner();
|
||||
set_level2var_for_grobner();
|
||||
for (unsigned i : m_rows) {
|
||||
add_row_to_pdd_grobner(m_lar_solver.A_r().m_rows[i]);
|
||||
add_row_to_grobner(m_lar_solver.A_r().m_rows[i]);
|
||||
}
|
||||
}
|
||||
catch (...) {
|
||||
|
@ -1422,8 +1441,6 @@ void core::run_pdd_grobner() {
|
|||
}
|
||||
#endif
|
||||
|
||||
// configure grobner
|
||||
// TBD: move this code somewhere self-contained, and tune it.
|
||||
double tree_size = 100;
|
||||
unsigned gr_eq_size = 0;
|
||||
for (auto* e : m_pdd_grobner.equations()) {
|
||||
|
@ -1434,27 +1451,13 @@ void core::run_pdd_grobner() {
|
|||
struct dd::solver::config cfg;
|
||||
cfg.m_expr_size_limit = (unsigned)tree_size;
|
||||
cfg.m_max_steps = gr_eq_size;
|
||||
cfg.m_eqs_threshold = m_nla_settings.grobner_eqs_growth() * ceil(log(gr_eq_size + 1)) * gr_eq_size;;
|
||||
cfg.m_max_simplified = m_nla_settings.grobner_max_simplified();
|
||||
|
||||
m_pdd_grobner.set(cfg);
|
||||
m_pdd_grobner.set_thresholds();
|
||||
m_pdd_grobner.set_thresholds(m_nla_settings.grobner_eqs_growth(), m_nla_settings.grobner_expr_size_growth(),
|
||||
m_nla_settings.grobner_expr_degree_growth());
|
||||
|
||||
m_pdd_manager.set_max_num_nodes(10000); // or something proportional to the number of initial nodes.
|
||||
m_pdd_grobner.saturate();
|
||||
bool conflict = false;
|
||||
for (auto eq : m_pdd_grobner.equations()) {
|
||||
if (check_pdd_eq(eq)) {
|
||||
conflict = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (conflict) {
|
||||
IF_VERBOSE(2, verbose_stream() << "grobner conflict\n");
|
||||
}
|
||||
else {
|
||||
IF_VERBOSE(2, verbose_stream() << "grobner miss\n");
|
||||
IF_VERBOSE(4, diagnose_pdd_miss(verbose_stream()));
|
||||
}
|
||||
}
|
||||
|
||||
std::ostream& core::diagnose_pdd_miss(std::ostream& out) {
|
||||
|
@ -1568,7 +1571,7 @@ dd::pdd core::pdd_expr(const rational& c, lpvar j, u_dependency*& dep) {
|
|||
return r;
|
||||
}
|
||||
|
||||
void core::add_row_to_pdd_grobner(const vector<lp::row_cell<rational>> & row) {
|
||||
void core::add_row_to_grobner(const vector<lp::row_cell<rational>> & row) {
|
||||
u_dependency *dep = nullptr;
|
||||
dd::pdd sum = m_pdd_manager.mk_val(rational(0));
|
||||
for (const auto &p : row) {
|
||||
|
@ -1639,7 +1642,7 @@ void core::set_active_vars_weights(nex_creator& nc) {
|
|||
}
|
||||
}
|
||||
|
||||
void core::set_level2var_for_pdd_grobner() {
|
||||
void core::set_level2var_for_grobner() {
|
||||
unsigned n = m_lar_solver.column_count();
|
||||
unsigned_vector sorted_vars(n), weighted_vars(n);
|
||||
for (unsigned j = 0; j < n; j++) {
|
||||
|
|
|
@ -399,7 +399,7 @@ public:
|
|||
return lp::print_linear_combination_customized(v, [this](lpvar j) { return var_str(j); },
|
||||
out);
|
||||
}
|
||||
void run_pdd_grobner();
|
||||
void run_grobner();
|
||||
void find_nl_cluster();
|
||||
void prepare_rows_and_active_vars();
|
||||
void add_var_and_its_factors_to_q_and_collect_new_rows(lpvar j, svector<lpvar>& q);
|
||||
|
@ -407,11 +407,12 @@ public:
|
|||
void display_matrix_of_m_rows(std::ostream & out) const;
|
||||
void set_active_vars_weights(nex_creator&);
|
||||
unsigned get_var_weight(lpvar) const;
|
||||
void add_row_to_pdd_grobner(const vector<lp::row_cell<rational>> & row);
|
||||
void add_row_to_grobner(const vector<lp::row_cell<rational>> & row);
|
||||
bool check_pdd_eq(const dd::solver::equation*);
|
||||
const rational& val_of_fixed_var_with_deps(lpvar j, u_dependency*& dep);
|
||||
dd::pdd pdd_expr(const rational& c, lpvar j, u_dependency*&);
|
||||
void set_level2var_for_pdd_grobner();
|
||||
void set_level2var_for_grobner();
|
||||
void configure_grobner();
|
||||
}; // end of core
|
||||
|
||||
struct pp_mon {
|
||||
|
|
|
@ -8,7 +8,10 @@ def_module_params('nla',
|
|||
('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'),
|
||||
('grobner', BOOL, True, 'run grobner\'s basis heuristic'),
|
||||
('grobner_eqs_growth', UINT, 10, 'grobner\'s maximum number of equalities'),
|
||||
('grobner_eqs_growth', UINT, 10, 'grobner\'s number of equalities growth '),
|
||||
('grobner_expr_size_growth', UINT, 10, 'grobner\'s maximum expr size growth'),
|
||||
('grobner_expr_degree_growth', UINT, 10, 'grobner\'s maximum expr degree growth'),
|
||||
('grobner_max_simplified', UINT, 10000, 'grobner\'s maximum number of simplifications'),
|
||||
('grobner_subs_fixed', BOOL, False, 'substitute fixed variables by constants')
|
||||
))
|
||||
|
||||
|
|
|
@ -33,6 +33,10 @@ class nla_settings {
|
|||
unsigned m_grobner_row_length_limit;
|
||||
bool m_grobner_subs_fixed;
|
||||
unsigned m_grobner_eqs_growth;
|
||||
unsigned m_grobner_tree_size_growth;
|
||||
unsigned m_grobner_expr_size_growth;
|
||||
unsigned m_grobner_expr_degree_growth;
|
||||
unsigned m_grobner_max_simplified;
|
||||
public:
|
||||
nla_settings() : m_run_order(true),
|
||||
m_run_tangents(true),
|
||||
|
@ -69,5 +73,19 @@ public:
|
|||
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; }
|
||||
|
||||
unsigned grobner_tree_size_growth() const { return m_grobner_tree_size_growth; }
|
||||
unsigned & grobner_tree_size_growth() { return m_grobner_tree_size_growth; }
|
||||
|
||||
unsigned grobner_expr_size_growth() const { return m_grobner_expr_size_growth; }
|
||||
unsigned & grobner_expr_size_growth() { return m_grobner_expr_size_growth; }
|
||||
|
||||
unsigned grobner_expr_degree_growth() const { return m_grobner_expr_degree_growth; }
|
||||
unsigned & grobner_expr_degree_growth() { return m_grobner_expr_degree_growth; }
|
||||
|
||||
unsigned grobner_max_simplified() const { return m_grobner_max_simplified; }
|
||||
unsigned & grobner_max_simplified() { return m_grobner_max_simplified; }
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
|
|
|
@ -457,6 +457,9 @@ class theory_lra::imp {
|
|||
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();
|
||||
m_nla->get_core()->m_nla_settings.grobner_eqs_growth() = nla.grobner_eqs_growth();
|
||||
m_nla->get_core()->m_nla_settings.grobner_expr_size_growth() = nla.grobner_expr_size_growth();
|
||||
m_nla->get_core()->m_nla_settings.grobner_expr_degree_growth() = nla.grobner_expr_degree_growth();
|
||||
m_nla->get_core()->m_nla_settings.grobner_max_simplified() = nla.grobner_max_simplified();
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue