mirror of
https://github.com/Z3Prover/z3
synced 2025-06-28 08:58:44 +00:00
NB fix in theory_lra mk_bound
Signed-off-by: Lev Nachmanson <levnach@hotmail.com>
This commit is contained in:
parent
fd1e0e4d80
commit
052814d165
1 changed files with 20 additions and 36 deletions
|
@ -1732,42 +1732,28 @@ public:
|
||||||
// create a bound atom representing term >= k is lower_bound is true, and term <= k if it is false
|
// create a bound atom representing term >= k is lower_bound is true, and term <= k if it is false
|
||||||
app_ref mk_bound(lp::lar_term const& term, rational const& k, bool lower_bound) {
|
app_ref mk_bound(lp::lar_term const& term, rational const& k, bool lower_bound) {
|
||||||
rational offset = k;
|
rational offset = k;
|
||||||
bool is_int = offset.is_int();
|
|
||||||
u_map<rational> coeffs;
|
u_map<rational> coeffs;
|
||||||
term2coeffs(term, coeffs);
|
term2coeffs(term, coeffs);
|
||||||
TRACE("arith",
|
bool is_int = true;
|
||||||
{
|
rational lc = denominator(k);
|
||||||
bool all_ints = true;
|
for (auto const& kv : coeffs) {
|
||||||
lp().print_term(term, tout << "term: ") << "\n";
|
theory_var w = kv.m_key;
|
||||||
for (auto const& kv : coeffs) {
|
expr* o = get_enode(w)->get_owner();
|
||||||
if (kv.m_value.is_int() == false)
|
is_int = a.is_int(o);
|
||||||
all_ints = false;
|
if (!is_int) break;
|
||||||
tout << "v" << kv.m_key << " * " << kv.m_value << "\n";
|
lc = lcm(lc, denominator(kv.m_value));
|
||||||
}
|
|
||||||
tout << offset << "\n";
|
|
||||||
if (all_ints) {
|
|
||||||
rational g(0);
|
|
||||||
for (auto const& kv : coeffs) {
|
|
||||||
g = gcd(g, kv.m_value);
|
|
||||||
}
|
|
||||||
tout << "gcd: " << g << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
bool all_ints = true;
|
|
||||||
if (is_int) {
|
|
||||||
for (auto const& kv : coeffs) {
|
|
||||||
if (kv.m_value.is_int() == false) {
|
|
||||||
all_ints = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_int && all_ints) {
|
// ensure that coefficients are integers when all variables are integers as well.
|
||||||
|
if (is_int && !lc.is_one()) {
|
||||||
|
SASSERT(lc.is_pos());
|
||||||
|
offset *= lc;
|
||||||
|
for (auto& kv : coeffs) kv.m_value *= lc;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_int) {
|
||||||
// 3x + 6y >= 5 -> x + 3y >= 5/3, then x + 3y >= 2
|
// 3x + 6y >= 5 -> x + 3y >= 5/3, then x + 3y >= 2
|
||||||
// 3x + 6y <= 5 -> x + 3y <= 1
|
// 3x + 6y <= 5 -> x + 3y <= 1
|
||||||
|
|
||||||
rational g = gcd_reduce(coeffs);
|
rational g = gcd_reduce(coeffs);
|
||||||
if (!g.is_one()) {
|
if (!g.is_one()) {
|
||||||
if (lower_bound) {
|
if (lower_bound) {
|
||||||
|
@ -1786,11 +1772,9 @@ public:
|
||||||
for (auto& kv : coeffs) kv.m_value.neg();
|
for (auto& kv : coeffs) kv.m_value.neg();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto const& kv : coeffs) {
|
// CTRACE("arith", is_int,
|
||||||
theory_var w = kv.m_key;
|
// lp().print_term(term, tout << "term: ") << "\n";
|
||||||
expr* o = get_enode(w)->get_owner();
|
// tout << "offset: " << offset << " gcd: " << g << "\n";);
|
||||||
is_int &= a.is_int(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
app_ref atom(m);
|
app_ref atom(m);
|
||||||
app_ref t = coeffs2app(coeffs, rational::zero(), is_int);
|
app_ref t = coeffs2app(coeffs, rational::zero(), is_int);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue