3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 11:25:51 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-05-01 13:10:34 -07:00
parent 82a364ed7b
commit 20277f4a3f
5 changed files with 250 additions and 72 deletions

View file

@ -60,9 +60,9 @@ namespace polysat {
struct var_info {
unsigned m_base2row:29;
unsigned m_is_base:1;
numeral m_lo;
numeral m_hi;
numeral m_value;
numeral m_lo { 0 };
numeral m_hi { 0 };
numeral m_value { 0 };
var_info():
m_base2row(0),
m_is_base(false)
@ -75,19 +75,19 @@ namespace polysat {
numeral m_base_coeff;
};
static const var_t null_var = 0;
static const var_t null_var = UINT_MAX;
reslimit& m_limit;
mutable manager m;
mutable matrix M;
unsigned m_max_iterations;
unsigned m_max_iterations { UINT_MAX };
var_heap m_to_patch;
vector<var_info> m_vars;
vector<row_info> m_rows;
bool m_bland;
unsigned m_blands_rule_threshold;
bool m_bland { false };
unsigned m_blands_rule_threshold { 1000 };
random_gen m_random;
uint_set m_left_basis;
unsigned m_infeasible_var;
unsigned m_infeasible_var { null_var };
unsigned_vector m_base_vars;
stats m_stats;
@ -95,10 +95,7 @@ namespace polysat {
fixplex(reslimit& lim):
m_limit(lim),
M(m),
m_max_iterations(UINT_MAX),
m_to_patch(1024),
m_bland(false),
m_blands_rule_threshold(1000) {}
m_to_patch(1024) {}
~fixplex();
@ -106,33 +103,29 @@ namespace polysat {
typedef typename matrix::row_iterator row_iterator;
typedef typename matrix::col_iterator col_iterator;
void set_lo(var_t var, numeral const& b) { m_vars[var].m_lo = b; }
void set_hi(var_t var, numeral const& b) { m_vars[var].m_hi = b; }
void set_bounds(var_t v, numeral const& lo, numeral const& hi);
void unset_bounds(var_t v) { m_vars[v].m_lo = m_vars[v].m_hi; }
var_t get_base_var(row const& r) const { return m_rows[r.id()].m_base; }
numeral const& lo(var_t var) const { return m_vars[var].m_lo; }
numeral const& hi(var_t var) const { return m_vars[var].m_hi; }
numeral const& value(var_t var) const { return m_vars[var].m_value; }
void set_max_iterations(unsigned n) { m_max_iterations = n; }
row_iterator row_begin(row const& r) { return M.row_begin(r); }
row_iterator row_end(row const& r) { return M.row_end(r); }
unsigned get_num_vars() const { return m_vars.size(); }
void ensure_var(var_t v);
void reset();
lbool make_feasible();
row add_row(var_t base, unsigned num_vars, var_t const* vars, numeral const* coeffs);
row add_row(var_t base, unsigned num_vars, var_t const* vars, numeral const* coeffs);
std::ostream& display(std::ostream& out) const;
void display_row(std::ostream& out, row const& r, bool values = true);
void collect_statistics(::statistics & st) const;
row get_infeasible_row();
#if 0
// TBD
row get_infeasible_row() { throw nullptr; }
void del_row(var_t base_var) {}
bool in_range(var_t var, numeral const& b) const {}
void unset_lo(var_t var) {}
void unset_hi(var_t var) {}
void set_value(var_t var, numeral const& b) {}
numeral const& get_value(var_t v) { throw nullptr; }
void display(std::ostream& out) const {}
void display_row(std::ostream& out, row const& r, bool values = true) {}
void collect_statistics(::statistics & st) const {}
void del_row(var_t base_var) {}
#endif
private:
@ -140,41 +133,45 @@ namespace polysat {
void make_basic(var_t v, row const& r);
void update_value_core(var_t v, numeral const& delta);
void ensure_var(var_t v);
// TBD:
void del_row(row const& r) {}
var_t select_var_to_fix() { throw nullptr; }
pivot_strategy_t pivot_strategy() { throw nullptr; }
var_t select_smallest_var() { return m_to_patch.empty()?null_var:m_to_patch.erase_min(); }
var_t select_error_var(bool least) { throw nullptr; }
void check_blands_rule(var_t v, unsigned& num_repeated) {}
lbool make_var_feasible(var_t x_i);
bool is_infeasible_row(var_t x);
void pivot(var_t x_i, var_t x_j, numeral const& b, numeral const& new_value);
void update_value(var_t v, numeral const& delta);
bool can_pivot(var_t x_i, numeral const& new_value, numeral const& a_ij, var_t x_j);
bool has_minimal_trailing_zeros(var_t y, numeral const& b);
var_t select_pivot_core(var_t x, numeral const& delta, numeral const& new_value, numeral& out_b);
numeral new_value(var_t v) const;
bool in_bounds(var_t v) const { return in_bounds(v, value(v)); }
bool in_bounds(var_t v, numeral const& b) const { return in_bounds(b, lo(v), hi(v)); }
bool in_bounds(numeral const& val, numeral const& lo, numeral const& hi) const;
bool is_free(var_t v) const { return lo(v) == hi(v); }
bool is_non_free(var_t v) const { return !is_free(v); }
bool is_base(var_t x) const { return m_vars[x].m_is_base; }
bool is_feasible() const;
int get_num_non_free_dep_vars(var_t x_j, int best_so_far);
void add_patch(var_t v);
var_t select_var_to_fix();
void check_blands_rule(var_t v, unsigned& num_repeated);
pivot_strategy_t pivot_strategy() { return m_bland ? S_BLAND : S_DEFAULT; }
var_t select_error_var(bool least);
bool well_formed() const;
bool well_formed_row(row const& r) const;
#if 0
// TBD:
void del_row(row const& r) {}
void move_to_bound(var_t x, bool to_lower) {}
bool can_pivot(var_t x_i, numeral const& new_value, numeral const& a_ij, var_t x_j);
bool has_minimal_trailing_zeros(var_t y, numeral const& b);
var_t select_pivot(var_t x_i, bool is_below, numeral& out_a_ij) { throw nullptr; }
var_t select_pivot_blands(var_t x_i, bool is_below, numeral& out_a_ij) { throw nullptr; }
var_t select_pivot_core(var_t x, numeral const& delta, numeral const& new_value, numeral& out_b);
int get_num_non_free_dep_vars(var_t x_j, int best_so_far) { throw nullptr; }
var_t pick_var_to_leave(var_t x_j, bool is_pos,
numeral& gain, numeral& new_a_ij, bool& inc) { throw nullptr; }
void select_pivot_primal(var_t v, var_t& x_i, var_t& x_j, numeral& a_ij, bool& inc_x_i, bool& inc_x_j) {}
numeral new_value(var_t v) const;
bool in_bounds(var_t v) const;
bool in_bounds(numeral const& val, numeral const& lo, numeral const& hi) const;
bool is_free(var_t v) const { return m_vars[v].m_lo == m_vars[v].m_hi; }
bool is_non_free(var_t v) const { return !is_free(v); }
bool is_base(var_t x) const { return m_vars[x].m_is_base; }
void add_patch(var_t v) {}
bool well_formed() const { return false; }
bool well_formed_row(row const& r) const { return false; }
bool is_feasible() const { return false; }
#endif
};
@ -200,9 +197,15 @@ namespace polysat {
// treat numerals as signed and check for overflow/underflow
bool signed_mul(numeral& r, numeral const& x, numeral const& y) { r = x * y; return true; }
bool signed_add(numeral& r, numeral const& x, numeral const& y) { r = x + y; return true; }
std::ostream& display(std::ostream& out, numeral const& x) const { return out << x; }
};
typedef _scoped_numeral<manager> scoped_numeral;
};
template<typename Ext>
inline std::ostream& operator<<(std::ostream& out, fixplex<Ext> const& fp) {
return fp.display(out);
}
};