3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-28 19:35:50 +00:00

tidy, initial polysat

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2021-04-20 12:21:50 -07:00
parent 82bc6474a3
commit fc60690742
8 changed files with 496 additions and 32 deletions

View file

@ -976,17 +976,10 @@ namespace dd {
bddv a_shifted = a;
bddv result = mk_zero(a.size());
for (unsigned i = 0; i < b.size(); ++i) {
#if 1
bddv s = a_shifted;
for (unsigned j = i; j < b.size(); ++j)
s[j] &= b[i];
result = mk_add(result, s);
#else
// From BuDDy's bvec_mul. It seems to compute more intermediate BDDs than the version above?
bddv added = mk_add(result, a_shifted);
for (unsigned j = 0; j < result.size(); ++j)
result[j] = mk_ite(b[i], added[j], result[j]);
#endif
a_shifted.shl();
}
return result;
@ -1014,31 +1007,40 @@ namespace dd {
return mk_mul(a, [b](unsigned i) { return b[i]; });
}
bddv bdd_manager::mk_concat(bddv const& a, bddv const& b) {
bddv result = a;
result.m_bits.append(b.m_bits);
return result;
}
/**
* Quotient remainder
*
* rem, div have size 2*|a| = worksize.
* Initialization:
* rem := a ++ false
* div := false ++ b
*/
void bdd_manager::mk_quot_rem(bddv const& a, bddv const& b, bddv& quot, bddv& rem) {
SASSERT(a.size() == b.size());
quot = mk_zero(a.size());
// We work with double-size vectors
unsigned worksize = a.size() + b.size();
// Extend dividend to worksize
rem = a;
for (unsigned i = b.size(); i-- > 0; )
rem.push_back(mk_false());
// Shift divisor to the left
bddv div(this);
for (unsigned i = a.size(); i-- > 0; )
div.push_back(mk_false());
div.m_bits.append(b.m_bits);
rem = a.append(mk_zero(b.size()));
bddv div = mk_zero(a.size()).append(b);
//
// Keep shifting divisor to the right and subtract whenever it is
// smaller than the remaining value
for (int i = 0; i <= b.size(); ++i) {
//
for (unsigned i = 0; i <= b.size(); ++i) {
bdd divLteRem = div <= rem;
bddv remSubDiv = rem - div;
for (int j = 0; j < worksize; ++j)
for (unsigned j = 0; j < worksize; ++j)
rem[j] = mk_ite(divLteRem, remSubDiv[j], rem[j]);
if (i > 0)
quot[b.size()-i] = divLteRem;
quot[b.size() - i] = divLteRem;
div.shr();
}
@ -1105,14 +1107,14 @@ namespace dd {
void bddv::shl() {
for (unsigned j = size(); j-- > 1;)
m_bits[j] = m_bits[j-1];
m_bits[j] = m_bits[j - 1];
m_bits[0] = m->mk_false();
}
void bddv::shr() {
for (unsigned j = 1; j < size(); ++j)
m_bits[j-1] = m_bits[j];
m_bits[size()-1] = m->mk_false();
m_bits[j - 1] = m_bits[j];
m_bits[size() - 1] = m->mk_false();
}
}

View file

@ -251,6 +251,7 @@ namespace dd {
bddv mk_mul(bddv const& a, bddv const& b);
bddv mk_mul(bddv const& a, bool_vector const& b);
bddv mk_mul(bddv const& a, rational const& val);
bddv mk_concat(bddv const& a, bddv const& b);
void mk_quot_rem(bddv const& a, bddv const& b, bddv& quot, bddv& rem);
bool is_constv(bddv const& a);
rational to_val(bddv const& a);
@ -303,7 +304,7 @@ namespace dd {
vector<bdd> m_bits;
bdd_manager* m;
bddv(vector<bdd> bits, bdd_manager* m): m_bits(bits), m(m) { SASSERT(m); }
bddv(vector<bdd> const& bits, bdd_manager* m): m_bits(bits), m(m) { SASSERT(m); }
bddv(vector<bdd>&& bits, bdd_manager* m): m_bits(std::move(bits)), m(m) { SASSERT(m); }
bddv(bdd_manager* m): m_bits(), m(m) { SASSERT(m); }
@ -347,7 +348,7 @@ namespace dd {
bddv operator*(bddv const& other) const { return m->mk_mul(*this, other); }
bddv operator*(rational const& other) const { return m->mk_mul(*this, other); }
bddv operator*(bool_vector const& other) const { return m->mk_mul(*this, other); }
bddv append(bddv const& other) const { return m->mk_concat(*this, other); }
void quot_rem(bddv const& divisor, bddv& quot, bddv& rem) const { m->mk_quot_rem(*this, divisor, quot, rem); }
bool is_const() const { return m->is_constv(*this); }