diff --git a/src/math/polysat/conflict.cpp b/src/math/polysat/conflict.cpp index 71122353f..410ff5f5a 100644 --- a/src/math/polysat/conflict.cpp +++ b/src/math/polysat/conflict.cpp @@ -211,8 +211,8 @@ namespace polysat { bool conflict::is_valid() const { SASSERT(!empty()); // If m_dep is set, the corresponding constraint was asserted at m_level and is not valid earlier. - if (!m_dep.is_null()) - return m_level <= s.m_level; + if (!m_dep.is_null() && m_level >= s.m_level) + return false; // All conflict constraints must be bool-assigned. for (unsigned lit_idx : m_literals) if (!s.m_bvars.is_assigned(sat::to_literal(lit_idx))) @@ -636,8 +636,8 @@ namespace polysat { if (s.m_bvars.is_assumption(lit)) { // only assumptions have external dependencies dependency const d = s.m_bvars.dep(lit); - if (!d.is_null()) - deps.insert(d.val()); + if (!d.is_null()) + deps.insert(d.val()); } else if (s.m_bvars.is_bool_propagation(lit)) { IF_VERBOSE(11, verbose_stream() << " reason " << *s.m_bvars.reason(lit) << "\n";); diff --git a/src/math/polysat/solver.cpp b/src/math/polysat/solver.cpp index dd60b11f5..70495437a 100644 --- a/src/math/polysat/solver.cpp +++ b/src/math/polysat/solver.cpp @@ -95,10 +95,33 @@ namespace polysat { } lbool solver::unit_propagate() { +#if 1 return l_undef; - // disabled to allow debugging unsoundness for watched literals +#elif 1 + + unsigned level = m_level; + SASSERT(!m_is_solving); + backjump(base_level()); + if (!is_conflict()) + propagate(); + VERIFY(level == m_level); + if (is_conflict()) { + ++m_stats.m_num_conflicts; + return l_false; + } + + return l_undef; +#else flet _max_d(m_config.m_max_conflicts, m_stats.m_num_conflicts + 2); - return check_sat(); + unsigned level = m_level; + lbool r = check_sat(); + if (r != l_false) { + backjump(level); + m_conflict.reset(); + } + SASSERT(level == m_level); + return r; +#endif } dd::pdd_manager& solver::sz2pdd(unsigned sz) const { diff --git a/src/sat/smt/bv_polysat.cpp b/src/sat/smt/bv_polysat.cpp index bda4362af..50161f046 100644 --- a/src/sat/smt/bv_polysat.cpp +++ b/src/sat/smt/bv_polysat.cpp @@ -220,7 +220,7 @@ namespace bv { force_push(); pdd p = var2pdd(v1); pdd q = var2pdd(v2); - auto sc = m_polysat.eq(p, q); + auto sc = m_polysat.eq(p, q); m_var_eqs.setx(m_var_eqs_head, std::make_pair(v1, v2), std::make_pair(v1, v2)); ctx.push(value_trail(m_var_eqs_head)); m_polysat.assign_eh(sc, polysat::dependency(2 * m_var_eqs_head)); @@ -266,11 +266,13 @@ namespace bv { sat::literal_vector core; euf::enode_pair_vector eqs; m_polysat.unsat_core(deps); - for (auto n : deps) { + for (auto n : deps) { if (0 != (n.val() & 1)) core.push_back(sat::to_literal(n.val() / 2)); - else { + else { auto [v1, v2] = m_var_eqs[n.val() / 2]; + VERIFY(var2enode(v1)->get_root() == var2enode(v2)->get_root()); + VERIFY(n.val() <= 2 * m_var_eqs_head); eqs.push_back(euf::enode_pair(var2enode(v1), var2enode(v2))); } }