3
0
Fork 0
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:
Nikolaj Bjorner 2020-08-18 21:52:52 -07:00
parent c50e869e5a
commit 4857d60c99
13 changed files with 141 additions and 63 deletions

View file

@ -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 {

View file

@ -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)

View file

@ -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) {

View file

@ -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.

View file

@ -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 {

View file

@ -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;

View file

@ -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;