3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-08-16 07:45:27 +00:00

use u_map in lar_term

Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
Lev Nachmanson 2019-12-30 17:58:56 -08:00 committed by Nikolaj Bjorner
parent f5c7b9fb2f
commit 1fff7bb51d
5 changed files with 70 additions and 60 deletions

View file

@ -19,20 +19,23 @@
--*/
#pragma once
#include "util/lp/indexed_vector.h"
#include "util/map.h"
namespace lp {
struct lar_term {
class lar_term {
// the term evaluates to sum of m_coeffs
std::unordered_map<unsigned, mpq> m_coeffs;
u_map<mpq> m_coeffs;
// mpq m_v;
public:
lar_term() {}
void add_monomial(const mpq& c, unsigned j) {
auto it = m_coeffs.find(j);
if (it == m_coeffs.end()) {
m_coeffs.emplace(j, c);
auto *e = m_coeffs.find_core(j);
if (e == nullptr) {
m_coeffs.insert(j, c);
} else {
it->second += c;
if (is_zero(it->second))
m_coeffs.erase(it);
e->get_data().m_value += c;
if (e->get_data().m_value.is_zero())
m_coeffs.erase(j);
}
}
@ -41,8 +44,9 @@ struct lar_term {
}
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;
}
@ -59,42 +63,51 @@ struct lar_term {
vector<std::pair<mpq, unsigned>> coeffs_as_vector() const {
vector<std::pair<mpq, unsigned>> ret;
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;
}
// j is the basic variable to substitute
void subst(unsigned j, indexed_vector<mpq> & li) {
auto it = m_coeffs.find(j);
if (it == m_coeffs.end()) return;
const mpq & b = it->second;
auto* it = m_coeffs.find_core(j);
if (it == nullptr) return;
const mpq & b = it->get_data().m_value;
for (unsigned it_j :li.m_index) {
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 {
return m_coeffs.find(j) != m_coeffs.end();
return m_coeffs.contains(j);
}
void negate() {
for (auto & t : m_coeffs)
t.second.neg();
t.m_value.neg();
}
template <typename T>
T apply(const vector<T>& x) const {
T ret(0);
for (const auto & t : m_coeffs) {
ret += t.second * x[t.first];
ret += t.m_value * x[t.m_key];
}
return ret;
}
void clear() {
m_coeffs.clear();
m_coeffs.reset();
}
struct ival {
@ -108,7 +121,7 @@ struct lar_term {
struct const_iterator {
//fields
std::unordered_map<unsigned, mpq>::const_iterator m_it;
u_map< mpq>::iterator m_it;
typedef const_iterator self_type;
typedef ival value_type;
@ -118,19 +131,20 @@ struct lar_term {
typedef std::forward_iterator_tag iterator_category;
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++(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 {
return m_it == other.m_it;
}
bool operator!=(const self_type &other) const { return !(*this == other); }
};
const_iterator begin() const { return m_coeffs.begin();}
const_iterator end() const { return m_coeffs.end(); }
};