mirror of
https://github.com/Z3Prover/z3
synced 2025-04-30 12:25:51 +00:00
smarter explanation.h (#4385)
* smarter explanation.h Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * clean explanation API Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * suppress warnings Signed-off-by: Lev Nachmanson <levnach@hotmail.com> * disable the warnings Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
3b0c40044f
commit
af2f74c05f
16 changed files with 109 additions and 89 deletions
|
@ -18,47 +18,70 @@ Revision History:
|
|||
|
||||
--*/
|
||||
#pragma once
|
||||
#include <unordered_set>
|
||||
#include "math/lp/lp_utils.h"
|
||||
#include "util/map.h"
|
||||
#include "util/optional.h"
|
||||
namespace lp {
|
||||
class explanation {
|
||||
vector<std::pair<mpq, constraint_index>> m_explanation;
|
||||
std::unordered_set<unsigned> m_set_of_ci;
|
||||
u_map<optional<mpq>> m_j_to_mpq;
|
||||
public:
|
||||
explanation() {}
|
||||
template <typename T>
|
||||
explanation(const T& t) { for ( unsigned c : t) add(c); }
|
||||
|
||||
void clear() { m_explanation.clear(); m_set_of_ci.clear(); }
|
||||
vector<std::pair<mpq, constraint_index>>::const_iterator begin() const { return m_explanation.begin(); }
|
||||
vector<std::pair<mpq, constraint_index>>::const_iterator end() const { return m_explanation.end(); }
|
||||
void push_justification(constraint_index j, const mpq& v) {
|
||||
if (m_set_of_ci.find(j) != m_set_of_ci.end()) return;
|
||||
m_set_of_ci.insert(j);
|
||||
m_explanation.push_back(std::make_pair(v, j));
|
||||
explanation(const T& t) {
|
||||
for ( unsigned c : t)
|
||||
push_back(c);
|
||||
}
|
||||
void push_justification(constraint_index j) {
|
||||
if (m_set_of_ci.find(j) != m_set_of_ci.end()) return;
|
||||
m_set_of_ci.insert(j);
|
||||
m_explanation.push_back(std::make_pair(one_of_type<mpq>(), j));
|
||||
|
||||
void clear() { m_j_to_mpq.reset(); }
|
||||
void add_with_coeff(constraint_index j, const mpq& v) {
|
||||
SASSERT(m_j_to_mpq.contains(j) == false); // if we hit the assert then we
|
||||
// might start using summation
|
||||
m_j_to_mpq.insert(j, optional<mpq>(v));
|
||||
}
|
||||
|
||||
// this signature is needed to use it in a template that also works for the vector type
|
||||
void push_back(constraint_index j) {
|
||||
push_justification(j);
|
||||
if (m_j_to_mpq.contains(j))
|
||||
return;
|
||||
m_j_to_mpq.insert(j, optional<mpq>());
|
||||
}
|
||||
|
||||
void add(const explanation& e) {
|
||||
for (const auto& p: e.m_explanation) {
|
||||
add(p.second);
|
||||
void add_expl(const explanation& e) {
|
||||
for (const auto& p: e.m_j_to_mpq) {
|
||||
m_j_to_mpq.insert(p.m_key, p.m_value);
|
||||
}
|
||||
}
|
||||
template <typename T>
|
||||
void add_expl(const T& e) { for (auto j: e) add(j); }
|
||||
void add(unsigned ci) { push_justification(ci); }
|
||||
|
||||
void add(const std::pair<mpq, constraint_index>& j) { push_justification(j.second, j.first); }
|
||||
|
||||
bool empty() const { return m_explanation.empty(); }
|
||||
size_t size() const { return m_explanation.size(); }
|
||||
void add_pair(const std::pair<mpq, constraint_index>& j) {
|
||||
add_with_coeff(j.second, j.first);
|
||||
}
|
||||
|
||||
bool empty() const { return m_j_to_mpq.empty(); }
|
||||
size_t size() const { return m_j_to_mpq.size(); }
|
||||
|
||||
class cimpq {
|
||||
constraint_index m_var;
|
||||
const optional<mpq> & m_coeff;
|
||||
public:
|
||||
cimpq(constraint_index var, const optional<mpq> & val) : m_var(var), m_coeff(val) { }
|
||||
constraint_index ci() const { return m_var; }
|
||||
mpq coeff() const { return m_coeff.undef()? one_of_type<mpq>(): *m_coeff; }
|
||||
};
|
||||
class iterator {
|
||||
u_map<optional<mpq>>::iterator m_it;
|
||||
public:
|
||||
cimpq operator*() const {
|
||||
return cimpq(m_it->m_key, m_it->m_value);
|
||||
}
|
||||
iterator operator++() { iterator i = *this; m_it++; return i; }
|
||||
iterator operator++(int) { m_it++; return *this; }
|
||||
iterator(u_map<optional<mpq>>::iterator it) : m_it(it) {}
|
||||
bool operator==(const iterator &other) const { return m_it == other.m_it; }
|
||||
bool operator!=(const iterator &other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
iterator begin() const { return iterator(m_j_to_mpq.begin()); }
|
||||
iterator end() const { return iterator(m_j_to_mpq.end()); }
|
||||
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue