3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 09:05:31 +00:00

implement user scopes for sat solver

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-07-30 09:27:03 -07:00
parent 2b1af8fd50
commit 4f0de9a0cf
6 changed files with 220 additions and 19 deletions

View file

@ -140,7 +140,16 @@ namespace sat {
for (unsigned i = 0; i < num_lits; i++)
SASSERT(m_eliminated[lits[i].var()] == false);
});
mk_clause_core(num_lits, lits, false);
if (m_user_scope_literals.empty()) {
mk_clause_core(num_lits, lits, false);
}
else {
m_aux_literals.reset();
m_aux_literals.append(num_lits, lits);
m_aux_literals.append(m_user_scope_literals);
mk_clause_core(m_aux_literals.size(), m_aux_literals.c_ptr(), false);
}
}
void solver::mk_clause(literal l1, literal l2) {
@ -686,6 +695,7 @@ namespace sat {
//
// -----------------------
lbool solver::check(unsigned num_lits, literal const* lits) {
pop_to_base_level();
IF_VERBOSE(2, verbose_stream() << "(sat.sat-solver using the efficient SAT solver)\n";);
SASSERT(scope_lvl() == 0);
#ifdef CLONE_BEFORE_SOLVING
@ -716,7 +726,7 @@ namespace sat {
m_restart_threshold = m_config.m_restart_initial;
}
// iff3_finder(*this)();
// iff3_finder(*this)();
simplify_problem();
if (inconsistent()) return l_false;
@ -858,18 +868,27 @@ namespace sat {
}
void solver::init_assumptions(unsigned num_lits, literal const* lits) {
if (num_lits == 0) {
if (num_lits == 0 && m_user_scope_literals.empty()) {
return;
}
push();
m_assumptions.reset();
m_assumption_set.reset();
m_assumption_set.reset();
push();
TRACE("sat", display(tout););
#define _INSERT_LIT(_l_) \
SASSERT(is_external((_l_).var())); \
m_assumption_set.insert(_l_); \
m_assumptions.push_back(_l_); \
mk_clause_core(1, &(_l_), false); \
for (unsigned i = 0; i < num_lits; ++i) {
literal l = lits[i];
SASSERT(is_external(l.var()));
m_assumption_set.insert(l);
m_assumptions.push_back(l);
mk_clause(1, &l);
literal lit = lits[i];
_INSERT_LIT(lit);
}
for (unsigned i = 0; i < m_user_scope_literals.size(); ++i) {
literal nlit = ~m_user_scope_literals[i];
_INSERT_LIT(nlit);
}
TRACE("sat", display(tout););
}
@ -879,7 +898,7 @@ namespace sat {
push();
for (unsigned i = 0; i < m_assumptions.size(); ++i) {
literal l = m_assumptions[i];
mk_clause(1, &l);
mk_clause_core(1, &l, false);
}
}
}
@ -911,6 +930,12 @@ namespace sat {
\brief Apply all simplifications.
*/
void solver::simplify_problem() {
if (tracking_assumptions()) {
// NB. simplification is disabled when tracking assumptions.
return;
}
SASSERT(scope_lvl() == 0);
m_cleaner();
@ -2110,6 +2135,71 @@ namespace sat {
m_clauses_to_reinit.shrink(j);
}
//
// All new clauses that are added to the solver
// are relative to the user-scope literals.
//
void solver::user_push() {
literal lit;
if (m_user_scope_literal_pool.empty()) {
bool_var new_v = mk_var(true, false);
lit = literal(new_v, false);
}
else {
lit = m_user_scope_literal_pool.back();
m_user_scope_literal_pool.pop_back();
}
m_user_scope_literals.push_back(lit);
}
void solver::gc_lit(clause_vector &clauses, literal lit) {
unsigned j = 0;
for (unsigned i = 0; i < clauses.size(); ++i) {
clause & c = *(clauses[i]);
if (c.contains(lit)) {
dettach_clause(c);
del_clause(c);
}
else {
clauses[j] = &c;
++j;
}
}
clauses.shrink(j);
}
void solver::gc_bin(bool learned, literal nlit) {
m_user_bin_clauses.reset();
collect_bin_clauses(m_user_bin_clauses, learned);
for (unsigned i = 0; i < m_user_bin_clauses.size(); ++i) {
literal l1 = m_user_bin_clauses[i].first;
literal l2 = m_user_bin_clauses[i].second;
if (nlit == l1 || nlit == l2) {
dettach_bin_clause(l1, l2, learned);
}
}
}
void solver::user_pop(unsigned num_scopes) {
pop_to_base_level();
while (num_scopes > 0) {
literal lit = m_user_scope_literals.back();
m_user_scope_literal_pool.push_back(lit);
m_user_scope_literals.pop_back();
gc_lit(m_learned, lit);
gc_lit(m_clauses, lit);
gc_bin(true, lit);
gc_bin(false, lit);
TRACE("sat", tout << "gc: " << lit << "\n"; display(tout););
--num_scopes;
}
}
void solver::pop_to_base_level() {
pop(scope_lvl());
}
// -----------------------
//
// Misc

View file

@ -224,6 +224,7 @@ namespace sat {
if (m_cancel) throw solver_exception(Z3_CANCELED_MSG);
if (memory::get_allocation_size() > m_config.m_max_memory) throw solver_exception(Z3_MAX_MEMORY_MSG);
}
typedef std::pair<literal, literal> bin_clause;
protected:
watch_list & get_wlist(literal l) { return m_watches[l.index()]; }
watch_list const & get_wlist(literal l) const { return m_watches[l.index()]; }
@ -350,13 +351,21 @@ namespace sat {
//
// -----------------------
void push();
public:
void pop(unsigned num_scopes);
protected:
void unassign_vars(unsigned old_sz);
void reinit_clauses(unsigned old_sz);
literal_vector m_user_scope_literals;
literal_vector m_user_scope_literal_pool;
literal_vector m_aux_literals;
svector<bin_clause> m_user_bin_clauses;
void gc_lit(clause_vector& clauses, literal lit);
void gc_bin(bool learned, literal nlit);
public:
void user_push();
void user_pop(unsigned num_scopes);
void pop_to_base_level();
// -----------------------
//
// Simplification
@ -400,7 +409,6 @@ namespace sat {
clause * const * end_clauses() const { return m_clauses.end(); }
clause * const * begin_learned() const { return m_learned.begin(); }
clause * const * end_learned() const { return m_learned.end(); }
typedef std::pair<literal, literal> bin_clause;
void collect_bin_clauses(svector<bin_clause> & r, bool learned) const;
// -----------------------

View file

@ -116,7 +116,7 @@ class sat_tactic : public tactic {
#if 0
IF_VERBOSE(TACTIC_VERBOSITY_LVL, verbose_stream() << "\"formula constains interpreted atoms, recovering formula from sat solver...\"\n";);
#endif
m_solver.pop(m_solver.scope_lvl());
m_solver.pop_to_base_level();
m_sat2goal(m_solver, map, m_params, *(g.get()), mc);
}
g->inc_depth();