mirror of
https://github.com/Z3Prover/z3
synced 2025-11-11 00:22:05 +00:00
132 lines
3.2 KiB
C++
132 lines
3.2 KiB
C++
/*++
|
|
Copyright (c) 2011 Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
reachable_cache.cpp
|
|
|
|
Abstract:
|
|
|
|
Object for caching of reachable states.
|
|
|
|
Author:
|
|
|
|
Krystof Hoder (t-khoder) 2011-9-14.
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#include "muz/pdr/pdr_reachable_cache.h"
|
|
|
|
namespace pdr {
|
|
|
|
reachable_cache::reachable_cache(pdr::manager & pm, datalog::PDR_CACHE_MODE cm)
|
|
: m(pm.get_manager()),
|
|
m_pm(pm),
|
|
m_ctx(nullptr),
|
|
m_ref_holder(m),
|
|
m_disj_connector(m),
|
|
m_cache_mode(cm) {
|
|
if (m_cache_mode == datalog::CONSTRAINT_CACHE) {
|
|
m_ctx = pm.mk_fresh();
|
|
m_ctx->assert_expr(m_pm.get_background());
|
|
}
|
|
}
|
|
|
|
|
|
void reachable_cache::add_disjuncted_formula(expr * f) {
|
|
app_ref new_connector(m.mk_fresh_const("disj_conn", m.mk_bool_sort()), m);
|
|
app_ref neg_new_connector(m.mk_not(new_connector), m);
|
|
app_ref extended_form(m);
|
|
|
|
if(m_disj_connector) {
|
|
extended_form = m.mk_or(m_disj_connector, neg_new_connector, f);
|
|
}
|
|
else {
|
|
extended_form = m.mk_or(neg_new_connector, f);
|
|
}
|
|
if (m_ctx) {
|
|
m_ctx->assert_expr(extended_form);
|
|
}
|
|
|
|
m_disj_connector = new_connector;
|
|
}
|
|
|
|
void reachable_cache::add_reachable(expr * cube) {
|
|
|
|
switch (m_cache_mode) {
|
|
case datalog::NO_CACHE:
|
|
break;
|
|
|
|
case datalog::HASH_CACHE:
|
|
m_stats.m_inserts++;
|
|
m_cache.insert(cube);
|
|
m_ref_holder.push_back(cube);
|
|
break;
|
|
|
|
case datalog::CONSTRAINT_CACHE:
|
|
m_stats.m_inserts++;
|
|
TRACE("pdr", tout << mk_pp(cube, m) << "\n";);
|
|
add_disjuncted_formula(cube);
|
|
break;
|
|
|
|
default:
|
|
UNREACHABLE();
|
|
}
|
|
}
|
|
|
|
bool reachable_cache::is_reachable(expr * cube) {
|
|
bool found = false;
|
|
switch (m_cache_mode) {
|
|
case datalog::NO_CACHE:
|
|
return false;
|
|
|
|
case datalog::HASH_CACHE:
|
|
found = m_cache.contains(cube);
|
|
break;
|
|
|
|
case datalog::CONSTRAINT_CACHE: {
|
|
if(!m_disj_connector) {
|
|
found = false;
|
|
break;
|
|
}
|
|
expr * connector = m_disj_connector.get();
|
|
expr_ref_vector assms(m);
|
|
assms.push_back(connector);
|
|
m_ctx->push();
|
|
m_ctx->assert_expr(cube);
|
|
lbool res = m_ctx->check(assms);
|
|
m_ctx->pop();
|
|
|
|
TRACE("pdr", tout << "is_reachable: " << res << " " << mk_pp(cube, m) << "\n";);
|
|
|
|
found = res == l_true;
|
|
break;
|
|
}
|
|
|
|
default:
|
|
UNREACHABLE();
|
|
break;
|
|
}
|
|
if (found) {
|
|
m_stats.m_hits++;
|
|
}
|
|
else {
|
|
m_stats.m_miss++;
|
|
}
|
|
return found;
|
|
}
|
|
|
|
void reachable_cache::collect_statistics(statistics& st) const {
|
|
st.update("cache inserts", m_stats.m_inserts);
|
|
st.update("cache miss", m_stats.m_miss);
|
|
st.update("cache hits", m_stats.m_hits);
|
|
}
|
|
|
|
void reachable_cache::reset_statistics() {
|
|
m_stats.reset();
|
|
}
|
|
|
|
|
|
}
|