mirror of
https://github.com/Z3Prover/z3
synced 2026-06-19 07:06:28 +00:00
goal2sat: skip caching singly-referenced AST nodes
A node that is referenced only once in the goal can never produce a cache hit: it appears at most once during goal2sat conversion, so its cached entry would never be retrieved. Memoizing it is pure overhead. Guard the cache on the single-reference condition in cache(), get_cached(), and process_cached(). The guard is applied symmetrically to both m_app2lit and m_lit2app so the two maps stay in sync and pop()/uncache() continue to clean up consistently. Also pre-allocate the mk_eq output vector in bit_blaster_tpl with reserve(sz) to avoid incremental reallocations during per-bit expansion. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
parent
f508854fe5
commit
969828b701
2 changed files with 13 additions and 4 deletions
|
|
@ -768,6 +768,8 @@ void bit_blaster_tpl<Cfg>::mk_smod(unsigned sz, expr * const * a_bits, expr * co
|
|||
template<typename Cfg>
|
||||
void bit_blaster_tpl<Cfg>::mk_eq(unsigned sz, expr * const * a_bits, expr * const * b_bits, expr_ref & out) {
|
||||
expr_ref_vector out_bits(m());
|
||||
out_bits.reserve(sz);
|
||||
out_bits.reset();
|
||||
for (unsigned i = 0; i < sz; ++i) {
|
||||
mk_iff(a_bits[i], b_bits[i], out);
|
||||
out_bits.push_back(out);
|
||||
|
|
|
|||
|
|
@ -261,16 +261,23 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
|||
|
||||
void cache(app* t, sat::literal l) override {
|
||||
force_push();
|
||||
m_cache_trail.push_back(t);
|
||||
// Only memoize nodes that can be revisited: a singly-referenced
|
||||
// node appears once in the goal, so it never produces a cache hit.
|
||||
// Skipping it keeps m_app2lit and m_lit2app in sync (both empty for
|
||||
// such nodes) so pop()/uncache() clean up consistently.
|
||||
if (t->get_ref_count() <= 1)
|
||||
return;
|
||||
SASSERT(!m_app2lit.contains(t));
|
||||
SASSERT(!m_lit2app.contains(l.index()));
|
||||
m_app2lit.insert(t, l);
|
||||
m_lit2app.insert(l.index(), t);
|
||||
m_cache_trail.push_back(t);
|
||||
}
|
||||
|
||||
sat::literal get_cached(app* t) const override {
|
||||
sat::literal lit = sat::null_literal;
|
||||
m_app2lit.find(t, lit);
|
||||
if (t->get_ref_count() > 1)
|
||||
m_app2lit.find(t, lit);
|
||||
return lit;
|
||||
}
|
||||
|
||||
|
|
@ -279,7 +286,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
|||
SASSERT(lit == sat::null_literal || l == lit);
|
||||
return l == lit;
|
||||
}
|
||||
|
||||
|
||||
void convert_atom(expr * t, bool root, bool sign) {
|
||||
SASSERT(m.is_bool(t));
|
||||
sat::literal l;
|
||||
|
|
@ -346,7 +353,7 @@ struct goal2sat::imp : public sat::sat_internalizer {
|
|||
|
||||
bool process_cached(app* t, bool root, bool sign) {
|
||||
sat::literal l = sat::null_literal;
|
||||
if (!m_app2lit.find(t, l))
|
||||
if (t->get_ref_count() <= 1 || !m_app2lit.find(t, l))
|
||||
return false;
|
||||
if (sign)
|
||||
l.neg();
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue