mirror of
https://github.com/Z3Prover/z3
synced 2025-06-09 07:33:24 +00:00
improve pre-processing
This commit is contained in:
parent
a634876180
commit
3cc9d7f443
22 changed files with 147 additions and 80 deletions
|
@ -564,7 +564,7 @@ extern "C" {
|
||||||
init_solver(c, s);
|
init_solver(c, s);
|
||||||
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
Z3_ast_vector_ref * v = alloc(Z3_ast_vector_ref, *mk_c(c), mk_c(c)->m());
|
||||||
mk_c(c)->save_object(v);
|
mk_c(c)->save_object(v);
|
||||||
expr_ref_vector trail = to_solver_ref(s)->get_trail();
|
expr_ref_vector trail = to_solver_ref(s)->get_trail(UINT_MAX);
|
||||||
for (expr* f : trail) {
|
for (expr* f : trail) {
|
||||||
v->m_ast_vector.push_back(f);
|
v->m_ast_vector.push_back(f);
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ public:
|
||||||
void move_to_front(expr* e) override { m_solver.move_to_front(e); }
|
void move_to_front(expr* e) override { m_solver.move_to_front(e); }
|
||||||
expr_ref_vector cube(expr_ref_vector&, unsigned) override { return expr_ref_vector(m); }
|
expr_ref_vector cube(expr_ref_vector&, unsigned) override { return expr_ref_vector(m); }
|
||||||
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override { m_solver.get_levels(vars, depth); }
|
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override { m_solver.get_levels(vars, depth); }
|
||||||
expr_ref_vector get_trail() override { return m_solver.get_trail(); }
|
expr_ref_vector get_trail(unsigned max_level) override { return m_solver.get_trail(max_level); }
|
||||||
|
|
||||||
void push() override;
|
void push() override;
|
||||||
void pop(unsigned n) override;
|
void pop(unsigned n) override;
|
||||||
|
|
|
@ -23,10 +23,9 @@ Author:
|
||||||
|
|
||||||
namespace opt {
|
namespace opt {
|
||||||
|
|
||||||
bool preprocess::find_mutexes(vector<soft>& softs, rational& lower) {
|
obj_map<expr, rational> preprocess::soft2map(vector<soft> const& softs, expr_ref_vector& fmls) {
|
||||||
expr_ref_vector fmls(m);
|
|
||||||
obj_map<expr, rational> new_soft;
|
obj_map<expr, rational> new_soft;
|
||||||
for (soft& sf : softs) {
|
for (soft const& sf : softs) {
|
||||||
m_trail.push_back(sf.s);
|
m_trail.push_back(sf.s);
|
||||||
if (new_soft.contains(sf.s))
|
if (new_soft.contains(sf.s))
|
||||||
new_soft[sf.s] += sf.weight;
|
new_soft[sf.s] += sf.weight;
|
||||||
|
@ -34,6 +33,12 @@ namespace opt {
|
||||||
new_soft.insert(sf.s, sf.weight);
|
new_soft.insert(sf.s, sf.weight);
|
||||||
fmls.push_back(sf.s);
|
fmls.push_back(sf.s);
|
||||||
}
|
}
|
||||||
|
return new_soft;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool preprocess::find_mutexes(vector<soft>& softs, rational& lower) {
|
||||||
|
expr_ref_vector fmls(m);
|
||||||
|
obj_map<expr, rational> new_soft = soft2map(softs, fmls);
|
||||||
vector<expr_ref_vector> mutexes;
|
vector<expr_ref_vector> mutexes;
|
||||||
lbool is_sat = s.find_mutexes(fmls, mutexes);
|
lbool is_sat = s.find_mutexes(fmls, mutexes);
|
||||||
if (is_sat == l_false)
|
if (is_sat == l_false)
|
||||||
|
@ -97,6 +102,8 @@ namespace opt {
|
||||||
preprocess::preprocess(solver& s): m(s.get_manager()), s(s), m_trail(m) {}
|
preprocess::preprocess(solver& s): m(s.get_manager()), s(s), m_trail(m) {}
|
||||||
|
|
||||||
bool preprocess::operator()(vector<soft>& soft, rational& lower) {
|
bool preprocess::operator()(vector<soft>& soft, rational& lower) {
|
||||||
return find_mutexes(soft, lower);
|
if (!find_mutexes(soft, lower))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace opt {
|
||||||
solver& s;
|
solver& s;
|
||||||
expr_ref_vector m_trail;
|
expr_ref_vector m_trail;
|
||||||
|
|
||||||
|
obj_map<expr, rational> soft2map(vector<soft> const& softs, expr_ref_vector& fmls);
|
||||||
bool find_mutexes(vector<soft>& softs, rational& lower);
|
bool find_mutexes(vector<soft>& softs, rational& lower);
|
||||||
void process_mutex(expr_ref_vector& mutex, obj_map<expr, rational>& new_soft, rational& lower);
|
void process_mutex(expr_ref_vector& mutex, obj_map<expr, rational>& new_soft, rational& lower);
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ namespace opt {
|
||||||
lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) override;
|
lbool find_mutexes(expr_ref_vector const& vars, vector<expr_ref_vector>& mutexes) override;
|
||||||
lbool preferred_sat(expr_ref_vector const& asms, vector<expr_ref_vector>& cores) override;
|
lbool preferred_sat(expr_ref_vector const& asms, vector<expr_ref_vector>& cores) override;
|
||||||
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override;
|
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override;
|
||||||
expr_ref_vector get_trail() override { return m_context.get_trail(); }
|
expr_ref_vector get_trail(unsigned max_level) override { return m_context.get_trail(max_level); }
|
||||||
expr_ref_vector cube(expr_ref_vector&, unsigned) override { return expr_ref_vector(m); }
|
expr_ref_vector cube(expr_ref_vector&, unsigned) override { return expr_ref_vector(m); }
|
||||||
void set_phase(expr* e) override { m_context.set_phase(e); }
|
void set_phase(expr* e) override { m_context.set_phase(e); }
|
||||||
phase* get_phase() override { return m_context.get_phase(); }
|
phase* get_phase() override { return m_context.get_phase(); }
|
||||||
|
|
|
@ -4194,7 +4194,7 @@ namespace sat {
|
||||||
unsigned_vector ps;
|
unsigned_vector ps;
|
||||||
for (literal lit : _lits)
|
for (literal lit : _lits)
|
||||||
ps.push_back(lit.index());
|
ps.push_back(lit.index());
|
||||||
mc.cliques(ps, _mutexes);
|
mc.cliques2(ps, _mutexes);
|
||||||
vector<vector<literal_vector>> sorted;
|
vector<vector<literal_vector>> sorted;
|
||||||
for (auto const& mux : _mutexes) {
|
for (auto const& mux : _mutexes) {
|
||||||
literal_vector clique;
|
literal_vector clique;
|
||||||
|
|
|
@ -390,7 +390,7 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector get_trail() override {
|
expr_ref_vector get_trail(unsigned max_level) override {
|
||||||
expr_ref_vector result(m);
|
expr_ref_vector result(m);
|
||||||
unsigned sz = m_solver.trail_size();
|
unsigned sz = m_solver.trail_size();
|
||||||
expr_ref_vector lit2expr(m);
|
expr_ref_vector lit2expr(m);
|
||||||
|
@ -398,7 +398,11 @@ public:
|
||||||
m_map.mk_inv(lit2expr);
|
m_map.mk_inv(lit2expr);
|
||||||
for (unsigned i = 0; i < sz; ++i) {
|
for (unsigned i = 0; i < sz; ++i) {
|
||||||
sat::literal lit = m_solver.trail_literal(i);
|
sat::literal lit = m_solver.trail_literal(i);
|
||||||
result.push_back(lit2expr[lit.index()].get());
|
if (m_solver.lvl(lit) > max_level)
|
||||||
|
continue;
|
||||||
|
expr_ref e(lit2expr.get(lit.index()), m);
|
||||||
|
if (e)
|
||||||
|
result.push_back(e);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,12 +41,12 @@ void atom2bool_var::mk_var_inv(expr_ref_vector & var2expr) const {
|
||||||
|
|
||||||
sat::bool_var atom2bool_var::to_bool_var(expr * n) const {
|
sat::bool_var atom2bool_var::to_bool_var(expr * n) const {
|
||||||
unsigned idx = m_id2map.get(n->get_id(), UINT_MAX);
|
unsigned idx = m_id2map.get(n->get_id(), UINT_MAX);
|
||||||
if (idx == UINT_MAX) {
|
if (idx == UINT_MAX)
|
||||||
return sat::null_bool_var;
|
return sat::null_bool_var;
|
||||||
}
|
else if (idx >= m_mapping.size())
|
||||||
else {
|
return sat::null_bool_var;
|
||||||
|
else
|
||||||
return m_mapping[idx].m_value;
|
return m_mapping[idx].m_value;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct collect_boolean_interface_proc {
|
struct collect_boolean_interface_proc {
|
||||||
|
|
|
@ -4612,9 +4612,15 @@ namespace smt {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector context::get_trail() {
|
expr_ref_vector context::get_trail(unsigned max_level) {
|
||||||
expr_ref_vector result(get_manager());
|
expr_ref_vector result(get_manager());
|
||||||
get_assignments(result);
|
for (literal lit : m_assigned_literals) {
|
||||||
|
if (get_assign_level(lit) > max_level + m_base_lvl)
|
||||||
|
continue;
|
||||||
|
expr_ref e(m);
|
||||||
|
literal2expr(lit, e);
|
||||||
|
result.push_back(std::move(e));
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4622,15 +4628,10 @@ namespace smt {
|
||||||
expr_mark visited;
|
expr_mark visited;
|
||||||
for (expr* fml : result)
|
for (expr* fml : result)
|
||||||
visited.mark(fml);
|
visited.mark(fml);
|
||||||
for (literal lit : m_assigned_literals) {
|
expr_ref_vector trail = get_trail(0);
|
||||||
if (get_assign_level(lit) > m_base_lvl)
|
for (expr* t : trail)
|
||||||
break;
|
if (!visited.is_marked(t))
|
||||||
expr_ref e(m);
|
result.push_back(t);
|
||||||
literal2expr(lit, e);
|
|
||||||
if (visited.is_marked(e))
|
|
||||||
continue;
|
|
||||||
result.push_back(std::move(e));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1667,7 +1667,7 @@ namespace smt {
|
||||||
|
|
||||||
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth);
|
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth);
|
||||||
|
|
||||||
expr_ref_vector get_trail();
|
expr_ref_vector get_trail(unsigned max_level);
|
||||||
|
|
||||||
void get_model(model_ref & m);
|
void get_model(model_ref & m);
|
||||||
|
|
||||||
|
|
|
@ -248,8 +248,8 @@ namespace smt {
|
||||||
m_imp->m_kernel.get_levels(vars, depth);
|
m_imp->m_kernel.get_levels(vars, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector kernel::get_trail() {
|
expr_ref_vector kernel::get_trail(unsigned max_level) {
|
||||||
return m_imp->m_kernel.get_trail();
|
return m_imp->m_kernel.get_trail(max_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void kernel::user_propagate_init(
|
void kernel::user_propagate_init(
|
||||||
|
|
|
@ -248,7 +248,7 @@ namespace smt {
|
||||||
/**
|
/**
|
||||||
\brief retrieve trail of assignment stack.
|
\brief retrieve trail of assignment stack.
|
||||||
*/
|
*/
|
||||||
expr_ref_vector get_trail();
|
expr_ref_vector get_trail(unsigned max_level);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
\brief (For debubbing purposes) Prints the state of the kernel
|
\brief (For debubbing purposes) Prints the state of the kernel
|
||||||
|
|
|
@ -208,8 +208,8 @@ namespace {
|
||||||
m_context.get_levels(vars, depth);
|
m_context.get_levels(vars, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector get_trail() override {
|
expr_ref_vector get_trail(unsigned max_level) override {
|
||||||
return m_context.get_trail();
|
return m_context.get_trail(max_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
void user_propagate_init(
|
void user_propagate_init(
|
||||||
|
|
|
@ -311,11 +311,11 @@ public:
|
||||||
m_solver2->get_levels(vars, depth);
|
m_solver2->get_levels(vars, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector get_trail() override {
|
expr_ref_vector get_trail(unsigned max_level) override {
|
||||||
if (m_use_solver1_results)
|
if (m_use_solver1_results)
|
||||||
return m_solver1->get_trail();
|
return m_solver1->get_trail(max_level);
|
||||||
else
|
else
|
||||||
return m_solver2->get_trail();
|
return m_solver2->get_trail(max_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
proof * get_proof() override {
|
proof * get_proof() override {
|
||||||
|
|
|
@ -265,7 +265,7 @@ public:
|
||||||
|
|
||||||
expr_ref_vector get_non_units();
|
expr_ref_vector get_non_units();
|
||||||
|
|
||||||
virtual expr_ref_vector get_trail() = 0; // { return expr_ref_vector(get_manager()); }
|
virtual expr_ref_vector get_trail(unsigned max_level) = 0; // { return expr_ref_vector(get_manager()); }
|
||||||
|
|
||||||
virtual void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) = 0;
|
virtual void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) = 0;
|
||||||
|
|
||||||
|
|
|
@ -127,8 +127,8 @@ public:
|
||||||
m_base->get_levels(vars, depth);
|
m_base->get_levels(vars, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector get_trail() override {
|
expr_ref_vector get_trail(unsigned max_level) override {
|
||||||
return m_base->get_trail();
|
return m_base->get_trail(max_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) override {
|
lbool check_sat_core2(unsigned num_assumptions, expr * const * assumptions) override {
|
||||||
|
|
|
@ -134,7 +134,7 @@ public:
|
||||||
throw default_exception("cannot retrieve depth from solvers created using tactics");
|
throw default_exception("cannot retrieve depth from solvers created using tactics");
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector get_trail() override {
|
expr_ref_vector get_trail(unsigned max_level) override {
|
||||||
throw default_exception("cannot retrieve trail from solvers created using tactics");
|
throw default_exception("cannot retrieve trail from solvers created using tactics");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -165,8 +165,8 @@ public:
|
||||||
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override {
|
void get_levels(ptr_vector<expr> const& vars, unsigned_vector& depth) override {
|
||||||
m_solver->get_levels(vars, depth);
|
m_solver->get_levels(vars, depth);
|
||||||
}
|
}
|
||||||
expr_ref_vector get_trail() override {
|
expr_ref_vector get_trail(unsigned max_level) override {
|
||||||
return m_solver->get_trail();
|
return m_solver->get_trail(max_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
model_converter* external_model_converter() const {
|
model_converter* external_model_converter() const {
|
||||||
|
|
|
@ -189,8 +189,8 @@ public:
|
||||||
m_solver->get_levels(vars, depth);
|
m_solver->get_levels(vars, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector get_trail() override {
|
expr_ref_vector get_trail(unsigned max_level) override {
|
||||||
return m_solver->get_trail();
|
return m_solver->get_trail(max_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_num_assertions() const override {
|
unsigned get_num_assertions() const override {
|
||||||
|
|
|
@ -105,8 +105,8 @@ public:
|
||||||
m_solver->get_levels(vars, depth);
|
m_solver->get_levels(vars, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector get_trail() override {
|
expr_ref_vector get_trail(unsigned max_level) override {
|
||||||
return m_solver->get_trail();
|
return m_solver->get_trail(max_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
model_converter* external_model_converter() const{
|
model_converter* external_model_converter() const{
|
||||||
|
|
|
@ -2098,9 +2098,9 @@ namespace smtfd {
|
||||||
m_fd_sat_solver->get_levels(vars, depth);
|
m_fd_sat_solver->get_levels(vars, depth);
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_ref_vector get_trail() override {
|
expr_ref_vector get_trail(unsigned max_level) override {
|
||||||
init();
|
init();
|
||||||
return m_fd_sat_solver->get_trail();
|
return m_fd_sat_solver->get_trail(max_level);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned get_num_assertions() const override {
|
unsigned get_num_assertions() const override {
|
||||||
|
|
|
@ -20,6 +20,7 @@ Notes:
|
||||||
|
|
||||||
#include "util/vector.h"
|
#include "util/vector.h"
|
||||||
#include "util/uint_set.h"
|
#include "util/uint_set.h"
|
||||||
|
#include "util/heap.h"
|
||||||
|
|
||||||
|
|
||||||
template<class T>
|
template<class T>
|
||||||
|
@ -43,12 +44,9 @@ class max_cliques : public T {
|
||||||
m_seen1.insert(p);
|
m_seen1.insert(p);
|
||||||
if (m_seen2.contains(p)) {
|
if (m_seen2.contains(p)) {
|
||||||
unsigned_vector const& tc = m_tc[p];
|
unsigned_vector const& tc = m_tc[p];
|
||||||
for (unsigned j = 0; j < tc.size(); ++j) {
|
for (unsigned np : tc)
|
||||||
unsigned np = tc[j];
|
if (goal.contains(np))
|
||||||
if (goal.contains(np)) {
|
|
||||||
reachable.insert(np);
|
reachable.insert(np);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
unsigned np = negate(p);
|
unsigned np = negate(p);
|
||||||
|
@ -61,30 +59,31 @@ class max_cliques : public T {
|
||||||
for (unsigned i = m_todo.size(); i > 0; ) {
|
for (unsigned i = m_todo.size(); i > 0; ) {
|
||||||
--i;
|
--i;
|
||||||
p = m_todo[i];
|
p = m_todo[i];
|
||||||
if (m_seen2.contains(p)) {
|
if (m_seen2.contains(p))
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
m_seen2.insert(p);
|
m_seen2.insert(p);
|
||||||
unsigned np = negate(p);
|
unsigned np = negate(p);
|
||||||
unsigned_vector& tc = m_tc[p];
|
unsigned_vector& tc = m_tc[p];
|
||||||
if (goal.contains(np)) {
|
if (goal.contains(np))
|
||||||
tc.push_back(np);
|
tc.push_back(np);
|
||||||
}
|
else
|
||||||
else {
|
for (unsigned s : next(np))
|
||||||
unsigned_vector const& succ = next(np);
|
tc.append(m_tc[s]);
|
||||||
for (unsigned j = 0; j < succ.size(); ++j) {
|
|
||||||
tc.append(m_tc[succ[j]]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
unsigned_vector const& next(unsigned vertex) const { return m_next[vertex]; }
|
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:
|
public:
|
||||||
void add_edge(unsigned src, unsigned dst) {
|
void add_edge(unsigned src, unsigned dst) {
|
||||||
m_next.reserve(std::max(src, dst) + 1);
|
m_next.reserve(std::max(src, dst) + 1);
|
||||||
|
@ -94,20 +93,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void cliques(unsigned_vector const& ps, vector<unsigned_vector>& cliques) {
|
void cliques(unsigned_vector const& ps, vector<unsigned_vector>& cliques) {
|
||||||
unsigned max = 0;
|
init(ps);
|
||||||
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());
|
|
||||||
unsigned_vector clique;
|
unsigned_vector clique;
|
||||||
uint_set vars;
|
uint_set vars;
|
||||||
for (unsigned i = 0; i < num_ps; ++i) {
|
for (unsigned v : ps)
|
||||||
vars.insert(ps[i]);
|
vars.insert(v);
|
||||||
}
|
|
||||||
|
|
||||||
while (!vars.empty()) {
|
while (!vars.empty()) {
|
||||||
clique.reset();
|
clique.reset();
|
||||||
|
@ -118,9 +108,8 @@ public:
|
||||||
m_reachable[turn].remove(p);
|
m_reachable[turn].remove(p);
|
||||||
vars.remove(p);
|
vars.remove(p);
|
||||||
clique.push_back(p);
|
clique.push_back(p);
|
||||||
if (m_reachable[turn].empty()) {
|
if (m_reachable[turn].empty())
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
m_reachable[!turn].reset();
|
m_reachable[!turn].reset();
|
||||||
get_reachable(p, m_reachable[turn], m_reachable[!turn]);
|
get_reachable(p, m_reachable[turn], m_reachable[!turn]);
|
||||||
turn = !turn;
|
turn = !turn;
|
||||||
|
@ -129,10 +118,75 @@ public:
|
||||||
if (clique.size() == 2 && clique[0] == negate(clique[1])) {
|
if (clique.size() == 2 && clique[0] == negate(clique[1])) {
|
||||||
// no op
|
// no op
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
cliques.push_back(clique);
|
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