mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
improve pre-processing
This commit is contained in:
parent
a634876180
commit
3cc9d7f443
22 changed files with 147 additions and 80 deletions
|
@ -20,6 +20,7 @@ Notes:
|
|||
|
||||
#include "util/vector.h"
|
||||
#include "util/uint_set.h"
|
||||
#include "util/heap.h"
|
||||
|
||||
|
||||
template<class T>
|
||||
|
@ -43,12 +44,9 @@ class max_cliques : public T {
|
|||
m_seen1.insert(p);
|
||||
if (m_seen2.contains(p)) {
|
||||
unsigned_vector const& tc = m_tc[p];
|
||||
for (unsigned j = 0; j < tc.size(); ++j) {
|
||||
unsigned np = tc[j];
|
||||
if (goal.contains(np)) {
|
||||
for (unsigned np : tc)
|
||||
if (goal.contains(np))
|
||||
reachable.insert(np);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
unsigned np = negate(p);
|
||||
|
@ -61,29 +59,30 @@ class max_cliques : public T {
|
|||
for (unsigned i = m_todo.size(); i > 0; ) {
|
||||
--i;
|
||||
p = m_todo[i];
|
||||
if (m_seen2.contains(p)) {
|
||||
if (m_seen2.contains(p))
|
||||
continue;
|
||||
}
|
||||
m_seen2.insert(p);
|
||||
unsigned np = negate(p);
|
||||
unsigned_vector& tc = m_tc[p];
|
||||
if (goal.contains(np)) {
|
||||
if (goal.contains(np))
|
||||
tc.push_back(np);
|
||||
}
|
||||
else {
|
||||
unsigned_vector const& succ = next(np);
|
||||
for (unsigned j = 0; j < succ.size(); ++j) {
|
||||
tc.append(m_tc[succ[j]]);
|
||||
}
|
||||
}
|
||||
else
|
||||
for (unsigned s : next(np))
|
||||
tc.append(m_tc[s]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
unsigned_vector const& next(unsigned vertex) const { return m_next[vertex]; }
|
||||
|
||||
void init(unsigned_vector const& ps) {
|
||||
unsigned max = 0;
|
||||
for (unsigned p : ps) {
|
||||
unsigned np = negate(p);
|
||||
max = std::max(max, std::max(np, p) + 1);
|
||||
}
|
||||
m_next.reserve(max);
|
||||
m_tc.reserve(m_next.size());
|
||||
}
|
||||
|
||||
public:
|
||||
void add_edge(unsigned src, unsigned dst) {
|
||||
|
@ -94,20 +93,11 @@ public:
|
|||
}
|
||||
|
||||
void cliques(unsigned_vector const& ps, vector<unsigned_vector>& cliques) {
|
||||
unsigned max = 0;
|
||||
unsigned num_ps = ps.size();
|
||||
for (unsigned i = 0; i < num_ps; ++i) {
|
||||
unsigned p = ps[i];
|
||||
unsigned np = negate(p);
|
||||
max = std::max(max, std::max(np, p) + 1);
|
||||
}
|
||||
m_next.reserve(max);
|
||||
m_tc.reserve(m_next.size());
|
||||
init(ps);
|
||||
unsigned_vector clique;
|
||||
uint_set vars;
|
||||
for (unsigned i = 0; i < num_ps; ++i) {
|
||||
vars.insert(ps[i]);
|
||||
}
|
||||
for (unsigned v : ps)
|
||||
vars.insert(v);
|
||||
|
||||
while (!vars.empty()) {
|
||||
clique.reset();
|
||||
|
@ -118,9 +108,8 @@ public:
|
|||
m_reachable[turn].remove(p);
|
||||
vars.remove(p);
|
||||
clique.push_back(p);
|
||||
if (m_reachable[turn].empty()) {
|
||||
if (m_reachable[turn].empty())
|
||||
break;
|
||||
}
|
||||
m_reachable[!turn].reset();
|
||||
get_reachable(p, m_reachable[turn], m_reachable[!turn]);
|
||||
turn = !turn;
|
||||
|
@ -129,10 +118,75 @@ public:
|
|||
if (clique.size() == 2 && clique[0] == negate(clique[1])) {
|
||||
// no op
|
||||
}
|
||||
else {
|
||||
else
|
||||
cliques.push_back(clique);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// better quality cliques
|
||||
void cliques2(unsigned_vector const& ps, vector<unsigned_vector>& cliques) {
|
||||
|
||||
uint_set all_vars, todo;
|
||||
u_map<uint_set> conns;
|
||||
|
||||
init(ps);
|
||||
|
||||
struct compare_degree {
|
||||
u_map<uint_set>& conns;
|
||||
compare_degree(u_map<uint_set>& conns): conns(conns) {}
|
||||
bool operator()(unsigned x, unsigned y) const {
|
||||
return conns[x].num_elems() < conns[y].num_elems();
|
||||
}
|
||||
};
|
||||
compare_degree lt(conns);
|
||||
heap<compare_degree> heap(m_next.size(), lt);
|
||||
|
||||
for (unsigned p : ps) {
|
||||
all_vars.insert(p);
|
||||
todo.insert(p);
|
||||
}
|
||||
|
||||
for (unsigned v : ps) {
|
||||
uint_set reach;
|
||||
get_reachable(v, all_vars, reach);
|
||||
conns.insert(v, reach);
|
||||
heap.insert(v);
|
||||
}
|
||||
|
||||
while (!todo.empty()) {
|
||||
unsigned v = heap.min_value();
|
||||
uint_set am1;
|
||||
unsigned_vector next;
|
||||
for (unsigned n : conns[v])
|
||||
if (todo.contains(n))
|
||||
next.push_back(n);
|
||||
std::sort(next.begin(), next.end(), [&](unsigned a, unsigned b) { return conns[a].num_elems() < conns[b].num_elems(); });
|
||||
for (unsigned x : next) {
|
||||
if (std::all_of(am1.begin(), am1.end(), [&](unsigned y) { return conns[x].contains(y); }))
|
||||
am1.insert(x);
|
||||
}
|
||||
am1.insert(v);
|
||||
for (unsigned x : am1) {
|
||||
todo.remove(x);
|
||||
for (unsigned y : conns[x]) {
|
||||
conns[y].remove(x);
|
||||
heap.decreased(y);
|
||||
}
|
||||
}
|
||||
for (unsigned x : am1)
|
||||
heap.erase(x);
|
||||
|
||||
if (am1.num_elems() > 1) {
|
||||
unsigned_vector mux;
|
||||
for (unsigned x : am1)
|
||||
mux.push_back(x);
|
||||
if (mux.size() == 2 && mux[0] == negate(mux[1])) {
|
||||
continue;
|
||||
}
|
||||
cliques.push_back(mux);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue