3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-27 19:05:51 +00:00

move m_fixed_var_table to lar_solver

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2020-06-11 18:02:36 -07:00
parent 3b87cdfd0f
commit fe0e042e40
6 changed files with 131 additions and 141 deletions

View file

@ -95,7 +95,6 @@ public:
unsigned size() const override { return m_term->size();}
};
class constraint_set {
region m_region;
column_namer& m_namer;
@ -151,20 +150,16 @@ public:
m_constraint_count = m_constraints.size();
m_constraint_count.push();
m_region.push_scope();
#if 1
m_active_lim = m_active.size();
m_active_lim.push();
#endif
}
void pop(unsigned k) {
#if 1
m_active_lim.pop(k);
for (unsigned i = m_active.size(); i-- > m_active_lim; ) {
m_constraints[m_active[i]]->deactivate();
}
m_active.shrink(m_active_lim);
#endif
m_constraint_count.pop(k);
for (unsigned i = m_constraints.size(); i-- > m_constraint_count; )
m_constraints[i]->~lar_base_constraint();
@ -181,17 +176,10 @@ public:
return add(new (m_region) lar_term_constraint(j, t, k, rhs));
}
#if 0
bool is_active(constraint_index ci) const { return true; }
void activate(constraint_index ci) {}
#else
// future behavior uses activation bit.
bool is_active(constraint_index ci) const { return m_constraints[ci]->is_active(); }
void activate(constraint_index ci) { auto& c = *m_constraints[ci]; if (!c.is_active()) { c.activate(); m_active.push_back(ci); } }
#endif
lar_base_constraint const& operator[](constraint_index ci) const { return *m_constraints[ci]; }
@ -283,9 +271,6 @@ public:
print_left_side_of_constraint(c, var_str, out);
return out << " " << lconstraint_kind_string(c.kind()) << " " << c.rhs() << std::endl;
}
};
inline std::ostream& operator<<(std::ostream& out, constraint_set const& cs) {

View file

@ -18,14 +18,16 @@ void clear() {lp_assert(false); // not implemented
}
lar_solver::lar_solver() : m_status(lp_status::UNKNOWN),
m_crossed_bounds_column(-1),
m_mpq_lar_core_solver(m_settings, *this),
m_int_solver(nullptr),
m_need_register_terms(false),
m_var_register(false),
m_term_register(true),
m_constraints(*this)
lar_solver::lar_solver(const std::function<void(unsigned, unsigned)>& report_equality_of_fixed_vars) :
m_status(lp_status::UNKNOWN),
m_crossed_bounds_column(-1),
m_mpq_lar_core_solver(m_settings, *this),
m_int_solver(nullptr),
m_need_register_terms(false),
m_var_register(false),
m_term_register(true),
m_constraints(*this),
m_report_equality_of_fixed_vars(report_equality_of_fixed_vars)
{}
void lar_solver::set_track_pivoted_rows(bool v) {
@ -271,6 +273,7 @@ void lar_solver::pop(unsigned k) {
m_columns_to_ul_pairs.pop(k);
m_mpq_lar_core_solver.pop(k);
remove_non_fixed_from_fixed_var_table();
clean_popped_elements(n, m_columns_with_changed_bound);
clean_popped_elements(n, m_incorrect_columns);
@ -1721,6 +1724,36 @@ constraint_index lar_solver::add_var_bound(var_index j, lconstraint_kind kind, c
return ci;
}
void lar_solver::remove_non_fixed_from_fixed_var_table() {
vector<value_sort_pair> to_remove;
for (const auto& p : m_fixed_var_table) {
unsigned j = p.m_value;
if (j >= column_count() || column_is_fixed(j) == false)
to_remove.push_back(p.m_key);
}
for (const auto & p : to_remove)
m_fixed_var_table.erase(p);
}
void lar_solver::register_in_fixed_var_table(unsigned j) {
SASSERT(column_is_fixed(j));
const impq& bound = get_lower_bound(j);
if (bound.y.is_zero() == false)
return;
value_sort_pair key(bound.x, column_is_int(j));
unsigned k;
if (m_fixed_var_table.find(key, k) == false ) {
m_fixed_var_table.insert(key, j);
return;
}
SASSERT(column_is_fixed(k));
if (j != k && column_is_int(j) == column_is_int(k))
m_report_equality_of_fixed_vars(
column_to_reported_index(j),
column_to_reported_index(k));
}
void lar_solver::activate(constraint_index ci) {
auto const& c = m_constraints[ci];
update_column_type_and_bound(c.column(), c.kind(), c.rhs(), ci);
@ -1784,13 +1817,19 @@ bool lar_solver::compare_values(impq const& lhs, lconstraint_kind k, const mpq &
}
}
void lar_solver::update_column_type_and_bound(var_index j, lconstraint_kind kind, const mpq & right_side,
void lar_solver::update_column_type_and_bound(var_index j,
lconstraint_kind kind,
const mpq & right_side,
constraint_index constr_index) {
m_constraints.activate(constr_index);
if (column_has_upper_bound(j))
update_column_type_and_bound_with_ub(j, kind, right_side, constr_index);
else
update_column_type_and_bound_with_no_ub(j, kind, right_side, constr_index);
if (column_is_fixed(j)) {
register_in_fixed_var_table(j);
}
}
constraint_index lar_solver::add_var_bound_on_constraint_for_term(var_index j, lconstraint_kind kind, const mpq & right_side) {

View file

@ -49,6 +49,8 @@ namespace lp {
class int_branch;
class int_solver;
class lar_solver : public column_namer {
typedef std::pair<mpq, bool> value_sort_pair;
typedef pair_hash<obj_hash<mpq>, bool_hash> value_sort_pair_hash;
struct term_hasher {
std::size_t operator()(const lar_term &t) const
{
@ -102,6 +104,12 @@ class lar_solver : public column_namer {
m_normalized_terms_to_columns;
vector<impq> m_backup_x;
stacked_vector<unsigned> m_usage_in_terms;
// ((x[j], is_int(j))->j) for fixed j, used in equalities propagation
map<value_sort_pair,
unsigned,
value_sort_pair_hash,
default_eq<value_sort_pair>> m_fixed_var_table;
std::function <void(unsigned, unsigned)> m_report_equality_of_fixed_vars;
// end of fields
////////////////// methods ////////////////////////////////
@ -142,7 +150,8 @@ class lar_solver : public column_namer {
void update_bound_with_no_ub_lb(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index constr_index);
void update_bound_with_ub_no_lb(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index constr_index);
void update_bound_with_no_ub_no_lb(var_index j, lconstraint_kind kind, const mpq & right_side, constraint_index constr_index);
void register_in_fixed_var_table(var_index);
void remove_non_fixed_from_fixed_var_table();
constraint_index add_var_bound_on_constraint_for_term(var_index j, lconstraint_kind kind, const mpq & right_side);
inline void set_infeasible_column(unsigned j) {
set_status(lp_status::INFEASIBLE);
@ -281,6 +290,18 @@ class lar_solver : public column_namer {
void register_normalized_term(const lar_term&, lpvar);
void deregister_normalized_term(const lar_term&);
public:
const map<value_sort_pair,
unsigned,
value_sort_pair_hash,
default_eq<value_sort_pair>>& fixed_var_table() const {
return m_fixed_var_table;
}
map<value_sort_pair,
unsigned,
value_sort_pair_hash,
default_eq<value_sort_pair>>& fixed_var_table() {
return m_fixed_var_table;
}
unsigned external_to_column_index(unsigned) const;
bool inside_bounds(lpvar, const impq&) const;
inline void set_column_value(unsigned j, const impq& v) {
@ -572,7 +593,7 @@ public:
void fill_explanation_from_crossed_bounds_column(explanation & evidence) const;
bool term_is_used_as_row(unsigned term) const;
bool tighten_term_bounds_by_delta(tv const& t, const impq&);
lar_solver();
lar_solver(const std::function <void(unsigned, unsigned)>& report_equality_of_fixed_vars);
void set_track_pivoted_rows(bool v);
bool get_track_pivoted_rows() const;
virtual ~lar_solver();

View file

@ -325,19 +325,9 @@ public:
if (y == null_lpvar) {
// x is an implied fixed var at k.
value_sort_pair key(k, is_int(x));
int x2;
if (m_imp.m_fixed_var_table.find(key, x2) &&
x2 < static_cast<int>(m_imp.get_num_vars())
&&
lp().column_is_fixed(x2 = imp_to_col(x2)) && // change x2
get_lower_bound_rational(x2) == k &&
// We must check whether x2 is an integer.
// The table m_fixed_var_table is not restored during backtrack. So, it may
// contain invalid (key -> value) pairs.
// So, we must check whether x2 is really equal to k (previous test)
// AND has the same sort of x.
is_int(x) == is_int(x2) &&
!is_equal(x, x2)) {
unsigned x2;
if (lp().fixed_var_table().find(key, x2) && !is_equal(x, x2)) {
SASSERT(lp().column_is_fixed(x2) && get_lower_bound_rational(x2) == k && is_int(x) == is_int(x2));
explanation ex;
constraint_index lc, uc;
lp().get_bound_constraint_witnesses_for_column(x2, lc, uc);

View file

@ -883,7 +883,7 @@ public:
}
lar_solver * create_lar_solver() {
lar_solver * solver = new lar_solver();
lar_solver * solver = new lar_solver([](unsigned, unsigned) { });
fill_lar_solver(solver);
return solver;
}