3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-05-12 02:04:43 +00:00

Propagator (#5845)

* user propagator without ids

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* user propagator without ids

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix signature

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* references #5818

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* fix c++ build

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* switch to vs 2022

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* switch 2022

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Update propagator example (I) (#5835)

* fix #5829

* na

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* switch to vs 2022

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Adapted the example to the changes in the propagator

Co-authored-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* context goes out of scope in stack allocation, so can't used scoped context when passing objects around

* parameter check

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* add rewriter

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>

* Fixed bug in user-propagator "created" (#5843)

Co-authored-by: Clemens Eisenhofer <56730610+CEisenhofer@users.noreply.github.com>
This commit is contained in:
Nikolaj Bjorner 2022-02-17 09:21:41 +02:00 committed by GitHub
parent 2e15e2aa4d
commit 2e00f2f32d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 261 additions and 328 deletions

View file

@ -23,7 +23,8 @@ Author:
using namespace smt;
theory_user_propagator::theory_user_propagator(context& ctx):
theory(ctx, ctx.get_manager().mk_family_id(user_propagator::plugin::name()))
theory(ctx, ctx.get_manager().mk_family_id(user_propagator::plugin::name())),
m_var2expr(ctx.get_manager())
{}
theory_user_propagator::~theory_user_propagator() {
@ -38,9 +39,10 @@ void theory_user_propagator::force_push() {
}
}
unsigned theory_user_propagator::add_expr(expr* e) {
void theory_user_propagator::add_expr(expr* term) {
force_push();
expr_ref r(m);
expr* e = term;
ctx.get_rewriter()(e, r);
if (r != e) {
r = m.mk_fresh_const("aux-expr", e->get_sort());
@ -52,8 +54,14 @@ unsigned theory_user_propagator::add_expr(expr* e) {
}
enode* n = ensure_enode(e);
if (is_attached_to_var(n))
return n->get_th_var(get_id());
return;
theory_var v = mk_var(n);
m_var2expr.reserve(v + 1);
m_var2expr[v] = term;
m_expr2var.setx(term->get_id(), v, null_theory_var);
if (m.is_bool(e) && !ctx.b_internalized(e)) {
bool_var bv = ctx.mk_bool_var(e);
ctx.set_var_theory(bv, get_id());
@ -65,22 +73,24 @@ unsigned theory_user_propagator::add_expr(expr* e) {
literal_vector explain;
if (ctx.is_fixed(n, r, explain))
m_prop.push_back(prop_info(explain, v, r));
return v;
}
void theory_user_propagator::propagate_cb(
unsigned num_fixed, unsigned const* fixed_ids,
unsigned num_eqs, unsigned const* eq_lhs, unsigned const* eq_rhs,
unsigned num_fixed, expr* const* fixed_ids,
unsigned num_eqs, expr* const* eq_lhs, expr* const* eq_rhs,
expr* conseq) {
CTRACE("user_propagate", ctx.lit_internalized(conseq) && ctx.get_assignment(ctx.get_literal(conseq)) == l_true,
ctx.display(tout << "redundant consequence: " << mk_pp(conseq, m) << "\n"));
if (ctx.lit_internalized(conseq) && ctx.get_assignment(ctx.get_literal(conseq)) == l_true)
expr_ref _conseq(conseq, m);
ctx.get_rewriter()(conseq, _conseq);
if (ctx.lit_internalized(_conseq) && ctx.get_assignment(ctx.get_literal(_conseq)) == l_true)
return;
m_prop.push_back(prop_info(num_fixed, fixed_ids, num_eqs, eq_lhs, eq_rhs, expr_ref(conseq, m)));
m_prop.push_back(prop_info(num_fixed, fixed_ids, num_eqs, eq_lhs, eq_rhs, _conseq));
}
unsigned theory_user_propagator::register_cb(expr* e) {
return add_expr(e);
void theory_user_propagator::register_cb(expr* e) {
add_expr(e);
}
theory * theory_user_propagator::mk_fresh(context * new_ctx) {
@ -91,6 +101,7 @@ theory * theory_user_propagator::mk_fresh(context * new_ctx) {
if ((bool)m_final_eh) th->register_final(m_final_eh);
if ((bool)m_eq_eh) th->register_eq(m_eq_eh);
if ((bool)m_diseq_eh) th->register_diseq(m_diseq_eh);
if ((bool)m_created_eh) th->register_created(m_created_eh);
return th;
}
@ -114,7 +125,7 @@ void theory_user_propagator::new_fixed_eh(theory_var v, expr* value, unsigned nu
m_fixed.insert(v);
ctx.push_trail(insert_map<uint_set, unsigned>(m_fixed, v));
m_id2justification.setx(v, literal_vector(num_lits, jlits), literal_vector());
m_fixed_eh(m_user_context, this, v, value);
m_fixed_eh(m_user_context, this, var2expr(v), value);
}
void theory_user_propagator::push_scope_eh() {
@ -142,12 +153,12 @@ void theory_user_propagator::propagate_consequence(prop_info const& prop) {
justification* js;
m_lits.reset();
m_eqs.reset();
for (unsigned id : prop.m_ids)
m_lits.append(m_id2justification[id]);
for (expr* id : prop.m_ids)
m_lits.append(m_id2justification[expr2var(id)]);
for (auto const& p : prop.m_eqs)
m_eqs.push_back(enode_pair(get_enode(p.first), get_enode(p.second)));
m_eqs.push_back(enode_pair(get_enode(expr2var(p.first)), get_enode(expr2var(p.second))));
DEBUG_CODE(for (auto const& p : m_eqs) VERIFY(p.first->get_root() == p.second->get_root()););
DEBUG_CODE(for (unsigned id : prop.m_ids) VERIFY(m_fixed.contains(id)););
DEBUG_CODE(for (expr* e : prop.m_ids) VERIFY(m_fixed.contains(expr2var(e))););
DEBUG_CODE(for (literal lit : m_lits) VERIFY(ctx.get_assignment(lit) == l_true););
TRACE("user_propagate", tout << "propagating #" << prop.m_conseq->get_id() << ": " << prop.m_conseq << "\n");
@ -216,12 +227,12 @@ bool theory_user_propagator::internalize_term(app* term) {
if (term->get_family_id() == get_id() && !ctx.e_internalized(term))
ctx.mk_enode(term, true, false, true);
unsigned v = add_expr(term);
add_expr(term);
if (!m_created_eh && (m_fixed_eh || m_eq_eh || m_diseq_eh))
throw default_exception("You have to register a created event handler for new terms if you track them");
if (!m_created_eh && (m_fixed_eh || m_eq_eh || m_diseq_eh))
return true;
if (m_created_eh)
m_created_eh(m_user_context, this, term, v);
m_created_eh(m_user_context, this, term);
return true;
}