3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-03 03:15:41 +00:00
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-06-20 12:38:20 -07:00
parent 4fad0385de
commit 19099244c4
5 changed files with 49 additions and 14 deletions

View file

@ -927,7 +927,7 @@ namespace dd {
SASSERT(a.size() == b.size()); SASSERT(a.size() == b.size());
bdd lt = mk_false(); bdd lt = mk_false();
bdd eq = mk_true(); bdd eq = mk_true();
for (unsigned i = a.size(); i-- > 0; ) { for (unsigned i = a.size(); i-- > 0 && !eq.is_false(); ) {
lt |= eq && (!a[i] && b[i]); lt |= eq && (!a[i] && b[i]);
eq &= !(a[i] ^ b[i]); eq &= !(a[i] ^ b[i]);
} }
@ -1179,4 +1179,19 @@ namespace dd {
m_bits[size() - 1] = m->mk_false(); m_bits[size() - 1] = m->mk_false();
} }
bdd bddv::all0() const {
bdd r = m->mk_true();
for (unsigned i = size(); i-- > 0; )
r &= !m_bits[i];
return r;
}
bdd bddv::all1() const {
bdd r = m->mk_true();
for (unsigned i = size(); i-- > 0; )
r &= m_bits[i];
return r;
}
} }

View file

@ -338,6 +338,9 @@ namespace dd {
bdd slt(bddv const& other) const { return m->mk_slt(*this, other); } bdd slt(bddv const& other) const { return m->mk_slt(*this, other); }
bdd sgt(bddv const& other) const { return m->mk_sgt(*this, other); } bdd sgt(bddv const& other) const { return m->mk_sgt(*this, other); }
bdd all0() const;
bdd all1() const;
bdd operator==(bddv const& other) const { return m->mk_eq(*this, other); } bdd operator==(bddv const& other) const { return m->mk_eq(*this, other); }
bdd operator==(rational const& other) const { return m->mk_eq(*this, other); } bdd operator==(rational const& other) const { return m->mk_eq(*this, other); }
bdd operator!=(bddv const& other) const { return !m->mk_eq(*this, other); } bdd operator!=(bddv const& other) const { return !m->mk_eq(*this, other); }

View file

@ -59,20 +59,29 @@ namespace polysat {
if (q.is_unilinear()) { if (q.is_unilinear()) {
// a*x + b == 0 // a*x + b == 0
pvar v = q.var(); pvar v = q.var();
s.push_cjust(v, this);
rational a = q.hi().val(); rational a = q.hi().val();
rational b = q.lo().val(); rational b = q.lo().val();
bddv const& x = s.var2bits(v).var(); bddv const& x = s.var2bits(v).var();
bddv lhs = a * x + b; if (b == 0 && a.is_odd()) {
rational zero = rational::zero(); // hacky test optimizing special case.
bdd xs = is_positive() ? (lhs == zero) : (lhs != zero); // general case is compute inverse(a)*-b for equality 2^k*a*x + b == 0
s.push_cjust(v, this); // then constrain x.
s.intersect_viable(v, xs); //
s.intersect_viable(v, is_positive() ? x.all0() : !x.all0());
}
else {
IF_VERBOSE(10, verbose_stream() << a << "*x + " << b << "\n");
rational val; bddv lhs = a * x + b;
if (s.find_viable(v, val) == dd::find_t::singleton) { bdd xs = is_positive() ? lhs.all0() : !lhs.all0();
s.propagate(v, val, *this); s.intersect_viable(v, xs);
} }
rational val;
if (s.find_viable(v, val) == dd::find_t::singleton)
s.propagate(v, val, *this);
return; return;
} }

View file

@ -188,6 +188,7 @@ namespace polysat {
void del_var(); void del_var();
dd::bdd_manager& get_bdd() { return m_bdd; }
dd::pdd_manager& sz2pdd(unsigned sz); dd::pdd_manager& sz2pdd(unsigned sz);
dd::fdd const& sz2bits(unsigned sz); dd::fdd const& sz2bits(unsigned sz);
dd::fdd const& var2bits(pvar v) { return sz2bits(size(v)); } dd::fdd const& var2bits(pvar v) { return sz2bits(size(v)); }

View file

@ -75,11 +75,18 @@ namespace polysat {
} }
if (v != null_var) { if (v != null_var) {
bddv const& x = s.var2bits(v).var(); bddv const& x = s.var2bits(v).var();
bddv l = a * x + b;
bddv r = c * x + d;
bdd xs = is_positive() ? (l <= r) : (l > r);
s.push_cjust(v, this); s.push_cjust(v, this);
s.intersect_viable(v, xs); // hacky special case
if (a == 1 && b == 0 && c == 0 && d == 0)
// x <= 0
s.intersect_viable(v, is_positive() ? x.all0() : !x.all0());
else {
IF_VERBOSE(10, verbose_stream() << a << "*x + " << b << (is_positive() ? " <= " : " > ") << c << "*x + " << d << "\n");
bddv l = a * x + b;
bddv r = c * x + d;
bdd xs = is_positive() ? (l <= r) : (l > r);
s.intersect_viable(v, xs);
}
rational val; rational val;
if (s.find_viable(v, val) == dd::find_t::singleton) { if (s.find_viable(v, val) == dd::find_t::singleton) {