mirror of
https://github.com/Z3Prover/z3
synced 2025-06-07 06:33:23 +00:00
fix how don't cares are handled
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
ba292346ae
commit
0e096c55a9
6 changed files with 33 additions and 47 deletions
|
@ -132,7 +132,7 @@ namespace sat {
|
||||||
SASSERT(n.is_and() && n.size() == 0);
|
SASSERT(n.is_and() && n.size() == 0);
|
||||||
reset(cs);
|
reset(cs);
|
||||||
cut c;
|
cut c;
|
||||||
c.m_table = (n.sign() ? 0x0 : 0x1);
|
c.set_table(n.sign() ? 0x0 : 0x1);
|
||||||
push_back(cs, c);
|
push_back(cs, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,11 +212,6 @@ namespace sat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void aig_cuts::replace(unsigned v, cut const& src, cut const& dst) {
|
|
||||||
m_cuts[v].replace(m_on_cut_add, m_on_cut_del, src, dst);
|
|
||||||
touch(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool aig_cuts::is_touched(node const& n) {
|
bool aig_cuts::is_touched(node const& n) {
|
||||||
for (unsigned i = 0; i < n.size(); ++i) {
|
for (unsigned i = 0; i < n.size(); ++i) {
|
||||||
|
@ -459,7 +454,7 @@ namespace sat {
|
||||||
m_clause.push_back(lit);
|
m_clause.push_back(lit);
|
||||||
}
|
}
|
||||||
literal rr = r;
|
literal rr = r;
|
||||||
if (0 == (c.m_table & (1ull << i))) rr.neg();
|
if (0 == (c.table() & (1ull << i))) rr.neg();
|
||||||
m_clause.push_back(rr);
|
m_clause.push_back(rr);
|
||||||
on_clause(m_clause);
|
on_clause(m_clause);
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,7 +109,6 @@ namespace sat {
|
||||||
bool is_touched(node const& n);
|
bool is_touched(node const& n);
|
||||||
bool is_touched(literal lit) const { return is_touched(lit.var()); }
|
bool is_touched(literal lit) const { return is_touched(lit.var()); }
|
||||||
bool is_touched(bool_var v) const { return m_last_touched[v] + m_aig.size() >= m_num_cut_calls * m_aig.size(); }
|
bool is_touched(bool_var v) const { return m_last_touched[v] + m_aig.size() >= m_num_cut_calls * m_aig.size(); }
|
||||||
void touch(bool_var v) { m_last_touched[v] = v + m_num_cut_calls * m_aig.size(); }
|
|
||||||
void reserve(unsigned v);
|
void reserve(unsigned v);
|
||||||
bool insert_aux(unsigned v, node const& n);
|
bool insert_aux(unsigned v, node const& n);
|
||||||
void init_cut_set(unsigned id);
|
void init_cut_set(unsigned id);
|
||||||
|
@ -166,7 +165,7 @@ namespace sat {
|
||||||
|
|
||||||
void cut2def(on_clause_t& on_clause, cut const& c, literal r);
|
void cut2def(on_clause_t& on_clause, cut const& c, literal r);
|
||||||
|
|
||||||
void replace(unsigned v, cut const& src, cut const& dst);
|
void touch(bool_var v) { m_last_touched[v] = v + m_num_cut_calls * m_aig.size(); }
|
||||||
|
|
||||||
|
|
||||||
std::ostream& display(std::ostream& out) const;
|
std::ostream& display(std::ostream& out) const;
|
||||||
|
|
|
@ -463,19 +463,14 @@ namespace sat {
|
||||||
rep(cut const& s, cut const& d, unsigned v):src(s), dst(d), v(v) {}
|
rep(cut const& s, cut const& d, unsigned v):src(s), dst(d), v(v) {}
|
||||||
rep():v(UINT_MAX) {}
|
rep():v(UINT_MAX) {}
|
||||||
};
|
};
|
||||||
vector<rep> to_replace;
|
for (auto& cs : cuts) {
|
||||||
cut d;
|
|
||||||
for (auto const& cs : cuts) {
|
|
||||||
for (auto const& c : cs) {
|
for (auto const& c : cs) {
|
||||||
if (rewrite_cut(c, d)) {
|
if (add_dont_care(c)) {
|
||||||
to_replace.push_back(rep(c, d, cs.var()));
|
m_aig_cuts.touch(cs.var());
|
||||||
|
m_stats.m_num_dont_care_reductions++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (auto const& p : to_replace) {
|
|
||||||
m_aig_cuts.replace(p.v, p.src, p.dst);
|
|
||||||
}
|
|
||||||
m_stats.m_num_dont_care_reductions += to_replace.size();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -497,18 +492,18 @@ namespace sat {
|
||||||
/**
|
/**
|
||||||
* apply obtained dont_cares to cut sets.
|
* apply obtained dont_cares to cut sets.
|
||||||
*/
|
*/
|
||||||
bool aig_simplifier::rewrite_cut(cut const& c, cut& d) {
|
bool aig_simplifier::add_dont_care(cut const & c) {
|
||||||
bool init = false;
|
uint64_t dc = 0;
|
||||||
for (unsigned i = 0; i < c.size(); ++i) {
|
for (unsigned i = 0; i < c.size(); ++i) {
|
||||||
for (unsigned j = i + 1; j < c.size(); ++j) {
|
for (unsigned j = i + 1; j < c.size(); ++j) {
|
||||||
var_pair p(c[i], c[j]);
|
var_pair p(c[i], c[j]);
|
||||||
if (m_pairs.find(p, p) && p.op != none) {
|
if (m_pairs.find(p, p) && p.op != none) {
|
||||||
if (!init) { d = c; init = true; }
|
dc |= op2dont_care(i, j, p);
|
||||||
d.set_table(d.m_table | op2dont_care(i, j, p));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return init && d.m_table != c.m_table;
|
|
||||||
|
return (dc != c.dont_care()) && (c.add_dont_care(dc), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void aig_simplifier::collect_statistics(statistics& st) const {
|
void aig_simplifier::collect_statistics(statistics& st) const {
|
||||||
|
|
|
@ -95,7 +95,7 @@ namespace sat {
|
||||||
void cuts2pairs(vector<cut_set> const& cuts);
|
void cuts2pairs(vector<cut_set> const& cuts);
|
||||||
void pairs2dont_cares();
|
void pairs2dont_cares();
|
||||||
void dont_cares2cuts(vector<cut_set> const& cuts);
|
void dont_cares2cuts(vector<cut_set> const& cuts);
|
||||||
bool rewrite_cut(cut const& c, cut& r);
|
bool add_dont_care(cut const & c);
|
||||||
uint64_t op2dont_care(unsigned i, unsigned j, var_pair const& p);
|
uint64_t op2dont_care(unsigned i, unsigned j, var_pair const& p);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -88,17 +88,6 @@ namespace sat {
|
||||||
m_cuts[m_size++] = c;
|
m_cuts[m_size++] = c;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cut_set::replace(on_update_t& on_add, on_update_t& on_del, cut const& src, cut const& dst) {
|
|
||||||
SASSERT(src != dst);
|
|
||||||
insert(on_add, on_del, dst);
|
|
||||||
for (unsigned i = 0; i < size(); ++i) {
|
|
||||||
if (src == (*this)[i]) {
|
|
||||||
evict(on_del, i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void cut_set::evict(on_update_t& on_del, unsigned idx) {
|
void cut_set::evict(on_update_t& on_del, unsigned idx) {
|
||||||
if (m_var != UINT_MAX && on_del) on_del(m_var, m_cuts[idx]);
|
if (m_var != UINT_MAX && on_del) on_del(m_var, m_cuts[idx]);
|
||||||
m_cuts[idx] = m_cuts[--m_size];
|
m_cuts[idx] = m_cuts[--m_size];
|
||||||
|
@ -146,12 +135,12 @@ namespace sat {
|
||||||
y = c[++j];
|
y = c[++j];
|
||||||
}
|
}
|
||||||
index |= (1 << c.m_size);
|
index |= (1 << c.m_size);
|
||||||
return compute_shift(m_table, index);
|
return compute_shift(table(), index);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cut::operator==(cut const& other) const {
|
bool cut::operator==(cut const& other) const {
|
||||||
if (m_size != other.m_size) return false;
|
if (m_size != other.m_size) return false;
|
||||||
if (m_table != other.m_table) return false;
|
if (table() != other.table()) return false;
|
||||||
for (unsigned i = 0; i < m_size; ++i) {
|
for (unsigned i = 0; i < m_size; ++i) {
|
||||||
if ((*this)[i] != other[i]) return false;
|
if ((*this)[i] != other[i]) return false;
|
||||||
}
|
}
|
||||||
|
@ -160,7 +149,7 @@ namespace sat {
|
||||||
|
|
||||||
unsigned cut::hash() const {
|
unsigned cut::hash() const {
|
||||||
return get_composite_hash(*this, m_size,
|
return get_composite_hash(*this, m_size,
|
||||||
[](cut const& c) { return (unsigned)c.m_table; },
|
[](cut const& c) { return (unsigned)c.table(); },
|
||||||
[](cut const& c, unsigned i) { return c[i]; });
|
[](cut const& c, unsigned i) { return c[i]; });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +161,7 @@ namespace sat {
|
||||||
}
|
}
|
||||||
out << "} ";
|
out << "} ";
|
||||||
for (unsigned i = 0; i < (1u << m_size); ++i) {
|
for (unsigned i = 0; i < (1u << m_size); ++i) {
|
||||||
if (0 != (m_table & (1ull << i))) out << "1"; else out << "0";
|
if (0 != (table() & (1ull << i))) out << "1"; else out << "0";
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,17 @@ namespace sat {
|
||||||
unsigned m_filter;
|
unsigned m_filter;
|
||||||
unsigned m_size;
|
unsigned m_size;
|
||||||
unsigned m_elems[4];
|
unsigned m_elems[4];
|
||||||
public:
|
|
||||||
uint64_t m_table;
|
uint64_t m_table;
|
||||||
cut(): m_filter(0), m_size(0), m_table(0) {}
|
mutable uint64_t m_dont_care;
|
||||||
|
|
||||||
cut(unsigned id): m_filter(1u << (id & 0x1F)), m_size(1), m_table(2) { m_elems[0] = id; }
|
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) {}
|
||||||
|
|
||||||
|
cut(unsigned id): m_filter(1u << (id & 0x1F)), m_size(1), m_table(2), m_dont_care(0) {
|
||||||
|
m_elems[0] = id;
|
||||||
|
}
|
||||||
|
|
||||||
cut(cut const& other) {
|
cut(cut const& other) {
|
||||||
*this = other;
|
*this = other;
|
||||||
|
@ -39,6 +45,7 @@ namespace sat {
|
||||||
m_filter = other.m_filter;
|
m_filter = other.m_filter;
|
||||||
m_size = other.m_size;
|
m_size = other.m_size;
|
||||||
m_table = other.m_table;
|
m_table = other.m_table;
|
||||||
|
m_dont_care = other.m_dont_care;
|
||||||
for (unsigned i = 0; i < m_size; ++i) m_elems[i] = other.m_elems[i];
|
for (unsigned i = 0; i < m_size; ++i) m_elems[i] = other.m_elems[i];
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -62,11 +69,14 @@ namespace sat {
|
||||||
}
|
}
|
||||||
void sort();
|
void sort();
|
||||||
void negate() { set_table(~m_table); }
|
void negate() { set_table(~m_table); }
|
||||||
uint64_t table_mask() const { return (1ull << (1ull << m_size)) - 1ull; }
|
|
||||||
void set_table(uint64_t t) { m_table = t & table_mask(); }
|
void set_table(uint64_t t) { m_table = t & table_mask(); }
|
||||||
|
uint64_t table() const { return (m_table | m_dont_care) & table_mask(); }
|
||||||
|
|
||||||
bool is_true() const { return 0 == (table_mask() & ~m_table); }
|
uint64_t dont_care() const { return m_dont_care; }
|
||||||
bool is_false() const { return 0 == (table_mask() & m_table); }
|
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;
|
||||||
bool operator!=(cut const& other) const { return !(*this == other); }
|
bool operator!=(cut const& other) const { return !(*this == other); }
|
||||||
|
@ -157,8 +167,6 @@ namespace sat {
|
||||||
}
|
}
|
||||||
void evict(on_update_t& on_del, unsigned idx);
|
void evict(on_update_t& on_del, unsigned idx);
|
||||||
|
|
||||||
void replace(on_update_t& on_add, on_update_t& on_del, cut const& src, cut const& dst);
|
|
||||||
|
|
||||||
std::ostream& display(std::ostream& out) const;
|
std::ostream& display(std::ostream& out) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue