diff --git a/src/math/polysat/forbidden_intervals.cpp b/src/math/polysat/forbidden_intervals.cpp index ff77db9d7..55a32a30f 100644 --- a/src/math/polysat/forbidden_intervals.cpp +++ b/src/math/polysat/forbidden_intervals.cpp @@ -20,10 +20,11 @@ Author: namespace polysat { - /** Precondition: all variables other than v are assigned. + /** * - * \param[out] out_interval The forbidden interval for this constraint - * \param[out] out_neg_cond Negation of the side condition (the side condition is true when the forbidden interval is trivial). May be NULL if the condition is constant. + * \param[in] c Original constraint + * \param[in] v Variable that is bounded by constraint + * \param[out] fi "forbidden interval" record that captures values not allowed for v * \returns True iff a forbidden interval exists and the output parameters were set. */ @@ -55,7 +56,7 @@ namespace polysat { SASSERT(b2.is_val()); // TBD: use fi.coeff = -1 to tell caller to treat it as a diseq_lin. - // record a1, a2, b1, b2 for fast access and add side conditions on b1, b2? + // record a1, a2, b1, b2 for fast access, add non_unit side conditions on b1 = e1, b2 = e2? if (a1 != a2 && !a1.is_zero() && !a2.is_zero()) return false; @@ -224,7 +225,9 @@ namespace polysat { void forbidden_intervals::add_non_unit_side_conds(fi_record& fi, pdd const& b1, pdd const& e1, pdd const& b2, pdd const& e2) { if (fi.coeff == 1) return; - fi.side_cond.push_back(s.eq(b1, e1)); - fi.side_cond.push_back(s.eq(b2, e2)); + if (b1 != e1) + fi.side_cond.push_back(s.eq(b1, e1)); + if (b2 != e2) + fi.side_cond.push_back(s.eq(b2, e2)); } } diff --git a/src/math/polysat/viable.cpp b/src/math/polysat/viable.cpp index ae5f5274a..29dcce50e 100644 --- a/src/math/polysat/viable.cpp +++ b/src/math/polysat/viable.cpp @@ -178,6 +178,10 @@ namespace polysat { return true; } + bool viable::refine_viable(pvar v, rational const& val) { + return refine_equal_lin(v, val) && refine_disequal_lin(v, val); + } + /** * Traverse all interval constraints with coefficients to check whether current value 'val' for * 'v' is feasible. If not, extract a (maximal) interval to block 'v' from being assigned val. @@ -187,7 +191,7 @@ namespace polysat { * be precisely the assigned values. This is to ensure that lo/hi that are computed based on lo_val * and division with coeff are valid. Is there a more relaxed scheme? */ - bool viable::refine_viable(pvar v, rational const& val) { + bool viable::refine_equal_lin(pvar v, rational const& val) { auto* e = m_equal_lin[v]; if (!e) return true; @@ -268,6 +272,14 @@ namespace polysat { return true; } + bool viable::refine_disequal_lin(pvar v, rational const& val) { + auto* e = m_diseq_lin[v]; + if (!e) + return true; + LOG("refine-disequal-lin is TBD"); + return true; + } + bool viable::has_viable(pvar v) { refined: auto* e = m_units[v]; @@ -460,6 +472,7 @@ namespace polysat { while (e != first); // core.set_bailout(); + // TODO - review this; c is true under current assignment? for (auto c : core) { if (c.bvalue(s) == l_false) { core.reset(); @@ -506,6 +519,7 @@ namespace polysat { std::ostream& viable::display(std::ostream& out, pvar v) const { display(out, v, m_units[v]); display(out, v, m_equal_lin[v]); + display(out, v, m_diseq_lin[v]); return out; } diff --git a/src/math/polysat/viable.h b/src/math/polysat/viable.h index d2470c04c..feb01af25 100644 --- a/src/math/polysat/viable.h +++ b/src/math/polysat/viable.h @@ -50,6 +50,10 @@ namespace polysat { bool refine_viable(pvar v, rational const& val); + bool refine_equal_lin(pvar v, rational const& val); + + bool refine_disequal_lin(pvar v, rational const& val); + std::ostream& display(std::ostream& out, pvar v, entry* e) const; void insert(entry* e, pvar v, ptr_vector& entries, entry_kind k); @@ -60,9 +64,9 @@ namespace polysat { ~viable(); // declare and remove var - void push(unsigned) { m_units.push_back(nullptr); m_equal_lin.push_back(nullptr); } + void push(unsigned) { m_units.push_back(nullptr); m_equal_lin.push_back(nullptr); m_diseq_lin.push_back(nullptr); } - void pop() { m_units.pop_back(); m_equal_lin.pop_back(); } + void pop() { m_units.pop_back(); m_equal_lin.pop_back(); m_diseq_lin.pop_back(); } void pop_viable();