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:
parent
b928734348
commit
8814ba0629
12 changed files with 187 additions and 298 deletions
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue