mirror of
https://github.com/Z3Prover/z3
synced 2025-04-23 17:15:31 +00:00
user propagator over the API
This commit is contained in:
parent
c50e869e5a
commit
4857d60c99
13 changed files with 141 additions and 63 deletions
|
@ -54,6 +54,7 @@ namespace smt {
|
|||
m_qmanager(alloc(quantifier_manager, *this, p, _p)),
|
||||
m_model_generator(alloc(model_generator, m)),
|
||||
m_relevancy_propagator(mk_relevancy_propagator(*this)),
|
||||
m_user_propagator(nullptr),
|
||||
m_random(p.m_random_seed),
|
||||
m_flushing(false),
|
||||
m_lemma_id(0),
|
||||
|
@ -514,6 +515,7 @@ namespace smt {
|
|||
|
||||
m_qmanager->add_eq_eh(r1, r2);
|
||||
|
||||
|
||||
merge_theory_vars(n2, n1, js);
|
||||
|
||||
// 'Proof' tree
|
||||
|
@ -528,7 +530,6 @@ namespace smt {
|
|||
// ---------------
|
||||
// r1 -> .. -> n1 -> n2 -> ... -> r2
|
||||
|
||||
|
||||
remove_parents_from_cg_table(r1);
|
||||
|
||||
enode * curr = r1;
|
||||
|
@ -1304,7 +1305,7 @@ namespace smt {
|
|||
bool_var v = l.var();
|
||||
bool_var_data & d = get_bdata(v);
|
||||
lbool val = get_assignment(v);
|
||||
CTRACE("propagate_atoms", v == 13, tout << "propagating atom, #" << bool_var2expr(v)->get_id() << ", is_enode(): " << d.is_enode()
|
||||
TRACE("propagate_atoms", tout << "propagating atom, #" << bool_var2expr(v)->get_id() << ", is_enode(): " << d.is_enode()
|
||||
<< " tag: " << (d.is_eq()?"eq":"") << (d.is_theory_atom()?"th":"") << (d.is_quantifier()?"q":"") << " " << l << "\n";);
|
||||
SASSERT(val != l_undef);
|
||||
if (d.is_enode())
|
||||
|
@ -1926,8 +1927,6 @@ namespace smt {
|
|||
|
||||
for (theory* t : m_theory_set)
|
||||
t->push_scope_eh();
|
||||
if (m_user_propagator)
|
||||
m_user_propagator->push_scope_eh();
|
||||
CASSERT("context", check_invariant());
|
||||
}
|
||||
|
||||
|
@ -2425,9 +2424,6 @@ namespace smt {
|
|||
for (theory* th : m_theory_set)
|
||||
th->pop_scope_eh(num_scopes);
|
||||
|
||||
if (m_user_propagator)
|
||||
m_user_propagator->pop_scope_eh(num_scopes);
|
||||
|
||||
del_justifications(m_justifications, s.m_justifications_lim);
|
||||
|
||||
m_asserted_formulas.pop_scope(num_scopes);
|
||||
|
@ -2882,11 +2878,13 @@ namespace smt {
|
|||
void* ctx,
|
||||
std::function<void(void*, unsigned, expr*)>& fixed_eh,
|
||||
std::function<void(void*)>& push_eh,
|
||||
std::function<void(void*, unsigned)>& pop_eh) {
|
||||
std::function<void(void*, unsigned)>& pop_eh,
|
||||
std::function<void*(void*)>& fresh_eh) {
|
||||
m_user_propagator = alloc(user_propagator, *this);
|
||||
m_user_propagator->add(ctx, fixed_eh, push_eh, pop_eh);
|
||||
m_user_propagator->add(ctx, fixed_eh, push_eh, pop_eh, fresh_eh);
|
||||
for (unsigned i = m_scopes.size(); i-- > 0; )
|
||||
m_user_propagator->push_scope_eh();
|
||||
register_plugin(m_user_propagator);
|
||||
}
|
||||
|
||||
bool context::watches_fixed(enode* n) const {
|
||||
|
|
|
@ -93,7 +93,7 @@ namespace smt {
|
|||
scoped_ptr<quantifier_manager> m_qmanager;
|
||||
scoped_ptr<model_generator> m_model_generator;
|
||||
scoped_ptr<relevancy_propagator> m_relevancy_propagator;
|
||||
scoped_ptr<user_propagator> m_user_propagator;
|
||||
user_propagator* m_user_propagator;
|
||||
random_gen m_random;
|
||||
bool m_flushing; // (debug support) true when flushing
|
||||
mutable unsigned m_lemma_id;
|
||||
|
@ -1686,7 +1686,8 @@ namespace smt {
|
|||
void* ctx,
|
||||
std::function<void(void*, unsigned, expr*)>& fixed_eh,
|
||||
std::function<void(void*)>& push_eh,
|
||||
std::function<void(void*, unsigned)>& pop_eh);
|
||||
std::function<void(void*, unsigned)>& pop_eh,
|
||||
std::function<void*(void*)>& fresh_eh);
|
||||
|
||||
unsigned user_propagate_register(expr* e) {
|
||||
if (!m_user_propagator)
|
||||
|
|
|
@ -237,8 +237,9 @@ namespace smt {
|
|||
void* ctx,
|
||||
std::function<void(void*, unsigned, expr*)>& fixed_eh,
|
||||
std::function<void(void*)>& push_eh,
|
||||
std::function<void(void*, unsigned)>& pop_eh) {
|
||||
m_kernel.user_propagate_init(ctx, fixed_eh, push_eh, pop_eh);
|
||||
std::function<void(void*, unsigned)>& pop_eh,
|
||||
std::function<void*(void*)>& fresh_eh) {
|
||||
m_kernel.user_propagate_init(ctx, fixed_eh, push_eh, pop_eh, fresh_eh);
|
||||
}
|
||||
|
||||
unsigned user_propagate_register(expr* e) {
|
||||
|
@ -464,8 +465,9 @@ namespace smt {
|
|||
void* ctx,
|
||||
std::function<void(void*, unsigned, expr*)>& fixed_eh,
|
||||
std::function<void(void*)>& push_eh,
|
||||
std::function<void(void*, unsigned)>& pop_eh) {
|
||||
m_imp->user_propagate_init(ctx, fixed_eh, push_eh, pop_eh);
|
||||
std::function<void(void*, unsigned)>& pop_eh,
|
||||
std::function<void*(void*)>& fresh_eh) {
|
||||
m_imp->user_propagate_init(ctx, fixed_eh, push_eh, pop_eh, fresh_eh);
|
||||
}
|
||||
|
||||
unsigned kernel::user_propagate_register(expr* e) {
|
||||
|
|
|
@ -291,7 +291,8 @@ namespace smt {
|
|||
void* ctx,
|
||||
std::function<void(void*, unsigned, expr*)>& fixed_eh,
|
||||
std::function<void(void*)>& push_eh,
|
||||
std::function<void(void*, unsigned)>& pop_eh);
|
||||
std::function<void(void*, unsigned)>& pop_eh,
|
||||
std::function<void*(void*)>& fresh_eh);
|
||||
|
||||
/**
|
||||
\brief register an expression to be tracked fro user propagation.
|
||||
|
|
|
@ -212,8 +212,9 @@ namespace {
|
|||
void* ctx,
|
||||
std::function<void(void*, unsigned, expr*)>& fixed_eh,
|
||||
std::function<void(void*)>& push_eh,
|
||||
std::function<void(void*, unsigned)>& pop_eh) override {
|
||||
m_context.user_propagate_init(ctx, fixed_eh, push_eh, pop_eh);
|
||||
std::function<void(void*, unsigned)>& pop_eh,
|
||||
std::function<void*(void*)>& fresh_eh) override {
|
||||
m_context.user_propagate_init(ctx, fixed_eh, push_eh, pop_eh, fresh_eh);
|
||||
}
|
||||
|
||||
unsigned user_propagate_register(expr* e) override {
|
||||
|
|
|
@ -16,6 +16,7 @@ Author:
|
|||
--*/
|
||||
|
||||
|
||||
#include "ast/ast_pp.h"
|
||||
#include "smt/user_propagator.h"
|
||||
#include "smt/smt_context.h"
|
||||
|
||||
|
@ -23,26 +24,47 @@ using namespace smt;
|
|||
|
||||
user_propagator::user_propagator(context& ctx):
|
||||
theory(ctx, ctx.get_manager().mk_family_id("user_propagator")),
|
||||
m_qhead(0)
|
||||
m_qhead(0),
|
||||
m_num_scopes(0)
|
||||
{}
|
||||
|
||||
void user_propagator::force_push() {
|
||||
for (; m_num_scopes > 0; --m_num_scopes) {
|
||||
theory::push_scope_eh();
|
||||
m_push_eh(m_user_context);
|
||||
m_prop_lim.push_back(m_prop.size());
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: check type of 'e', either Bool or Bit-vector.
|
||||
//
|
||||
|
||||
unsigned user_propagator::add_expr(expr* e) {
|
||||
// TODO: check type of 'e', either Bool or Bit-vector.
|
||||
return mk_var(ensure_enode(e));
|
||||
force_push();
|
||||
enode* n = ensure_enode(e);
|
||||
if (is_attached_to_var(n))
|
||||
return n->get_th_var(get_id());
|
||||
theory_var v = mk_var(n);
|
||||
ctx.attach_th_var(n, this, v);
|
||||
return v;
|
||||
}
|
||||
|
||||
void user_propagator::new_fixed_eh(theory_var v, expr* value, unsigned num_lits, literal const* jlits) {
|
||||
force_push();
|
||||
m_id2justification.setx(v, literal_vector(num_lits, jlits), literal_vector());
|
||||
m_fixed_eh(m_user_context, v, value);
|
||||
}
|
||||
|
||||
void user_propagator::push_scope_eh() {
|
||||
theory::push_scope_eh();
|
||||
m_push_eh(m_user_context);
|
||||
m_prop_lim.push_back(m_prop.size());
|
||||
++m_num_scopes;
|
||||
}
|
||||
|
||||
void user_propagator::pop_scope_eh(unsigned num_scopes) {
|
||||
unsigned n = std::min(num_scopes, m_num_scopes);
|
||||
m_num_scopes -= n;
|
||||
num_scopes -= n;
|
||||
if (num_scopes == 0)
|
||||
return;
|
||||
m_pop_eh(m_user_context, num_scopes);
|
||||
theory::pop_scope_eh(num_scopes);
|
||||
unsigned old_sz = m_prop_lim.size() - num_scopes;
|
||||
|
@ -55,6 +77,7 @@ bool user_propagator::can_propagate() {
|
|||
}
|
||||
|
||||
void user_propagator::propagate() {
|
||||
force_push();
|
||||
unsigned qhead = m_qhead;
|
||||
literal_vector lits;
|
||||
enode_pair_vector eqs;
|
||||
|
|
|
@ -32,6 +32,7 @@ namespace smt {
|
|||
std::function<void(void*, unsigned, expr*)> m_fixed_eh;
|
||||
std::function<void(void*)> m_push_eh;
|
||||
std::function<void(void*, unsigned)> m_pop_eh;
|
||||
std::function<void*(void*)> m_fresh_eh;
|
||||
struct prop_info {
|
||||
unsigned_vector m_ids;
|
||||
expr_ref m_conseq;
|
||||
|
@ -44,6 +45,9 @@ namespace smt {
|
|||
vector<prop_info> m_prop;
|
||||
unsigned_vector m_prop_lim;
|
||||
vector<literal_vector> m_id2justification;
|
||||
unsigned m_num_scopes;
|
||||
|
||||
void force_push();
|
||||
|
||||
public:
|
||||
user_propagator(context& ctx);
|
||||
|
@ -57,11 +61,13 @@ namespace smt {
|
|||
void* ctx,
|
||||
std::function<void(void*, unsigned, expr*)>& fixed_eh,
|
||||
std::function<void(void*)>& push_eh,
|
||||
std::function<void(void*, unsigned)>& pop_eh) {
|
||||
std::function<void(void*, unsigned)>& pop_eh,
|
||||
std::function<void*(void*)>& fresh_eh) {
|
||||
m_user_context = ctx;
|
||||
m_fixed_eh = fixed_eh;
|
||||
m_push_eh = push_eh;
|
||||
m_pop_eh = pop_eh;
|
||||
m_fresh_eh = fresh_eh;
|
||||
}
|
||||
|
||||
unsigned add_expr(expr* e);
|
||||
|
@ -72,16 +78,21 @@ namespace smt {
|
|||
|
||||
void new_fixed_eh(theory_var v, expr* value, unsigned num_lits, literal const* jlits);
|
||||
|
||||
theory * mk_fresh(context * new_ctx) override { UNREACHABLE(); return alloc(user_propagator, *new_ctx); }
|
||||
theory * mk_fresh(context * new_ctx) override {
|
||||
auto* th = alloc(user_propagator, *new_ctx);
|
||||
void* ctx = m_fresh_eh(m_user_context);
|
||||
th->add(ctx, m_fixed_eh, m_push_eh, m_pop_eh, m_fresh_eh);
|
||||
return th;
|
||||
}
|
||||
bool internalize_atom(app * atom, bool gate_ctx) override { UNREACHABLE(); return false; }
|
||||
bool internalize_term(app * term) override { UNREACHABLE(); return false; }
|
||||
void new_eq_eh(theory_var v1, theory_var v2) override { UNREACHABLE(); }
|
||||
void new_diseq_eh(theory_var v1, theory_var v2) override { UNREACHABLE(); }
|
||||
void new_eq_eh(theory_var v1, theory_var v2) override { }
|
||||
void new_diseq_eh(theory_var v1, theory_var v2) override { }
|
||||
bool use_diseqs() const override { return false; }
|
||||
bool build_models() const override { return false; }
|
||||
final_check_status final_check_eh() override { UNREACHABLE(); return FC_DONE; }
|
||||
final_check_status final_check_eh() override { return FC_DONE; }
|
||||
void reset_eh() override {}
|
||||
void assign_eh(bool_var v, bool is_true) override { UNREACHABLE(); }
|
||||
void assign_eh(bool_var v, bool is_true) override { }
|
||||
void init_search_eh() override {}
|
||||
void push_scope_eh() override;
|
||||
void pop_scope_eh(unsigned num_scopes) override;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue