Skip to content

Commit f073da9

Browse files
committed
cleaning up the inner tightening code
Signed-off-by: Lev Nachmanson <[email protected]>
1 parent 8c96178 commit f073da9

File tree

1 file changed

+33
-21
lines changed

1 file changed

+33
-21
lines changed

src/math/lp/dioph_eq.cpp

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1666,10 +1666,11 @@ namespace lp {
16661666
TRACE("dio",
16671667
tout << "current " << (is_upper? "upper":"lower") << " bound for x" << j << ":"
16681668
<< rs << std::endl;);
1669-
rs = (rs - m_c) / g;
1670-
TRACE("dio", tout << "((rs - m_c) / g):" << rs << std::endl;);
1671-
if (!rs.is_int()) {
1672-
if (tighten_bound_kind(g, j, rs, is_upper))
1669+
mpq rs_mod_g = (rs - m_c) % g;
1670+
SASSERT(!rs_mod_g.is_neg() && rs_mod_g.is_int());
1671+
TRACE("dio", tout << "(rs - m_c) % g:" << rs_mod_g << std::endl;);
1672+
if (!rs_mod_g.is_zero()) {
1673+
if (tighten_bound_kind(g, j, rs, rs_mod_g, is_upper))
16731674
return lia_move::conflict;
16741675
} else {
16751676
TRACE("dio", tout << "no improvement in the bound\n";);
@@ -1678,16 +1679,22 @@ namespace lp {
16781679
return lia_move::undef;
16791680
}
16801681

1681-
// returns true only on a conflict
1682-
bool tighten_bound_kind(const mpq& g, unsigned j, const mpq& ub, bool upper) {
1683-
// ub = (upper_bound(j) - m_c)/g.
1684-
// we have xj = t = g*t_+ m_c <= upper_bound(j), then
1685-
// t_ <= floor((upper_bound(j) - m_c)/g) = floor(ub)
1686-
//
1687-
// so xj = g*t_+m_c <= g*floor(ub) + m_c is new upper bound
1688-
// <= can be replaced with >= for lower bounds, with ceil instead of
1689-
// floor
1690-
mpq bound = g * (upper ? floor(ub) : ceil(ub)) + m_c;
1682+
// returns true only on a conflict
1683+
bool tighten_bound_kind(const mpq& g, unsigned j, const mpq& rs, const mpq& rs_mod_g, bool upper) {
1684+
// In case of an upper bound we have
1685+
// xj = t = g*t_+ m_c <= rs, also, by definition fo rs_mod_g, for some integer k holds rs - m_c = k*g + rs_mod_g.
1686+
// Then g*t_ <= rs - mc = k*g + rs_mod_g => g*t_ <= k*g = rs - m_c - rs_mod_g.
1687+
// Adding m_c to both parts gets us
1688+
// xj = g*t_ + m_c <= rs - rs_mod_g
1689+
1690+
// In case of a lower bound we have
1691+
// xj = t = g*t_+ m_c >= rs, also, by definition fo rs_mod_g, for some integer k holds rs - m_c = k*g + rs_mod_g.
1692+
// Then g*t_ >= rs - mc = k*g + rs_mod_g => g*t_ >= k*g = rs - m_c + g - rs_mod_g.
1693+
// Adding m_c to both parts gets us
1694+
// xj = g*t_ + m_c >= rs + g - rs_mod_g
1695+
1696+
1697+
mpq bound = upper ? rs - rs_mod_g : rs + g - rs_mod_g;
16911698
TRACE("dio", tout << "is upper:" << upper << std::endl;
16921699
tout << "new " << (upper ? "upper" : "lower")
16931700
<< " bound:" << bound << std::endl;);
@@ -1696,15 +1703,20 @@ namespace lp {
16961703
(!upper && bound > lra.get_lower_bound(j).x));
16971704
lconstraint_kind kind = upper ? lconstraint_kind::LE : lconstraint_kind::GE;
16981705
u_dependency* dep = upper ? lra.get_column_upper_bound_witness(j) : lra.get_column_lower_bound_witness(j);
1699-
auto rs = open_fixed_from_ml(m_lspace);
1706+
auto fixed_part_of_the_term = open_fixed_from_ml(m_lspace);
17001707
// the right side is off by 1*j from m_espace
17011708
if (is_fixed(j))
1702-
rs.add(mpq(1), j);
1703-
for (const auto& p: rs) {
1704-
SASSERT(is_fixed(p.var()));
1705-
if ((p.coeff() / g).is_int())
1706-
continue; // explain todo!!!
1707-
1709+
fixed_part_of_the_term.add(mpq(1), j);
1710+
for (const auto& p: fixed_part_of_the_term) {
1711+
SASSERT(is_fixed(p.var()));
1712+
if ((p.coeff() % g).is_zero()) {
1713+
// we can skip thise dependency,
1714+
// because the monomial p.coeff()*p.var() is null by modulo g, and it does not matter that p.var() is fixed.
1715+
// We could have added p.coeff()*p.var() to t_, substructed the value of p.coeff()*p.var() from m_c and
1716+
// still get the same result.
1717+
TRACE("dio", tout << "skipped dep:\n"; print_deps(tout, lra.get_bound_constraint_witnesses_for_column(p.var())););
1718+
continue;
1719+
}
17081720
dep = lra.join_deps(dep, lra.get_bound_constraint_witnesses_for_column(p.var()));
17091721
}
17101722
TRACE("dio", tout << "jterm:";

0 commit comments

Comments
 (0)