mirror of
https://github.com/Z3Prover/z3
synced 2025-05-09 00:35:47 +00:00
Z3 sources
Signed-off-by: Leonardo de Moura <leonardo@microsoft.com>
This commit is contained in:
parent
3f9edad676
commit
e9eab22e5c
1186 changed files with 381859 additions and 0 deletions
140
lib/shared_occs.cpp
Normal file
140
lib/shared_occs.cpp
Normal file
|
@ -0,0 +1,140 @@
|
|||
/*++
|
||||
Copyright (c) 2011 Microsoft Corporation
|
||||
|
||||
Module Name:
|
||||
|
||||
shared_occs.cpp
|
||||
|
||||
Abstract:
|
||||
|
||||
Functor for computing the shared subterms in a given
|
||||
term.
|
||||
|
||||
Author:
|
||||
|
||||
Leonardo de Moura (leonardo) 2011-04-01.
|
||||
|
||||
Revision History:
|
||||
--*/
|
||||
#include"shared_occs.h"
|
||||
#include"ast_smt2_pp.h"
|
||||
#include"ref_util.h"
|
||||
|
||||
inline void shared_occs::insert(expr * t) {
|
||||
obj_hashtable<expr>::entry * dummy;
|
||||
if (m_shared.insert_if_not_there_core(t, dummy))
|
||||
m.inc_ref(t);
|
||||
}
|
||||
|
||||
void shared_occs::reset() {
|
||||
dec_ref_collection_values(m, m_shared);
|
||||
m_shared.reset();
|
||||
}
|
||||
|
||||
void shared_occs::cleanup() {
|
||||
reset();
|
||||
m_shared.finalize();
|
||||
m_stack.finalize();
|
||||
}
|
||||
|
||||
shared_occs::~shared_occs() {
|
||||
reset();
|
||||
}
|
||||
|
||||
inline bool shared_occs::process(expr * t, shared_occs_mark & visited) {
|
||||
switch (t->get_kind()) {
|
||||
case AST_APP: {
|
||||
unsigned num_args = to_app(t)->get_num_args();
|
||||
if (t->get_ref_count() > 1 && (m_track_atomic || num_args > 0)) {
|
||||
if (visited.is_marked(t)) {
|
||||
insert(t);
|
||||
return true;
|
||||
}
|
||||
visited.mark(t);
|
||||
}
|
||||
if (num_args == 0)
|
||||
return true; // done with t
|
||||
m_stack.push_back(frame(t, 0)); // need to create frame if num_args > 0
|
||||
return false;
|
||||
}
|
||||
case AST_VAR:
|
||||
if (m_track_atomic && t->get_ref_count() > 1) {
|
||||
if (visited.is_marked(t))
|
||||
insert(t);
|
||||
else
|
||||
visited.mark(t);
|
||||
}
|
||||
return true; // done with t
|
||||
case AST_QUANTIFIER:
|
||||
if (t->get_ref_count() > 1) {
|
||||
if (visited.is_marked(t)) {
|
||||
insert(t);
|
||||
return true; // done with t
|
||||
}
|
||||
visited.mark(t);
|
||||
}
|
||||
if (!m_visit_quantifiers)
|
||||
return true;
|
||||
m_stack.push_back(frame(t, 0));
|
||||
return false;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
void shared_occs::operator()(expr * t, shared_occs_mark & visited) {
|
||||
SASSERT(m_stack.empty());
|
||||
if (process(t, visited)) {
|
||||
return;
|
||||
}
|
||||
SASSERT(!m_stack.empty());
|
||||
while (!m_stack.empty()) {
|
||||
start:
|
||||
frame & fr = m_stack.back();
|
||||
expr * curr = fr.first;
|
||||
switch (curr->get_kind()) {
|
||||
case AST_APP: {
|
||||
unsigned num_args = to_app(curr)->get_num_args();
|
||||
while (fr.second < num_args) {
|
||||
expr * arg = to_app(curr)->get_arg(fr.second);
|
||||
fr.second++;
|
||||
if (!process(arg, visited))
|
||||
goto start;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case AST_QUANTIFIER: {
|
||||
SASSERT(m_visit_quantifiers);
|
||||
unsigned num_children = m_visit_patterns ? to_quantifier(curr)->get_num_children() : 1;
|
||||
while (fr.second < num_children) {
|
||||
expr * child = to_quantifier(curr)->get_child(fr.second);
|
||||
fr.second++;
|
||||
if (!process(child, visited))
|
||||
goto start;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
break;
|
||||
}
|
||||
m_stack.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void shared_occs::operator()(expr * t) {
|
||||
SASSERT(m_stack.empty());
|
||||
shared_occs_mark visited;
|
||||
reset();
|
||||
operator()(t, visited);
|
||||
}
|
||||
|
||||
void shared_occs::display(std::ostream & out, ast_manager & m) const {
|
||||
iterator it = begin_shared();
|
||||
iterator end = end_shared();
|
||||
for (; it != end; ++it) {
|
||||
out << mk_ismt2_pp(*it, m) << "\n";
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue