3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-07 01:54:08 +00:00
z3/src/ast/euf/euf_enode.cpp
Nikolaj Bjorner 796e2fd9eb
arrays (#4684)
* arrays

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

* arrays

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

* na

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

* arrays

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

* na

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

* fill

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

* update drat and fix euf bugs

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

* na

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

* na

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

* na

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

* const qualifiers

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

* na

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

* reorg ba

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

* reorg

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

* build warnings

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
2020-09-13 19:29:59 -07:00

117 lines
3 KiB
C++

/*++
Copyright (c) 2020 Microsoft Corporation
Module Name:
euf_enode.cpp
Abstract:
enode layer
Author:
Nikolaj Bjorner (nbjorner) 2020-08-23
--*/
#include "ast/euf/euf_enode.h"
namespace euf {
void enode::invariant() {
unsigned class_size = 0;
bool found_root = false;
bool found_this = false;
for (enode* c : enode_class(this)) {
VERIFY(c->m_root == m_root);
found_root |= c == m_root;
found_this |= c == this;
}
VERIFY(found_root);
VERIFY(found_this);
VERIFY(this != m_root || class_size == m_class_size);
if (is_root()) {
VERIFY(!m_target);
for (enode* p : enode_parents(this)) {
bool found = false;
for (enode* arg : enode_args(p)) {
found |= arg->get_root() == this;
}
VERIFY(found);
}
for (enode* c : enode_class(this)) {
if (c == this)
continue;
for (enode* p : enode_parents(c)) {
bool found = false;
for (enode* q : enode_parents(this)) {
found |= p->congruent(q);
}
VERIFY(found);
}
}
}
}
bool enode::congruent(enode* n) const {
if (get_decl() != n->get_decl())
return false;
if (num_args() != n->num_args())
return false;
SASSERT(!m_commutative || num_args() == 2);
if (m_commutative &&
get_arg(0)->get_root() == n->get_arg(1)->get_root() &&
get_arg(1)->get_root() == n->get_arg(0)->get_root())
return true;
for (unsigned i = num_args(); i-- > 0; )
if (get_arg(i)->get_root() != n->get_arg(i)->get_root())
return false;
return true;
}
bool enode::acyclic() const {
enode const* n = this;
enode const* p = this;
while (n) {
n = n->m_target;
if (n) {
p = p->m_target;
n = n->m_target;
}
if (n == p)
return false;
}
return true;
}
bool enode::reaches(enode* n) const {
enode const* r = this;
SASSERT(acyclic());
while (r) {
if (r == n)
return true;
r = r->m_target;
}
return false;
}
void enode::reverse_justification() {
enode* curr = m_target;
enode* prev = this;
justification js = m_justification;
prev->m_target = nullptr;
prev->m_justification = justification::axiom();
while (curr != nullptr) {
enode* new_curr = curr->m_target;
justification new_js = curr->m_justification;
curr->m_target = prev;
curr->m_justification = js;
prev = curr;
js = new_js;
curr = new_curr;
}
}
}