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:
parent
9cce1ff836
commit
6103c9d718
9 changed files with 124 additions and 21 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue