z3-z3-4.13.0.src.sat.sat_cutset.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2020 Microsoft Corporation
Module Name:
sat_cutset.cpp
Author:
Nikolaj Bjorner 2020-01-02
--*/
#pragma once
#include "util/region.h"
#include "util/debug.h"
#include "util/util.h"
#include "util/lbool.h"
#include "util/vector.h"
#include
#include
#include
namespace sat {
struct cut_val {
cut_val():m_t(0ull), m_f(0ull) {}
cut_val(uint64_t t, uint64_t f): m_t(t), m_f(f) {}
uint64_t m_t, m_f;
};
typedef svector cut_eval;
class cut {
unsigned m_filter;
unsigned m_size;
unsigned m_elems[5];
uint64_t m_table;
mutable uint64_t m_dont_care;
uint64_t table_mask() const { return (1ull << (1ull << m_size)) - 1ull; }
public:
cut(): m_filter(0), m_size(0), m_table(0), m_dont_care(0) {
m_elems[0] = m_elems[1] = m_elems[2] = m_elems[3] = m_elems[4] = 0;
}
cut(unsigned id): m_filter(1u << (id & 0x1F)), m_size(1), m_table(2), m_dont_care(0) {
m_elems[0] = id;
m_elems[1] = m_elems[2] = m_elems[3] = m_elems[4] = 0;
}
cut_val eval(cut_eval const& env) const;
unsigned size() const { return m_size; }
unsigned filter() const { return m_filter; }
static unsigned max_cut_size() { return 5; }
unsigned const* begin() const { return m_elems; }
unsigned const* end() const { return m_elems + m_size; }
bool add(unsigned i) {
if (m_size >= max_cut_size()) {
return false;
}
else {
m_elems[m_size++] = i;
m_filter |= (1u << (i & 0x1F));
return true;
}
}
void negate() { set_table(~m_table); }
void set_table(uint64_t t) { m_table = t & table_mask(); }
uint64_t table() const { return (m_table | m_dont_care) & table_mask(); }
uint64_t ntable() const { return (~m_table | m_dont_care) & table_mask(); }
uint64_t dont_care() const { return m_dont_care; }
void add_dont_care(uint64_t t) const { m_dont_care |= t; }
bool is_true() const { return 0 == (table_mask() & ~table()); }
bool is_false() const { return 0 == (table_mask() & ~m_dont_care & m_table); }
bool operator==(cut const& other) const;
bool operator!=(cut const& other) const { return !(*this == other); }
unsigned hash() const;
unsigned dom_hash() const;
bool dom_eq(cut const& other) const;
struct eq_proc {
bool operator()(cut const& a, cut const& b) const { return a == b; }
bool operator()(cut const* a, cut const* b) const { return *a == *b; }
};
struct hash_proc {
unsigned operator()(cut const& a) const { return a.hash(); }
unsigned operator()(cut const* a) const { return a->hash(); }
};
struct dom_eq_proc {
bool operator()(cut const& a, cut const& b) const { return a.dom_eq(b); }
bool operator()(cut const* a, cut const* b) const { return a->dom_eq(*b); }
};
struct dom_hash_proc {
unsigned operator()(cut const& a) const { return a.dom_hash(); }
unsigned operator()(cut const* a) const { return a->dom_hash(); }
};
unsigned operator[](unsigned idx) const {
return (idx >= m_size) ? UINT_MAX : m_elems[idx];
}
uint64_t shift_table(cut const& other) const;
bool merge(cut const& a, cut const& b) {
unsigned i = 0, j = 0;
unsigned x = a[i];
unsigned y = b[j];
while (x != UINT_MAX || y != UINT_MAX) {
if (!add(std::min(x, y))) {
return false;
}
if (x < y) {
x = a[++i];
}
else if (y < x) {
y = b[++j];
}
else {
x = a[++i];
y = b[++j];
}
}
return true;
}
bool subset_of(cut const& other) const {
if (other.m_filter != (m_filter | other.m_filter)) {
return false;
}
unsigned i = 0;
unsigned other_id = other[i];
for (unsigned id : *this) {
while (id > other_id) {
other_id = other[++i];
}
if (id != other_id) return false;
other_id = other[++i];
}
return true;
}
void remove_elem(unsigned i);
static uint64_t effect_mask(unsigned i);
std::ostream& display(std::ostream& out) const;
static std::ostream& display_table(std::ostream& out, unsigned num_input, uint64_t table);
static std::string table2string(unsigned num_input, uint64_t table);
};
class cut_set {
unsigned m_var;
region* m_region;
unsigned m_size;
unsigned m_max_size;
cut * m_cuts;
public:
typedef std::function on_update_t;
cut_set(): m_var(UINT_MAX), m_region(nullptr), m_size(0), m_max_size(0), m_cuts(nullptr) {}
void init(region& r, unsigned max_sz, unsigned v);
bool insert(on_update_t& on_add, on_update_t& on_del, cut const& c);
bool no_duplicates() const;
unsigned var() const { return m_var; }
unsigned size() const { return m_size; }
cut const * begin() const { return m_cuts; }
cut const * end() const { return m_cuts + m_size; }
cut const & back() { return m_cuts[m_size-1]; }
void push_back(on_update_t& on_add, cut const& c);
void reset(on_update_t& on_del) { shrink(on_del, 0); }
cut const & operator[](unsigned idx) const { return m_cuts[idx]; }
void shrink(on_update_t& on_del, unsigned j);
void swap(cut_set& other) noexcept {
std::swap(m_var, other.m_var);
std::swap(m_size, other.m_size);
std::swap(m_max_size, other.m_max_size);
std::swap(m_cuts, other.m_cuts);
}
void evict(on_update_t& on_del, unsigned idx);
void evict(on_update_t& on_del, cut const& c);
std::ostream& display(std::ostream& out) const;
};
inline std::ostream& operator<<(std::ostream& out, cut const& c) { return c.display(out); }
inline std::ostream& operator<<(std::ostream& out, cut_set const& cs) { return cs.display(out); }
}