3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-29 11:55:51 +00:00

coalesce updates to bounds

This commit is contained in:
Nikolaj Bjorner 2025-04-23 14:05:17 -07:00
parent 579ba8bd70
commit 5cc57b8958
2 changed files with 42 additions and 64 deletions

View file

@ -574,14 +574,18 @@ namespace lp {
A_r().pop(k); A_r().pop(k);
} }
void lar_solver::set_upper_bound_witness(lpvar j, u_dependency* dep) { void lar_solver::set_upper_bound_witness(lpvar j, u_dependency* dep, impq const& high) {
m_trail.push(vector_value_trail(m_columns, j)); m_trail.push(vector_value_trail(m_columns, j));
m_columns[j].upper_bound_witness() = dep; m_columns[j].upper_bound_witness() = dep;
m_mpq_lar_core_solver.m_r_upper_bounds[j] = high;
insert_to_columns_with_changed_bounds(j);
} }
void lar_solver::set_lower_bound_witness(lpvar j, u_dependency* dep) { void lar_solver::set_lower_bound_witness(lpvar j, u_dependency* dep, impq const& low) {
m_trail.push(vector_value_trail(m_columns, j)); m_trail.push(vector_value_trail(m_columns, j));
m_columns[j].lower_bound_witness() = dep; m_columns[j].lower_bound_witness() = dep;
m_mpq_lar_core_solver.m_r_lower_bounds[j] = low;
insert_to_columns_with_changed_bounds(j);
} }
void lar_solver::register_monoid_in_map(std::unordered_map<lpvar, mpq>& coeffs, const mpq& a, unsigned j) { void lar_solver::register_monoid_in_map(std::unordered_map<lpvar, mpq>& coeffs, const mpq& a, unsigned j) {
@ -592,7 +596,6 @@ namespace lp {
it->second += a; it->second += a;
} }
void lar_solver::substitute_terms_in_linear_expression(const vector<std::pair<mpq, lpvar>>& left_side_with_terms, void lar_solver::substitute_terms_in_linear_expression(const vector<std::pair<mpq, lpvar>>& left_side_with_terms,
vector<std::pair<mpq, lpvar>>& left_side) const { vector<std::pair<mpq, lpvar>>& left_side) const {
std::unordered_map<lpvar, mpq> coeffs; std::unordered_map<lpvar, mpq> coeffs;
@ -1150,10 +1153,7 @@ namespace lp {
const vector<std::pair<mpq, unsigned>>& inf_row, const vector<std::pair<mpq, unsigned>>& inf_row,
int inf_sign) const { int inf_sign) const {
for (auto& it : inf_row) { for (auto& [coeff, j] : inf_row) {
mpq coeff = it.first;
unsigned j = it.second;
int adj_sign = coeff.is_pos() ? inf_sign : -inf_sign; int adj_sign = coeff.is_pos() ? inf_sign : -inf_sign;
const column& ul = m_columns[j]; const column& ul = m_columns[j];
@ -1946,14 +1946,13 @@ namespace lp {
auto const& c = m_constraints[ci]; auto const& c = m_constraints[ci];
TRACE("lar_solver_validate", tout << "adding constr with column = "<< c.column() << "\n"; m_constraints.display(tout, c); tout << std::endl;); TRACE("lar_solver_validate", tout << "adding constr with column = "<< c.column() << "\n"; m_constraints.display(tout, c); tout << std::endl;);
vector<std::pair<mpq, lpvar>> coeffs; vector<std::pair<mpq, lpvar>> coeffs;
for (auto p : c.coeffs()) { for (auto const& [coeff, jext] : c.coeffs()) {
lpvar jext = p.second;
lpvar j = ls.external_to_local(jext); lpvar j = ls.external_to_local(jext);
if (j == null_lpvar) { if (j == null_lpvar) {
ls.add_var(jext, column_is_int(jext)); ls.add_var(jext, column_is_int(jext));
j = ls.external_to_local(jext); j = ls.external_to_local(jext);
} }
coeffs.push_back(std::make_pair(p.first, j)); coeffs.push_back({coeff, j});
} }
lpvar column_ext = c.column(); lpvar column_ext = c.column();
@ -2077,10 +2076,10 @@ namespace lp {
set_crossed_bounds_column_and_deps(j, true, dep); set_crossed_bounds_column_and_deps(j, true, dep);
} }
else { else {
if (up >= m_mpq_lar_core_solver.m_r_upper_bounds[j]) return; impq const& old_up = m_mpq_lar_core_solver.m_r_upper_bounds[j];
m_mpq_lar_core_solver.m_r_upper_bounds[j] = up; if (up >= old_up)
set_upper_bound_witness(j, dep); return;
insert_to_columns_with_changed_bounds(j); set_upper_bound_witness(j, dep, up);
} }
break; break;
} }
@ -2091,31 +2090,25 @@ namespace lp {
auto low = numeric_pair<mpq>(right_side, y_of_bound); auto low = numeric_pair<mpq>(right_side, y_of_bound);
if (low > m_mpq_lar_core_solver.m_r_upper_bounds[j]) { if (low > m_mpq_lar_core_solver.m_r_upper_bounds[j]) {
set_crossed_bounds_column_and_deps(j, false, dep); set_crossed_bounds_column_and_deps(j, false, dep);
} else {
if (low < m_mpq_lar_core_solver.m_r_lower_bounds[j]) {
return;
} }
m_mpq_lar_core_solver.m_r_lower_bounds[j] = low; else {
set_lower_bound_witness(j, dep); impq const& old_low = m_mpq_lar_core_solver.m_r_lower_bounds[j];
if (low < old_low)
return;
set_lower_bound_witness(j, dep, low);
m_mpq_lar_core_solver.m_column_types[j] = (low == m_mpq_lar_core_solver.m_r_upper_bounds[j] ? column_type::fixed : column_type::boxed); m_mpq_lar_core_solver.m_column_types[j] = (low == m_mpq_lar_core_solver.m_r_upper_bounds[j] ? column_type::fixed : column_type::boxed);
insert_to_columns_with_changed_bounds(j);
} }
break; break;
} }
case EQ: { case EQ: {
auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>()); auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>());
if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j]){ if (v > m_mpq_lar_core_solver.m_r_upper_bounds[j])
set_crossed_bounds_column_and_deps(j, false, dep); set_crossed_bounds_column_and_deps(j, false, dep);
} else if (v < m_mpq_lar_core_solver.m_r_lower_bounds[j])
else if (v < m_mpq_lar_core_solver.m_r_lower_bounds[j]) {
set_crossed_bounds_column_and_deps(j, true, dep); set_crossed_bounds_column_and_deps(j, true, dep);
}
else { else {
set_upper_bound_witness(j, dep); set_upper_bound_witness(j, dep, v);
set_lower_bound_witness(j, dep); set_lower_bound_witness(j, dep, v);
m_mpq_lar_core_solver.m_r_upper_bounds[j] = m_mpq_lar_core_solver.m_r_lower_bounds[j] = v;
insert_to_columns_with_changed_bounds(j);
} }
break; break;
} }
@ -2144,10 +2137,8 @@ namespace lp {
set_crossed_bounds_column_and_deps(j, true, dep); set_crossed_bounds_column_and_deps(j, true, dep);
} }
else { else {
m_mpq_lar_core_solver.m_r_upper_bounds[j] = up; set_upper_bound_witness(j, dep, up);
set_upper_bound_witness(j, dep);
m_mpq_lar_core_solver.m_column_types[j] = (up == m_mpq_lar_core_solver.m_r_lower_bounds[j] ? column_type::fixed : column_type::boxed); m_mpq_lar_core_solver.m_column_types[j] = (up == m_mpq_lar_core_solver.m_r_lower_bounds[j] ? column_type::fixed : column_type::boxed);
insert_to_columns_with_changed_bounds(j);
} }
break; break;
} }
@ -2158,9 +2149,7 @@ namespace lp {
if (low < m_mpq_lar_core_solver.m_r_lower_bounds[j]) { if (low < m_mpq_lar_core_solver.m_r_lower_bounds[j]) {
return; return;
} }
m_mpq_lar_core_solver.m_r_lower_bounds[j] = low; set_lower_bound_witness(j, dep, low);
set_lower_bound_witness(j, dep);
insert_to_columns_with_changed_bounds(j);
break; break;
} }
case EQ: { case EQ: {
@ -2169,11 +2158,9 @@ namespace lp {
set_crossed_bounds_column_and_deps(j, true, dep); set_crossed_bounds_column_and_deps(j, true, dep);
} }
else { else {
set_upper_bound_witness(j, dep); set_upper_bound_witness(j, dep, v);
set_lower_bound_witness(j, dep); set_lower_bound_witness(j, dep, v);
m_mpq_lar_core_solver.m_r_upper_bounds[j] = m_mpq_lar_core_solver.m_r_lower_bounds[j] = v;
m_mpq_lar_core_solver.m_column_types[j] = column_type::fixed; m_mpq_lar_core_solver.m_column_types[j] = column_type::fixed;
insert_to_columns_with_changed_bounds(j);
} }
break; break;
} }
@ -2194,10 +2181,9 @@ namespace lp {
case LE: case LE:
{ {
auto up = numeric_pair<mpq>(right_side, y_of_bound); auto up = numeric_pair<mpq>(right_side, y_of_bound);
if (up >= m_mpq_lar_core_solver.m_r_upper_bounds[j]) return; if (up >= m_mpq_lar_core_solver.m_r_upper_bounds[j])
m_mpq_lar_core_solver.m_r_upper_bounds[j] = up; return;
set_upper_bound_witness(j, dep); set_upper_bound_witness(j, dep, up);
insert_to_columns_with_changed_bounds(j);
} }
break; break;
case GT: case GT:
@ -2210,10 +2196,8 @@ namespace lp {
set_crossed_bounds_column_and_deps(j, false, dep); set_crossed_bounds_column_and_deps(j, false, dep);
} }
else { else {
m_mpq_lar_core_solver.m_r_lower_bounds[j] = low; set_lower_bound_witness(j, dep, low);
set_lower_bound_witness(j, dep);
m_mpq_lar_core_solver.m_column_types[j] = (low == m_mpq_lar_core_solver.m_r_upper_bounds[j] ? column_type::fixed : column_type::boxed); m_mpq_lar_core_solver.m_column_types[j] = (low == m_mpq_lar_core_solver.m_r_upper_bounds[j] ? column_type::fixed : column_type::boxed);
insert_to_columns_with_changed_bounds(j);
} }
} }
break; break;
@ -2224,11 +2208,9 @@ namespace lp {
set_crossed_bounds_column_and_deps(j, false, dep); set_crossed_bounds_column_and_deps(j, false, dep);
} }
else { else {
set_upper_bound_witness(j, dep); set_upper_bound_witness(j, dep, v);
set_lower_bound_witness(j, dep); set_lower_bound_witness(j, dep, v);
m_mpq_lar_core_solver.m_r_upper_bounds[j] = m_mpq_lar_core_solver.m_r_lower_bounds[j] = v;
m_mpq_lar_core_solver.m_column_types[j] = column_type::fixed; m_mpq_lar_core_solver.m_column_types[j] = column_type::fixed;
insert_to_columns_with_changed_bounds(j);
} }
break; break;
} }
@ -2248,8 +2230,7 @@ namespace lp {
Z3_fallthrough; Z3_fallthrough;
case LE: { case LE: {
auto up = numeric_pair<mpq>(right_side, y_of_bound); auto up = numeric_pair<mpq>(right_side, y_of_bound);
m_mpq_lar_core_solver.m_r_upper_bounds[j] = up; set_upper_bound_witness(j, dep, up);
set_upper_bound_witness(j, dep);
m_mpq_lar_core_solver.m_column_types[j] = column_type::upper_bound; m_mpq_lar_core_solver.m_column_types[j] = column_type::upper_bound;
} break; } break;
case GT: case GT:
@ -2257,16 +2238,14 @@ namespace lp {
Z3_fallthrough; Z3_fallthrough;
case GE: { case GE: {
auto low = numeric_pair<mpq>(right_side, y_of_bound); auto low = numeric_pair<mpq>(right_side, y_of_bound);
m_mpq_lar_core_solver.m_r_lower_bounds[j] = low; set_lower_bound_witness(j, dep, low);
set_lower_bound_witness(j, dep);
m_mpq_lar_core_solver.m_column_types[j] = column_type::lower_bound; m_mpq_lar_core_solver.m_column_types[j] = column_type::lower_bound;
} break; } break;
case EQ: { case EQ: {
auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>()); auto v = numeric_pair<mpq>(right_side, zero_of_type<mpq>());
set_upper_bound_witness(j, dep); set_upper_bound_witness(j, dep, v);
set_lower_bound_witness(j, dep); set_lower_bound_witness(j, dep, v);
m_mpq_lar_core_solver.m_r_upper_bounds[j] = m_mpq_lar_core_solver.m_r_lower_bounds[j] = v;
m_mpq_lar_core_solver.m_column_types[j] = column_type::fixed; m_mpq_lar_core_solver.m_column_types[j] = column_type::fixed;
break; break;
} }
@ -2274,7 +2253,6 @@ namespace lp {
default: default:
UNREACHABLE(); UNREACHABLE();
} }
insert_to_columns_with_changed_bounds(j);
} }
lpvar lar_solver::to_column(unsigned ext_j) const { lpvar lar_solver::to_column(unsigned ext_j) const {

View file

@ -202,8 +202,8 @@ class lar_solver : public column_namer {
void pop_core_solver_params(); void pop_core_solver_params();
void pop_core_solver_params(unsigned k); void pop_core_solver_params(unsigned k);
void set_upper_bound_witness(lpvar j, u_dependency* ci); void set_upper_bound_witness(lpvar j, u_dependency* ci, impq const& high);
void set_lower_bound_witness(lpvar j, u_dependency* ci); void set_lower_bound_witness(lpvar j, u_dependency* ci, impq const& low);
void substitute_terms_in_linear_expression(const vector<std::pair<mpq, lpvar>>& left_side_with_terms, void substitute_terms_in_linear_expression(const vector<std::pair<mpq, lpvar>>& left_side_with_terms,
vector<std::pair<mpq, lpvar>>& left_side) const; vector<std::pair<mpq, lpvar>>& left_side) const;