// return true if n contains a variable in the range [begin, end] bool operator()(expr * n, unsigned begin = 0, unsigned end = UINT_MAX) { m_contains = false; m_window = end - begin; m_todo.reset(); m_cache.reset(); m_todo.push_back(expr_delta_pair(n, begin)); while (!m_todo.empty()) { expr_delta_pair e = m_todo.back(); if (visit_children(e.m_node, e.m_delta)) { m_cache.insert(e); m_todo.pop_back(); } if (m_contains) { return true; } } SASSERT(!m_contains); return false; }
void used_vars::process(expr * n, unsigned delta) { unsigned j, idx; m_cache.reset(); m_todo.reset(); m_todo.push_back(expr_delta_pair(n, delta)); while (!m_todo.empty()) { expr_delta_pair const & p = m_todo.back(); n = p.m_node; if (n->get_ref_count() > 1 && m_cache.contains(p)) { m_todo.pop_back(); continue; } if (n->get_ref_count() > 1) { // cache only shared and non-constant nodes m_cache.insert(p); } delta = p.m_delta; m_todo.pop_back(); switch (n->get_kind()) { case AST_APP: j = to_app(n)->get_num_args(); while (j > 0) { --j; expr * arg = to_app(n)->get_arg(j); m_todo.push_back(expr_delta_pair(arg, delta)); } break; case AST_VAR: idx = to_var(n)->get_idx(); if (idx >= delta) { idx = idx - delta; if (idx >= m_found_vars.size()) m_found_vars.resize(idx + 1, 0); m_found_vars[idx] = to_var(n)->get_sort(); } break; case AST_QUANTIFIER: // recurse so that memoization is correct with respect to 'delta'. delta += to_quantifier(n)->get_num_decls(); j = to_quantifier(n)->get_num_patterns(); while (j > 0) { --j; m_todo.push_back(expr_delta_pair(to_quantifier(n)->get_pattern(j), delta)); } j = to_quantifier(n)->get_num_no_patterns(); while (j > 0) { --j; m_todo.push_back(expr_delta_pair(to_quantifier(n)->get_no_pattern(j), delta)); } m_todo.push_back(expr_delta_pair(to_quantifier(n)->get_expr(), delta)); break; default: break; } } }