mirror of
https://github.com/Z3Prover/z3
synced 2025-06-28 08:58:44 +00:00
use u_map in lar_term
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
f5c7b9fb2f
commit
1fff7bb51d
5 changed files with 70 additions and 60 deletions
|
@ -2708,21 +2708,21 @@ public:
|
||||||
lp::var_index vi = m_theory_var2var_index[v];
|
lp::var_index vi = m_theory_var2var_index[v];
|
||||||
SASSERT(m_solver->is_term(vi));
|
SASSERT(m_solver->is_term(vi));
|
||||||
lp::lar_term const& term = m_solver->get_term(vi);
|
lp::lar_term const& term = m_solver->get_term(vi);
|
||||||
for (auto const & coeff : term.m_coeffs) {
|
for (auto const mono : term) {
|
||||||
lp::var_index wi = coeff.first;
|
lp::var_index wi = mono.var();
|
||||||
lp::constraint_index ci;
|
lp::constraint_index ci;
|
||||||
rational value;
|
rational value;
|
||||||
bool is_strict;
|
bool is_strict;
|
||||||
if (m_solver->is_term(wi)) {
|
if (m_solver->is_term(wi)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (coeff.second.is_neg() == is_lub) {
|
if (mono.coeff().is_neg() == is_lub) {
|
||||||
// -3*x ... <= lub based on lower bound for x.
|
// -3*x ... <= lub based on lower bound for x.
|
||||||
if (!m_solver->has_lower_bound(wi, ci, value, is_strict)) {
|
if (!m_solver->has_lower_bound(wi, ci, value, is_strict)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (is_strict) {
|
if (is_strict) {
|
||||||
r += inf_rational(rational::zero(), coeff.second.is_pos());
|
r += inf_rational(rational::zero(), mono.coeff().is_pos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -2730,10 +2730,10 @@ public:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (is_strict) {
|
if (is_strict) {
|
||||||
r += inf_rational(rational::zero(), coeff.second.is_pos());
|
r += inf_rational(rational::zero(), mono.coeff().is_pos());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
r += value * coeff.second;
|
r += value * mono.coeff();
|
||||||
set_evidence(ci);
|
set_evidence(ci);
|
||||||
}
|
}
|
||||||
TRACE("arith_verbose", tout << (is_lub?"lub":"glb") << " is " << r << "\n";);
|
TRACE("arith_verbose", tout << (is_lub?"lub":"glb") << " is " << r << "\n";);
|
||||||
|
|
|
@ -186,8 +186,8 @@ struct gomory_test {
|
||||||
|
|
||||||
void print_term(lar_term & t, std::ostream & out) {
|
void print_term(lar_term & t, std::ostream & out) {
|
||||||
vector<std::pair<mpq, unsigned>> row;
|
vector<std::pair<mpq, unsigned>> row;
|
||||||
for (auto p : t.m_coeffs)
|
for (auto p : t)
|
||||||
row.push_back(std::make_pair(p.second, p.first));
|
row.push_back(std::make_pair(p.coeff(), p.var()));
|
||||||
print_row(out, row);
|
print_row(out, row);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -128,18 +128,18 @@ bool lar_solver::implied_bound_is_correctly_explained(implied_bound const & be,
|
||||||
}
|
}
|
||||||
rs_of_evidence /= ratio;
|
rs_of_evidence /= ratio;
|
||||||
} else {
|
} else {
|
||||||
const lar_term * t = m_terms[adjust_term_index(be.m_j)];
|
lar_term & t = *m_terms[adjust_term_index(be.m_j)];
|
||||||
const auto first_coeff = *t->m_coeffs.begin();
|
auto first_coeff = t.begin();
|
||||||
unsigned j = first_coeff.first;
|
unsigned j = (*first_coeff).var();
|
||||||
auto it = coeff_map.find(j);
|
auto it = coeff_map.find(j);
|
||||||
if (it == coeff_map.end())
|
if (it == coeff_map.end())
|
||||||
return false;
|
return false;
|
||||||
mpq ratio = it->second / first_coeff.second;
|
mpq ratio = it->second / (*first_coeff).coeff();
|
||||||
for (auto & p : t->m_coeffs) {
|
for (auto p : t) {
|
||||||
it = coeff_map.find(p.first);
|
it = coeff_map.find(p.var());
|
||||||
if (it == coeff_map.end())
|
if (it == coeff_map.end())
|
||||||
return false;
|
return false;
|
||||||
if (p.second * ratio != it->second)
|
if (p.coeff() * ratio != it->second)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ratio < zero_of_type<mpq>()) {
|
if (ratio < zero_of_type<mpq>()) {
|
||||||
|
@ -686,8 +686,8 @@ void lar_solver::substitute_terms_in_linear_expression(const vector<std::pair<mp
|
||||||
register_monoid_in_map(coeffs, t.first, j);
|
register_monoid_in_map(coeffs, t.first, j);
|
||||||
} else {
|
} else {
|
||||||
const lar_term & term = * m_terms[adjust_term_index(t.second)];
|
const lar_term & term = * m_terms[adjust_term_index(t.second)];
|
||||||
for (auto & p : term.coeffs()){
|
for (auto p : term){
|
||||||
register_monoid_in_map(coeffs, t.first * p.second , p.first);
|
register_monoid_in_map(coeffs, t.first * p.coeff() , p.var());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -943,10 +943,10 @@ void lar_solver::fill_last_row_of_A_r(static_matrix<mpq, numeric_pair<mpq>> & A,
|
||||||
lp_assert(A.column_count() > 0);
|
lp_assert(A.column_count() > 0);
|
||||||
unsigned last_row = A.row_count() - 1;
|
unsigned last_row = A.row_count() - 1;
|
||||||
lp_assert(A.m_rows[last_row].size() == 0);
|
lp_assert(A.m_rows[last_row].size() == 0);
|
||||||
for (auto & t : ls->m_coeffs) {
|
for (auto t : *ls) {
|
||||||
lp_assert(!is_zero(t.second));
|
lp_assert(!is_zero(t.coeff()));
|
||||||
var_index j = t.first;
|
var_index j = t.var();
|
||||||
A.set(last_row, j, - t.second);
|
A.set(last_row, j, - t.coeff());
|
||||||
}
|
}
|
||||||
unsigned basis_j = A.column_count() - 1;
|
unsigned basis_j = A.column_count() - 1;
|
||||||
A.set(last_row, basis_j, mpq(1));
|
A.set(last_row, basis_j, mpq(1));
|
||||||
|
@ -1364,8 +1364,8 @@ void lar_solver::fill_var_set_for_random_update(unsigned sz, var_index const * v
|
||||||
for (unsigned i = 0; i < sz; i++) {
|
for (unsigned i = 0; i < sz; i++) {
|
||||||
var_index var = vars[i];
|
var_index var = vars[i];
|
||||||
if (var >= m_terms_start_index) { // handle the term
|
if (var >= m_terms_start_index) { // handle the term
|
||||||
for (auto & it : m_terms[var - m_terms_start_index]->m_coeffs) {
|
for (auto it : *m_terms[var - m_terms_start_index]) {
|
||||||
column_list.push_back(it.first);
|
column_list.push_back(it.var());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
column_list.push_back(var);
|
column_list.push_back(var);
|
||||||
|
@ -1560,8 +1560,8 @@ bool lar_solver::model_is_int_feasible() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool lar_solver::term_is_int(const lar_term * t) const {
|
bool lar_solver::term_is_int(const lar_term * t) const {
|
||||||
for (auto const & p : t->m_coeffs)
|
for (auto const p : *t)
|
||||||
if (! (column_is_int(p.first) && p.second.is_int()))
|
if (! (column_is_int(p.var()) && p.coeff().is_int()))
|
||||||
return false;
|
return false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1920,10 +1920,10 @@ void lar_solver::fill_last_row_of_A_d(static_matrix<double, double> & A, const l
|
||||||
unsigned last_row = A.row_count() - 1;
|
unsigned last_row = A.row_count() - 1;
|
||||||
lp_assert(A.m_rows[last_row].empty());
|
lp_assert(A.m_rows[last_row].empty());
|
||||||
|
|
||||||
for (auto & t : ls->m_coeffs) {
|
for (auto t : *ls) {
|
||||||
lp_assert(!is_zero(t.second));
|
lp_assert(!is_zero(t.coeff()));
|
||||||
var_index j = t.first;
|
var_index j = t.var();
|
||||||
A.set(last_row, j, -t.second.get_double());
|
A.set(last_row, j, -t.coeff().get_double());
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned basis_j = A.column_count() - 1;
|
unsigned basis_j = A.column_count() - 1;
|
||||||
|
|
|
@ -545,17 +545,13 @@ public:
|
||||||
|
|
||||||
void subs_term_columns(lar_term& t) {
|
void subs_term_columns(lar_term& t) {
|
||||||
vector<std::pair<unsigned,unsigned>> columns_to_subs;
|
vector<std::pair<unsigned,unsigned>> columns_to_subs;
|
||||||
for (const auto & m : t.m_coeffs) {
|
for (const auto & m : t) {
|
||||||
unsigned tj = adjust_column_index_to_term_index(m.first);
|
unsigned tj = adjust_column_index_to_term_index(m.var());
|
||||||
if (tj == m.first) continue;
|
if (tj == m.var()) continue;
|
||||||
columns_to_subs.push_back(std::make_pair(m.first, tj));
|
columns_to_subs.push_back(std::make_pair(m.var(), tj));
|
||||||
}
|
}
|
||||||
for (const auto & p : columns_to_subs) {
|
for (const auto & p : columns_to_subs) {
|
||||||
auto it = t.m_coeffs.find(p.first);
|
t.subst_index(p.first, p.second);
|
||||||
lp_assert(it != t.m_coeffs.end());
|
|
||||||
mpq v = it->second;
|
|
||||||
t.m_coeffs.erase(it);
|
|
||||||
t.m_coeffs[p.second] = v;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,20 +19,23 @@
|
||||||
--*/
|
--*/
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "util/lp/indexed_vector.h"
|
#include "util/lp/indexed_vector.h"
|
||||||
|
#include "util/map.h"
|
||||||
|
|
||||||
namespace lp {
|
namespace lp {
|
||||||
struct lar_term {
|
class lar_term {
|
||||||
// the term evaluates to sum of m_coeffs
|
// the term evaluates to sum of m_coeffs
|
||||||
std::unordered_map<unsigned, mpq> m_coeffs;
|
u_map<mpq> m_coeffs;
|
||||||
// mpq m_v;
|
// mpq m_v;
|
||||||
|
public:
|
||||||
lar_term() {}
|
lar_term() {}
|
||||||
void add_monomial(const mpq& c, unsigned j) {
|
void add_monomial(const mpq& c, unsigned j) {
|
||||||
auto it = m_coeffs.find(j);
|
auto *e = m_coeffs.find_core(j);
|
||||||
if (it == m_coeffs.end()) {
|
if (e == nullptr) {
|
||||||
m_coeffs.emplace(j, c);
|
m_coeffs.insert(j, c);
|
||||||
} else {
|
} else {
|
||||||
it->second += c;
|
e->get_data().m_value += c;
|
||||||
if (is_zero(it->second))
|
if (e->get_data().m_value.is_zero())
|
||||||
m_coeffs.erase(it);
|
m_coeffs.erase(j);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,8 +44,9 @@ struct lar_term {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned size() const { return static_cast<unsigned>(m_coeffs.size()); }
|
unsigned size() const { return static_cast<unsigned>(m_coeffs.size()); }
|
||||||
|
|
||||||
const std::unordered_map<unsigned, mpq> & coeffs() const {
|
template <typename T>
|
||||||
|
const T & coeffs() const {
|
||||||
return m_coeffs;
|
return m_coeffs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,42 +63,51 @@ struct lar_term {
|
||||||
vector<std::pair<mpq, unsigned>> coeffs_as_vector() const {
|
vector<std::pair<mpq, unsigned>> coeffs_as_vector() const {
|
||||||
vector<std::pair<mpq, unsigned>> ret;
|
vector<std::pair<mpq, unsigned>> ret;
|
||||||
for (const auto & p : m_coeffs) {
|
for (const auto & p : m_coeffs) {
|
||||||
ret.push_back(std::make_pair(p.second, p.first));
|
ret.push_back(std::make_pair(p.m_value, p.m_key));
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// j is the basic variable to substitute
|
// j is the basic variable to substitute
|
||||||
void subst(unsigned j, indexed_vector<mpq> & li) {
|
void subst(unsigned j, indexed_vector<mpq> & li) {
|
||||||
auto it = m_coeffs.find(j);
|
auto* it = m_coeffs.find_core(j);
|
||||||
if (it == m_coeffs.end()) return;
|
if (it == nullptr) return;
|
||||||
const mpq & b = it->second;
|
const mpq & b = it->get_data().m_value;
|
||||||
for (unsigned it_j :li.m_index) {
|
for (unsigned it_j :li.m_index) {
|
||||||
add_monomial(- b * li.m_data[it_j], it_j);
|
add_monomial(- b * li.m_data[it_j], it_j);
|
||||||
}
|
}
|
||||||
m_coeffs.erase(it);
|
m_coeffs.erase(j);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the monomial ax[j] is substituted by ax[k]
|
||||||
|
void subst_index(unsigned j, unsigned k) {
|
||||||
|
auto* it = m_coeffs.find_core(j);
|
||||||
|
if (it == nullptr) return;
|
||||||
|
mpq b = it->get_data().m_value;
|
||||||
|
m_coeffs.erase(j);
|
||||||
|
m_coeffs.insert(k, b);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool contains(unsigned j) const {
|
bool contains(unsigned j) const {
|
||||||
return m_coeffs.find(j) != m_coeffs.end();
|
return m_coeffs.contains(j);
|
||||||
}
|
}
|
||||||
|
|
||||||
void negate() {
|
void negate() {
|
||||||
for (auto & t : m_coeffs)
|
for (auto & t : m_coeffs)
|
||||||
t.second.neg();
|
t.m_value.neg();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T apply(const vector<T>& x) const {
|
T apply(const vector<T>& x) const {
|
||||||
T ret(0);
|
T ret(0);
|
||||||
for (const auto & t : m_coeffs) {
|
for (const auto & t : m_coeffs) {
|
||||||
ret += t.second * x[t.first];
|
ret += t.m_value * x[t.m_key];
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void clear() {
|
void clear() {
|
||||||
m_coeffs.clear();
|
m_coeffs.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ival {
|
struct ival {
|
||||||
|
@ -108,7 +121,7 @@ struct lar_term {
|
||||||
|
|
||||||
struct const_iterator {
|
struct const_iterator {
|
||||||
//fields
|
//fields
|
||||||
std::unordered_map<unsigned, mpq>::const_iterator m_it;
|
u_map< mpq>::iterator m_it;
|
||||||
|
|
||||||
typedef const_iterator self_type;
|
typedef const_iterator self_type;
|
||||||
typedef ival value_type;
|
typedef ival value_type;
|
||||||
|
@ -118,19 +131,20 @@ struct lar_term {
|
||||||
typedef std::forward_iterator_tag iterator_category;
|
typedef std::forward_iterator_tag iterator_category;
|
||||||
|
|
||||||
reference operator*() const {
|
reference operator*() const {
|
||||||
return ival(m_it->first, m_it->second);
|
return ival(m_it->m_key, m_it->m_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
self_type operator++() { self_type i = *this; m_it++; return i; }
|
self_type operator++() { self_type i = *this; m_it++; return i; }
|
||||||
self_type operator++(int) { m_it++; return *this; }
|
self_type operator++(int) { m_it++; return *this; }
|
||||||
|
|
||||||
const_iterator(std::unordered_map<unsigned, mpq>::const_iterator it) : m_it(it) {}
|
const_iterator(u_map<mpq>::iterator it) : m_it(it) {}
|
||||||
bool operator==(const self_type &other) const {
|
bool operator==(const self_type &other) const {
|
||||||
return m_it == other.m_it;
|
return m_it == other.m_it;
|
||||||
}
|
}
|
||||||
bool operator!=(const self_type &other) const { return !(*this == other); }
|
bool operator!=(const self_type &other) const { return !(*this == other); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
const_iterator begin() const { return m_coeffs.begin();}
|
const_iterator begin() const { return m_coeffs.begin();}
|
||||||
const_iterator end() const { return m_coeffs.end(); }
|
const_iterator end() const { return m_coeffs.end(); }
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue