toProcess.push_back(n);
+ // incrementally iterate and add to toProcess
for (unsigned i = 0; i < toProcess.size(); ++i)
{
TNode current = toProcess[i];
- if (current.hasOperator() && current.getOperator() == t)
+ for (unsigned j = 0, j_end = current.getNumChildren(); j <= j_end; ++j)
{
- return true;
- }
- for (unsigned j = 0, j_end = current.getNumChildren(); j < j_end; ++j)
- {
- TNode child = current[j];
+ TNode child;
+ // try children then operator
+ if (j < j_end)
+ {
+ child = current[j];
+ }
+ else if (current.hasOperator())
+ {
+ child = current.getOperator();
+ }
+ else
+ {
+ break;
+ }
if (child == t)
{
return true;
return false;
}
+bool hasSubterm(TNode n, const std::vector<Node>& t, bool strict)
+{
+ if (t.empty())
+ {
+ return false;
+ }
+ if (!strict && std::find(t.begin(), t.end(), n) != t.end())
+ {
+ return true;
+ }
+
+ std::unordered_set<TNode, TNodeHashFunction> visited;
+ std::vector<TNode> toProcess;
+
+ toProcess.push_back(n);
+
+ // incrementally iterate and add to toProcess
+ for (unsigned i = 0; i < toProcess.size(); ++i)
+ {
+ TNode current = toProcess[i];
+ for (unsigned j = 0, j_end = current.getNumChildren(); j <= j_end; ++j)
+ {
+ TNode child;
+ // try children then operator
+ if (j < j_end)
+ {
+ child = current[j];
+ }
+ else if (current.hasOperator())
+ {
+ child = current.getOperator();
+ }
+ else
+ {
+ break;
+ }
+ if (std::find(t.begin(), t.end(), child) != t.end())
+ {
+ return true;
+ }
+ if (visited.find(child) != visited.end())
+ {
+ continue;
+ }
+ else
+ {
+ visited.insert(child);
+ toProcess.push_back(child);
+ }
+ }
+ }
+
+ return false;
+}
+
struct HasBoundVarTag
{
};
*/
bool hasSubtermMulti(TNode n, TNode t);
+/**
+ * Check if the node n has a subterm that occurs in t.
+ * @param n The node to search in
+ * @param t The set of subterms to search for
+ * @param strict If true, a term is not considered to be a subterm of itself
+ * @return true iff there is a term in t that is a subterm in n
+ */
+bool hasSubterm(TNode n, const std::vector<Node>& t, bool strict = false);
+
/**
* Returns true iff the node n contains a bound variable, that is a node of
* kind BOUND_VARIABLE. This bound variable may or may not be free.
Node nretc = children.size()==1 ? children[0] : NodeManager::currentNM()->mkNode( PLUS, children );
nretc = Rewriter::rewrite( nretc );
//ensure that nret does not contain vars
- if( !TermUtil::containsTerms( nretc, vars ) ){
+ if (!expr::hasSubterm(nretc, vars))
+ {
//result is ( nret / pv_prop.d_coeff )
nret = nretc;
}else{
#include "theory/quantifiers/instantiate.h"
+#include "expr/node_algorithm.h"
#include "options/quantifiers_options.h"
#include "smt/smt_statistics_registry.h"
#include "theory/quantifiers/cegqi/inst_strategy_cegqi.h"
<< terms[i] << std::endl;
bad_inst = true;
}
- else if (quantifiers::TermUtil::containsTerms(
- terms[i], d_term_util->d_inst_constants[q]))
+ else if (expr::hasSubterm(terms[i], d_term_util->d_inst_constants[q]))
{
Trace("inst") << "***& inst contains inst constants : " << terms[i]
<< std::endl;
Node newBody = body;
NodeBuilder<> body_split(kind::OR);
NodeBuilder<> tb(kind::OR);
- for( unsigned i=0; i<body.getNumChildren(); i++ ){
- Node trm = body[i];
- if( TermUtil::containsTerms( body[i], args ) ){
+ for (const Node& trm : body)
+ {
+ if (expr::hasSubterm(trm, args))
+ {
tb << trm;
}else{
body_split << trm;
bool TermUtil::containsVtsTerm( Node n, bool isFree ) {
std::vector< Node > t;
getVtsTerms( t, isFree, false );
- return containsTerms( n, t );
+ return expr::hasSubterm(n, t);
}
bool TermUtil::containsVtsTerm( std::vector< Node >& n, bool isFree ) {
std::vector< Node > t;
getVtsTerms( t, isFree, false );
if( !t.empty() ){
- for( unsigned i=0; i<n.size(); i++ ){
- if( containsTerms( n[i], t ) ){
+ for (const Node& nc : n)
+ {
+ if (expr::hasSubterm(nc, t))
+ {
return true;
}
}
bool TermUtil::containsVtsInfinity( Node n, bool isFree ) {
std::vector< Node > t;
getVtsTerms( t, isFree, false, false );
- return containsTerms( n, t );
+ return expr::hasSubterm(n, t);
}
Node TermUtil::ensureType( Node n, TypeNode tn ) {
}
}
-bool TermUtil::containsTerms2( Node n, std::vector< Node >& t, std::map< Node, bool >& visited ) {
- if (visited.find(n) == visited.end())
- {
- if( std::find( t.begin(), t.end(), n )!=t.end() ){
- return true;
- }
- visited[n] = true;
- if (n.hasOperator())
- {
- if (containsTerms2(n.getOperator(), t, visited))
- {
- return true;
- }
- }
- for (const Node& nc : n)
- {
- if (containsTerms2(nc, t, visited))
- {
- return true;
- }
- }
- }
- return false;
-}
-
-bool TermUtil::containsTerms( Node n, std::vector< Node >& t ) {
- if( t.empty() ){
- return false;
- }else{
- std::map< Node, bool > visited;
- return containsTerms2( n, t, visited );
- }
-}
-
int TermUtil::getTermDepth( Node n ) {
if (!n.hasAttribute(TermDepthAttribute()) ){
int maxDepth = -1;
//general utilities
// TODO #1216 : promote these?
private:
- //helper for contains term
- static bool containsTerms2( Node n, std::vector< Node >& t, std::map< Node, bool >& visited );
/** cache for getTypeValue */
std::unordered_map<TypeNode,
std::unordered_map<int, Node>,
d_type_value_offset_status;
public:
- /** simple check for contains term, true if contains at least one term in t */
- static bool containsTerms( Node n, std::vector< Node >& t );
/** contains uninterpreted constant */
static bool containsUninterpretedConstant( Node n );
/** get the term depth of n */