mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +00:00
model-add/del
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
3de8c193ea
commit
caaf0ba33c
28 changed files with 271 additions and 251 deletions
|
@ -59,7 +59,7 @@ namespace sat {
|
|||
vector<entry>::const_iterator begin = m_entries.begin();
|
||||
vector<entry>::const_iterator it = m_entries.end();
|
||||
bool first = true;
|
||||
VERIFY(!m_solver || m_solver->check_clauses(m));
|
||||
//VERIFY(!m_solver || m_solver->check_clauses(m));
|
||||
while (it != begin) {
|
||||
--it;
|
||||
SASSERT(it->get_kind() != ELIM_VAR || m[it->var()] == l_undef);
|
||||
|
@ -80,7 +80,7 @@ namespace sat {
|
|||
process_stack(m, clause, st->stack());
|
||||
}
|
||||
sat = false;
|
||||
if (first && m_solver && !m_solver->check_clauses(m)) {
|
||||
if (false && first && m_solver && !m_solver->check_clauses(m)) {
|
||||
display(std::cout, *it) << "\n";
|
||||
first = false;
|
||||
}
|
||||
|
@ -94,6 +94,8 @@ namespace sat {
|
|||
continue;
|
||||
bool sign = l.sign();
|
||||
bool_var v = l.var();
|
||||
if (v >= m.size()) std::cout << v << " model size: " << m.size() << "\n";
|
||||
VERIFY(v < m.size());
|
||||
if (v == it->var())
|
||||
var_sign = sign;
|
||||
if (value_at(l, m) == l_true)
|
||||
|
@ -103,7 +105,7 @@ namespace sat {
|
|||
m[v] = sign ? l_false : l_true;
|
||||
// if (first) std::cout << "set: " << l << "\n";
|
||||
sat = true;
|
||||
if (first && m_solver && !m_solver->check_clauses(m)) {
|
||||
if (false && first && m_solver && !m_solver->check_clauses(m)) {
|
||||
display(std::cout, *it) << "\n";;
|
||||
first = false;
|
||||
}
|
||||
|
@ -289,7 +291,7 @@ namespace sat {
|
|||
out << ")";
|
||||
for (literal l : entry.m_clauses) {
|
||||
if (l != null_literal) {
|
||||
if (m_solver && m_solver->was_eliminated(l.var())) out << "\neliminated: " << l;
|
||||
if (false && m_solver && m_solver->was_eliminated(l.var())) out << "\neliminated: " << l;
|
||||
}
|
||||
}
|
||||
return out;
|
||||
|
@ -317,12 +319,12 @@ namespace sat {
|
|||
return result;
|
||||
}
|
||||
|
||||
void model_converter::expand(vector<literal_vector>& update_stack) {
|
||||
literal_vector clause;
|
||||
void model_converter::expand(literal_vector& update_stack) {
|
||||
sat::literal_vector clause;
|
||||
for (entry const& e : m_entries) {
|
||||
clause.reset();
|
||||
unsigned index = 0;
|
||||
bool var_sign = false;
|
||||
clause.reset();
|
||||
for (literal l : e.m_clauses) {
|
||||
if (l == null_literal) {
|
||||
elim_stack* st = e.m_elim_stack[index];
|
||||
|
@ -343,10 +345,12 @@ namespace sat {
|
|||
}
|
||||
}
|
||||
SASSERT(found);
|
||||
update_stack.push_back(literal_vector(csz, clause.c_ptr()));
|
||||
update_stack.append(csz, clause.c_ptr());
|
||||
update_stack.push_back(null_literal);
|
||||
}
|
||||
}
|
||||
update_stack.push_back(clause);
|
||||
update_stack.append(clause);
|
||||
update_stack.push_back(null_literal);
|
||||
clause.reset();
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -39,39 +39,47 @@ namespace sat {
|
|||
|
||||
class solver;
|
||||
|
||||
static unsigned counter = 0;
|
||||
|
||||
class model_converter {
|
||||
|
||||
public:
|
||||
typedef svector<std::pair<unsigned, literal>> elim_stackv;
|
||||
|
||||
|
||||
class elim_stack {
|
||||
unsigned m_refcount;
|
||||
unsigned m_counter;
|
||||
unsigned m_refcount;
|
||||
elim_stackv m_stack;
|
||||
elim_stack(elim_stack const& );
|
||||
public:
|
||||
elim_stack(elim_stackv const& stack):
|
||||
m_counter(0),
|
||||
m_refcount(0),
|
||||
m_stack(stack) {
|
||||
m_counter = ++counter;
|
||||
}
|
||||
~elim_stack() { }
|
||||
void inc_ref() { ++m_refcount; }
|
||||
void dec_ref() { if (0 == --m_refcount) dealloc(this); }
|
||||
void dec_ref() { if (0 == --m_refcount) { dealloc(this); } }
|
||||
elim_stackv const& stack() const { return m_stack; }
|
||||
unsigned ref_count() const { return m_refcount; }
|
||||
};
|
||||
|
||||
enum kind { ELIM_VAR = 0, BLOCK_LIT, CCE, ACCE };
|
||||
class entry {
|
||||
friend class model_converter;
|
||||
unsigned m_var:30;
|
||||
unsigned m_kind:2;
|
||||
literal_vector m_clauses; // the different clauses are separated by null_literal
|
||||
sref_vector<elim_stack> m_elim_stack;
|
||||
entry(kind k, bool_var v):m_var(v), m_kind(k) {}
|
||||
unsigned m_var:30;
|
||||
unsigned m_kind:2;
|
||||
literal_vector m_clauses; // the different clauses are separated by null_literal
|
||||
sref_vector<elim_stack> m_elim_stack;
|
||||
entry(kind k, bool_var v): m_var(v), m_kind(k) {}
|
||||
public:
|
||||
entry(entry const & src):
|
||||
m_var(src.m_var),
|
||||
m_kind(src.m_kind),
|
||||
m_clauses(src.m_clauses),
|
||||
m_elim_stack(src.m_elim_stack) {
|
||||
m_clauses(src.m_clauses) {
|
||||
m_elim_stack.append(src.m_elim_stack);
|
||||
}
|
||||
bool_var var() const { return m_var; }
|
||||
kind get_kind() const { return static_cast<kind>(m_kind); }
|
||||
|
@ -115,7 +123,7 @@ namespace sat {
|
|||
* lit0 := lit0 or (~lit1 & ~lit2 & ... & ~lit_k)
|
||||
*
|
||||
*/
|
||||
void expand(vector<literal_vector>& update_stack);
|
||||
void expand(literal_vector& update_stack);
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -61,6 +61,7 @@ namespace sat {
|
|||
m_num_checkpoints = 0;
|
||||
m_simplifications = 0;
|
||||
m_cuber = nullptr;
|
||||
m_mc.set_solver(nullptr);
|
||||
}
|
||||
|
||||
solver::~solver() {
|
||||
|
@ -1550,7 +1551,7 @@ namespace sat {
|
|||
|
||||
if (m_config.m_drat) m_drat.check_model(m_model);
|
||||
|
||||
// m_mc.set_solver(this);
|
||||
m_mc.set_solver(nullptr);
|
||||
m_mc(m_model);
|
||||
|
||||
|
||||
|
|
|
@ -61,6 +61,7 @@ class inc_sat_solver : public solver {
|
|||
proof_converter_ref m_pc;
|
||||
model_converter_ref m_mc;
|
||||
model_converter_ref m_mc0;
|
||||
model_converter_ref m_sat_mc;
|
||||
expr_dependency_ref m_dep_core;
|
||||
svector<double> m_weights;
|
||||
std::string m_unknown;
|
||||
|
@ -444,10 +445,11 @@ public:
|
|||
}
|
||||
|
||||
virtual model_converter_ref get_model_converter() const {
|
||||
if (m_internalized && m_internalized_converted) {
|
||||
NOT_IMPLEMENTED_YET();
|
||||
const_cast<inc_sat_solver*>(this)->convert_internalized();
|
||||
if (m_internalized && m_internalized_converted) {
|
||||
model_converter_ref mc = concat(m_mc0.get(), mk_bit_blaster_model_converter(m, m_bb_rewriter->const2bits()));
|
||||
mc = concat(solver::get_model_converter().get(), mc.get());
|
||||
mc = concat(mc.get(), m_sat_mc.get());
|
||||
return mc;
|
||||
}
|
||||
else {
|
||||
|
@ -456,28 +458,14 @@ public:
|
|||
}
|
||||
|
||||
void convert_internalized() {
|
||||
if (!m_internalized) return;
|
||||
if (!m_internalized || m_internalized_converted) return;
|
||||
sat2goal s2g;
|
||||
model_converter_ref mc;
|
||||
goal g(m, false, false, false);
|
||||
s2g(m_solver, m_map, m_params, g, mc);
|
||||
extract_model();
|
||||
if (!m_model) {
|
||||
m_model = alloc(model, m);
|
||||
}
|
||||
model_ref mdl = m_model;
|
||||
if (m_mc) (*m_mc)(mdl);
|
||||
for (unsigned i = 0; i < mdl->get_num_constants(); ++i) {
|
||||
func_decl* c = mdl->get_constant(i);
|
||||
expr_ref eq(m.mk_eq(m.mk_const(c), mdl->get_const_interp(c)), m);
|
||||
g.assert_expr(eq);
|
||||
}
|
||||
m_sat_mc = nullptr;
|
||||
goal g(m, false, true, false);
|
||||
s2g(m_solver, m_map, m_params, g, m_sat_mc);
|
||||
m_internalized_fmls.reset();
|
||||
g.get_formulas(m_internalized_fmls);
|
||||
m_internalized_converted = true;
|
||||
// if (mc) mc->display(std::cout << "mc");
|
||||
// if (m_mc) m_mc->display(std::cout << "m_mc\n");
|
||||
// if (m_mc0) m_mc0->display(std::cout << "m_mc0\n");
|
||||
}
|
||||
|
||||
void init_preprocess() {
|
||||
|
|
|
@ -52,7 +52,7 @@ struct goal2sat::imp {
|
|||
};
|
||||
ast_manager & m;
|
||||
pb_util pb;
|
||||
sat::ba_solver* m_ext;
|
||||
sat::ba_solver* m_ext;
|
||||
svector<frame> m_frame_stack;
|
||||
svector<sat::literal> m_result_stack;
|
||||
obj_map<app, sat::literal> m_cache;
|
||||
|
@ -896,20 +896,34 @@ struct sat2goal::imp {
|
|||
public:
|
||||
sat_model_converter(ast_manager & m, sat::solver const & s):m_var2expr(m) {
|
||||
m_mc.copy(s.get_model_converter());
|
||||
m_mc.set_solver(&s);
|
||||
m_fmc = alloc(filter_model_converter, m);
|
||||
}
|
||||
|
||||
ast_manager & m() { return m_var2expr.get_manager(); }
|
||||
|
||||
void insert(expr * atom, bool aux) {
|
||||
m_var2expr.push_back(atom);
|
||||
|
||||
void init(unsigned num_vars) {
|
||||
m_var2expr.resize(num_vars);
|
||||
}
|
||||
|
||||
void insert(unsigned v, expr * atom, bool aux) {
|
||||
VERIFY(!m_var2expr.get(v));
|
||||
m_var2expr[v] = atom;
|
||||
if (aux) {
|
||||
SASSERT(is_uninterp_const(atom));
|
||||
SASSERT(m().is_bool(atom));
|
||||
m_fmc->insert(to_app(atom)->get_decl());
|
||||
}
|
||||
}
|
||||
|
||||
void finish() {
|
||||
sat::literal_vector updates;
|
||||
m_mc.expand(updates);
|
||||
for (sat::literal l : updates) {
|
||||
if (l != sat::null_literal && !m_var2expr.get(l.var())) {
|
||||
insert(l.var(), m().mk_fresh_const(0, m().mk_bool_sort()), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
virtual void operator()(model_ref & md, unsigned goal_idx) {
|
||||
SASSERT(goal_idx == 0);
|
||||
|
@ -929,6 +943,10 @@ struct sat2goal::imp {
|
|||
sat::model sat_md;
|
||||
expr_ref val(m());
|
||||
for (expr * atom : m_var2expr) {
|
||||
if (!atom) {
|
||||
sat_md.push_back(l_undef);
|
||||
continue;
|
||||
}
|
||||
ev(atom, val);
|
||||
if (m().is_true(val))
|
||||
sat_md.push_back(l_true);
|
||||
|
@ -945,7 +963,7 @@ struct sat2goal::imp {
|
|||
unsigned sz = m_var2expr.size();
|
||||
for (sat::bool_var v = 0; v < sz; v++) {
|
||||
expr * atom = m_var2expr.get(v);
|
||||
if (is_uninterp_const(atom)) {
|
||||
if (atom && is_uninterp_const(atom)) {
|
||||
func_decl * d = to_app(atom)->get_decl();
|
||||
lbool new_val = sat_md[v];
|
||||
if (new_val == l_true)
|
||||
|
@ -964,11 +982,12 @@ struct sat2goal::imp {
|
|||
sat_model_converter * res = alloc(sat_model_converter, translator.to());
|
||||
res->m_fmc = static_cast<filter_model_converter*>(m_fmc->translate(translator));
|
||||
for (expr* e : m_var2expr)
|
||||
res->m_var2expr.push_back(translator(e));
|
||||
res->m_var2expr.push_back(e ? translator(e) : nullptr);
|
||||
return res;
|
||||
}
|
||||
|
||||
expr_ref lit2expr(sat::literal l) {
|
||||
VERIFY(m_var2expr.get(l.var()));
|
||||
expr_ref result(m_var2expr.get(l.var()), m());
|
||||
if (l.sign()) {
|
||||
result = m().mk_not(result);
|
||||
|
@ -977,25 +996,43 @@ struct sat2goal::imp {
|
|||
}
|
||||
|
||||
void display(std::ostream & out) {
|
||||
vector<sat::literal_vector> updates;
|
||||
sat::literal_vector updates;
|
||||
m_mc.expand(updates);
|
||||
for (sat::literal_vector const& clause : updates) {
|
||||
expr_ref_vector tail(m());
|
||||
sat::literal lit0 = clause[0];
|
||||
for (unsigned i = 1; i < clause.size(); ++i) {
|
||||
tail.push_back(lit2expr(~clause[i]));
|
||||
sat::literal_vector clause;
|
||||
expr_ref_vector tail(m());
|
||||
expr_ref def(m());
|
||||
for (sat::literal l : updates) {
|
||||
if (l == sat::null_literal) {
|
||||
sat::literal lit0 = clause[0];
|
||||
for (unsigned i = 1; i < clause.size(); ++i) {
|
||||
tail.push_back(lit2expr(~clause[i]));
|
||||
}
|
||||
def = m().mk_or(lit2expr(lit0), mk_and(tail));
|
||||
if (lit0.sign()) {
|
||||
lit0.neg();
|
||||
def = m().mk_not(def);
|
||||
}
|
||||
display_add(out, m(), to_app(lit2expr(lit0))->get_decl(), def);
|
||||
clause.reset();
|
||||
tail.reset();
|
||||
}
|
||||
expr_ref def(m().mk_or(lit2expr(lit0), mk_and(tail)), m());
|
||||
if (lit0.sign()) {
|
||||
lit0.neg();
|
||||
def = m().mk_not(def);
|
||||
else {
|
||||
clause.push_back(l);
|
||||
}
|
||||
display_add(out, m(), to_app(lit2expr(lit0))->get_decl(), def);
|
||||
}
|
||||
m_fmc->display(out);
|
||||
}
|
||||
|
||||
virtual void collect(ast_pp_util& visitor) {
|
||||
m_env = &visitor.env();
|
||||
for (expr* e : m_var2expr) if (e) visitor.coll.visit(e);
|
||||
if (m_fmc) m_fmc->collect(visitor);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
typedef ref<sat_model_converter> sat_model_converter_ref;
|
||||
|
||||
ast_manager & m;
|
||||
expr_ref_vector m_lit2expr;
|
||||
unsigned long long m_max_memory;
|
||||
|
@ -1019,83 +1056,80 @@ struct sat2goal::imp {
|
|||
throw tactic_exception(TACTIC_MAX_MEMORY_MSG);
|
||||
}
|
||||
|
||||
void init_lit2expr(sat::solver const & s, atom2bool_var const & map, model_converter_ref & mc, bool produce_models) {
|
||||
ref<sat_model_converter> _mc;
|
||||
if (produce_models)
|
||||
_mc = alloc(sat_model_converter, m, s);
|
||||
void init_lit2expr(sat::solver const & s, atom2bool_var const & map, sat_model_converter_ref & mc) {
|
||||
unsigned num_vars = s.num_vars();
|
||||
m_lit2expr.resize(num_vars * 2);
|
||||
map.mk_inv(m_lit2expr);
|
||||
sort * b = m.mk_bool_sort();
|
||||
for (sat::bool_var v = 0; v < num_vars; v++) {
|
||||
checkpoint();
|
||||
sat::literal l(v, false);
|
||||
if (m_lit2expr.get(l.index()) == 0) {
|
||||
SASSERT(m_lit2expr.get((~l).index()) == 0);
|
||||
app * aux = m.mk_fresh_const(0, b);
|
||||
if (_mc)
|
||||
_mc->insert(aux, true);
|
||||
m_lit2expr.set(l.index(), aux);
|
||||
m_lit2expr.set((~l).index(), m.mk_not(aux));
|
||||
}
|
||||
else {
|
||||
if (_mc)
|
||||
_mc->insert(m_lit2expr.get(l.index()), false);
|
||||
SASSERT(m_lit2expr.get((~l).index()) != 0);
|
||||
if (mc) {
|
||||
mc->init(num_vars);
|
||||
for (sat::bool_var v = 0; v < num_vars; v++) {
|
||||
checkpoint();
|
||||
sat::literal l(v, false);
|
||||
if (m_lit2expr.get(l.index())) {
|
||||
mc->insert(v, m_lit2expr.get(l.index()), false);
|
||||
SASSERT(m_lit2expr[(~l).index()]);
|
||||
}
|
||||
}
|
||||
}
|
||||
mc = _mc.get();
|
||||
}
|
||||
|
||||
expr * lit2expr(sat::literal l) {
|
||||
expr * lit2expr(sat_model_converter_ref& mc, sat::literal l) {
|
||||
if (!m_lit2expr.get(l.index())) {
|
||||
SASSERT(m_lit2expr.get((~l).index()) == 0);
|
||||
app * aux = m.mk_fresh_const(0, m.mk_bool_sort());
|
||||
if (mc)
|
||||
mc->insert(l.var(), aux, true);
|
||||
m_lit2expr.set(l.index(), aux);
|
||||
m_lit2expr.set((~l).index(), m.mk_not(aux));
|
||||
}
|
||||
return m_lit2expr.get(l.index());
|
||||
}
|
||||
|
||||
void assert_pb(goal& r, sat::ba_solver::pb const& p) {
|
||||
void assert_pb(sat_model_converter_ref& mc, goal& r, sat::ba_solver::pb const& p) {
|
||||
pb_util pb(m);
|
||||
ptr_buffer<expr> lits;
|
||||
vector<rational> coeffs;
|
||||
for (auto const& wl : p) {
|
||||
lits.push_back(lit2expr(wl.second));
|
||||
lits.push_back(lit2expr(mc, wl.second));
|
||||
coeffs.push_back(rational(wl.first));
|
||||
}
|
||||
rational k(p.k());
|
||||
expr_ref fml(pb.mk_ge(p.size(), coeffs.c_ptr(), lits.c_ptr(), k), m);
|
||||
|
||||
if (p.lit() != sat::null_literal) {
|
||||
fml = m.mk_eq(lit2expr(p.lit()), fml);
|
||||
fml = m.mk_eq(lit2expr(mc, p.lit()), fml);
|
||||
}
|
||||
r.assert_expr(fml);
|
||||
}
|
||||
|
||||
void assert_card(goal& r, sat::ba_solver::card const& c) {
|
||||
void assert_card(sat_model_converter_ref& mc, goal& r, sat::ba_solver::card const& c) {
|
||||
pb_util pb(m);
|
||||
ptr_buffer<expr> lits;
|
||||
for (sat::literal l : c) {
|
||||
lits.push_back(lit2expr(l));
|
||||
lits.push_back(lit2expr(mc, l));
|
||||
}
|
||||
expr_ref fml(pb.mk_at_least_k(c.size(), lits.c_ptr(), c.k()), m);
|
||||
|
||||
if (c.lit() != sat::null_literal) {
|
||||
fml = m.mk_eq(lit2expr(c.lit()), fml);
|
||||
fml = m.mk_eq(lit2expr(mc, c.lit()), fml);
|
||||
}
|
||||
r.assert_expr(fml);
|
||||
}
|
||||
|
||||
void assert_xor(goal & r, sat::ba_solver::xor const& x) {
|
||||
void assert_xor(sat_model_converter_ref& mc, goal & r, sat::ba_solver::xor const& x) {
|
||||
ptr_buffer<expr> lits;
|
||||
for (sat::literal l : x) {
|
||||
lits.push_back(lit2expr(l));
|
||||
lits.push_back(lit2expr(mc, l));
|
||||
}
|
||||
expr_ref fml(m.mk_xor(x.size(), lits.c_ptr()), m);
|
||||
|
||||
if (x.lit() != sat::null_literal) {
|
||||
fml = m.mk_eq(lit2expr(x.lit()), fml);
|
||||
fml = m.mk_eq(lit2expr(mc, x.lit()), fml);
|
||||
}
|
||||
r.assert_expr(fml);
|
||||
}
|
||||
|
||||
void assert_clauses(sat::solver const & s, sat::clause_vector const& clauses, goal & r, bool asserted) {
|
||||
void assert_clauses(sat_model_converter_ref& mc, sat::solver const & s, sat::clause_vector const& clauses, goal & r, bool asserted) {
|
||||
ptr_buffer<expr> lits;
|
||||
for (sat::clause* cp : clauses) {
|
||||
checkpoint();
|
||||
|
@ -1104,7 +1138,7 @@ struct sat2goal::imp {
|
|||
unsigned sz = c.size();
|
||||
if (asserted || m_learned || c.glue() <= s.get_config().m_gc_small_lbd) {
|
||||
for (sat::literal l : c) {
|
||||
lits.push_back(lit2expr(l));
|
||||
lits.push_back(lit2expr(mc, l));
|
||||
}
|
||||
r.assert_expr(m.mk_or(lits.size(), lits.c_ptr()));
|
||||
}
|
||||
|
@ -1121,17 +1155,22 @@ struct sat2goal::imp {
|
|||
r.assert_expr(m.mk_false());
|
||||
return;
|
||||
}
|
||||
init_lit2expr(s, map, mc, r.models_enabled());
|
||||
ref<sat_model_converter> _mc;
|
||||
if (r.models_enabled()) {
|
||||
_mc = alloc(sat_model_converter, m, s);
|
||||
}
|
||||
mc = _mc.get();
|
||||
init_lit2expr(s, map, _mc);
|
||||
// collect units
|
||||
unsigned num_vars = s.num_vars();
|
||||
for (sat::bool_var v = 0; v < num_vars; v++) {
|
||||
checkpoint();
|
||||
switch (s.value(v)) {
|
||||
case l_true:
|
||||
r.assert_expr(lit2expr(sat::literal(v, false)));
|
||||
r.assert_expr(lit2expr(_mc, sat::literal(v, false)));
|
||||
break;
|
||||
case l_false:
|
||||
r.assert_expr(lit2expr(sat::literal(v, true)));
|
||||
r.assert_expr(lit2expr(_mc, sat::literal(v, true)));
|
||||
break;
|
||||
case l_undef:
|
||||
break;
|
||||
|
@ -1142,96 +1181,50 @@ struct sat2goal::imp {
|
|||
s.collect_bin_clauses(bin_clauses, m_learned);
|
||||
for (sat::solver::bin_clause const& bc : bin_clauses) {
|
||||
checkpoint();
|
||||
r.assert_expr(m.mk_or(lit2expr(bc.first), lit2expr(bc.second)));
|
||||
r.assert_expr(m.mk_or(lit2expr(_mc, bc.first), lit2expr(_mc, bc.second)));
|
||||
}
|
||||
// collect clauses
|
||||
assert_clauses(s, s.clauses(), r, true);
|
||||
assert_clauses(_mc, s, s.clauses(), r, true);
|
||||
|
||||
sat::ba_solver* ext = get_ba_solver(s);
|
||||
if (ext) {
|
||||
for (auto* c : ext->constraints()) {
|
||||
switch (c->tag()) {
|
||||
case sat::ba_solver::card_t:
|
||||
assert_card(r, c->to_card());
|
||||
assert_card(_mc, r, c->to_card());
|
||||
break;
|
||||
case sat::ba_solver::pb_t:
|
||||
assert_pb(r, c->to_pb());
|
||||
assert_pb(_mc, r, c->to_pb());
|
||||
break;
|
||||
case sat::ba_solver::xor_t:
|
||||
assert_xor(r, c->to_xor());
|
||||
assert_xor(_mc, r, c->to_xor());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
//s.display(std::cout);
|
||||
//r.display(std::cout);
|
||||
if (_mc) _mc->finish();
|
||||
}
|
||||
|
||||
void add_clause(sat::literal_vector const& lits, expr_ref_vector& lemmas) {
|
||||
void add_clause(sat_model_converter_ref& mc, sat::literal_vector const& lits, expr_ref_vector& lemmas) {
|
||||
expr_ref_vector lemma(m);
|
||||
for (sat::literal l : lits) {
|
||||
expr* e = m_lit2expr.get(l.index(), 0);
|
||||
expr* e = lit2expr(mc, l);
|
||||
if (!e) return;
|
||||
lemma.push_back(e);
|
||||
}
|
||||
lemmas.push_back(mk_or(lemma));
|
||||
}
|
||||
|
||||
void add_clause(sat::clause const& c, expr_ref_vector& lemmas) {
|
||||
void add_clause(sat_model_converter_ref& mc, sat::clause const& c, expr_ref_vector& lemmas) {
|
||||
expr_ref_vector lemma(m);
|
||||
for (sat::literal l : c) {
|
||||
expr* e = m_lit2expr.get(l.index(), 0);
|
||||
expr* e = lit2expr(mc, l);
|
||||
if (!e) return;
|
||||
lemma.push_back(e);
|
||||
}
|
||||
lemmas.push_back(mk_or(lemma));
|
||||
}
|
||||
|
||||
void get_learned(sat::solver const& s, atom2bool_var const& map, expr_ref_vector& lemmas) {
|
||||
if (s.inconsistent()) {
|
||||
lemmas.push_back(m.mk_false());
|
||||
return;
|
||||
}
|
||||
|
||||
unsigned num_vars = s.num_vars();
|
||||
m_lit2expr.resize(num_vars * 2);
|
||||
map.mk_inv(m_lit2expr);
|
||||
|
||||
sat::literal_vector lits;
|
||||
// collect units
|
||||
for (sat::bool_var v = 0; v < num_vars; v++) {
|
||||
checkpoint();
|
||||
lits.reset();
|
||||
switch (s.value(v)) {
|
||||
case l_true:
|
||||
lits.push_back(sat::literal(v, false));
|
||||
add_clause(lits, lemmas);
|
||||
break;
|
||||
case l_false:
|
||||
lits.push_back(sat::literal(v, false));
|
||||
add_clause(lits, lemmas);
|
||||
break;
|
||||
case l_undef:
|
||||
break;
|
||||
}
|
||||
}
|
||||
// collect learned binary clauses
|
||||
svector<sat::solver::bin_clause> bin_clauses;
|
||||
s.collect_bin_clauses(bin_clauses, true, true);
|
||||
for (sat::solver::bin_clause const& bc : bin_clauses) {
|
||||
checkpoint();
|
||||
lits.reset();
|
||||
lits.push_back(bc.first);
|
||||
lits.push_back(bc.second);
|
||||
add_clause(lits, lemmas);
|
||||
}
|
||||
// collect clauses
|
||||
for (sat::clause const* c : s.learned()) {
|
||||
add_clause(*c, lemmas);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
sat2goal::sat2goal():m_imp(0) {
|
||||
|
@ -1260,9 +1253,4 @@ void sat2goal::operator()(sat::solver const & t, atom2bool_var const & m, params
|
|||
proc(t, m, g, mc);
|
||||
}
|
||||
|
||||
void sat2goal::get_learned(sat::solver const & t, atom2bool_var const & m, params_ref const& p, expr_ref_vector& lemmas) {
|
||||
imp proc(lemmas.get_manager(), p);
|
||||
scoped_set_imp set(this, &proc);
|
||||
proc.get_learned(t, m, lemmas);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue