3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-24 01:25:31 +00:00

Added decide-callback to user-propagator (#5978)

* Fixed registering expressions in push/pop

* Reused existing function

* Reverted reusing can_propagate

* Added decide-callback to user-propagator

* Refactoring

* Fixed index
This commit is contained in:
Clemens Eisenhofer 2022-04-15 20:07:17 +02:00 committed by GitHub
parent 9ecd4f8406
commit e11496bc65
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 284 additions and 87 deletions

View file

@ -975,6 +975,14 @@ extern "C" {
Z3_CATCH;
}
void Z3_API Z3_solver_propagate_decide(Z3_context c, Z3_solver s, Z3_decide_eh decide_eh) {
Z3_TRY;
RESET_ERROR_CODE();
user_propagator::decide_eh_t c = (void(*)(void*, user_propagator::callback*, expr*&, unsigned&, lbool&))decide_eh;
to_solver_ref(s)->user_propagate_register_decide(c);
Z3_CATCH;
}
Z3_func_decl Z3_API Z3_solver_propagate_declare(Z3_context c, Z3_symbol name, unsigned n, Z3_sort* domain, Z3_sort range) {
Z3_TRY;
LOG_Z3_solver_propagate_declare(c, name, n, domain, range);

View file

@ -3943,11 +3943,13 @@ namespace z3 {
typedef std::function<void(void)> final_eh_t;
typedef std::function<void(expr const&, expr const&)> eq_eh_t;
typedef std::function<void(expr const&)> created_eh_t;
typedef std::function<void(expr&, unsigned&, Z3_lbool&)> decide_eh_t;
final_eh_t m_final_eh;
eq_eh_t m_eq_eh;
fixed_eh_t m_fixed_eh;
created_eh_t m_created_eh;
decide_eh_t m_decide_eh;
solver* s;
context* c;
std::vector<z3::context*> subcontexts;
@ -4009,8 +4011,15 @@ namespace z3 {
expr e(p->ctx(), _e);
p->m_created_eh(e);
}
static void decide_eh(void* _p, Z3_solver_callback cb, Z3_ast& _val, unsigned& bit, Z3_lbool& is_pos) {
user_propagator_base* p = static_cast<user_propagator_base*>(_p);
scoped_cb _cb(p, cb);
expr val(p->ctx(), _val);
p->m_decide_eh(val, bit, is_pos);
_val = val;
}
public:
user_propagator_base(context& c) : s(nullptr), c(&c) {}
@ -4119,6 +4128,22 @@ namespace z3 {
Z3_solver_propagate_created(ctx(), *s, created_eh);
}
}
void register_decide(decide_eh_t& c) {
m_decide_eh = c;
if (s) {
Z3_solver_propagate_decide(ctx(), *s, decide_eh);
}
}
void register_decide() {
m_decide_eh = [this](expr& val, unsigned& bit, Z3_lbool& is_pos) {
decide(val, bit, is_pos);
};
if (s) {
Z3_solver_propagate_decide(ctx(), *s, decide_eh);
}
}
virtual void fixed(expr const& /*id*/, expr const& /*e*/) { }
@ -4127,6 +4152,8 @@ namespace z3 {
virtual void final() { }
virtual void created(expr const& /*e*/) {}
virtual void decide(expr& /*val*/, unsigned& /*bit*/, Z3_lbool& /*is_pos*/) {}
/**
\brief tracks \c e by a unique identifier that is returned by the call.

View file

@ -1444,6 +1444,7 @@ Z3_DECLARE_CLOSURE(Z3_fixed_eh, void, (void* ctx, Z3_solver_callback cb, Z3_as
Z3_DECLARE_CLOSURE(Z3_eq_eh, void, (void* ctx, Z3_solver_callback cb, Z3_ast s, Z3_ast t));
Z3_DECLARE_CLOSURE(Z3_final_eh, void, (void* ctx, Z3_solver_callback cb));
Z3_DECLARE_CLOSURE(Z3_created_eh, void, (void* ctx, Z3_solver_callback cb, Z3_ast t));
Z3_DECLARE_CLOSURE(Z3_decide_eh, void, (void* ctx, Z3_solver_callback cb, Z3_ast&, unsigned&, Z3_lbool&));
/**
@ -6758,6 +6759,14 @@ extern "C" {
* The registered function appears at the top level and is created using \ref Z3_propagate_solver_declare.
*/
void Z3_API Z3_solver_propagate_created(Z3_context c, Z3_solver s, Z3_created_eh created_eh);
/**
* \brief register a callback when a the solver decides to split on a registered expression
* The callback may set passed expression to another registered expression which will be selected instead.
* In case the expression is a bitvector the bit to split on is determined by the bit argument and the
* truth-value to try first is given by is_pos
*/
void Z3_API Z3_solver_propagate_decide(Z3_context c, Z3_solver s, Z3_decide_eh decide_eh);
/**
Create uninterpreted function declaration for the user propagator.