z3-z3-4.12.6.src.ast.has_free_vars.cpp Maven / Gradle / Ivy
/*++
Copyright (c) 2006 Microsoft Corporation
Module Name:
has_free_vars.cpp
Abstract:
Author:
Leonardo de Moura (leonardo) 2008-06-23.
Revision History:
--*/
#include "ast/ast.h"
#include "ast/expr_delta_pair.h"
#include "ast/has_free_vars.h"
#include "util/hashtable.h"
class contains_vars::imp {
typedef hashtable, default_eq > cache;
cache m_cache;
svector m_todo;
bool m_contains;
unsigned m_window;
void visit(expr * n, unsigned delta, bool & visited) {
expr_delta_pair e(n, delta);
if (!m_cache.contains(e)) {
m_todo.push_back(e);
visited = false;
}
}
bool visit_children(expr * n, unsigned delta) {
bool visited = true;
unsigned dw;
unsigned j;
switch (n->get_kind()) {
case AST_VAR:
dw = m_window <= UINT_MAX - delta ? m_window + delta : UINT_MAX;
if (to_var(n)->get_idx() >= delta && to_var(n)->get_idx() <= dw)
m_contains = true;
break;
case AST_APP:
j = to_app(n)->get_num_args();
while (j > 0) {
--j;
visit(to_app(n)->get_arg(j), delta, visited);
}
break;
case AST_QUANTIFIER:
if (delta <= UINT_MAX - to_quantifier(n)->get_num_decls()) {
visit(to_quantifier(n)->get_expr(), delta + to_quantifier(n)->get_num_decls(), visited);
}
break;
default:
break;
}
return visited;
}
public:
// 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;
}
};
contains_vars::contains_vars() {
m_imp = alloc(imp);
}
contains_vars::~contains_vars() {
dealloc(m_imp);
}
bool contains_vars::operator()(expr* e) {
return (*m_imp)(e);
}
bool has_free_vars(expr * n) {
contains_vars p;
return p(n);
}