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

testing maxres with sat core

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2014-08-02 12:27:57 -07:00
parent b928734348
commit 8814ba0629
12 changed files with 187 additions and 298 deletions

View file

@ -104,6 +104,7 @@ namespace sat {
m_gc_increment = p.gc_increment();
}
m_minimize_lemmas = p.minimize_lemmas();
m_minimize_core = p.minimize_core();
m_dyn_sub_res = p.dyn_sub_res();
}

View file

@ -68,6 +68,8 @@ namespace sat {
bool m_minimize_lemmas;
bool m_dyn_sub_res;
bool m_minimize_core;
symbol m_always_true;
symbol m_always_false;

View file

@ -15,8 +15,6 @@ Author:
Notes:
Model rotation needs fixes to ensure that hard constraints are satisfied
under pertubed model. Model rotation also has o be consistent with theories.
--*/
@ -32,26 +30,23 @@ namespace sat {
void mus::reset() {
m_core.reset();
m_mus.reset();
m_assumptions.reset();
}
void mus::set_core() {
void mus::set_core() {
m_core.append(m_mus);
s.m_core.reset();
s.m_core.append(m_core);
}
lbool mus::operator()() {
flet<bool> _disable_min(s.m_config.m_minimize_core, false);
TRACE("sat", tout << "old core: " << s.get_core() << "\n";);
IF_VERBOSE(2, verbose_stream() << "(sat.mus " << s.get_core() << ")\n";);
reset();
literal_vector& core = m_core;
literal_vector& mus = m_mus;
literal_vector& assumptions = m_assumptions;
core.append(s.get_core());
SASSERT(!core.empty());
if (core.size() == 1) {
return l_true;
}
while (!core.empty()) {
TRACE("sat",
tout << "core: " << core << "\n";
@ -63,29 +58,38 @@ namespace sat {
}
literal lit = core.back();
core.pop_back();
unsigned sz = assumptions.size();
assumptions.push_back(~lit);
assumptions.append(core);
lbool is_sat = s.check(assumptions.size(), assumptions.c_ptr());
assumptions.resize(sz);
unsigned sz = mus.size();
//mus.push_back(~lit); // TBD: measure
mus.append(core);
lbool is_sat = s.check(mus.size(), mus.c_ptr());
mus.resize(sz);
switch (is_sat) {
case l_undef:
core.push_back(lit);
set_core();
return l_undef;
case l_true: {
assumptions.push_back(lit);
SASSERT(value_at(lit, s.get_model()) == l_false);
mus.push_back(lit);
unsigned sz = core.size();
if (core.empty()) {
break;
}
sz = core.size();
core.append(mus);
rmr();
core.resize(sz);
IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << mus << " " << core << ")\n";);
break;
}
case l_false:
literal_vector const& new_core = s.get_core();
if (new_core.contains(~lit)) {
break;
}
IF_VERBOSE(2, verbose_stream() << "(sat.mus.new " << new_core << ")\n";);
core.reset();
for (unsigned i = 0; i < s.get_core().size(); ++i) {
literal lit = s.get_core()[i];
for (unsigned i = 0; i < new_core.size(); ++i) {
literal lit = new_core[i];
if (!mus.contains(lit)) {
core.push_back(lit);
}
@ -93,22 +97,23 @@ namespace sat {
break;
}
}
TRACE("sat", tout << "new core: " << mus << "\n";);
set_core();
return l_true;
}
lbool mus::eval(literal l) const {
return value_at(l, s.get_model());
}
void mus::rmr() {
model& model = s.m_model;
literal lit = m_mus.back();
literal assumption_lit;
SASSERT(eval(lit) == l_false); // literal is false in current model.
SASSERT(value_at(lit, model) == l_false);
// literal is false in current model.
unsigned sz = m_toswap.size();
find_swappable(lit);
for (unsigned i = 0; i < m_toswap.size(); ++i) {
unsigned sz1 = m_toswap.size();
for (unsigned i = sz; i < sz1; ++i) {
lit = m_toswap[i];
SASSERT(eval(lit) == l_false);
SASSERT(value_at(lit, model) == l_false);
model[lit.var()] = ~model[lit.var()]; // swap assignment
if (has_single_unsat(assumption_lit) && !m_mus.contains(assumption_lit)) {
m_mus.push_back(assumption_lit);
@ -116,6 +121,7 @@ namespace sat {
}
model[lit.var()] = ~model[lit.var()]; // swap assignment back
}
m_toswap.resize(sz);
}
bool mus::has_single_unsat(literal& assumption_lit) {
@ -123,41 +129,50 @@ namespace sat {
return false;
}
//
// lit is false in model.
// find clauses where ~lit occurs, and all other literals
// are false in model.
// for each of the probed literals, determine if swapping the
// assignment falsifies a hard clause, if not, add to m_toswap.
//
void mus::find_swappable(literal lit) {
m_toswap.reset();
IF_VERBOSE(2, verbose_stream() << "(sat.mus swap " << lit << ")\n";);
unsigned sz = m_toswap.size();
literal lit2, lit3;
model const& model = s.get_model();
SASSERT(value_at(lit, model) == l_false);
watch_list const& wlist = s.get_wlist(lit);
watch_list::const_iterator it = wlist.begin();
watch_list::const_iterator end = wlist.end();
for (; it != end; ++it) {
switch (it->get_kind()) {
case watched::BINARY:
lit2 = it->get_literal();
TRACE("sat", tout << ~lit << " " << lit2 << "\n";);
break;
case watched::TERNARY:
lit2 = it->get_literal1();
lit3 = it->get_literal2();
TRACE("sat", tout << ~lit << " " << lit2 << " " << lit3 << "\n";);
break;
case watched::CLAUSE: {
clause_offset cls_off = it->get_clause_offset();
clause& c = *(s.m_cls_allocator.get_clause(cls_off));
if (c.is_learned()) {
break;
}
TRACE("sat", tout << c << "\n";);
break;
}
case watched::EXT_CONSTRAINT:
TRACE("sat", tout << "external constraint - should avoid rmr\n";);
m_toswap.resize(sz);
return;
}
}
}
}
#if 0
bool has_single_unsat(svector<bool> const& model, unsigned& cls_id) const {
cls_id = UINT_MAX;
for (unsigned i = 0; i < m_cls2lits.size(); ++i) {
if (!eval(model, m_cls2lits[i])) {
if (cls_id == UINT_MAX) {
cls_id = i;
}
else {
return false;
}
}
}
TRACE("opt", display_vec(tout << "clause: " << cls_id << " model: ", model););
return cls_id != UINT_MAX;
}
bool eval(svector<bool> const& model, smt::literal_vector const& cls) const {
bool result = false;
for (unsigned i = 0; !result && i < cls.size(); ++i) {
result = (model[cls[i].var()] != cls[i].sign());
}
TRACE("opt", display_vec(tout << "model: ", model);
display_vec(tout << "clause: ", cls);
tout << "result: " << result << "\n";);
return result;
}
#endif

View file

@ -22,7 +22,6 @@ Notes:
namespace sat {
class mus {
literal_vector m_core;
literal_vector m_assumptions;
literal_vector m_mus;
literal_vector m_toswap;
solver& s;
@ -31,12 +30,12 @@ namespace sat {
~mus();
lbool operator()();
private:
lbool mus2();
void rmr();
bool has_single_unsat(literal& assumption_lit);
void find_swappable(literal lit);
void reset();
void set_core();
lbool eval(literal l) const;
};
};

View file

@ -46,8 +46,7 @@ namespace sat {
m_case_split_queue(m_activity),
m_qhead(0),
m_scope_lvl(0),
m_params(p),
m_minimize_core(p.get_bool("minimize_core", false)) {
m_params(p) {
m_config.updt_params(p);
}
@ -1045,7 +1044,7 @@ namespace sat {
}
if (!m_mc.check_model(m))
ok = false;
TRACE("sat", tout << "checl: " << ok << "\n" << m << "\n";);
TRACE("sat", tout << "check: " << ok << "\n" << m << "\n";);
return ok;
}
@ -1621,7 +1620,7 @@ namespace sat {
}
while (idx > 0);
reset_unmark(old_size);
if (m_minimize_core) {
if (m_config.m_minimize_core) {
m_mus(); //ignore return value on cancelation.
}
}
@ -2236,7 +2235,6 @@ namespace sat {
m_probing.updt_params(p);
m_scc.updt_params(p);
m_rand.set_seed(p.get_uint("random_seed", 0));
m_minimize_core = p.get_bool("minimize_core", false);
}
void solver::collect_param_descrs(param_descrs & d) {

View file

@ -123,7 +123,6 @@ namespace sat {
literal_vector m_assumptions;
literal_set m_assumption_set;
literal_vector m_core;
bool m_minimize_core;
void del_clauses(clause * const * begin, clause * const * end);