mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 09:35:32 +00:00
implementing model updates
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
92b5301b7f
commit
3de8c193ea
63 changed files with 482 additions and 294 deletions
|
@ -295,51 +295,6 @@ namespace sat {
|
|||
return out;
|
||||
}
|
||||
|
||||
void model_converter::validate_is_blocked(entry const& e, clause const& c) {
|
||||
if (c.is_blocked() || c.is_learned()) return;
|
||||
unsigned index = 0;
|
||||
literal lit = null_literal;
|
||||
bool_var v = e.var();
|
||||
for (literal l : c) {
|
||||
if (l.var() == v) {
|
||||
lit = l;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (lit == null_literal) return;
|
||||
|
||||
bool sat = false;
|
||||
for (literal l : e.m_clauses) {
|
||||
if (l == null_literal) {
|
||||
if (!sat) {
|
||||
display(std::cout << "clause is not blocked\n", e) << "\n";
|
||||
std::cout << c << "\n";
|
||||
}
|
||||
sat = false;
|
||||
elim_stack* st = e.m_elim_stack[index];
|
||||
if (st) {
|
||||
elim_stackv const& stack = st->stack();
|
||||
unsigned sz = stack.size();
|
||||
for (unsigned i = sz; i-- > 0; ) {
|
||||
// verify ...
|
||||
}
|
||||
|
||||
}
|
||||
++index;
|
||||
continue;
|
||||
}
|
||||
if (sat) {
|
||||
continue;
|
||||
}
|
||||
if (l.var() == v) {
|
||||
sat = l == lit;
|
||||
}
|
||||
else {
|
||||
sat = c.contains(~l);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void model_converter::copy(model_converter const & src) {
|
||||
reset();
|
||||
m_entries.append(src.m_entries);
|
||||
|
@ -362,4 +317,45 @@ namespace sat {
|
|||
return result;
|
||||
}
|
||||
|
||||
void model_converter::expand(vector<literal_vector>& update_stack) {
|
||||
literal_vector clause;
|
||||
for (entry const& e : m_entries) {
|
||||
clause.reset();
|
||||
unsigned index = 0;
|
||||
bool var_sign = false;
|
||||
for (literal l : e.m_clauses) {
|
||||
if (l == null_literal) {
|
||||
elim_stack* st = e.m_elim_stack[index];
|
||||
if (st) {
|
||||
// clause sizes increase
|
||||
elim_stackv const& stack = st->stack();
|
||||
unsigned sz = stack.size();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
unsigned csz = stack[i].first;
|
||||
literal lit = stack[i].second;
|
||||
BOOL found = false;
|
||||
unsigned j = 0;
|
||||
for (j = 0; j < csz; ++j) {
|
||||
if (clause[j] == lit) {
|
||||
std::swap(clause[j], clause[0]);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
SASSERT(found);
|
||||
update_stack.push_back(literal_vector(csz, clause.c_ptr()));
|
||||
}
|
||||
}
|
||||
update_stack.push_back(clause);
|
||||
clause.reset();
|
||||
continue;
|
||||
}
|
||||
clause.push_back(l);
|
||||
if (l.var() == e.var()) {
|
||||
std::swap(clause[0], clause.back());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -84,8 +84,6 @@ namespace sat {
|
|||
|
||||
std::ostream& display(std::ostream & out, entry const& entry) const;
|
||||
|
||||
void validate_is_blocked(entry const& e, clause const& c);
|
||||
|
||||
public:
|
||||
model_converter();
|
||||
~model_converter();
|
||||
|
@ -109,6 +107,15 @@ namespace sat {
|
|||
void copy(model_converter const & src);
|
||||
void collect_vars(bool_var_set & s) const;
|
||||
unsigned max_var(unsigned min) const;
|
||||
/*
|
||||
* \brief expand entries to a list of clauses, such that
|
||||
* the first literal in each clause is the literal whose
|
||||
* truth value is updated as follows:
|
||||
*
|
||||
* lit0 := lit0 or (~lit1 & ~lit2 & ... & ~lit_k)
|
||||
*
|
||||
*/
|
||||
void expand(vector<literal_vector>& update_stack);
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -1318,7 +1318,7 @@ namespace sat {
|
|||
|
||||
void prepare_block_clause(clause& c, literal l, model_converter::entry*& new_entry, model_converter::kind k) {
|
||||
TRACE("blocked_clause", tout << "new blocked clause: " << c << "\n";);
|
||||
if (new_entry == 0)
|
||||
if (new_entry == 0 && !s.m_retain_blocked_clauses)
|
||||
new_entry = &(mc.mk(k, l.var()));
|
||||
m_to_remove.push_back(&c);
|
||||
for (literal lit : c) {
|
||||
|
@ -1330,17 +1330,19 @@ namespace sat {
|
|||
|
||||
void block_clause(clause& c, literal l, model_converter::entry *& new_entry) {
|
||||
prepare_block_clause(c, l, new_entry, model_converter::BLOCK_LIT);
|
||||
mc.insert(*new_entry, c);
|
||||
if (!s.m_retain_blocked_clauses)
|
||||
mc.insert(*new_entry, c);
|
||||
}
|
||||
|
||||
void block_covered_clause(clause& c, literal l, model_converter::kind k) {
|
||||
model_converter::entry * new_entry = 0;
|
||||
prepare_block_clause(c, l, new_entry, k);
|
||||
mc.insert(*new_entry, m_covered_clause, m_elim_stack);
|
||||
if (!s.m_retain_blocked_clauses)
|
||||
mc.insert(*new_entry, m_covered_clause, m_elim_stack);
|
||||
}
|
||||
|
||||
void prepare_block_binary(watch_list::iterator it, literal l1, literal blocked, model_converter::entry*& new_entry, model_converter::kind k) {
|
||||
if (new_entry == 0)
|
||||
if (new_entry == 0 && !s.m_retain_blocked_clauses)
|
||||
new_entry = &(mc.mk(k, blocked.var()));
|
||||
literal l2 = it->get_literal();
|
||||
TRACE("blocked_clause", tout << "new blocked clause: " << l2 << " " << l1 << "\n";);
|
||||
|
@ -1356,13 +1358,15 @@ namespace sat {
|
|||
|
||||
void block_binary(watch_list::iterator it, literal l, model_converter::entry *& new_entry) {
|
||||
prepare_block_binary(it, l, l, new_entry, model_converter::BLOCK_LIT);
|
||||
mc.insert(*new_entry, l, it->get_literal());
|
||||
if (!s.m_retain_blocked_clauses)
|
||||
mc.insert(*new_entry, l, it->get_literal());
|
||||
}
|
||||
|
||||
void block_covered_binary(watch_list::iterator it, literal l, literal blocked, model_converter::kind k) {
|
||||
model_converter::entry * new_entry = 0;
|
||||
prepare_block_binary(it, l, blocked, new_entry, k);
|
||||
mc.insert(*new_entry, m_covered_clause, m_elim_stack);
|
||||
if (!s.m_retain_blocked_clauses)
|
||||
mc.insert(*new_entry, m_covered_clause, m_elim_stack);
|
||||
}
|
||||
|
||||
void bca() {
|
||||
|
|
|
@ -114,6 +114,7 @@ public:
|
|||
if (m_mc0.get()) result->m_mc0 = m_mc0->translate(tr);
|
||||
result->m_internalized = m_internalized;
|
||||
result->m_internalized_converted = m_internalized_converted;
|
||||
if (mc0()) result->set_model_converter(mc0()->translate(tr));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -299,7 +300,7 @@ public:
|
|||
r.reset();
|
||||
r.append(m_core.size(), m_core.c_ptr());
|
||||
}
|
||||
virtual void get_model(model_ref & mdl) {
|
||||
virtual void get_model_core(model_ref & mdl) {
|
||||
if (!m_model.get()) {
|
||||
extract_model();
|
||||
}
|
||||
|
@ -442,6 +443,18 @@ public:
|
|||
return m_asmsf[idx];
|
||||
}
|
||||
|
||||
virtual model_converter_ref get_model_converter() const {
|
||||
if (m_internalized && m_internalized_converted) {
|
||||
NOT_IMPLEMENTED_YET();
|
||||
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());
|
||||
return mc;
|
||||
}
|
||||
else {
|
||||
return solver::get_model_converter();
|
||||
}
|
||||
}
|
||||
|
||||
void convert_internalized() {
|
||||
if (!m_internalized) return;
|
||||
sat2goal s2g;
|
||||
|
|
|
@ -968,21 +968,31 @@ struct sat2goal::imp {
|
|||
return res;
|
||||
}
|
||||
|
||||
void display(std::ostream & out) {
|
||||
out << "(sat-model-converter\n";
|
||||
m_mc.display(out);
|
||||
sat::bool_var_set vars;
|
||||
m_mc.collect_vars(vars);
|
||||
out << "(atoms";
|
||||
unsigned sz = m_var2expr.size();
|
||||
for (unsigned i = 0; i < sz; i++) {
|
||||
if (vars.contains(i)) {
|
||||
out << "\n (" << i << "\n " << mk_ismt2_pp(m_var2expr.get(i), m(), 2) << ")";
|
||||
}
|
||||
expr_ref lit2expr(sat::literal l) {
|
||||
expr_ref result(m_var2expr.get(l.var()), m());
|
||||
if (l.sign()) {
|
||||
result = m().mk_not(result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void display(std::ostream & out) {
|
||||
vector<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]));
|
||||
}
|
||||
expr_ref def(m().mk_or(lit2expr(lit0), mk_and(tail)), m());
|
||||
if (lit0.sign()) {
|
||||
lit0.neg();
|
||||
def = m().mk_not(def);
|
||||
}
|
||||
display_add(out, m(), to_app(lit2expr(lit0))->get_decl(), def);
|
||||
}
|
||||
out << ")\n";
|
||||
m_fmc->display(out);
|
||||
out << ")\n";
|
||||
}
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue