3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-10 19:27:06 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-10-04 19:50:42 -07:00
parent 2bf0b5f33f
commit db20b2502d
11 changed files with 338 additions and 92 deletions

View file

@ -1264,6 +1264,21 @@ namespace datalog {
return check_kind(t)?alloc(filter_proj_fn, get(t), get_ast_manager(), condition, removed_col_cnt, removed_cols):0;
}
relation_join_fn * udoc_plugin::mk_join_project_fn(
relation_base const& t1, relation_base const& t2,
unsigned joined_col_cnt, const unsigned * cols1, const unsigned * cols2,
unsigned removed_col_cnt, const unsigned * removed_cols) {
if (check_kind(t1) && check_kind(t2))
return 0;
#if 0
return alloc(join_proj_fn, get(t1), ge(t2),
joined_col_cnt, cols1, cols2,
removed_col_cnt, removed_cols);
#endif
else
return 0;
}

View file

@ -81,6 +81,7 @@ namespace datalog {
class udoc_plugin : public relation_plugin {
friend class udoc_relation;
class join_fn;
class join_project_fn;
class project_fn;
class union_fn;
class rename_fn;
@ -138,6 +139,11 @@ namespace datalog {
virtual relation_transformer_fn * mk_filter_interpreted_and_project_fn(
const relation_base & t, app * condition,
unsigned removed_col_cnt, const unsigned * removed_cols);
virtual relation_join_fn * mk_join_project_fn(
relation_base const& t1, relation_base const& t2,
unsigned joined_col_cnt, const unsigned * cols1, const unsigned * cols2,
unsigned removed_col_cnt, const unsigned * removed_cols);
void disable_fast_pass() { m_disable_fast_pass = true; }
};
};

View file

@ -316,6 +316,7 @@ private:
for (; it != end; ++it) {
asms.push_back(it->m_value);
}
//IF_VERBOSE(0, verbose_stream() << asms << "\n";);
}
void extract_core(dep2asm_t& dep2asm) {
@ -341,7 +342,7 @@ private:
m_core.reset();
for (unsigned i = 0; i < core.size(); ++i) {
expr* e;
VERIFY (asm2dep.find(core[i].index(), e));
VERIFY(asm2dep.find(core[i].index(), e));
m_core.push_back(e);
}
@ -397,6 +398,14 @@ private:
SASSERT(m_model);
// IF_VERBOSE(0, model_smt2_pp(verbose_stream(), m, *(m_model.get()), 0););
DEBUG_CODE(
for (unsigned i = 0; i < m_fmls.size(); ++i) {
expr_ref tmp(m);
VERIFY(m_model->eval(m_fmls[i].get(), tmp));
CTRACE("opt", !m.is_true(tmp),
tout << "Evaluation failed: " << mk_pp(m_fmls[i].get(), m) << "\n";);
SASSERT(m.is_true(tmp));
});
}
};

View file

@ -64,6 +64,7 @@ Notes:
#include "pb_decl_plugin.h"
#include "opt_params.hpp"
#include "ast_util.h"
#include "smt_solver.h"
using namespace opt;
@ -150,6 +151,7 @@ public:
}
void new_assumption(expr* e, rational const& w) {
IF_VERBOSE(3, verbose_stream() << "new assumption " << mk_pp(e, m) << " " << w << "\n";);
TRACE("opt", tout << "insert: " << mk_pp(e, m) << " : " << w << "\n";);
m_asm2weight.insert(e, w);
m_asms.push_back(e);
@ -171,7 +173,6 @@ public:
if (m_cancel) {
return l_undef;
}
model_ref mdl;
switch (is_sat) {
case l_true:
found_optimum();
@ -179,7 +180,6 @@ public:
case l_false:
is_sat = process_unsat();
if (is_sat != l_true) return is_sat;
get_mus_model(mdl);
break;
case l_undef:
return l_undef;
@ -187,6 +187,7 @@ public:
break;
}
}
trace_bounds("maxres");
return l_true;
}
@ -370,6 +371,7 @@ public:
}
void found_optimum() {
IF_VERBOSE(1, verbose_stream() << "found optimum\n";);
s().get_model(m_model);
DEBUG_CODE(
for (unsigned i = 0; i < m_asms.size(); ++i) {
@ -404,6 +406,9 @@ public:
while (is_sat == l_false) {
core.reset();
s().get_unsat_core(core);
//verify_core(core);
model_ref mdl;
get_mus_model(mdl);
is_sat = minimize_core(core);
if (is_sat != l_true) {
break;
@ -420,18 +425,12 @@ public:
break;
}
remove_soft(core, asms);
TRACE("opt",
display_vec(tout << "core: ", core.size(), core.c_ptr());
display_vec(tout << "assumptions: ", asms.size(), asms.c_ptr()););
is_sat = check_sat_hill_climb(asms);
}
TRACE("opt",
tout << "num cores: " << cores.size() << "\n";
for (unsigned i = 0; i < cores.size(); ++i) {
for (unsigned j = 0; j < cores[i].size(); ++j) {
tout << mk_pp(cores[i][j], m) << " ";
}
tout << "\n";
display_vec(tout, cores[i].size(), cores[i].c_ptr());
}
tout << "num satisfying: " << asms.size() << "\n";);
@ -535,6 +534,7 @@ public:
if (m_c.sat_enabled()) {
// SAT solver core extracts some model
// during unsat core computation.
mdl = 0;
s().get_model(mdl);
}
else {
@ -601,10 +601,7 @@ public:
// find the minimal weight:
rational w = get_weight(core[0]);
for (unsigned i = 1; i < core.size(); ++i) {
rational w2 = get_weight(core[i]);
if (w2 < w) {
w = w2;
}
w = std::min(w, get_weight(core[i]));
}
// add fresh soft clauses for weights that are above w.
for (unsigned i = 0; i < core.size(); ++i) {
@ -614,6 +611,7 @@ public:
new_assumption(core[i], w3);
}
}
return w;
}
@ -754,6 +752,7 @@ public:
case l_false:
core.reset();
s().get_unsat_core(core);
DEBUG_CODE(verify_core(core););
is_sat = minimize_core(core);
if (is_sat != l_true) {
break;
@ -786,14 +785,9 @@ public:
rational upper(0);
expr_ref tmp(m);
for (unsigned i = 0; i < m_soft.size(); ++i) {
expr* n = m_soft[i];
VERIFY(mdl->eval(n, tmp));
if (!m.is_true(tmp)) {
if (!is_true(mdl, m_soft[i])) {
upper += m_weights[i];
}
TRACE("opt", tout << mk_pp(n, m) << " |-> " << mk_pp(tmp, m) << "\n";);
CTRACE("opt", !m.is_true(tmp) && !m.is_false(tmp),
tout << mk_pp(n, m) << " |-> " << mk_pp(tmp, m) << "\n";);
}
if (upper >= m_upper) {
return;
@ -804,7 +798,7 @@ public:
m_assignment[i] = is_true(m_soft[i]);
}
m_upper = upper;
// verify_assignment();
DEBUG_CODE(verify_assignment(););
trace_bounds("maxres");
add_upper_bound_block();
@ -888,6 +882,38 @@ public:
}
}
void verify_core(exprs const& core) {
IF_VERBOSE(3, verbose_stream() << "verify core\n";);
ref<solver> sat_solver = mk_inc_sat_solver(m, m_params);
for (unsigned i = 0; i < s().get_num_assertions(); ++i) {
sat_solver->assert_expr(s().get_assertion(i));
}
expr_ref n(m);
for (unsigned i = 0; i < core.size(); ++i) {
IF_VERBOSE(1, verbose_stream() << mk_pp(core[i],m) << " ";);
sat_solver->assert_expr(core[i]);
}
IF_VERBOSE(1, verbose_stream() << "\n";);
lbool is_sat = sat_solver->check_sat(0, 0);
if (is_sat != l_false) {
IF_VERBOSE(0, verbose_stream() << "!!!not a core\n";);
}
sat_solver = mk_smt_solver(m, m_params, symbol());
for (unsigned i = 0; i < s().get_num_assertions(); ++i) {
sat_solver->assert_expr(s().get_assertion(i));
}
for (unsigned i = 0; i < core.size(); ++i) {
sat_solver->assert_expr(core[i]);
}
is_sat = sat_solver->check_sat(0, 0);
if (is_sat == l_true) {
IF_VERBOSE(0, verbose_stream() << "not a core\n";);
}
}
void verify_assignment() {
IF_VERBOSE(0, verbose_stream() << "verify assignment\n";);
ref<solver> sat_solver = mk_inc_sat_solver(m, m_params);

View file

@ -22,6 +22,7 @@ Revision History:
#include"trace.h"
#include"bit_vector.h"
#include"map.h"
#include"sat_elim_eqs.h"
namespace sat {
@ -54,7 +55,7 @@ namespace sat {
}
}
bin_clauses bc;
m_solver.collect_bin_clauses(bc, false);
m_solver.collect_bin_clauses(bc, false); // exclude roots.
literal lits[2];
for (unsigned i = 0; i < bc.size(); ++i) {
lits[0] = bc[i].first;
@ -215,7 +216,7 @@ namespace sat {
m_L.append(new_clauses);
m_L_blits.append(new_blits);
}
std::cout << "Number left after BCE: " << clauses.size() << "\n";
if (!clauses.empty()) std::cout << "Number left after BCE: " << clauses.size() << "\n";
return clauses.empty();
}
@ -362,7 +363,13 @@ namespace sat {
while (v != i) {
if (!m_solver.was_eliminated(v)) {
if (last_v != UINT_MAX) {
check_equality(v, last_v);
if (check_equality(v, last_v)) {
// last_v was eliminated.
}
else {
// TBD: refine partition.
}
}
last_v = v;
}
@ -371,7 +378,7 @@ namespace sat {
}
}
void bceq::check_equality(unsigned v1, unsigned v2) {
bool bceq::check_equality(unsigned v1, unsigned v2) {
TRACE("sat", tout << "check: " << v1 << " = " << v2 << "\n";);
uint64 val1 = m_rbits[v1];
uint64 val2 = m_rbits[v2];
@ -381,9 +388,9 @@ namespace sat {
SASSERT(val1 == ~val2);
l2.neg();
}
if (is_equiv(l1, l2)) {
if (is_already_equiv(l1, l2)) {
TRACE("sat", tout << "Already equivalent: " << l1 << " " << l2 << "\n";);
return;
return false;
}
literal lits[2];
@ -397,13 +404,16 @@ namespace sat {
}
if (is_sat == l_false) {
TRACE("sat", tout << "Found equivalent: " << l1 << " " << l2 << "\n";);
assert_equality(l1, l2);
}
else {
TRACE("sat", tout << "Not equivalent: " << l1 << " " << l2 << "\n";);
// TBD: if is_sat == l_true, then refine partition.
}
return is_sat == l_false;
}
bool bceq::is_equiv(literal l1, literal l2) {
bool bceq::is_already_equiv(literal l1, literal l2) {
watch_list const& w1 = m_solver.get_wlist(l1);
bool found = false;
for (unsigned i = 0; !found && i < w1.size(); ++i) {
@ -420,6 +430,24 @@ namespace sat {
return found;
}
void bceq::assert_equality(literal l1, literal l2) {
if (l2.sign()) {
l1.neg();
l2.neg();
}
literal_vector roots;
bool_var_vector vars;
for (unsigned i = 0; i < m_solver.num_vars(); ++i) {
roots.push_back(literal(i, false));
}
roots[l2.var()] = l1;
vars.push_back(l2.var());
elim_eqs elim(m_solver);
for (unsigned i = 0; i < vars.size(); ++i) {
std::cout << "var: " << vars[i] << " root: " << roots[vars[i]] << "\n";
}
elim(roots, vars);
}
void bceq::cleanup() {
m_solver.del_clauses(m_bin_clauses.begin(), m_bin_clauses.end());
@ -430,15 +458,23 @@ namespace sat {
void bceq::operator()() {
if (!m_solver.m_config.m_bcd) return;
flet<bool> _disable_bcd(m_solver.m_config.m_bcd, false);
flet<bool> _disable_min(m_solver.m_config.m_minimize_core, false);
flet<bool> _disable_opt(m_solver.m_config.m_optimize_model, false);
flet<unsigned> _bound_maxc(m_solver.m_config.m_max_conflicts, 1500);
use_list ul;
solver s(m_solver.m_params, 0);
s.m_config.m_bcd = false;
s.m_config.m_minimize_core = false;
s.m_config.m_optimize_model = false;
s.m_config.m_max_conflicts = 1500;
m_use_list = &ul;
m_s = &s;
ul.init(m_solver.num_vars());
init();
pure_decompose();
post_decompose();
std::cout << "Decomposed set " << m_L.size() << "\n";
std::cout << "Decomposed set " << m_L.size() << " rest: " << m_R.size() << "\n";
TRACE("sat",
tout << "Decomposed set " << m_L.size() << "\n";

View file

@ -65,8 +65,9 @@ namespace sat {
uint64 eval_clause(clause const& cls) const;
void verify_sweep();
void extract_partition();
void check_equality(unsigned v1, unsigned v2);
bool is_equiv(literal l1, literal l2);
bool check_equality(unsigned v1, unsigned v2);
bool is_already_equiv(literal l1, literal l2);
void assert_equality(literal l1, literal l2);
public:
bceq(solver & s);
void operator()();

View file

@ -7,7 +7,7 @@ Module Name:
Abstract:
Faster MUS extraction based on Belov et.al. HYB (Algorithm 3, 4)
Faster MUS extraction
Author:
@ -33,12 +33,27 @@ namespace sat {
m_mus.reset();
m_model.reset();
m_best_value = 0;
m_max_restarts = 10;
m_restart = s.m_stats.m_restart;
}
void mus::set_core() {
m_core.append(m_mus);
void mus::set_core() {
m_mus.append(m_core);
s.m_core.reset();
s.m_core.append(m_core);
s.m_core.append(m_mus);
}
void mus::update_model() {
double new_value = s.m_wsls.evaluate_model(s.m_model);
if (m_model.empty()) {
m_model.append(s.m_model);
m_best_value = new_value;
}
else if (m_best_value > new_value) {
m_model.reset();
m_model.append(s.m_model);
m_best_value = new_value;
}
}
lbool mus::operator()() {
@ -56,6 +71,9 @@ namespace sat {
TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
literal_vector& core = get_core();
literal_vector& mus = m_mus;
if (core.size() > 64) {
return mus2();
}
unsigned delta_time = 0;
unsigned core_miss = 0;
while (!core.empty()) {
@ -75,41 +93,31 @@ namespace sat {
literal lit = core.back();
core.pop_back();
unsigned sz = mus.size();
mus.append(core);
if (true || core_miss < 2) {
mus.push_back(~lit); // TBD: measure
lbool is_sat;
{
scoped_append _sa(mus, core);
if (true || core_miss < 2) {
mus.push_back(~lit); // TBD: measure
}
is_sat = s.check(mus.size(), mus.c_ptr());
TRACE("sat", tout << "mus: " << mus << "\n";);
}
lbool is_sat = s.check(mus.size(), mus.c_ptr());
TRACE("sat", tout << "mus: " << mus << "\n";);
switch (is_sat) {
case l_undef:
mus.resize(sz);
core.push_back(lit);
set_core();
return l_undef;
case l_true: {
SASSERT(value_at(lit, s.get_model()) == l_false);
mus.resize(sz);
mus.push_back(lit);
update_model();
if (!core.empty()) {
// mr(); // TBD: measure
}
double new_value = s.m_wsls.evaluate_model(s.m_model);
if (m_model.empty()) {
m_model.append(s.m_model);
m_best_value = new_value;
}
else if (m_best_value > new_value) {
m_model.reset();
m_model.append(s.m_model);
m_best_value = new_value;
}
break;
}
case l_false:
literal_vector const& new_core = s.get_core();
mus.resize(sz);
if (new_core.contains(~lit)) {
IF_VERBOSE(2, verbose_stream() << "miss core " << lit << "\n";);
++core_miss;
@ -141,27 +149,93 @@ namespace sat {
IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << core << ")\n";);
return l_true;
}
// bisection search.
lbool mus::mus2() {
literal_vector& core = get_core();
literal_vector& mus = m_mus;
while (true) {
literal_set core(get_core());
literal_set support;
lbool is_sat = qx(core, support, false);
s.m_core.reset();
s.m_core.append(core.to_vector());
IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << s.m_core << ")\n";);
return is_sat;
}
#if 0
unsigned start = 0;
unsigned len = core.size();
SASSERT(start < len);
unsigned mid = (len-start+1)/2;
mus.append(mid, core.c_ptr() + start);
start = start + mid;
#endif
lbool mus::qx(literal_set& assignment, literal_set& support, bool has_support) {
lbool is_sat = l_true;
if (s.m_stats.m_restart - m_restart > m_max_restarts) {
IF_VERBOSE(1, verbose_stream() << "restart budget exceeded\n";);
return l_true;
}
return l_undef;
if (has_support) {
scoped_append _sa(m_mus, support.to_vector());
is_sat = s.check(m_mus.size(), m_mus.c_ptr());
switch (is_sat) {
case l_false: {
literal_set core(s.get_core());
support &= core;
assignment.reset();
return l_true;
}
case l_undef:
return l_undef;
case l_true:
update_model();
break;
default:
break;
}
}
if (assignment.size() == 1) {
return l_true;
}
literal_set assign2;
split(assignment, assign2);
support |= assignment;
is_sat = qx(assign2, support, !assignment.empty());
unsplit(support, assignment);
if (is_sat != l_true) return is_sat;
support |= assign2;
is_sat = qx(assignment, support, !assign2.empty());
assignment |= assign2;
unsplit(support, assign2);
return is_sat;
}
void mus::unsplit(literal_set& A, literal_set& B) {
literal_set A1, B1;
literal_set::iterator it = A.begin(), end = A.end();
for (; it != end; ++it) {
if (B.contains(*it)) {
B1.insert(*it);
}
else {
A1.insert(*it);
}
}
A = A1;
B = B1;
}
void mus::split(literal_set& lits1, literal_set& lits2) {
unsigned half = lits1.size()/2;
literal_set lits3;
literal_set::iterator it = lits1.begin(), end = lits1.end();
for (unsigned i = 0; it != end; ++it, ++i) {
if (i < half) {
lits3.insert(*it);
}
else {
lits2.insert(*it);
}
}
lits1 = lits3;
}
literal_vector& mus::get_core() {
m_core.reset();
m_mus.reset();
literal_vector& core = m_core;
core.append(s.get_core());
for (unsigned i = 0; i < core.size(); ++i) {
@ -175,6 +249,11 @@ namespace sat {
return core;
}
void mus::verify_core(literal_vector const& core) {
lbool is_sat = s.check(core.size(), core.c_ptr());
IF_VERBOSE(3, verbose_stream() << "core verification: " << is_sat << " " << core << "\n";);
}
void mus::mr() {
sls sls(s);
literal_vector tabu;

View file

@ -26,6 +26,8 @@ namespace sat {
bool m_is_active;
model m_model; // model obtained during minimal unsat core
double m_best_value;
unsigned m_restart;
unsigned m_max_restarts;
solver& s;
@ -38,10 +40,30 @@ namespace sat {
private:
lbool mus1();
lbool mus2();
lbool qx(literal_set& assignment, literal_set& support, bool has_support);
void mr();
void reset();
void set_core();
void update_model();
literal_vector & get_core();
void verify_core(literal_vector const& lits);
void split(literal_set& src, literal_set& dst);
void intersect(literal_set& dst, literal_set const& src);
void unsplit(literal_set& A, literal_set& B);
class scoped_append {
unsigned m_size;
literal_vector& m_lits;
public:
scoped_append(literal_vector& lits, literal_vector const& other):
m_size(lits.size()),
m_lits(lits) {
m_lits.append(other);
}
~scoped_append() {
m_lits.resize(m_size);
}
};
};
};

View file

@ -21,7 +21,6 @@ Revision History:
#include"sat_simplifier.h"
#include"sat_simplifier_params.hpp"
#include"sat_solver.h"
#include"sat_bceq.h"
#include"stopwatch.h"
#include"trace.h"
@ -138,8 +137,10 @@ namespace sat {
return;
if (!m_subsumption && !m_elim_blocked_clauses && !m_resolution)
return;
CASSERT("sat_solver", s.check_invariant());
TRACE("before_simplifier", s.display(tout););
s.m_cleaner(true);
m_last_sub_trail_sz = s.m_trail.size();
TRACE("after_cleanup", s.display(tout););
@ -157,13 +158,6 @@ namespace sat {
if (!learned && (m_elim_blocked_clauses || m_elim_blocked_clauses_at == m_num_calls))
elim_blocked_clauses();
#if 1
// experiment is disabled.
if (!learned) { // && m_equality_inference
bceq bc(s);
bc();
}
#endif
if (!learned)
m_num_calls++;
@ -188,23 +182,21 @@ namespace sat {
bool vars_eliminated = m_num_elim_vars > old_num_elim_vars;
if (!m_need_cleanup) {
if (m_need_cleanup) {
TRACE("after_simplifier", tout << "cleanning watches...\n";);
cleanup_watches();
cleanup_clauses(s.m_learned, true, vars_eliminated, learned_in_use_lists);
cleanup_clauses(s.m_clauses, false, vars_eliminated, true);
}
else {
TRACE("after_simplifier", tout << "skipping cleanup...\n";);
if (vars_eliminated) {
// must remove learned clauses with eliminated variables
cleanup_clauses(s.m_learned, true, true, learned_in_use_lists);
}
CASSERT("sat_solver", s.check_invariant());
TRACE("after_simplifier", s.display(tout); tout << "model_converter:\n"; s.m_mc.display(tout););
free_memory();
return;
}
TRACE("after_simplifier", tout << "cleanning watches...\n";);
cleanup_watches();
cleanup_clauses(s.m_learned, true, vars_eliminated, learned_in_use_lists);
cleanup_clauses(s.m_clauses, false, vars_eliminated, true);
TRACE("after_simplifier", s.display(tout); tout << "model_converter:\n"; s.m_mc.display(tout););
CASSERT("sat_solver", s.check_invariant());
TRACE("after_simplifier", s.display(tout); tout << "model_converter:\n"; s.m_mc.display(tout););
free_memory();
}
@ -926,10 +918,9 @@ namespace sat {
void process(literal l) {
TRACE("blocked_clause", tout << "processing: " << l << "\n";);
if (s.is_external(l.var()) || s.was_eliminated(l.var())) {
return;
}
model_converter::entry * new_entry = 0;
if (s.is_external(l.var()) || s.was_eliminated(l.var()))
return;
{
m_to_remove.reset();
{
@ -1186,7 +1177,6 @@ namespace sat {
continue;
m_visited[l2.index()] = false;
}
return res;
}

View file

@ -483,7 +483,6 @@ namespace sat {
void solver::set_conflict(justification c, literal not_l) {
if (m_inconsistent)
return;
TRACE("sat", tout << "conflict: " << not_l << "\n";);
m_inconsistent = true;
m_conflict = c;
m_not_l = not_l;
@ -960,7 +959,11 @@ namespace sat {
m_stopwatch.start();
m_core.reset();
TRACE("sat", display(tout););
if (m_config.m_bcd) {
bceq bc(*this);
bc();
}
}
/**
@ -1737,11 +1740,10 @@ namespace sat {
// TBD:
// apply optional clause minimization by detecting subsumed literals.
// initial experiment suggests it has no effect.
m_mus(); // ignore return value on cancelation.
m_model.reset();
m_model.append(m_mus.get_model());
m_model_is_current = true;
m_model_is_current = !m_model.empty();
}
}

View file

@ -160,6 +160,12 @@ namespace sat {
m_in_set[v] = true;
m_set.push_back(v);
}
uint_set& operator=(uint_set const& other) {
m_in_set = other.m_in_set;
m_set = other.m_set;
return *this;
}
bool contains(unsigned v) const {
return v < m_in_set.size() && m_in_set[v] != 0;
@ -177,10 +183,31 @@ namespace sat {
m_in_set[v] = false;
return v;
}
unsigned size() const { return m_set.size(); }
iterator begin() const { return m_set.begin(); }
iterator end() const { return m_set.end(); }
void reset() { m_set.reset(); m_in_set.reset(); }
void cleanup() { m_set.finalize(); m_in_set.finalize(); }
uint_set& operator&=(uint_set const& other) {
unsigned j = 0;
for (unsigned i = 0; i < m_set.size(); ++i) {
if (other.contains(m_set[i])) {
m_set[j] = m_set[i];
++j;
}
else {
m_in_set[m_set[i]] = false;
}
}
m_set.resize(j);
return *this;
}
uint_set& operator|=(uint_set const& other) {
for (unsigned i = 0; i < other.m_set.size(); ++i) {
insert(other.m_set[i]);
}
return *this;
}
};
typedef uint_set bool_var_set;
@ -188,11 +215,44 @@ namespace sat {
class literal_set {
uint_set m_set;
public:
literal_set(literal_vector const& v) {
for (unsigned i = 0; i < v.size(); ++i) insert(v[i]);
}
literal_set() {}
literal_vector to_vector() const {
literal_vector result;
iterator it = begin(), e = end();
for (; it != e; ++it) {
result.push_back(*it);
}
return result;
}
void insert(literal l) { m_set.insert(l.index()); }
bool contains(literal l) const { return m_set.contains(l.index()); }
bool empty() const { return m_set.empty(); }
unsigned size() const { return m_set.size(); }
void reset() { m_set.reset(); }
void cleanup() { m_set.cleanup(); }
class iterator {
uint_set::iterator m_it;
public:
iterator(uint_set::iterator it):m_it(it) {}
literal operator*() const { return to_literal(*m_it); }
iterator& operator++() { ++m_it; return *this; }
iterator operator++(int) { iterator tmp = *this; ++m_it; return tmp; }
bool operator==(iterator const& it) const { return m_it == it.m_it; }
bool operator!=(iterator const& it) const { return m_it != it.m_it; }
};
iterator begin() const { return iterator(m_set.begin()); }
iterator end() const { return iterator(m_set.end()); }
literal_set& operator&=(literal_set const& other) {
m_set &= other.m_set;
return *this;
}
literal_set& operator|=(literal_set const& other) {
m_set |= other.m_set;
return *this;
}
};
struct mem_stat {