mirror of
https://github.com/Z3Prover/z3
synced 2025-04-15 13:28:47 +00:00
Merge branch 'unstable' of https://github.com/Z3Prover/z3 into unstable
This commit is contained in:
commit
8feed01034
|
@ -892,7 +892,6 @@ namespace sat {
|
||||||
if (num_lits == 0 && m_user_scope_literals.empty()) {
|
if (num_lits == 0 && m_user_scope_literals.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
m_replay_lit = null_literal;
|
|
||||||
|
|
||||||
retry_init_assumptions:
|
retry_init_assumptions:
|
||||||
m_assumptions.reset();
|
m_assumptions.reset();
|
||||||
|
@ -923,7 +922,7 @@ namespace sat {
|
||||||
if (m_config.m_optimize_model) {
|
if (m_config.m_optimize_model) {
|
||||||
m_wsls.set_soft(num_lits, lits, weights);
|
m_wsls.set_soft(num_lits, lits, weights);
|
||||||
}
|
}
|
||||||
else if (!init_weighted_assumptions(num_lits, lits, weights, max_weight)) {
|
if (!init_weighted_assumptions(num_lits, lits, weights, max_weight)) {
|
||||||
goto retry_init_assumptions;
|
goto retry_init_assumptions;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
@ -948,55 +947,58 @@ namespace sat {
|
||||||
bool solver::init_weighted_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight) {
|
bool solver::init_weighted_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight) {
|
||||||
double weight = 0;
|
double weight = 0;
|
||||||
literal_vector blocker;
|
literal_vector blocker;
|
||||||
literal_vector min_core;
|
m_min_core_valid = false;
|
||||||
bool min_core_valid = false;
|
m_min_core.reset();
|
||||||
|
unsigned old_sz = 0;
|
||||||
for (unsigned i = 0; !inconsistent() && i < num_lits; ++i) {
|
for (unsigned i = 0; !inconsistent() && i < num_lits; ++i) {
|
||||||
literal lit = lits[i];
|
literal lit = lits[i];
|
||||||
SASSERT(is_external(lit.var()));
|
SASSERT(is_external(lit.var()));
|
||||||
TRACE("sat", tout << "propagate: " << lit << " " << value(lit) << "\n";);
|
TRACE("sat", tout << "propagate: " << lit << " " << value(lit) << "\n";);
|
||||||
SASSERT(m_scope_lvl == 1);
|
SASSERT(m_scope_lvl == 1);
|
||||||
|
|
||||||
if (m_replay_lit == lit && value(lit) == l_undef) {
|
|
||||||
mk_clause(m_replay_clause);
|
|
||||||
propagate(false);
|
|
||||||
SASSERT(inconsistent() || value(lit) == l_false);
|
|
||||||
if (inconsistent()) {
|
|
||||||
IF_VERBOSE(1, verbose_stream() << lit << " cannot be false either\n";);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
IF_VERBOSE(1, verbose_stream() << lit << " set to false\n";);
|
|
||||||
SASSERT(value(lit) == l_false);
|
|
||||||
if (m_replay_clause.size() < min_core.size() || !min_core_valid) {
|
|
||||||
min_core.reset();
|
|
||||||
min_core.append(m_replay_clause);
|
|
||||||
min_core_valid = true;
|
|
||||||
}
|
|
||||||
m_replay_clause.reset();
|
|
||||||
m_replay_lit = null_literal;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
switch(value(lit)) {
|
switch(value(lit)) {
|
||||||
case l_undef:
|
case l_undef:
|
||||||
m_assumption_set.insert(lit);
|
m_assumption_set.insert(lit);
|
||||||
m_assumptions.push_back(lit);
|
m_assumptions.push_back(lit);
|
||||||
|
old_sz = m_qhead;
|
||||||
assign(lit, justification());
|
assign(lit, justification());
|
||||||
propagate(false);
|
propagate(false);
|
||||||
if (inconsistent()) {
|
if (inconsistent()) {
|
||||||
resolve_weighted();
|
resolve_weighted();
|
||||||
m_replay_clause.reset();
|
m_assumption_set.pop();
|
||||||
m_replay_lit = lit;
|
m_assumptions.pop_back();
|
||||||
// next time around, the negation of the literal will be implied.
|
unassign_vars(old_sz);
|
||||||
|
m_inconsistent = false;
|
||||||
|
update_min_core();
|
||||||
|
blocker.reset();
|
||||||
for (unsigned j = 0; j < m_core.size(); ++j) {
|
for (unsigned j = 0; j < m_core.size(); ++j) {
|
||||||
m_replay_clause.push_back(~m_core[j]);
|
blocker.push_back(~m_core[j]);
|
||||||
}
|
}
|
||||||
pop_to_base_level();
|
TRACE("sat", tout << "Blocker: " << blocker << "\n";);
|
||||||
|
mk_clause(blocker);
|
||||||
|
propagate(false);
|
||||||
|
if (inconsistent()) {
|
||||||
|
//
|
||||||
|
// TBD: this could be improved by emulating normal
|
||||||
|
// conflict resolution and backjumping directly and
|
||||||
|
// continuing with the backjumped state instead of
|
||||||
|
// baling out using the best core so far.
|
||||||
|
//
|
||||||
|
resolve_weighted();
|
||||||
|
update_min_core();
|
||||||
|
IF_VERBOSE(1, verbose_stream() << "Conflicting assignment: " << m_core << "\n"
|
||||||
|
<< "Core: " << m_min_core << "\n";);
|
||||||
|
pop_to_base_level();
|
||||||
|
reassert_min_core();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
SASSERT(value(lit) == l_false);
|
||||||
IF_VERBOSE(11,
|
IF_VERBOSE(11,
|
||||||
verbose_stream() << "undef: " << lit << " : " << m_replay_clause << "\n";
|
verbose_stream() << "undef: " << lit << " : " << blocker << "\n";
|
||||||
verbose_stream() << m_assumptions << "\n";);
|
verbose_stream() << m_assumptions << "\n";);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
blocker.push_back(~lit);
|
blocker.push_back(~lit);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case l_false:
|
case l_false:
|
||||||
m_assumption_set.insert(lit);
|
m_assumption_set.insert(lit);
|
||||||
|
@ -1014,49 +1016,60 @@ namespace sat {
|
||||||
IF_VERBOSE(11, verbose_stream() << "small core: " << m_core << "\n";);
|
IF_VERBOSE(11, verbose_stream() << "small core: " << m_core << "\n";);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (weight >= max_weight) {
|
update_min_core();
|
||||||
++m_stats.m_blocked_corr_sets;
|
SASSERT(m_min_core_valid);
|
||||||
TRACE("opt", tout << "blocking soft correction set: " << blocker << "\n";);
|
|
||||||
// block the current correction set candidate.
|
|
||||||
IF_VERBOSE(11, verbose_stream() << "blocking " << blocker << "\n";);
|
|
||||||
pop_to_base_level();
|
|
||||||
mk_clause(blocker);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
VERIFY(m_assumptions.back() == m_assumption_set.pop());
|
VERIFY(m_assumptions.back() == m_assumption_set.pop());
|
||||||
m_assumptions.pop_back();
|
m_assumptions.pop_back();
|
||||||
m_inconsistent = false;
|
m_inconsistent = false;
|
||||||
if (!min_core_valid || m_core.size() < min_core.size()) {
|
if (weight < max_weight) {
|
||||||
min_core.reset();
|
blocker.push_back(lit);
|
||||||
min_core.append(m_core);
|
|
||||||
min_core_valid = true;
|
|
||||||
}
|
}
|
||||||
blocker.push_back(lit);
|
|
||||||
break;
|
break;
|
||||||
case l_true:
|
case l_true:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TRACE("sat", tout << "initialized\n";);
|
TRACE("sat", tout << "initialized\n";);
|
||||||
IF_VERBOSE(11, verbose_stream() << "Blocker: " << blocker << " - " << min_core << "\n";);
|
IF_VERBOSE(11, verbose_stream() << "Blocker: " << blocker << " - " << m_min_core << "\n";);
|
||||||
if (min_core_valid && blocker.size() > min_core.size()) {
|
if (m_min_core_valid && blocker.size() >= m_min_core.size()) {
|
||||||
|
reassert_min_core();
|
||||||
|
}
|
||||||
|
else if (weight > max_weight) {
|
||||||
|
++m_stats.m_blocked_corr_sets;
|
||||||
|
TRACE("opt", tout << "blocking soft correction set: " << blocker << "\n";);
|
||||||
|
// block the current correction set candidate.
|
||||||
|
IF_VERBOSE(11, verbose_stream() << "blocking " << blocker << "\n";);
|
||||||
pop_to_base_level();
|
pop_to_base_level();
|
||||||
push();
|
mk_clause(blocker);
|
||||||
m_assumption_set.reset();
|
return false;
|
||||||
m_assumptions.reset();
|
|
||||||
for (unsigned i = 0; i < min_core.size(); ++i) {
|
|
||||||
literal lit = min_core[i];
|
|
||||||
SASSERT(is_external(lit.var()));
|
|
||||||
m_assumption_set.insert(lit);
|
|
||||||
m_assumptions.push_back(lit);
|
|
||||||
assign(lit, justification());
|
|
||||||
}
|
|
||||||
propagate(false);
|
|
||||||
SASSERT(inconsistent());
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void solver::update_min_core() {
|
||||||
|
if (!m_min_core_valid || m_core.size() < m_min_core.size()) {
|
||||||
|
m_min_core.reset();
|
||||||
|
m_min_core.append(m_core);
|
||||||
|
m_min_core_valid = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void solver::reassert_min_core() {
|
||||||
|
SASSERT(m_min_core_valid);
|
||||||
|
pop_to_base_level();
|
||||||
|
push();
|
||||||
|
m_assumption_set.reset();
|
||||||
|
m_assumptions.reset();
|
||||||
|
for (unsigned i = 0; i < m_min_core.size(); ++i) {
|
||||||
|
literal lit = m_min_core[i];
|
||||||
|
SASSERT(is_external(lit.var()));
|
||||||
|
m_assumption_set.insert(lit);
|
||||||
|
m_assumptions.push_back(lit);
|
||||||
|
assign(lit, justification());
|
||||||
|
}
|
||||||
|
propagate(false);
|
||||||
|
SASSERT(inconsistent());
|
||||||
|
}
|
||||||
|
|
||||||
void solver::reinit_assumptions() {
|
void solver::reinit_assumptions() {
|
||||||
if (tracking_assumptions() && scope_lvl() == 0) {
|
if (tracking_assumptions() && scope_lvl() == 0) {
|
||||||
|
|
|
@ -298,10 +298,12 @@ namespace sat {
|
||||||
lbool bounded_search();
|
lbool bounded_search();
|
||||||
void init_search();
|
void init_search();
|
||||||
|
|
||||||
literal m_replay_lit;
|
literal_vector m_min_core;
|
||||||
literal_vector m_replay_clause;
|
bool m_min_core_valid;
|
||||||
void init_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight);
|
void init_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight);
|
||||||
bool init_weighted_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight);
|
bool init_weighted_assumptions(unsigned num_lits, literal const* lits, double const* weights, double max_weight);
|
||||||
|
void reassert_min_core();
|
||||||
|
void update_min_core();
|
||||||
void resolve_weighted();
|
void resolve_weighted();
|
||||||
void reinit_assumptions();
|
void reinit_assumptions();
|
||||||
bool tracking_assumptions() const;
|
bool tracking_assumptions() const;
|
||||||
|
|
Loading…
Reference in a new issue