3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00

bug fixes

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2023-12-27 11:29:42 -08:00
parent 9cce1ff836
commit 6103c9d718
9 changed files with 124 additions and 21 deletions

View file

@ -103,7 +103,7 @@ namespace euf {
return mk(e, 0, nullptr);
}
void bv_plugin::merge_eh(enode* x, enode* y) {
void bv_plugin::propagate_merge(enode* x, enode* y) {
if (!bv.is_bv(x->get_expr()))
return;
@ -128,6 +128,35 @@ namespace euf {
propagate_extract(n);
}
void bv_plugin::register_node(enode* n) {
m_queue.push_back(n);
m_trail.push_back(new (get_region()) push_back_vector(m_queue));
push_plugin_undo(bv.get_family_id());
}
void bv_plugin::merge_eh(enode* n1, enode* n2) {
m_queue.push_back(enode_pair(n1, n2));
m_trail.push_back(new (get_region()) push_back_vector(m_queue));
push_plugin_undo(bv.get_family_id());
}
void bv_plugin::propagate() {
if (m_qhead == m_queue.size())
return;
m_trail.push_back(new (get_region()) value_trail(m_qhead));
push_plugin_undo(bv.get_family_id());
for (; m_qhead < m_queue.size(); ++m_qhead) {
if (std::holds_alternative<enode*>(m_queue[m_qhead])) {
auto n = *std::get_if<enode*>(&m_queue[m_qhead]);
propagate_register_node(n);
}
else {
auto [a, b] = *std::get_if<enode_pair>(&m_queue[m_qhead]);
propagate_merge(a, b);
}
}
}
// enforce concat(v1, v2) = v2*2^|v1| + v1
void bv_plugin::propagate_values(enode* x) {
if (!is_value(x))
@ -203,21 +232,32 @@ namespace euf {
}
}
void bv_plugin::push_undo_split(enode* n) {
m_undo_split.push_back(n);
class bv_plugin::undo_split : public trail {
bv_plugin& p;
enode* n;
public:
undo_split(bv_plugin& p, enode* n): p(p), n(n) {}
void undo() override {
auto& i = p.info(n);
i.value = nullptr;
i.lo = nullptr;
i.hi = nullptr;
i.cut = null_cut;
}
};
void bv_plugin::push_undo_split(enode* n) {
m_trail.push_back(new (get_region()) undo_split(*this, n));
push_plugin_undo(bv.get_family_id());
}
void bv_plugin::undo() {
enode* n = m_undo_split.back();
m_undo_split.pop_back();
auto& i = info(n);
i.lo = nullptr;
i.hi = nullptr;
i.cut = null_cut;
m_trail.back()->undo();
m_trail.pop_back();
}
void bv_plugin::register_node(enode* n) {
void bv_plugin::propagate_register_node(enode* n) {
TRACE("bv", tout << "register " << g.bpp(n) << "\n");
auto& i = info(n);
i.value = n;
@ -236,6 +276,7 @@ namespace euf {
push_merge(mk_extract(arg, 0, w - 1), arg);
ensure_slice(arg, lo, hi);
}
TRACE("bv", tout << "done register " << g.bpp(n) << "\n");
}
//
@ -487,10 +528,10 @@ namespace euf {
}
std::ostream& bv_plugin::display(std::ostream& out) const {
out << "bv\n";
out << "bv\n";
for (auto const& i : m_info)
if (i.lo)
out << g.bpp(i.value) << " cut " << i.cut << " lo " << g.bpp(i.lo) << " hi " << g.bpp(i.hi) << "\n";
if (i.lo)
out << g.bpp(i.value) << " cut " << i.cut << " lo " << g.bpp(i.lo) << " hi " << g.bpp(i.hi) << "\n";
return out;
}
}

View file

@ -19,6 +19,7 @@ Author:
#pragma once
#include "util/trail.h"
#include "ast/bv_decl_plugin.h"
#include "ast/euf/euf_plugin.h"
@ -81,8 +82,16 @@ namespace euf {
svector<std::tuple<enode*, unsigned, unsigned>> m_jtodo;
void clear_offsets();
enode_vector m_undo_split;
ptr_vector<trail> m_trail;
class undo_split;
void push_undo_split(enode* n);
vector<std::variant<enode*, enode_pair>> m_queue;
unsigned m_qhead = 0;
void propagate_register_node(enode* n);
void propagate_merge(enode* a, enode* b);
public:
bv_plugin(egraph& g);
@ -97,7 +106,7 @@ namespace euf {
void diseq_eh(enode* eq) override {}
void propagate() override {}
void propagate() override;
void undo() override;

View file

@ -107,7 +107,10 @@ namespace euf {
void egraph::update_children(enode* n) {
for (enode* child : enode_args(n))
child->get_root()->add_parent(n);
for (enode* child : enode_args(n))
SASSERT(child->get_root()->m_parents.back() == n);
m_updates.push_back(update_record(n, update_record::update_children()));
TRACE("euf", tout << "update children " << bpp(n) << "\n"; display(tout));
}
enode* egraph::mk(expr* f, unsigned generation, unsigned num_args, enode *const* args) {
@ -441,7 +444,10 @@ namespace euf {
p.r1->set_relevant(false);
break;
case update_record::tag_t::is_update_children:
TRACE("euf", tout << "reverse update children " << bpp(p.r1) << "\n"; display(tout));
for (unsigned i = 0; i < p.r1->num_args(); ++i) {
CTRACE("euf", (p.r1->m_args[i]->get_root()->m_parents.back() != p.r1),
display(tout << bpp(p.r1->m_args[i]) << " " << bpp(p.r1->m_args[i]->get_root()) << " "););
SASSERT(p.r1->m_args[i]->get_root()->m_parents.back() == p.r1);
p.r1->m_args[i]->get_root()->m_parents.pop_back();
}