3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-03 11:25:40 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-09-25 17:26:18 -07:00
parent a574eebd05
commit 95e2d174c7
5 changed files with 37 additions and 23 deletions

View file

@ -90,7 +90,7 @@ namespace polysat {
SASSERT(empty()); SASSERT(empty());
m_conflict_var = v; m_conflict_var = v;
for (auto c : s.m_cjust[v]) { for (auto c : s.m_cjust[v]) {
c->set_var_dependent(); c->set_var_dependent(); // ??
insert(c); insert(c);
} }
SASSERT(!empty()); SASSERT(!empty());
@ -104,7 +104,7 @@ namespace polysat {
SASSERT(empty()); SASSERT(empty());
for (auto lit : cl) { for (auto lit : cl) {
auto c = s.lit2cnstr(lit); auto c = s.lit2cnstr(lit);
c->set_var_dependent(); // no c->set_var_dependent();
insert(~c); insert(~c);
} }
SASSERT(!empty()); SASSERT(!empty());

View file

@ -78,8 +78,9 @@ namespace polysat {
// solver handles unsat clauses by creating a conflict. // solver handles unsat clauses by creating a conflict.
// solver also can propagate, but need to check that it does indeed. // solver also can propagate, but need to check that it does indeed.
void constraint_manager::watch(clause& cl, solver& s) { void constraint_manager::watch(clause& cl, solver& s) {
if (cl.size() <= 1) if (cl.empty())
return; return;
bool first = true; bool first = true;
for (unsigned i = 0; i < cl.size(); ++i) { for (unsigned i = 0; i < cl.size(); ++i) {
if (m_bvars.is_false(cl[i])) if (m_bvars.is_false(cl[i]))
@ -93,6 +94,7 @@ namespace polysat {
if (first) if (first)
m_bvars.watch(cl[0]).push_back(&cl); m_bvars.watch(cl[0]).push_back(&cl);
if (cl.size() > 1)
m_bvars.watch(cl[1]).push_back(&cl); m_bvars.watch(cl[1]).push_back(&cl);
if (m_bvars.is_true(cl[0])) if (m_bvars.is_true(cl[0]))
return; return;

View file

@ -137,6 +137,7 @@ namespace polysat {
lbool m_external_sign = l_undef; lbool m_external_sign = l_undef;
bool m_is_marked = false; bool m_is_marked = false;
bool m_is_var_dependent = false; bool m_is_var_dependent = false;
bool m_is_active = false;
/** The boolean variable associated to this constraint, if any. /** The boolean variable associated to this constraint, if any.
* If this is not null_bool_var, then the constraint corresponds to a literal on the assignment stack. * If this is not null_bool_var, then the constraint corresponds to a literal on the assignment stack.
* Convention: the plain constraint corresponds the positive sat::literal. * Convention: the plain constraint corresponds the positive sat::literal.
@ -189,7 +190,10 @@ namespace polysat {
void set_var_dependent() { m_is_var_dependent = true; } void set_var_dependent() { m_is_var_dependent = true; }
void unset_var_dependent() { m_is_var_dependent = false; } void unset_var_dependent() { m_is_var_dependent = false; }
bool is_var_dependent() { return m_is_var_dependent; } bool is_var_dependent() const { return m_is_var_dependent; }
bool is_active() const { return m_is_active; }
void set_active(bool f) { m_is_active = f; }
}; };
inline std::ostream& operator<<(std::ostream& out, constraint const& c) { return c.display(out); } inline std::ostream& operator<<(std::ostream& out, constraint const& c) { return c.display(out); }

View file

@ -161,7 +161,7 @@ namespace polysat {
* Propagate assignment to a Boolean variable * Propagate assignment to a Boolean variable
*/ */
void solver::propagate(sat::literal lit) { void solver::propagate(sat::literal lit) {
LOG_H2("Propagate bool " << lit); LOG_H2("Propagate bool " << lit << "@" << m_bvars.level(lit) << " " << m_level << " qhead: " << m_qhead);
signed_constraint c = lit2cnstr(lit); signed_constraint c = lit2cnstr(lit);
SASSERT(c); SASSERT(c);
activate_constraint(c); activate_constraint(c);
@ -192,22 +192,23 @@ namespace polysat {
bool solver::propagate(sat::literal lit, clause& cl) { bool solver::propagate(sat::literal lit, clause& cl) {
SASSERT(cl.size() >= 2); SASSERT(cl.size() >= 2);
std::cout << lit << ": " << cl << "\n";
unsigned idx = cl[0] == ~lit ? 1 : 0; unsigned idx = cl[0] == ~lit ? 1 : 0;
SASSERT(cl[1 - idx] == ~lit); SASSERT(cl[1 - idx] == ~lit);
if (m_bvars.is_true(cl[idx])) if (m_bvars.is_true(cl[idx]))
return true; return false;
unsigned i = 2; unsigned i = 2;
for (; i < cl.size() && m_bvars.is_false(cl[i]); ++i); for (; i < cl.size() && m_bvars.is_false(cl[i]); ++i);
if (i < cl.size()) { if (i < cl.size()) {
m_bvars.watch(cl[i]).push_back(&cl); m_bvars.watch(cl[i]).push_back(&cl);
std::swap(cl[1 - idx], cl[i]); std::swap(cl[1 - idx], cl[i]);
return false; return true;
} }
if (m_bvars.is_false(cl[idx])) if (m_bvars.is_false(cl[idx]))
set_conflict(cl); set_conflict(cl);
else else
assign_bool(level(cl), cl[idx], &cl, nullptr); assign_bool(level(cl), cl[idx], &cl, nullptr);
return true; return false;
} }
void solver::linear_propagate() { void solver::linear_propagate() {
@ -254,9 +255,6 @@ namespace polysat {
switch (m_trail.back()) { switch (m_trail.back()) {
case trail_instr_t::qhead_i: { case trail_instr_t::qhead_i: {
pop_qhead(); pop_qhead();
for (unsigned i = m_search.size(); i-- > m_qhead; )
if (m_search[i].is_boolean())
deactivate_constraint(lit2cnstr(m_search[i].lit()));
break; break;
} }
case trail_instr_t::add_var_i: { case trail_instr_t::add_var_i: {
@ -282,8 +280,13 @@ namespace polysat {
} }
case trail_instr_t::assign_bool_i: { case trail_instr_t::assign_bool_i: {
sat::literal lit = m_search.back().lit(); sat::literal lit = m_search.back().lit();
signed_constraint c = lit2cnstr(lit);
LOG_V("Undo assign_bool_i: " << lit); LOG_V("Undo assign_bool_i: " << lit);
unsigned active_level = m_bvars.level(lit); unsigned active_level = m_bvars.level(lit);
if (c->is_active())
deactivate_constraint(c);
if (active_level <= target_level) if (active_level <= target_level)
replay.push_back(lit); replay.push_back(lit);
else else
@ -454,8 +457,6 @@ namespace polysat {
revert_decision(v); revert_decision(v);
return; return;
} }
//SASSERT(j.is_propagation());
//resolve_value(v);
} }
else { else {
// Resolve over boolean literal // Resolve over boolean literal
@ -484,12 +485,12 @@ namespace polysat {
return m_conflict.resolve_value(v, m_cjust[v]); return m_conflict.resolve_value(v, m_cjust[v]);
} }
/** Conflict resolution case where boolean literal 'lit' is on top of the stack */ /** Conflict resolution case where boolean literal 'lit' is on top of the stack
* NOTE: boolean resolution should work normally even in bailout mode.
*/
void solver::resolve_bool(sat::literal lit) { void solver::resolve_bool(sat::literal lit) {
sat::bool_var const var = lit.var(); SASSERT(m_bvars.is_propagation(lit.var()));
SASSERT(m_bvars.is_propagation(var)); clause other = *m_bvars.reason(lit.var());
// NOTE: boolean resolution should work normally even in bailout mode.
clause other = *m_bvars.reason(var);
LOG_H3("resolve_bool: " << lit << " " << other); LOG_H3("resolve_bool: " << lit << " " << other);
m_conflict.resolve(m_constraints, lit, other); m_conflict.resolve(m_constraints, lit, other);
} }
@ -635,6 +636,7 @@ namespace polysat {
// - drawback: might have to bail out at boolean resolution // - drawback: might have to bail out at boolean resolution
// Also: maybe we can skip ~L in some cases? but in that case it shouldn't be marked. // Also: maybe we can skip ~L in some cases? but in that case it shouldn't be marked.
// //
std::cout << "ADD extra " << ~lit << "\n";
reason_builder.push(~lit); reason_builder.push(~lit);
} }
clause_ref reason = reason_builder.build(); clause_ref reason = reason_builder.build();
@ -700,6 +702,8 @@ namespace polysat {
SASSERT(c); SASSERT(c);
LOG("Activating constraint: " << c); LOG("Activating constraint: " << c);
SASSERT(m_bvars.value(c.blit()) == l_true); SASSERT(m_bvars.value(c.blit()) == l_true);
SASSERT(!c->is_active());
c->set_active(true);
add_watch(c); add_watch(c);
c.narrow(*this); c.narrow(*this);
#if ENABLE_LINEAR_SOLVER #if ENABLE_LINEAR_SOLVER
@ -709,7 +713,8 @@ namespace polysat {
/// Deactivate constraint /// Deactivate constraint
void solver::deactivate_constraint(signed_constraint c) { void solver::deactivate_constraint(signed_constraint c) {
LOG("Deactivating constraint: " << c); LOG("Deactivating constraint: " << c.blit());
c->set_active(false);
erase_watch(c); erase_watch(c);
} }

View file

@ -1047,6 +1047,9 @@ namespace polysat {
void tst_polysat() { void tst_polysat() {
polysat::test_ineq_basic4();
return;
polysat::test_p3(); polysat::test_p3();
polysat::test_var_minimize(); polysat::test_var_minimize();