mirror of
https://github.com/Z3Prover/z3
synced 2025-04-24 01:25:31 +00:00
adding ack/model
Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
parent
7f0b5bc129
commit
4244ce4aad
31 changed files with 831 additions and 914 deletions
|
@ -255,7 +255,10 @@ namespace euf {
|
|||
explanations up to the least common ancestors.
|
||||
*/
|
||||
void egraph::push_congruence(enode* n1, enode* n2, bool comm) {
|
||||
SASSERT(is_app(n1->get_owner()));
|
||||
SASSERT(n1->get_decl() == n2->get_decl());
|
||||
if (m_used_cc)
|
||||
m_used_cc(to_app(n1->get_owner()), to_app(n2->get_owner()));
|
||||
if (comm &&
|
||||
n1->get_arg(0)->get_root() == n2->get_arg(1)->get_root() &&
|
||||
n1->get_arg(1)->get_root() == n2->get_arg(0)->get_root()) {
|
||||
|
@ -268,30 +271,28 @@ namespace euf {
|
|||
push_lca(n1->get_arg(i), n2->get_arg(i));
|
||||
}
|
||||
|
||||
void egraph::push_lca(enode* a, enode* b) {
|
||||
enode* egraph::find_lca(enode* a, enode* b) {
|
||||
SASSERT(a->get_root() == b->get_root());
|
||||
enode* n = a;
|
||||
while (n) {
|
||||
n->mark2();
|
||||
n = n->m_target;
|
||||
}
|
||||
n = b;
|
||||
while (n) {
|
||||
if (n->is_marked2())
|
||||
n->unmark2();
|
||||
else if (!n->is_marked1())
|
||||
m_todo.push_back(n);
|
||||
n = n->m_target;
|
||||
}
|
||||
n = a;
|
||||
while (n->is_marked2()) {
|
||||
n->unmark2();
|
||||
if (!n->is_marked1())
|
||||
m_todo.push_back(n);
|
||||
a->mark2_targets<true>();
|
||||
while (!b->is_marked2())
|
||||
b = b->m_target;
|
||||
a->mark2_targets<false>();
|
||||
return b;
|
||||
}
|
||||
|
||||
void egraph::push_to_lca(enode* n, enode* lca) {
|
||||
while (n != lca) {
|
||||
m_todo.push_back(n);
|
||||
n = n->m_target;
|
||||
}
|
||||
}
|
||||
|
||||
void egraph::push_lca(enode* a, enode* b) {
|
||||
enode* lca = find_lca(a, b);
|
||||
push_to_lca(a, lca);
|
||||
push_to_lca(b, lca);
|
||||
}
|
||||
|
||||
void egraph::push_todo(enode* n) {
|
||||
while (n) {
|
||||
m_todo.push_back(n);
|
||||
|
@ -313,7 +314,11 @@ namespace euf {
|
|||
void egraph::explain_eq(ptr_vector<T>& justifications, enode* a, enode* b, bool comm) {
|
||||
SASSERT(m_todo.empty());
|
||||
SASSERT(a->get_root() == b->get_root());
|
||||
push_lca(a, b);
|
||||
enode* lca = find_lca(a, b);
|
||||
push_to_lca(a, lca);
|
||||
push_to_lca(b, lca);
|
||||
if (m_used_eq)
|
||||
m_used_eq(a->get_owner(), b->get_owner(), lca->get_owner());
|
||||
explain_todo(justifications);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,7 +70,8 @@ namespace euf {
|
|||
enode_vector m_new_lits;
|
||||
enode_vector m_todo;
|
||||
stats m_stats;
|
||||
|
||||
std::function<void(expr*,expr*,expr*)> m_used_eq;
|
||||
std::function<void(app*,app*)> m_used_cc;
|
||||
|
||||
void push_eq(enode* r1, enode* n1, unsigned r2_num_parents) {
|
||||
m_eqs.push_back(add_eq_record(r1, n1, r2_num_parents));
|
||||
|
@ -87,6 +88,8 @@ namespace euf {
|
|||
void reinsert_equality(enode* p);
|
||||
void update_children(enode* n);
|
||||
void push_lca(enode* a, enode* b);
|
||||
enode* find_lca(enode* a, enode* b);
|
||||
void push_to_lca(enode* a, enode* lca);
|
||||
void push_congruence(enode* n1, enode* n2, bool commutative);
|
||||
void push_todo(enode* n);
|
||||
template <typename T>
|
||||
|
@ -126,6 +129,10 @@ namespace euf {
|
|||
bool inconsistent() const { return m_inconsistent; }
|
||||
enode_vector const& new_eqs() const { return m_new_eqs; }
|
||||
enode_vector const& new_lits() const { return m_new_lits; }
|
||||
|
||||
void set_used_eq(std::function<void(expr*,expr*,expr*)>& used_eq) { m_used_eq = used_eq; }
|
||||
void set_used_cc(std::function<void(app*,app*)>& used_cc) { m_used_cc = used_cc; }
|
||||
|
||||
template <typename T>
|
||||
void explain(ptr_vector<T>& justifications);
|
||||
template <typename T>
|
||||
|
|
|
@ -104,11 +104,29 @@ namespace euf {
|
|||
void mark2() { m_mark2 = true; }
|
||||
void unmark2() { m_mark2 = false; }
|
||||
bool is_marked2() { return m_mark2; }
|
||||
|
||||
template<bool m> void mark1_targets() {
|
||||
enode* n = this;
|
||||
while (n) {
|
||||
if (m) n->mark1(); else n->unmark1();
|
||||
n = n->m_target;
|
||||
}
|
||||
}
|
||||
template<bool m> void mark2_targets() {
|
||||
enode* n = this;
|
||||
while (n) {
|
||||
if (m) n->mark2(); else n->unmark2();
|
||||
n = n->m_target;
|
||||
}
|
||||
}
|
||||
|
||||
void add_parent(enode* p) { m_parents.push_back(p); }
|
||||
unsigned class_size() const { return m_class_size; }
|
||||
bool is_root() const { return m_root == this; }
|
||||
enode* get_root() const { return m_root; }
|
||||
expr* get_owner() const { return m_owner; }
|
||||
unsigned get_owner_id() const { return m_owner->get_id(); }
|
||||
unsigned get_root_id() const { return m_root->m_owner->get_id(); }
|
||||
void inc_class_size(unsigned n) { m_class_size += n; }
|
||||
void dec_class_size(unsigned n) { m_class_size -= n; }
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue