diff --git a/src/math/polysat/boolean.cpp b/src/math/polysat/boolean.cpp index 7a9e46a09..695460a18 100644 --- a/src/math/polysat/boolean.cpp +++ b/src/math/polysat/boolean.cpp @@ -40,7 +40,6 @@ namespace polysat { SASSERT_EQ(m_clause[var], nullptr); SASSERT_EQ(m_deps[var], null_dependency); } - m_free_vars.mk_var_eh(var); return var; } @@ -72,6 +71,12 @@ namespace polysat { SASSERT(is_decision(lit)); } + void bool_var_manager::decide(sat::literal lit, unsigned lvl) { + LOG("Decide literal " << lit << " @ " << lvl); + assign(kind_t::decision, lit, lvl, nullptr); + SASSERT(is_decision(lit)); + } + void bool_var_manager::eval(sat::literal lit, unsigned lvl) { LOG("Eval literal " << lit << " @ " << lvl); assign(kind_t::propagation, lit, lvl, nullptr); diff --git a/src/math/polysat/boolean.h b/src/math/polysat/boolean.h index 2ef826779..7a6b7edba 100644 --- a/src/math/polysat/boolean.h +++ b/src/math/polysat/boolean.h @@ -74,6 +74,7 @@ namespace polysat { unsigned_vector& activity() { return m_activity; } bool can_decide() const { return !m_free_vars.empty(); } sat::bool_var next_var() { return m_free_vars.next_var(); } + void track_var(sat::literal lit) { m_free_vars.mk_var_eh(lit.var()); } // TODO connect activity updates with solver void inc_activity(sat::literal lit) { m_activity[lit.var()]++; } @@ -82,6 +83,8 @@ namespace polysat { /// Set the given literal to true void propagate(sat::literal lit, unsigned lvl, clause& reason); void decide(sat::literal lit, unsigned lvl, clause& lemma); + void decide(sat::literal lit, unsigned lvl); + void eval(sat::literal lit, unsigned lvl); void asserted(sat::literal lit, unsigned lvl, dependency dep); void unassign(sat::literal lit); diff --git a/src/math/polysat/solver.cpp b/src/math/polysat/solver.cpp index d057d5a97..44583e735 100644 --- a/src/math/polysat/solver.cpp +++ b/src/math/polysat/solver.cpp @@ -150,20 +150,13 @@ namespace polysat { add_eq(b * q + r - a); add_noovfl(b, q); add_ule(r, b*q+r); - auto c1 = eq(b); - auto c2 = ult(r, b); - auto c3 = diseq(b); - auto c4 = eq(q + 1); - add_clause(c1, c2, false); - add_clause(c3, c4, false); - // BUG: - // need to watch these constraints. - // ... but activation discipline seems to - // work only for lemmas. Literals are watched only when assigned true. - // The literals are de-activated - // after propagation - // Should these clauses then be added as lemmas that force a branch? + auto c_eq = eq(b); + add_clause(c_eq, ult(r, b), false); + add_clause(~c_eq, eq(q + 1), false); + + // force decisions on whether b == 0 + m_bvars.track_var(c_eq.blit()); return std::tuple(q, r); } @@ -449,7 +442,10 @@ namespace polysat { void solver::decide() { LOG_H2("Decide"); SASSERT(can_decide()); - pdecide(m_free_pvars.next_var()); + if (!m_free_pvars.empty()) + pdecide(m_free_pvars.next_var()); + else + bdecide(m_bvars.next_var()); } void solver::pdecide(pvar v) { @@ -472,9 +468,16 @@ namespace polysat { push_level(); assign_core(v, val, justification::decision(m_level)); break; - } + } } + void solver::bdecide(sat::bool_var b) { + sat::literal lit(b); + m_bvars.decide(lit, m_level); + m_trail.push_back(trail_instr_t::assign_bool_i); + m_search.push_boolean(lit); + } + void solver::assign_core(pvar v, rational const& val, justification const& j) { if (j.is_decision()) ++m_stats.m_num_decisions; @@ -766,16 +769,14 @@ namespace polysat { // The lemma where 'lit' comes from. // Currently, boolean decisions always come from guessing a literal of a learned non-unit lemma. clause* lemma = m_bvars.lemma(var); // need to grab this while 'lit' is still assigned - // We only revert decisions that come from lemmas, so lemma must not be NULL here. - // (Externally asserted literals are at a base level, so we would return UNSAT instead of reverting.) - SASSERT(lemma); backjump(m_bvars.level(var) - 1); // reason should force ~lit after propagation add_clause(*reason); - enqueue_decision_on_lemma(*lemma); + if (lemma) + enqueue_decision_on_lemma(*lemma); } unsigned solver::level(sat::literal lit0, clause const& cl) { diff --git a/src/math/polysat/solver.h b/src/math/polysat/solver.h index c98feaf3c..88cb90914 100644 --- a/src/math/polysat/solver.h +++ b/src/math/polysat/solver.h @@ -185,7 +185,7 @@ namespace polysat { void set_conflict(clause& cl) { m_conflict.set(cl); } void set_conflict(pvar v) { m_conflict.set(v); } - bool can_decide() const { return !m_free_pvars.empty(); } + bool can_decide() const { return !m_free_pvars.empty() || m_bvars.can_decide(); } void decide(); void pdecide(pvar v); void bdecide(sat::bool_var b);