3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2026-05-31 14:17:47 +00:00
make it recompile constraints with duplicates
This commit is contained in:
Nikolaj Bjorner 2026-02-11 17:38:06 -08:00
parent fb172b67ac
commit ae51cb04ba
3 changed files with 34 additions and 22 deletions

View file

@ -34,6 +34,7 @@ namespace pb {
literal lit() const { return m_lit; } literal lit() const { return m_lit; }
wliteral operator[](unsigned i) const { return m_wlits[i]; } wliteral operator[](unsigned i) const { return m_wlits[i]; }
wliteral& operator[](unsigned i) { return m_wlits[i]; } wliteral& operator[](unsigned i) { return m_wlits[i]; }
wliteral *data() { return m_wlits; }
wliteral const* begin() const { return m_wlits; } wliteral const* begin() const { return m_wlits; }
wliteral const* end() const { return begin() + m_size; } wliteral const* end() const { return begin() + m_size; }

View file

@ -397,19 +397,17 @@ namespace pb {
return l_undef; return l_undef;
} }
void solver::recompile(pbc& p) { std::pair<unsigned, unsigned> solver::normalize(wliteral* begin, wliteral* end, unsigned k) {
// IF_VERBOSE(2, verbose_stream() << "re: " << p << "\n";);
SASSERT(p.num_watch() == 0); SASSERT(p.num_watch() == 0);
m_weights.resize(2*s().num_vars(), 0); m_weights.resize(2 * s().num_vars(), 0);
for (auto [w, lit] : p) { for (auto it = begin; it != end; ++it) {
auto [w, lit] = *it;
m_weights[lit.index()] += w; m_weights[lit.index()] += w;
} }
unsigned k = p.k(); auto j = begin;
unsigned sz = p.size(); unsigned sz = 0;
bool all_units = true; for (auto it = begin; it != end; ++it) {
unsigned j = 0; auto [w, l] = *it;
for (unsigned i = 0; i < sz && 0 < k; ++i) {
auto [w, l] = p[i];
unsigned w1 = m_weights[l.index()]; unsigned w1 = m_weights[l.index()];
unsigned w2 = m_weights[(~l).index()]; unsigned w2 = m_weights[(~l).index()];
if (w1 == 0 || w1 < w2) { if (w1 == 0 || w1 < w2) {
@ -429,18 +427,28 @@ namespace pb {
continue; continue;
} }
else { else {
p[j] = wliteral(w1, l); *j = wliteral(w1, l);
all_units &= w1 == 1;
++j; ++j;
++sz;
} }
} }
} }
sz = j;
// clear weights // clear weights
for (auto [w, lit] : p) { while (begin != end) {
m_weights[lit.index()] = 0; auto [w, l] = *begin;
m_weights[(~lit).index()] = 0; m_weights[l.index()] = 0;
m_weights[(~l).index()] = 0;
++begin;
} }
return {sz, k};
}
void solver::recompile(pbc& p) {
// IF_VERBOSE(2, verbose_stream() << "re: " << p << "\n";);
auto [sz, k] = normalize(p.data(), p.data() + p.size(), p.k());
p.set_size(sz);
auto all_units = all_of(p, [](wliteral const& wl) { return wl.first == 1; });
if (k == 0) { if (k == 0) {
if (p.lit() != sat::null_literal) { if (p.lit() != sat::null_literal) {
@ -464,7 +472,6 @@ namespace pb {
return; return;
} }
else { else {
p.set_size(sz);
p.update_max_sum(); p.update_max_sum();
if (p.max_sum() < k) { if (p.max_sum() < k) {
if (p.lit() == sat::null_literal) { if (p.lit() == sat::null_literal) {
@ -1463,7 +1470,10 @@ namespace pb {
for (auto const&[w, l] : wlits) { for (auto const&[w, l] : wlits) {
auto v = l.var(); auto v = l.var();
if (is_visited(v)) { if (is_visited(v)) {
throw default_exception("malformed constraint: variable appears more than once - is pre-processing disabled?"); svector<wliteral> wlits2(wlits);
auto [sz, k2] = normalize(wlits2.data(), wlits2.data() + wlits2.size(), k);
wlits2.shrink(sz);
return add_pb_ge(lit, wlits2, k2, learned);
} }
mark_visited(v); mark_visited(v);
} }

View file

@ -235,6 +235,7 @@ namespace pb {
void simplify(constraint& p); void simplify(constraint& p);
void simplify2(pbc& p); void simplify2(pbc& p);
bool is_cardinality(pbc const& p); bool is_cardinality(pbc const& p);
std::pair<unsigned, unsigned> normalize(wliteral *begin, wliteral *end, unsigned k);
void flush_roots(pbc& p); void flush_roots(pbc& p);
void recompile(pbc& p); void recompile(pbc& p);
bool clausify(pbc& p); bool clausify(pbc& p);