/*++ Copyright (c) 2006 Microsoft Corporation Module Name: num_occurs.cpp Abstract: Author: Leonardo de Moura (leonardo) 2008-01-27. Revision History: --*/ #include "ast/num_occurs.h" void num_occurs::process(expr * t, expr_fast_mark1 & visited) { ptr_buffer stack; #define VISIT(ARG) { \ if (!m_ignore_ref_count1 || ARG->get_ref_count() > 1) { \ m_num_occurs.insert_if_not_there(ARG, 0)++; \ } \ if (!visited.is_marked(ARG)) { \ visited.mark(ARG, true); \ stack.push_back(ARG); \ } \ } VISIT(t); while (!stack.empty()) { expr * t = stack.back(); stack.pop_back(); unsigned j; switch (t->get_kind()) { case AST_APP: j = to_app(t)->get_num_args(); while (j > 0) { --j; expr * arg = to_app(t)->get_arg(j); VISIT(arg); } break; case AST_QUANTIFIER: if (!m_ignore_quantifiers) { expr * child = to_quantifier(t)->get_expr(); VISIT(child); } break; default: break; } } } void num_occurs::validate() { for (auto & kv : m_num_occurs) { VERIFY(0 < kv.m_key->get_ref_count()); } } void num_occurs::operator()(expr * t) { expr_fast_mark1 visited; process(t, visited); } void num_occurs::operator()(unsigned num, expr * const * ts) { expr_fast_mark1 visited; for (unsigned i = 0; i < num; i++) { process(ts[i], visited); } }