/*++ Copyright (c) 2006 Microsoft Corporation Module Name: for_each_expr.h Abstract: Author: Leonardo de Moura (leonardo) 2007-12-28. Revision History: --*/ #ifndef _FOR_EACH_EXPR_H_ #define _FOR_EACH_EXPR_H_ #include"ast.h" #include"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 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); bool has_skolem_functions(expr * n); #endif /* _FOR_EACH_EXPR_H_ */