3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-15 13:28:47 +00:00

further tuning pb

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-02-25 23:30:14 -08:00
parent 478b3160ac
commit 54e3b5ee0d
6 changed files with 74 additions and 35 deletions

View file

@ -50,16 +50,21 @@ namespace simplex {
typedef typename Ext::eps_manager eps_manager;
typedef typename Ext::scoped_numeral scoped_numeral;
typedef _scoped_numeral<eps_manager> scoped_eps_numeral;
typedef typename _scoped_numeral_vector<eps_manager> scoped_eps_numeral_vector;
typedef sparse_matrix<Ext> matrix;
struct var_lt {
bool operator()(var_t v1, var_t v2) const { return v1 < v2; }
};
typedef heap<var_lt> var_heap;
struct stats {
unsigned m_num_pivots;
stats() { reset(); }
void reset() {
memset(this, sizeof(*this), 0);
}
};
enum pivot_strategy_t {
S_BLAND,
S_GREATEST_ERROR,
@ -99,6 +104,7 @@ namespace simplex {
uint_set m_left_basis;
unsigned m_infeasible_var;
unsigned_vector m_base_vars;
stats m_stats;
public:
simplex():
@ -144,6 +150,8 @@ namespace simplex {
row_iterator row_begin(row const& r) { return M.row_begin(r); }
row_iterator row_end(row const& r) { return M.row_end(r); }
void collect_statistics(::statistics & st) const;
private:
var_t select_var_to_fix();

View file

@ -306,6 +306,7 @@ namespace simplex {
template<typename Ext>
void simplex<Ext>::pivot(var_t x_i, var_t x_j, numeral const& a_ij) {
++m_stats.m_num_pivots;
var_info& x_iI = m_vars[x_i];
var_info& x_jI = m_vars[x_j];
unsigned r_i = x_iI.m_base2row;
@ -868,6 +869,13 @@ namespace simplex {
return true;
}
template<typename Ext>
void simplex<Ext>::collect_statistics(::statistics & st) const {
M.collect_statistics(st);
st.update("simplex num pivots", m_stats.m_num_pivots);
}
};
#endif

View file

@ -20,6 +20,7 @@ Notes:
#define _SPARSE_MATRIX_H_
#include "mpq_inf.h"
#include "statistics.h"
namespace simplex {
@ -39,6 +40,14 @@ namespace simplex {
private:
struct stats {
unsigned m_add_rows;
stats() { reset(); }
void reset() {
memset(this, sizeof(*this), 0);
}
};
static const int dead_id = -1;
/**
@ -126,6 +135,7 @@ namespace simplex {
vector<column> m_columns; // per var
svector<int> m_var_pos; // temporary map from variables to positions in row
unsigned_vector m_var_pos_idx; // indices in m_var_pos
stats m_stats;
bool well_formed_row(unsigned row_id) const;
bool well_formed_column(unsigned column_id) const;
@ -238,6 +248,7 @@ namespace simplex {
void display_row(std::ostream& out, row const& r);
bool well_formed() const;
void collect_statistics(::statistics & st) const;
};

View file

@ -322,7 +322,7 @@ namespace simplex {
*/
template<typename Ext>
void sparse_matrix<Ext>::add(row row1, numeral const& n, row row2) {
// m_stats.m_add_rows++;
m_stats.m_add_rows++;
_row & r1 = m_rows[row1.id()];
_row & r2 = m_rows[row2.id()];
@ -547,6 +547,15 @@ namespace simplex {
return true;
}
/**
\brief statistics
*/
template<typename Ext>
void sparse_matrix<Ext>::collect_statistics(::statistics & st) const {
st.update("simplex add rows", m_stats.m_add_rows);
}
/**
\brief display method
*/

View file

@ -723,6 +723,7 @@ namespace smt {
st.update("pb compilations", m_stats.m_num_compiles);
st.update("pb compiled clauses", m_stats.m_num_compiled_clauses);
st.update("pb compiled vars", m_stats.m_num_compiled_vars);
m_simplex.collect_statistics(st);
}
void theory_pb::reset_eh() {
@ -979,10 +980,10 @@ namespace smt {
literal l = c.lit();
lbool asgn = ctx.get_assignment(l);
if (c.max_sum() < c.k() && asgn == l_false) {
if (c.max_sum() < c.mpz_k() && asgn == l_false) {
return;
}
if (c.is_ge() && c.min_sum() >= c.k() && asgn == l_true) {
if (c.is_ge() && c.min_sum() >= c.mpz_k() && asgn == l_true) {
return;
}
for (i = 0; i < c.size(); ++i) {
@ -1003,11 +1004,11 @@ namespace smt {
c.m_min_sum += c.ncoeff(i);
}
DEBUG_CODE(
numeral sum(0);
numeral maxs(0);
scoped_mpz sum(m_mpz_mgr);
scoped_mpz maxs(m_mpz_mgr);
for (unsigned i = 0; i < c.size(); ++i) {
if (ctx.get_assignment(c.lit(i)) == l_true) sum += c.coeff(i);
if (ctx.get_assignment(c.lit(i)) != l_false) maxs += c.coeff(i);
if (ctx.get_assignment(c.lit(i)) == l_true) sum += c.ncoeff(i);
if (ctx.get_assignment(c.lit(i)) != l_false) maxs += c.ncoeff(i);
}
CTRACE("pb", (maxs > c.max_sum()), display(tout, c, true););
SASSERT(c.min_sum() <= sum);
@ -1015,32 +1016,32 @@ namespace smt {
SASSERT(maxs <= c.max_sum());
);
SASSERT(c.min_sum() <= c.max_sum());
SASSERT(!c.min_sum().is_neg());
SASSERT(!m_mpz_mgr.is_neg(c.min_sum()));
ctx.push_trail(value_trail<context, unsigned>(c.m_nfixed));
++c.m_nfixed;
SASSERT(c.nfixed() <= c.size());
if (c.is_ge() && c.min_sum() >= c.k() && asgn != l_true) {
if (c.is_ge() && c.min_sum() >= c.mpz_k() && asgn != l_true) {
TRACE("pb", display(tout << "Set " << l << "\n", c, true););
add_assign(c, get_helpful_literals(c, false), l);
}
else if (c.max_sum() < c.k() && asgn != l_false) {
else if (c.max_sum() < c.mpz_k() && asgn != l_false) {
TRACE("pb", display(tout << "Set " << ~l << "\n", c, true););
add_assign(c, get_unhelpful_literals(c, true), ~l);
}
else if (c.is_eq() && c.nfixed() == c.size() && c.min_sum() == c.k() && asgn != l_true) {
else if (c.is_eq() && c.nfixed() == c.size() && c.min_sum() == c.mpz_k() && asgn != l_true) {
TRACE("pb", display(tout << "Set " << l << "\n", c, true););
add_assign(c, get_all_literals(c, false), l);
}
else if (c.is_eq() && c.nfixed() == c.size() && c.min_sum() != c.k() && asgn != l_false) {
else if (c.is_eq() && c.nfixed() == c.size() && c.min_sum() != c.mpz_k() && asgn != l_false) {
TRACE("pb", display(tout << "Set " << ~l << "\n", c, true););
add_assign(c, get_all_literals(c, false), ~l);
}
#if 0
else if (c.is_eq() && c.min_sum() > c.k() && asgn != l_false) {
else if (c.is_eq() && c.min_sum() > c.mpz_k() && asgn != l_false) {
TRACE("pb", display(tout << "Set " << ~l << "\n", c, true););
add_assign(c, get_all_literals(c, false), ~l);
}
else if (c.is_eq() && asgn == l_true && c.min_sum() == c.k() && c.max_sum() > c.k()) {
else if (c.is_eq() && asgn == l_true && c.min_sum() == c.mpz_k() && c.max_sum() > c.mpz_k()) {
literal_vector& lits = get_all_literals(c, false);
lits.push_back(c.lit());
for (unsigned i = 0; i < c.size(); ++i) {
@ -1076,17 +1077,19 @@ namespace smt {
// Adjust set of watched literals.
//
numeral k = c.k();
numeral coeff = c.coeff(w);
bool add_more = c.watch_sum() - coeff < k + c.max_watch();
scoped_mpz k_coeff(m_mpz_mgr), k(m_mpz_mgr);
k = c.mpz_k();
k_coeff = k;
k_coeff += c.ncoeff(w);
bool add_more = c.watch_sum() < k_coeff + c.max_watch();
for (unsigned i = c.watch_size(); add_more && i < c.size(); ++i) {
if (ctx.get_assignment(c.lit(i)) != l_false) {
add_watch(c, i);
add_more = c.watch_sum() - coeff < k + c.max_watch();
add_more = c.watch_sum() < k_coeff + c.max_watch();
}
}
if (c.watch_sum() - coeff < k) {
if (c.watch_sum() < k_coeff) {
//
// L: 3*x1 + 2*x2 + x4 >= 3, but x1 <- 0, x2 <- 0
// create clause x1 or x2 or ~L
@ -1113,9 +1116,10 @@ namespace smt {
literal_vector& lits = get_unhelpful_literals(c, true);
lits.push_back(c.lit());
numeral deficit = c.watch_sum() - k;
scoped_mpz deficit(m_mpz_mgr);
deficit = c.watch_sum() - k;
for (unsigned i = 0; i < c.size(); ++i) {
if (ctx.get_assignment(c.lit(i)) == l_undef && deficit < c.coeff(i)) {
if (ctx.get_assignment(c.lit(i)) == l_undef && deficit < c.ncoeff(i)) {
DEBUG_CODE(validate_assign(c, lits, c.lit(i)););
add_assign(c, lits, c.lit(i));
// break;
@ -1770,16 +1774,15 @@ namespace smt {
void theory_pb::validate_watch(ineq const& c) const {
context& ctx = get_context();
numeral sum = numeral::zero();
numeral max = numeral::zero();
scoped_mpz sum(m_mpz_mgr), max(m_mpz_mgr);
for (unsigned i = 0; i < c.watch_size(); ++i) {
sum += c.coeff(i);
if (c.coeff(i) > max) {
max = c.coeff(i);
sum += c.ncoeff(i);
if (max < c.ncoeff(i)) {
max = c.ncoeff(i);
}
}
SASSERT(c.watch_sum() == sum);
SASSERT(sum >= c.k());
SASSERT(sum >= c.mpz_k());
SASSERT(max == c.max_watch());
}

View file

@ -142,14 +142,14 @@ namespace smt {
unsigned size() const { return args().size(); }
class mpz const& watch_sum() const { return m_watch_sum; }
class mpz const& max_watch() const { return m_max_watch.get(); }
scoped_mpz const& watch_sum() const { return m_watch_sum; }
scoped_mpz const& max_watch() const { return m_max_watch; }
void set_max_watch(mpz const& n) { m_max_watch = n; }
unsigned watch_size() const { return m_watch_sz; }
// variable watch infrastructure
class mpz const& min_sum() const { return m_min_sum; }
class mpz const& max_sum() const { return m_max_sum; }
scoped_mpz const& min_sum() const { return m_min_sum; }
scoped_mpz const& max_sum() const { return m_max_sum; }
unsigned nfixed() const { return m_nfixed; }
bool vwatch_initialized() const { return !m_mpz.is_zero(max_sum()); }
void vwatch_reset() { m_min_sum.reset(); m_max_sum.reset(); m_nfixed = 0; }
@ -205,7 +205,7 @@ namespace smt {
literal_vector m_explain_lower; // Simplex: explanations for lower bounds
literal_vector m_explain_upper; // Simplex: explanations for upper bounds
unsynch_mpq_inf_manager m_mpq_inf_mgr; // Simplex: manage inf_mpq numerals
unsynch_mpz_manager m_mpz_mgr; // Simplex: manager mpz numerals
mutable unsynch_mpz_manager m_mpz_mgr; // Simplex: manager mpz numerals
unsigned_vector m_ineqs_trail;
unsigned_vector m_ineqs_lim;
literal_vector m_literals; // temporary vector