z3-z3-4.13.0.src.ast.for_each_expr.h Maven / Gradle / Ivy
The newest version!
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
for_each_expr.h
Abstract:
Author:
Leonardo de Moura (leonardo) 2007-12-28.
Revision History:
--*/
#pragma once
#include "ast/ast.h"
#include "util/trace.h"
template
void for_each_expr_core(ForEachProc & proc, ExprMark & visited, expr * n) {
typedef std::pair frame;
if (MarkAll || n->get_ref_count() > 1) {
if (visited.is_marked(n))
return;
visited.mark(n);
}
sbuffer stack;
stack.push_back(frame(n, 0));
while (!stack.empty()) {
start:
frame & fr = stack.back();
expr * curr = fr.first;
switch (curr->get_kind()) {
case AST_VAR:
proc(to_var(curr));
stack.pop_back();
break;
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 (MarkAll || arg->get_ref_count() > 1) {
if (visited.is_marked(arg))
continue;
visited.mark(arg);
}
switch (arg->get_kind()) {
case AST_VAR:
proc(to_var(arg));
break;
case AST_QUANTIFIER:
stack.push_back(frame(arg, 0));
goto start;
case AST_APP:
if (to_app(arg)->get_num_args() == 0) {
proc(to_app(arg));
}
else {
stack.push_back(frame(arg, 0));
goto start;
}
break;
default:
UNREACHABLE();
break;
}
}
stack.pop_back();
proc(to_app(curr));
break;
}
case AST_QUANTIFIER: {
quantifier * q = to_quantifier(curr);
unsigned num_children = IgnorePatterns ? 1 : q->get_num_children();
while (fr.second < num_children) {
expr * child = q->get_child(fr.second);
fr.second++;
if (MarkAll || child->get_ref_count() > 1) {
if (visited.is_marked(child))
continue;
visited.mark(child);
}
stack.push_back(frame(child, 0));
goto start;
}
stack.pop_back();
proc(to_quantifier(curr));
break;
}
default:
UNREACHABLE();
break;
}
}
}
template
bool for_each_expr_args(ptr_vector & stack, expr_mark & visited, unsigned num_args, T * const * args) {
bool result = true;
for (unsigned i = 0; i < num_args; i++) {
T * arg = args[i];
if (!visited.is_marked(arg)) {
stack.push_back(arg);
result = false;
}
}
return result;
}
template
void for_each_expr(ForEachProc & proc, expr_mark & visited, expr * n) {
for_each_expr_core(proc, visited, n);
}
template
void for_each_expr(ForEachProc & proc, expr * n) {
expr_mark visited;
for_each_expr_core(proc, visited, n);
}
template
void for_each_expr(ForEachProc & proc, unsigned n, expr * const* es) {
expr_mark visited;
for (unsigned i = 0; i < n; ++i)
for_each_expr_core(proc, visited, es[i]);
}
template
void for_each_expr(ForEachProc & proc, expr_ref_vector const& es) {
expr_mark visited;
for (expr* e : es)
for_each_expr_core(proc, visited, e);
}
template
void quick_for_each_expr(ForEachProc & proc, expr_fast_mark1 & visited, expr * n) {
for_each_expr_core(proc, visited, n);
}
template
void quick_for_each_expr(ForEachProc & proc, expr * n) {
expr_fast_mark1 visited;
for_each_expr_core(proc, visited, n);
}
template
struct for_each_expr_proc : public EscapeProc {
void operator()(expr * n) { EscapeProc::operator()(n); }
void operator()(var * n) { operator()(static_cast(n)); }
void operator()(app * n) { operator()(static_cast(n)); }
void operator()(quantifier * n) { operator()(static_cast(n)); }
};
unsigned get_num_exprs(expr * n);
unsigned get_num_exprs(expr * n, expr_mark & visited);
unsigned get_num_exprs(expr * n, expr_fast_mark1 & visited);
void get_num_internal_exprs(unsigned_vector& counts, ptr_vector& todo, expr * n);
unsigned count_internal_nodes(unsigned_vector& counts, ptr_vector& todo);
bool has_skolem_functions(expr * n);
// pre-order traversal of subterms
class subterms {
bool m_include_bound = false;
expr_ref_vector m_es;
ptr_vector* m_esp = nullptr;
expr_mark* m_vp = nullptr;
subterms(expr_ref const& e, bool include_bound, ptr_vector* esp, expr_mark* vp);
subterms(expr_ref_vector const& es, bool include_bound, ptr_vector* esp, expr_mark* vp);
public:
~subterms() { if (m_vp) m_vp->reset(); }
class iterator {
bool m_include_bound = false;
ptr_vector m_es;
ptr_vector* m_esp = nullptr;
expr_mark m_visited;
expr_mark* m_visitedp = nullptr;
public:
iterator(subterms const& f, ptr_vector* esp, expr_mark* vp, bool start);
expr* operator*();
iterator operator++(int);
iterator& operator++();
bool operator==(iterator const& other) const;
bool operator!=(iterator const& other) const;
};
static subterms all(expr_ref const& e, ptr_vector* esp = nullptr, expr_mark* vp = nullptr) { return subterms(e, true, esp, vp); }
static subterms ground(expr_ref const& e, ptr_vector* esp = nullptr, expr_mark* vp = nullptr) { return subterms(e, false, esp, vp); }
static subterms all(expr_ref_vector const& e, ptr_vector* esp = nullptr, expr_mark* vp = nullptr) { return subterms(e, true, esp, vp); }
static subterms ground(expr_ref_vector const& e, ptr_vector* esp = nullptr, expr_mark* vp = nullptr) { return subterms(e, false, esp, vp); }
iterator begin() const;
iterator end() const;
};
class subterms_postorder {
bool m_include_bound;
expr_ref_vector m_es;
subterms_postorder(expr_ref_vector const& es, bool include_bound);
subterms_postorder(expr_ref const& e, bool include_bound);
public:
class iterator {
bool m_include_bound = false;
expr_ref_vector m_es;
expr_mark m_visited, m_seen;
void next();
public:
iterator(subterms_postorder& f, bool start);
expr* operator*();
iterator operator++(int);
iterator& operator++();
bool operator==(iterator const& other) const;
bool operator!=(iterator const& other) const;
};
static subterms_postorder all(expr_ref_vector const& es) { return subterms_postorder(es, true); }
static subterms_postorder ground(expr_ref_vector const& es) { return subterms_postorder(es, false); }
static subterms_postorder all(expr_ref const& e) { return subterms_postorder(e, true); }
static subterms_postorder ground(expr_ref const& e) { return subterms_postorder(e, false); }
iterator begin();
iterator end();
};