Move node algorithms to separate file (#2311)
authorAndres Noetzli <andres.noetzli@gmail.com>
Thu, 16 Aug 2018 23:46:05 +0000 (16:46 -0700)
committerAndrew Reynolds <andrew.j.reynolds@gmail.com>
Thu, 16 Aug 2018 23:46:05 +0000 (18:46 -0500)
32 files changed:
src/expr/Makefile.am
src/expr/expr_template.cpp
src/expr/node.cpp
src/expr/node.h
src/expr/node_algorithm.cpp [new file with mode: 0644]
src/expr/node_algorithm.h [new file with mode: 0644]
src/smt/term_formula_removal.cpp
src/theory/arith/arith_static_learner.cpp
src/theory/arith/nonlinear_extension.cpp
src/theory/arith/theory_arith_private.cpp
src/theory/arrays/theory_arrays.cpp
src/theory/booleans/circuit_propagator.cpp
src/theory/builtin/theory_builtin_rewriter.cpp
src/theory/bv/bv_subtheory_algebraic.cpp
src/theory/bv/theory_bv.cpp
src/theory/bv/theory_bv_rewrite_rules_normalization.h
src/theory/quantifiers/cegqi/ceg_arith_instantiator.cpp
src/theory/quantifiers/cegqi/ceg_dt_instantiator.cpp
src/theory/quantifiers/cegqi/ceg_epr_instantiator.cpp
src/theory/quantifiers/cegqi/ceg_instantiator.cpp
src/theory/quantifiers/cegqi/inst_strategy_cbqi.cpp
src/theory/quantifiers/ematching/trigger.cpp
src/theory/quantifiers/fmf/bounded_integers.cpp
src/theory/quantifiers/quant_conflict_find.cpp
src/theory/quantifiers/quantifiers_rewriter.cpp
src/theory/quantifiers/sygus/ce_guided_single_inv.cpp
src/theory/quantifiers/sygus/ce_guided_single_inv_sol.cpp
src/theory/quantifiers/term_util.cpp
src/theory/sets/theory_sets_private.cpp
src/theory/substitutions.cpp
src/theory/theory.cpp
src/theory/theory_engine.cpp

index bf4ad9acdc57ec8eb77b836eb429815bce001613..f8f9dbd118a085a11da521e4bfaa9c6c7a5e6a67 100644 (file)
@@ -37,6 +37,8 @@ libexpr_la_SOURCES = \
        matcher.h \
        node.cpp \
        node.h \
+       node_algorithm.cpp \
+       node_algorithm.h \
        node_builder.h \
        node_manager.cpp \
        node_manager.h \
index 3a0d31b2d7d85c145e6dbd0d35f22566ce610dc3..3c867e4428515d41127a7758b27ed5b4d75fa3ba 100644 (file)
 #include <vector>
 
 #include "base/cvc4_assert.h"
-#include "expr/node.h"
 #include "expr/expr_manager_scope.h"
-#include "expr/variable_type_map.h"
+#include "expr/node.h"
+#include "expr/node_algorithm.h"
 #include "expr/node_manager_attributes.h"
+#include "expr/variable_type_map.h"
 
 ${includes}
 
@@ -537,7 +538,7 @@ bool Expr::hasFreeVariable() const
 {
   ExprManagerScope ems(*this);
   Assert(d_node != NULL, "Unexpected NULL expression pointer!");
-  return d_node->hasFreeVar();
+  return expr::hasFreeVar(*d_node);
 }
 
 void Expr::toStream(std::ostream& out, int depth, bool types, size_t dag,
index fdb1e4d9001cd03ac3da41551f095da4234c048c..b983c81f5cf8f4041e91d7afeca6d99cc814ddd0 100644 (file)
@@ -73,13 +73,8 @@ UnknownTypeException::UnknownTypeException(TNode n)
 /** Is this node constant? (and has that been computed yet?) */
 struct IsConstTag { };
 struct IsConstComputedTag { };
-struct HasBoundVarTag { };
-struct HasBoundVarComputedTag { };
 typedef expr::Attribute<IsConstTag, bool> IsConstAttr;
 typedef expr::Attribute<IsConstComputedTag, bool> IsConstComputedAttr;
-/** Attribute true for expressions with bound variables in them */
-typedef expr::Attribute<HasBoundVarTag, bool> HasBoundVarAttr;
-typedef expr::Attribute<HasBoundVarComputedTag, bool> HasBoundVarComputedAttr;
 
 template <bool ref_count>
 bool NodeTemplate<ref_count>::isConst() const {
@@ -114,100 +109,7 @@ bool NodeTemplate<ref_count>::isConst() const {
   }
 }
 
-template <bool ref_count>
-bool NodeTemplate<ref_count>::hasBoundVar() {
-  assertTNodeNotExpired();
-  if(! getAttribute(HasBoundVarComputedAttr())) {
-    bool hasBv = false;
-    if(getKind() == kind::BOUND_VARIABLE) {
-      hasBv = true;
-    } else {
-      for(iterator i = begin(); i != end() && !hasBv; ++i) {
-        hasBv = (*i).hasBoundVar();
-      }
-    }
-    if (!hasBv && hasOperator()) {
-      hasBv = getOperator().hasBoundVar();
-    }
-    setAttribute(HasBoundVarAttr(), hasBv);
-    setAttribute(HasBoundVarComputedAttr(), true);
-    Debug("bva") << *this << " has bva : " << getAttribute(HasBoundVarAttr()) << std::endl;
-    return hasBv;
-  }
-  return getAttribute(HasBoundVarAttr());
-}
-
-template <bool ref_count>
-bool NodeTemplate<ref_count>::hasFreeVar()
-{
-  assertTNodeNotExpired();
-  std::unordered_set<TNode, TNodeHashFunction> bound_var;
-  std::unordered_map<TNode, bool, TNodeHashFunction> visited;
-  std::vector<TNode> visit;
-  TNode cur;
-  visit.push_back(*this);
-  do
-  {
-    cur = visit.back();
-    visit.pop_back();
-    // can skip if it doesn't have a bound variable
-    if (!cur.hasBoundVar())
-    {
-      continue;
-    }
-    Kind k = cur.getKind();
-    bool isQuant = k == kind::FORALL || k == kind::EXISTS || k == kind::LAMBDA
-                   || k == kind::CHOICE;
-    std::unordered_map<TNode, bool, TNodeHashFunction>::iterator itv =
-        visited.find(cur);
-    if (itv == visited.end())
-    {
-      if (k == kind::BOUND_VARIABLE)
-      {
-        if (bound_var.find(cur) == bound_var.end())
-        {
-          return true;
-        }
-      }
-      else if (isQuant)
-      {
-        for (const TNode& cn : cur[0])
-        {
-          // should not shadow
-          Assert(bound_var.find(cn) == bound_var.end());
-          bound_var.insert(cn);
-        }
-        visit.push_back(cur);
-      }
-      // must visit quantifiers again to clean up below
-      visited[cur] = !isQuant;
-      if (cur.hasOperator())
-      {
-        visit.push_back(cur.getOperator());
-      }
-      for (const TNode& cn : cur)
-      {
-        visit.push_back(cn);
-      }
-    }
-    else if (!itv->second)
-    {
-      Assert(isQuant);
-      for (const TNode& cn : cur[0])
-      {
-        bound_var.erase(cn);
-      }
-      visited[cur] = true;
-    }
-  } while (!visit.empty());
-  return false;
-}
-
 template bool NodeTemplate<true>::isConst() const;
 template bool NodeTemplate<false>::isConst() const;
-template bool NodeTemplate<true>::hasBoundVar();
-template bool NodeTemplate<false>::hasBoundVar();
-template bool NodeTemplate<true>::hasFreeVar();
-template bool NodeTemplate<false>::hasFreeVar();
 
 }/* CVC4 namespace */
index 92794ffe260edd8987a2da86fa62b9d17012f6b1..4b12c7ece054537d440381aabc08a00aa3f4a8cc 100644 (file)
@@ -428,18 +428,6 @@ public:
   // bool containsDecision(); // is "atomic"
   // bool properlyContainsDecision(); // maybe not atomic but all children are
 
-  /**
-   * Returns true iff this node contains a bound variable.  This bound
-   * variable may or may not be free.
-   * @return true iff this node contains a bound variable.
-   */
-  bool hasBoundVar();
-
-  /**
-   * Returns true iff this node contains a free variable.
-   * @return true iff this node contains a free variable.
-   */
-  bool hasFreeVar();
 
   /**
    * Convert this Node into an Expr using the currently-in-scope
@@ -889,11 +877,6 @@ public:
    */
   inline void printAst(std::ostream& out, int indent = 0) const;
 
-  /**
-   * Check if the node has a subterm t.
-   */
-  inline bool hasSubterm(NodeTemplate<false> t, bool strict = false) const;
-
   template <bool ref_count2>
   NodeTemplate<true> eqNode(const NodeTemplate<ref_count2>& right) const;
 
@@ -1524,42 +1507,6 @@ inline Node NodeTemplate<true>::fromExpr(const Expr& e) {
   return NodeManager::fromExpr(e);
 }
 
-template<bool ref_count>
-bool NodeTemplate<ref_count>::hasSubterm(NodeTemplate<false> t, bool strict) const {
-  typedef std::unordered_set<TNode, TNodeHashFunction> node_set;
-
-  if (!strict && *this == t) {
-    return true;
-  }
-
-  node_set visited;
-  std::vector<TNode> toProcess;
-
-  toProcess.push_back(*this);
-
-  for (unsigned i = 0; i < toProcess.size(); ++ i) {
-    TNode current = toProcess[i];
-    if (current.hasOperator() && current.getOperator() == t)
-    {
-      return true;
-    }
-    for(unsigned j = 0, j_end = current.getNumChildren(); j < j_end; ++ j) {
-      TNode child = current[j];
-      if (child == t) {
-        return true;
-      }
-      if (visited.find(child) != visited.end()) {
-        continue;
-      } else {
-        visited.insert(child);
-        toProcess.push_back(child);
-      }
-    }
-  }
-
-  return false;
-}
-
 #ifdef CVC4_DEBUG
 /**
  * Pretty printer for use within gdb.  This is not intended to be used
diff --git a/src/expr/node_algorithm.cpp b/src/expr/node_algorithm.cpp
new file mode 100644 (file)
index 0000000..5443a3a
--- /dev/null
@@ -0,0 +1,170 @@
+/*********************                                                        */
+/*! \file node_algorithm.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ **   Morgan Deters, Andrew Reynolds, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved.  See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Common algorithms on nodes
+ **
+ ** This file implements common algorithms applied to nodes, such as checking if
+ ** a node contains a free or a bound variable.
+ **/
+
+#include "expr/node_algorithm.h"
+
+#include "expr/attribute.h"
+
+namespace CVC4 {
+namespace expr {
+
+bool hasSubterm(TNode n, TNode t, bool strict)
+{
+  if (!strict && n == t)
+  {
+    return true;
+  }
+
+  std::unordered_set<TNode, TNodeHashFunction> visited;
+  std::vector<TNode> toProcess;
+
+  toProcess.push_back(n);
+
+  for (unsigned i = 0; i < toProcess.size(); ++i)
+  {
+    TNode current = toProcess[i];
+    if (current.hasOperator() && current.getOperator() == t)
+    {
+      return true;
+    }
+    for (unsigned j = 0, j_end = current.getNumChildren(); j < j_end; ++j)
+    {
+      TNode child = current[j];
+      if (child == t)
+      {
+        return true;
+      }
+      if (visited.find(child) != visited.end())
+      {
+        continue;
+      }
+      else
+      {
+        visited.insert(child);
+        toProcess.push_back(child);
+      }
+    }
+  }
+
+  return false;
+}
+
+struct HasBoundVarTag
+{
+};
+struct HasBoundVarComputedTag
+{
+};
+/** Attribute true for expressions with bound variables in them */
+typedef expr::Attribute<HasBoundVarTag, bool> HasBoundVarAttr;
+typedef expr::Attribute<HasBoundVarComputedTag, bool> HasBoundVarComputedAttr;
+
+bool hasBoundVar(TNode n)
+{
+  if (!n.getAttribute(HasBoundVarComputedAttr()))
+  {
+    bool hasBv = false;
+    if (n.getKind() == kind::BOUND_VARIABLE)
+    {
+      hasBv = true;
+    }
+    else
+    {
+      for (auto i = n.begin(); i != n.end() && !hasBv; ++i)
+      {
+        hasBv = hasBoundVar(*i);
+      }
+    }
+    if (!hasBv && n.hasOperator())
+    {
+      hasBv = hasBoundVar(n.getOperator());
+    }
+    n.setAttribute(HasBoundVarAttr(), hasBv);
+    n.setAttribute(HasBoundVarComputedAttr(), true);
+    Debug("bva") << n << " has bva : " << n.getAttribute(HasBoundVarAttr())
+                 << std::endl;
+    return hasBv;
+  }
+  return n.getAttribute(HasBoundVarAttr());
+}
+
+bool hasFreeVar(TNode n)
+{
+  std::unordered_set<TNode, TNodeHashFunction> bound_var;
+  std::unordered_map<TNode, bool, TNodeHashFunction> visited;
+  std::vector<TNode> visit;
+  TNode cur;
+  visit.push_back(n);
+  do
+  {
+    cur = visit.back();
+    visit.pop_back();
+    // can skip if it doesn't have a bound variable
+    if (!hasBoundVar(cur))
+    {
+      continue;
+    }
+    Kind k = cur.getKind();
+    bool isQuant = k == kind::FORALL || k == kind::EXISTS || k == kind::LAMBDA
+                   || k == kind::CHOICE;
+    std::unordered_map<TNode, bool, TNodeHashFunction>::iterator itv =
+        visited.find(cur);
+    if (itv == visited.end())
+    {
+      if (k == kind::BOUND_VARIABLE)
+      {
+        if (bound_var.find(cur) == bound_var.end())
+        {
+          return true;
+        }
+      }
+      else if (isQuant)
+      {
+        for (const TNode& cn : cur[0])
+        {
+          // should not shadow
+          Assert(bound_var.find(cn) == bound_var.end());
+          bound_var.insert(cn);
+        }
+        visit.push_back(cur);
+      }
+      // must visit quantifiers again to clean up below
+      visited[cur] = !isQuant;
+      if (cur.hasOperator())
+      {
+        visit.push_back(cur.getOperator());
+      }
+      for (const TNode& cn : cur)
+      {
+        visit.push_back(cn);
+      }
+    }
+    else if (!itv->second)
+    {
+      Assert(isQuant);
+      for (const TNode& cn : cur[0])
+      {
+        bound_var.erase(cn);
+      }
+      visited[cur] = true;
+    }
+  } while (!visit.empty());
+  return false;
+}
+
+}  // namespace expr
+}  // namespace CVC4
diff --git a/src/expr/node_algorithm.h b/src/expr/node_algorithm.h
new file mode 100644 (file)
index 0000000..61e81c4
--- /dev/null
@@ -0,0 +1,59 @@
+/*********************                                                        */
+/*! \file node_algorithm.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ **   Morgan Deters, Andrew Reynolds, Tim King
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2018 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved.  See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief Common algorithms on nodes
+ **
+ ** This file implements common algorithms applied to nodes, such as checking if
+ ** a node contains a free or a bound variable. This file should generally only
+ ** be included in source files.
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef __CVC4__EXPR__NODE_ALGORITHM_H
+#define __CVC4__EXPR__NODE_ALGORITHM_H
+
+#include <unordered_map>
+#include <vector>
+
+#include "expr/node.h"
+
+namespace CVC4 {
+namespace expr {
+
+/**
+ * Check if the node n has a subterm t.
+ * @param n The node to search in
+ * @param t The subterm to search for
+ * @param strict If true, a term is not considered to be a subterm of itself
+ * @return true iff t is a subterm in n
+ */
+bool hasSubterm(TNode n, TNode t, bool strict = false);
+
+/**
+ * Returns true iff the node n contains a bound variable. This bound
+ * variable may or may not be free.
+ * @param n The node under investigation
+ * @return true iff this node contains a bound variable
+ */
+bool hasBoundVar(TNode n);
+
+/**
+ * Returns true iff the node n contains a free variable.
+ * @param n The node under investigation
+ * @return true iff this node contains a free variable.
+ */
+bool hasFreeVar(TNode n);
+
+}  // namespace expr
+}  // namespace CVC4
+
+#endif
index ade34d12767efe1674531b0f3a82d6449cf540ad..2e18899a2cce3f5191cd5039d24784e1510b991b 100644 (file)
@@ -17,6 +17,7 @@
 
 #include <vector>
 
+#include "expr/node_algorithm.h"
 #include "options/proof_options.h"
 #include "proof/proof_manager.h"
 
@@ -85,7 +86,7 @@ Node RemoveTermFormulas::run(TNode node, std::vector<Node>& output,
   Node newAssertion;
   if(node.getKind() == kind::ITE) {
     // If an ITE, replace it
-    if (!nodeType.isBoolean() && (!inQuant || !node.hasBoundVar()))
+    if (!nodeType.isBoolean() && (!inQuant || !expr::hasBoundVar(node)))
     {
       skolem = getSkolemForNode(node);
       if (skolem.isNull())
index ed68df89cec90bfa7ce0fef56b856514ba427828..4bfc1a4f9b1893884a2716a334b5ab1ae749b7a0 100644 (file)
@@ -19,6 +19,7 @@
 
 #include "base/output.h"
 #include "expr/expr.h"
+#include "expr/node_algorithm.h"
 #include "options/arith_options.h"
 #include "smt/smt_statistics_registry.h"
 #include "theory/arith/arith_static_learner.h"
@@ -107,9 +108,11 @@ void ArithStaticLearner::process(TNode n, NodeBuilder<>& learned, const TNodeSet
 
   switch(n.getKind()){
   case ITE:
-    if(n.hasBoundVar()) {
+    if (expr::hasBoundVar(n))
+    {
       // Unsafe with non-ground ITEs; do nothing
-      Debug("arith::static") << "(potentially) non-ground ITE, ignoring..." << endl;
+      Debug("arith::static")
+          << "(potentially) non-ground ITE, ignoring..." << endl;
       break;
     }
 
index 30debf6d7d1cace710c170b6dc13ec66748d6132..f4e9f9d6b38a4618d326d20a0a5918702c49b88f 100644 (file)
@@ -20,6 +20,7 @@
 #include <cmath>
 #include <set>
 
+#include "expr/node_algorithm.h"
 #include "expr/node_builder.h"
 #include "options/arith_options.h"
 #include "theory/arith/arith_msum.h"
@@ -1199,7 +1200,7 @@ bool NonlinearExtension::solveEqualitySimple(Node eq)
         {
           Assert(!slv.isNull());
           // currently do not support substitution-with-coefficients
-          if (veqc.isNull() && !slv.hasSubterm(uv))
+          if (veqc.isNull() && !expr::hasSubterm(slv, uv))
           {
             Trace("nl-ext-cm")
                 << "check-model-subs : " << uv << " -> " << slv << std::endl;
@@ -1454,7 +1455,7 @@ bool NonlinearExtension::simpleCheckModelLit(Node lit)
     // is it a valid variable?
     std::map<Node, std::pair<Node, Node> >::iterator bit =
         d_check_model_bounds.find(v);
-    if (!invalid_vsum.hasSubterm(v) && bit != d_check_model_bounds.end())
+    if (!expr::hasSubterm(invalid_vsum, v) && bit != d_check_model_bounds.end())
     {
       std::map<Node, Node>::iterator it = v_a.find(v);
       if (it != v_a.end())
index 6db246b8bbb8eb540c41d5546497b6afd15ef917..9689700499cf8ef003e0ed63b01c40f4c685e79f 100644 (file)
@@ -32,6 +32,7 @@
 #include "expr/kind.h"
 #include "expr/metakind.h"
 #include "expr/node.h"
+#include "expr/node_algorithm.h"
 #include "expr/node_builder.h"
 #include "options/arith_options.h"
 #include "options/smt_options.h"  // for incrementalSolving()
@@ -1354,24 +1355,37 @@ Theory::PPAssertStatus TheoryArithPrivate::ppAssert(TNode in, SubstitutionMap& o
       // Add the substitution if not recursive
       Assert(elim == Rewriter::rewrite(elim));
 
-
-      if(right.size() > options::ppAssertMaxSubSize()){
-        Debug("simplify") << "TheoryArithPrivate::solve(): did not substitute due to the right hand side containing too many terms: " << minVar << ":" << elim << endl;
+      if (right.size() > options::ppAssertMaxSubSize())
+      {
+        Debug("simplify")
+            << "TheoryArithPrivate::solve(): did not substitute due to the "
+               "right hand side containing too many terms: "
+            << minVar << ":" << elim << endl;
         Debug("simplify") << right.size() << endl;
-      }else if(elim.hasSubterm(minVar)){
-        Debug("simplify") << "TheoryArithPrivate::solve(): can't substitute due to recursive pattern with sharing: " << minVar << ":" << elim << endl;
-
-      }else if (!minVar.getType().isInteger() || right.isIntegral()) {
-        Assert(!elim.hasSubterm(minVar));
+      }
+      else if (expr::hasSubterm(elim, minVar))
+      {
+        Debug("simplify") << "TheoryArithPrivate::solve(): can't substitute "
+                             "due to recursive pattern with sharing: "
+                          << minVar << ":" << elim << endl;
+      }
+      else if (!minVar.getType().isInteger() || right.isIntegral())
+      {
+        Assert(!expr::hasSubterm(elim, minVar));
         // cannot eliminate integers here unless we know the resulting
         // substitution is integral
-        Debug("simplify") << "TheoryArithPrivate::solve(): substitution " << minVar << " |-> " << elim << endl;
+        Debug("simplify") << "TheoryArithPrivate::solve(): substitution "
+                          << minVar << " |-> " << elim << endl;
 
         outSubstitutions.addSubstitution(minVar, elim);
         return Theory::PP_ASSERT_STATUS_SOLVED;
-      } else {
-        Debug("simplify") << "TheoryArithPrivate::solve(): can't substitute b/c it's integer: " << minVar << ":" << minVar.getType() << " |-> " << elim << ":" << elim.getType() << endl;
-
+      }
+      else
+      {
+        Debug("simplify") << "TheoryArithPrivate::solve(): can't substitute "
+                             "b/c it's integer: "
+                          << minVar << ":" << minVar.getType() << " |-> "
+                          << elim << ":" << elim.getType() << endl;
       }
     }
   }
index 9af564a05fd610c4cbd6da3f6c7cb782c8d8136f..4407d45d8f1e2acdc3f1767c1c3c9961ccf029c1 100644 (file)
@@ -20,6 +20,7 @@
 #include <memory>
 
 #include "expr/kind.h"
+#include "expr/node_algorithm.h"
 #include "options/arrays_options.h"
 #include "options/smt_options.h"
 #include "proof/array_proof.h"
@@ -342,11 +343,15 @@ Theory::PPAssertStatus TheoryArrays::ppAssert(TNode in, SubstitutionMap& outSubs
     {
       d_ppFacts.push_back(in);
       d_ppEqualityEngine.assertEquality(in, true, in);
-      if (in[0].isVar() && !in[1].hasSubterm(in[0]) && (in[1].getType()).isSubtypeOf(in[0].getType()) ){
+      if (in[0].isVar() && !expr::hasSubterm(in[1], in[0])
+          && (in[1].getType()).isSubtypeOf(in[0].getType()))
+      {
         outSubstitutions.addSubstitution(in[0], in[1]);
         return PP_ASSERT_STATUS_SOLVED;
       }
-      if (in[1].isVar() && !in[0].hasSubterm(in[1]) && (in[0].getType()).isSubtypeOf(in[1].getType())){
+      if (in[1].isVar() && !expr::hasSubterm(in[0], in[1])
+          && (in[0].getType()).isSubtypeOf(in[1].getType()))
+      {
         outSubstitutions.addSubstitution(in[1], in[0]);
         return PP_ASSERT_STATUS_SOLVED;
       }
index aa87b65ba7d9c993d30d7ac53eed39d1a3af0708..d04b71ee18dda91c51e526b55bce675ee87b9140 100644 (file)
  **/
 
 #include "theory/booleans/circuit_propagator.h"
-#include "util/utility.h"
 
 #include <stack>
 #include <vector>
 #include <algorithm>
 
+#include "expr/node_algorithm.h"
+#include "util/utility.h"
+
 using namespace std;
 
 namespace CVC4 {
@@ -208,7 +210,7 @@ void CircuitPropagator::propagateForward(TNode child, bool childAssignment) {
   for(; parent_it != parent_it_end && !d_conflict; ++ parent_it) {
     // The current parent of the child
     TNode parent = *parent_it;
-    Assert(parent.hasSubterm(child));
+    Assert(expr::hasSubterm(parent, child));
 
     // Forward rules
     switch(parent.getKind()) {
index da28b1ffdc6cf40d2abae72e31ba3c0e6b3d795d..4c14ec177884829aec951b511859041629fdb550 100644 (file)
@@ -19,6 +19,7 @@
 #include "theory/builtin/theory_builtin_rewriter.h"
 
 #include "expr/chain.h"
+#include "expr/node_algorithm.h"
 
 using namespace std;
 
@@ -88,7 +89,7 @@ RewriteResponse TheoryBuiltinRewriter::postRewrite(TNode node) {
         Trace("builtin-rewrite") << "  array rep : " << anode << ", constant = " << anode.isConst() << std::endl;
         Assert( anode.isConst()==retNode.isConst() );
         Assert( retNode.getType()==node.getType() );
-        Assert(node.hasFreeVar() == retNode.hasFreeVar());
+        Assert(expr::hasFreeVar(node) == expr::hasFreeVar(retNode));
         return RewriteResponse(REWRITE_DONE, retNode);
       } 
     }else{
index 8ea474ad7860235dd7d4f8cfc48f79aaaf537c01..0150264fd48b15535db85f14a6bbbdfefefdf36f 100644 (file)
@@ -15,6 +15,9 @@
  **/
 #include "theory/bv/bv_subtheory_algebraic.h"
 
+#include <unordered_set>
+
+#include "expr/node_algorithm.h"
 #include "options/bv_options.h"
 #include "smt/smt_statistics_registry.h"
 #include "smt_util/boolean_simplification.h"
@@ -23,8 +26,6 @@
 #include "theory/bv/theory_bv_utils.h"
 #include "theory/theory_model.h"
 
-#include <unordered_set>
-
 using namespace CVC4::context;
 using namespace CVC4::prop;
 using namespace CVC4::theory::bv::utils;
@@ -490,11 +491,13 @@ bool AlgebraicSolver::solve(TNode fact, TNode reason, SubstitutionEx& subst) {
   TNode left = fact[0];
   TNode right = fact[1];
 
-  if (left.isVar() && !right.hasSubterm(left)) {
-    bool changed  = subst.addSubstitution(left, right, reason);
+  if (left.isVar() && !expr::hasSubterm(right, left))
+  {
+    bool changed = subst.addSubstitution(left, right, reason);
     return changed;
   }
-  if (right.isVar() && !left.hasSubterm(right)) {
+  if (right.isVar() && !expr::hasSubterm(left, right))
+  {
     bool changed = subst.addSubstitution(right, left, reason);
     return changed;
   }
@@ -507,7 +510,8 @@ bool AlgebraicSolver::solve(TNode fact, TNode reason, SubstitutionEx& subst) {
       return false;
 
     // simplify xor with same variable on both sides
-    if (right.hasSubterm(var)) {
+    if (expr::hasSubterm(right, var))
+    {
       std::vector<Node> right_children;
       for (unsigned i = 0; i < right.getNumChildren(); ++i) {
         if (right[i] != var)
@@ -548,9 +552,10 @@ bool AlgebraicSolver::solve(TNode fact, TNode reason, SubstitutionEx& subst) {
   }
 
   // (a xor t = a) <=> (t = 0)
-  if (left.getKind() == kind::BITVECTOR_XOR &&
-      right.getMetaKind() == kind::metakind::VARIABLE &&
-      left.hasSubterm(right)) {
+  if (left.getKind() == kind::BITVECTOR_XOR
+      && right.getMetaKind() == kind::metakind::VARIABLE
+      && expr::hasSubterm(left, right))
+  {
     TNode var = right;
     Node new_left = nm->mkNode(kind::BITVECTOR_XOR, var, left);
     Node zero = utils::mkConst(utils::getSize(var), 0u);
@@ -559,9 +564,10 @@ bool AlgebraicSolver::solve(TNode fact, TNode reason, SubstitutionEx& subst) {
     return changed;
   }
 
-  if (right.getKind() == kind::BITVECTOR_XOR &&
-      left.getMetaKind() == kind::metakind::VARIABLE &&
-      right.hasSubterm(left)) {
+  if (right.getKind() == kind::BITVECTOR_XOR
+      && left.getMetaKind() == kind::metakind::VARIABLE
+      && expr::hasSubterm(right, left))
+  {
     TNode var = left;
     Node new_right = nm->mkNode(kind::BITVECTOR_XOR, var, right);
     Node zero = utils::mkConst(utils::getSize(var), 0u);
@@ -584,9 +590,10 @@ bool AlgebraicSolver::solve(TNode fact, TNode reason, SubstitutionEx& subst) {
   return false;
 }
 
-bool AlgebraicSolver::isSubstitutableIn(TNode node, TNode in) {
-  if (node.getMetaKind() == kind::metakind::VARIABLE &&
-      !in.hasSubterm(node))
+bool AlgebraicSolver::isSubstitutableIn(TNode node, TNode in)
+{
+  if (node.getMetaKind() == kind::metakind::VARIABLE
+      && !expr::hasSubterm(in, node))
     return true;
   return false;
 }
index 9ecbbc99caa1a1cf9673fdf5d99144d7c7caf1de..541b77fe6fc7ea9b3c4d1b5f53e6bfec7fcfd23f 100644 (file)
@@ -15,6 +15,7 @@
 
 #include "theory/bv/theory_bv.h"
 
+#include "expr/node_algorithm.h"
 #include "options/bv_options.h"
 #include "options/smt_options.h"
 #include "proof/proof_manager.h"
@@ -670,13 +671,13 @@ Theory::PPAssertStatus TheoryBV::ppAssert(TNode in,
   {
     case kind::EQUAL:
     {
-      if (in[0].isVar() && !in[1].hasSubterm(in[0]))
+      if (in[0].isVar() && !expr::hasSubterm(in[1], in[0]))
       {
         ++(d_statistics.d_solveSubstitutions);
         outSubstitutions.addSubstitution(in[0], in[1]);
         return PP_ASSERT_STATUS_SOLVED;
       }
-      if (in[1].isVar() && !in[0].hasSubterm(in[1]))
+      if (in[1].isVar() && !expr::hasSubterm(in[0], in[1]))
       {
         ++(d_statistics.d_solveSubstitutions);
         outSubstitutions.addSubstitution(in[1], in[0]);
index a02bf305f95c2c170f645deb112fc97704320804..1293f8311280475f09426ebfe1910749d5ffdd38 100644 (file)
 #include <unordered_map>
 #include <unordered_set>
 
-#include "theory/rewriter.h"
+#include "expr/node_algorithm.h"
 #include "theory/bv/theory_bv_rewrite_rules.h"
 #include "theory/bv/theory_bv_utils.h"
+#include "theory/rewriter.h"
 
 namespace CVC4 {
 namespace theory {
@@ -601,11 +602,13 @@ inline Node RewriteRule<ConcatToMult>::apply(TNode node)
   return NodeManager::currentNM()->mkNode(kind::BITVECTOR_MULT, factor, coef);
 }
 
-template<> inline
-bool RewriteRule<SolveEq>::applies(TNode node) {
-  if (node.getKind() != kind::EQUAL ||
-      (node[0].isVar() && !node[1].hasSubterm(node[0])) ||
-      (node[1].isVar() && !node[0].hasSubterm(node[1]))) {
+template <>
+inline bool RewriteRule<SolveEq>::applies(TNode node)
+{
+  if (node.getKind() != kind::EQUAL
+      || (node[0].isVar() && !expr::hasSubterm(node[1], node[0]))
+      || (node[1].isVar() && !expr::hasSubterm(node[0], node[1])))
+  {
     return false;
   }
   return true;
index f1235d18543f3907e2d45021184d8c06cb9a7f7a..4ea006d54329b0848e554d4b3831bdc5f1e9000f 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "theory/quantifiers/cegqi/ceg_arith_instantiator.h"
 
+#include "expr/node_algorithm.h"
 #include "options/quantifiers_options.h"
 #include "theory/arith/arith_msum.h"
 #include "theory/arith/partial_model.h"
@@ -851,7 +852,7 @@ int ArithInstantiator::solve_arith(CegInstantiator* ci,
         << pv << " " << atom.getKind() << " " << val << std::endl;
   }
   // when not pure LIA/LRA, we must check whether the lhs contains pv
-  if (val.hasSubterm(pv))
+  if (expr::hasSubterm(val, pv))
   {
     Trace("cegqi-arith-debug") << "fail : contains bad term" << std::endl;
     return 0;
index 3a0db027383f16c7dd9844b392004f9bd5a487f8..e56d5f5dbbaee1440be36b1b5af827dae6d63958 100644 (file)
@@ -14,6 +14,8 @@
 
 #include "theory/quantifiers/cegqi/ceg_dt_instantiator.h"
 
+#include "expr/node_algorithm.h"
+
 using namespace std;
 using namespace CVC4::kind;
 using namespace CVC4::context;
@@ -170,7 +172,7 @@ Node DtInstantiator::solve_dt(Node v, Node a, Node b, Node sa, Node sb)
   if (!ret.isNull())
   {
     // ensure does not contain v
-    if (ret.hasSubterm(v))
+    if (expr::hasSubterm(ret, v))
     {
       ret = Node::null();
     }
index 9f12f8b23d2904b36ae3b0337a673dc51d939903..3535b57b7679c789e2a2dc292bf1f9ec94d362a0 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "theory/quantifiers/cegqi/ceg_epr_instantiator.h"
 
+#include "expr/node_algorithm.h"
 #include "options/quantifiers_options.h"
 #include "theory/quantifiers/ematching/trigger.h"
 #include "theory/quantifiers/term_database.h"
@@ -145,7 +146,7 @@ void EprInstantiator::computeMatchScore(CegInstantiator* ci,
                                         Node eqc,
                                         std::map<Node, int>& match_score)
 {
-  if (!inst::Trigger::isAtomicTrigger(catom) || !catom.hasSubterm(pv))
+  if (!inst::Trigger::isAtomicTrigger(catom) || !expr::hasSubterm(catom, pv))
   {
     return;
   }
index 1abd1d4e127787cad7cd625bc8d98019daa2ad44..2a17f1e361a78960bf61e8084992a6801c406274 100644 (file)
@@ -19,6 +19,7 @@
 #include "theory/quantifiers/cegqi/ceg_dt_instantiator.h"
 #include "theory/quantifiers/cegqi/ceg_epr_instantiator.h"
 
+#include "expr/node_algorithm.h"
 #include "options/quantifiers_options.h"
 #include "smt/term_formula_removal.h"
 #include "theory/arith/arith_msum.h"
@@ -1214,7 +1215,7 @@ void collectPresolveEqTerms( Node n, std::map< Node, std::vector< Node > >& teq
     {
       Node nn = n[i == 0 ? 1 : 0];
       std::map<Node, std::vector<Node> >::iterator it = teq.find(n[i]);
-      if (it != teq.end() && !nn.hasFreeVar()
+      if (it != teq.end() && !expr::hasFreeVar(nn)
           && std::find(it->second.begin(), it->second.end(), nn)
                  == it->second.end())
       {
@@ -1268,7 +1269,7 @@ void CegInstantiator::presolve( Node q ) {
       Node g = NodeManager::currentNM()->mkSkolem( "g", NodeManager::currentNM()->booleanType() );
       lem = NodeManager::currentNM()->mkNode( OR, g, lem );
       Trace("cbqi-presolve-debug") << "Presolve lemma : " << lem << std::endl;
-      Assert(!lem.hasFreeVar());
+      Assert(!expr::hasFreeVar(lem));
       d_qe->getOutputChannel().lemma( lem, false, true );
     }
   }
index 615968704cf7f55d99735412d63249847166de41..c281e81ca3ae112b54e86e5f465af9eb28764418 100644 (file)
@@ -13,6 +13,7 @@
  **/
 #include "theory/quantifiers/cegqi/inst_strategy_cbqi.h"
 
+#include "expr/node_algorithm.h"
 #include "options/quantifiers_options.h"
 #include "smt/term_formula_removal.h"
 #include "theory/arith/partial_model.h"
@@ -662,7 +663,7 @@ bool InstStrategyCegqi::isEligibleForInstantiation( Node n ) {
         }
       }
       //only legal if current quantified formula contains n
-      return d_curr_quant.hasSubterm(n);
+      return expr::hasSubterm(d_curr_quant, n);
     }
   }else{
     return true;
index 1fce68de03165193518738749d9ddcad4dab7859..3615ef6f456dce623b078b7c286213ac61805538 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "theory/quantifiers/ematching/trigger.h"
 
+#include "expr/node_algorithm.h"
 #include "theory/arith/arith_msum.h"
 #include "theory/quantifiers/ematching/candidate_generator.h"
 #include "theory/quantifiers/ematching/ho_trigger.h"
@@ -305,10 +306,12 @@ bool Trigger::isUsableEqTerms( Node q, Node n1, Node n2 ) {
     }
   }else if( isUsableAtomicTrigger( n1, q ) ){
     if (options::relationalTriggers() && n2.getKind() == INST_CONSTANT
-        && !n1.hasSubterm(n2))
+        && !expr::hasSubterm(n1, n2))
     {
       return true;
-    }else if( !quantifiers::TermUtil::hasInstConstAttr(n2) ){
+    }
+    else if (!quantifiers::TermUtil::hasInstConstAttr(n2))
+    {
       return true;
     }
   }
index fd98aa208295eee6d8c8d37e6df7d5eaaac508b3..f0789a50398d96f9855224fb01136c96311fea0c 100644 (file)
@@ -16,6 +16,7 @@
 
 #include "theory/quantifiers/fmf/bounded_integers.h"
 
+#include "expr/node_algorithm.h"
 #include "options/quantifiers_options.h"
 #include "theory/arith/arith_msum.h"
 #include "theory/quantifiers/first_order_model.h"
@@ -436,17 +437,23 @@ void BoundedIntegers::checkOwnership(Node f)
                                << bound_lit_map[2][v] << std::endl;
           }
         }else if( it->second==BOUND_FIXED_SET ){
-          setBoundedVar( f, v, BOUND_FIXED_SET );
+          setBoundedVar(f, v, BOUND_FIXED_SET);
           setBoundVar = true;
-          for( unsigned i=0; i<bound_fixed_set[v].size(); i++ ){
+          for (unsigned i = 0; i < bound_fixed_set[v].size(); i++)
+          {
             Node t = bound_fixed_set[v][i];
-            if( t.hasBoundVar() ){
-              d_fixed_set_ngr_range[f][v].push_back( t ); 
-            }else{
-              d_fixed_set_gr_range[f][v].push_back( t ); 
+            if (expr::hasBoundVar(t))
+            {
+              d_fixed_set_ngr_range[f][v].push_back(t);
             }
-          } 
-          Trace("bound-int") << "Variable " << v << " is bound because of disequality conjunction " << bound_lit_map[3][v] << std::endl;
+            else
+            {
+              d_fixed_set_gr_range[f][v].push_back(t);
+            }
+          }
+          Trace("bound-int") << "Variable " << v
+                             << " is bound because of disequality conjunction "
+                             << bound_lit_map[3][v] << std::endl;
         }
         if( setBoundVar ){
           success = true;
@@ -543,9 +550,11 @@ void BoundedIntegers::checkOwnership(Node f)
         Node r = itr->second;
         Assert( !r.isNull() );
         bool isProxy = false;
-        if( r.hasBoundVar() ){
-          //introduce a new bound
-          Node new_range = NodeManager::currentNM()->mkSkolem( "bir", r.getType(), "bound for term" );
+        if (expr::hasBoundVar(r))
+        {
+          // introduce a new bound
+          Node new_range = NodeManager::currentNM()->mkSkolem(
+              "bir", r.getType(), "bound for term");
           d_nground_range[f][v] = r;
           d_range[f][v] = new_range;
           r = new_range;
@@ -645,13 +654,21 @@ void BoundedIntegers::getBoundValues( Node f, Node v, RepSetIterator * rsi, Node
   return;
 }
 
-bool BoundedIntegers::isGroundRange( Node q, Node v ) {
-  if( isBoundVar(q,v) ){
-    if( d_bound_type[q][v]==BOUND_INT_RANGE ){
-      return !getLowerBound(q,v).hasBoundVar() && !getUpperBound(q,v).hasBoundVar();
-    }else if( d_bound_type[q][v]==BOUND_SET_MEMBER ){
-      return !d_setm_range[q][v].hasBoundVar();
-    }else if( d_bound_type[q][v]==BOUND_FIXED_SET ){
+bool BoundedIntegers::isGroundRange(Node q, Node v)
+{
+  if (isBoundVar(q, v))
+  {
+    if (d_bound_type[q][v] == BOUND_INT_RANGE)
+    {
+      return !expr::hasBoundVar(getLowerBound(q, v))
+             && !expr::hasBoundVar(getUpperBound(q, v));
+    }
+    else if (d_bound_type[q][v] == BOUND_SET_MEMBER)
+    {
+      return !expr::hasBoundVar(d_setm_range[q][v]);
+    }
+    else if (d_bound_type[q][v] == BOUND_FIXED_SET)
+    {
       return !d_fixed_set_ngr_range[q][v].empty();
     }
   }
@@ -684,7 +701,7 @@ Node BoundedIntegers::getSetRangeValue( Node q, Node v, RepSetIterator * rsi ) {
     return sr;
   }
   Trace("bound-int-rsi") << "Get value in model for..." << sr << std::endl;
-  Assert(!sr.hasFreeVar());
+  Assert(!expr::hasFreeVar(sr));
   Node sro = sr;
   sr = d_quantEngine->getModel()->getValue(sr);
   // if non-constant, then sr does not occur in the model, we fail
@@ -915,4 +932,3 @@ bool BoundedIntegers::getBoundElements( RepSetIterator * rsi, bool initial, Node
     return true;
   }
 }
-
index 3b2a650abc077ae2de742227562de71394118ced..3006a07bfd491b0a0b2d174f1fc97630d7942453 100644 (file)
 
 #include <vector>
 
+#include "expr/node_algorithm.h"
 #include "options/quantifiers_options.h"
 #include "smt/smt_statistics_registry.h"
+#include "theory/quantifiers/ematching/trigger.h"
 #include "theory/quantifiers/first_order_model.h"
 #include "theory/quantifiers/instantiate.h"
 #include "theory/quantifiers/quant_util.h"
 #include "theory/quantifiers/term_database.h"
 #include "theory/quantifiers/term_util.h"
-#include "theory/quantifiers/ematching/trigger.h"
 #include "theory/theory_engine.h"
 
 using namespace CVC4::kind;
@@ -179,23 +180,34 @@ void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant )
     registerNode( n[1], hasPol, pol, true );
   }else{
     if( !MatchGen::isHandledBoolConnective( n ) ){
-      if( n.hasBoundVar() ){
-        //literals
-        if( n.getKind()==EQUAL ){
-          for( unsigned i=0; i<n.getNumChildren(); i++ ){
-            flatten( n[i], beneathQuant );
+      if (expr::hasBoundVar(n))
+      {
+        // literals
+        if (n.getKind() == EQUAL)
+        {
+          for (unsigned i = 0; i < n.getNumChildren(); i++)
+          {
+            flatten(n[i], beneathQuant);
           }
-        }else if( MatchGen::isHandledUfTerm( n ) ){
-          flatten( n, beneathQuant );
-        }else if( n.getKind()==ITE ){
-          for( unsigned i=1; i<=2; i++ ){
-            flatten( n[i], beneathQuant );
+        }
+        else if (MatchGen::isHandledUfTerm(n))
+        {
+          flatten(n, beneathQuant);
+        }
+        else if (n.getKind() == ITE)
+        {
+          for (unsigned i = 1; i <= 2; i++)
+          {
+            flatten(n[i], beneathQuant);
           }
-          registerNode( n[0], false, pol, beneathQuant );
-        }else if( options::qcfTConstraint() ){
-          //a theory-specific predicate
-          for( unsigned i=0; i<n.getNumChildren(); i++ ){
-            flatten( n[i], beneathQuant );
+          registerNode(n[0], false, pol, beneathQuant);
+        }
+        else if (options::qcfTConstraint())
+        {
+          // a theory-specific predicate
+          for (unsigned i = 0; i < n.getNumChildren(); i++)
+          {
+            flatten(n[i], beneathQuant);
           }
         }
       }
@@ -215,7 +227,8 @@ void QuantInfo::registerNode( Node n, bool hasPol, bool pol, bool beneathQuant )
 
 void QuantInfo::flatten( Node n, bool beneathQuant ) {
   Trace("qcf-qregister-debug2") << "Flatten : " << n << std::endl;
-  if( n.hasBoundVar() ){
+  if (expr::hasBoundVar(n))
+  {
     if( n.getKind()==BOUND_VARIABLE ){
       d_inMatchConstraint[n] = true;
     }
@@ -982,7 +995,8 @@ MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar )
       }
     }
   }else{
-    if( n.hasBoundVar() ){
+    if (expr::hasBoundVar(n))
+    {
       d_type_not = false;
       d_n = n;
       if( d_n.getKind()==NOT ){
@@ -1012,21 +1026,28 @@ MatchGen::MatchGen( QuantInfo * qi, Node n, bool isVar )
           Assert( d_n.getType().isBoolean() );
           d_type = typ_bool_var;
         }else if( d_n.getKind()==EQUAL || options::qcfTConstraint() ){
-          for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
-            if( d_n[i].hasBoundVar() ){
-              if( !qi->isVar( d_n[i] ) ){
-                Trace("qcf-qregister-debug")  << "ERROR : not var " << d_n[i] << std::endl;
+          for (unsigned i = 0; i < d_n.getNumChildren(); i++)
+          {
+            if (expr::hasBoundVar(d_n[i]))
+            {
+              if (!qi->isVar(d_n[i]))
+              {
+                Trace("qcf-qregister-debug")
+                    << "ERROR : not var " << d_n[i] << std::endl;
               }
-              Assert( qi->isVar( d_n[i] ) );
-              if( d_n.getKind()!=EQUAL && qi->isVar( d_n[i] ) ){
-                d_qni_var_num[i+1] = qi->d_var_num[d_n[i]];
+              Assert(qi->isVar(d_n[i]));
+              if (d_n.getKind() != EQUAL && qi->isVar(d_n[i]))
+              {
+                d_qni_var_num[i + 1] = qi->d_var_num[d_n[i]];
               }
-            }else{
+            }
+            else
+            {
               d_qni_gterm[i] = d_n[i];
-              qi->setGroundSubterm( d_n[i] );
+              qi->setGroundSubterm(d_n[i]);
             }
           }
-          d_type = d_n.getKind()==EQUAL ? typ_eq : typ_tconstraint;
+          d_type = d_n.getKind() == EQUAL ? typ_eq : typ_tconstraint;
           Trace("qcf-tconstraint") << "T-Constraint : " << d_n << std::endl;
         }
       }
@@ -1180,12 +1201,17 @@ void MatchGen::reset_round( QuantConflictFind * p ) {
       }
     }
   }else if( d_type==typ_eq ){
-    for( unsigned i=0; i<d_n.getNumChildren(); i++ ){
-      if( !d_n[i].hasBoundVar() ){
-        TNode t = p->getTermDatabase()->getEntailedTerm( d_n[i] );
-        if( t.isNull() ){
+    for (unsigned i = 0; i < d_n.getNumChildren(); i++)
+    {
+      if (!expr::hasBoundVar(d_n[i]))
+      {
+        TNode t = p->getTermDatabase()->getEntailedTerm(d_n[i]);
+        if (t.isNull())
+        {
           d_ground_eval[i] = d_n[i];
-        }else{
+        }
+        else
+        {
           d_ground_eval[i] = t;
         }
       }
@@ -1772,7 +1798,8 @@ Node MatchGen::getMatchOperator( QuantConflictFind * p, Node n ) {
 }
 
 bool MatchGen::isHandled( TNode n ) {
-  if( n.getKind()!=BOUND_VARIABLE && n.hasBoundVar() ){
+  if (n.getKind() != BOUND_VARIABLE && expr::hasBoundVar(n))
+  {
     if( !isHandledBoolConnective( n ) && !isHandledUfTerm( n ) && n.getKind()!=EQUAL && n.getKind()!=ITE ){
       return false;
     }
index 4799de09d7029d62e691f7e5ba9662eb13599c46..37451b7769119713d23da35fa75ee297ecbc55d6 100644 (file)
 
 #include "theory/quantifiers/quantifiers_rewriter.h"
 
+#include "expr/node_algorithm.h"
 #include "options/quantifiers_options.h"
 #include "theory/arith/arith_msum.h"
 #include "theory/quantifiers/bv_inverter.h"
+#include "theory/quantifiers/ematching/trigger.h"
 #include "theory/quantifiers/quantifiers_attributes.h"
 #include "theory/quantifiers/skolemize.h"
 #include "theory/quantifiers/term_database.h"
 #include "theory/quantifiers/term_util.h"
-#include "theory/quantifiers/ematching/trigger.h"
 
 using namespace std;
 using namespace CVC4::kind;
@@ -774,9 +775,11 @@ bool QuantifiersRewriter::isConditionalVariableElim( Node n, int pol ){
       }
     }
   }else if( n.getKind()==EQUAL ){
-    for( unsigned i=0; i<2; i++ ){
-      if( n[i].getKind()==BOUND_VARIABLE ){
-        if (!n[1 - i].hasSubterm(n[i]))
+    for (unsigned i = 0; i < 2; i++)
+    {
+      if (n[i].getKind() == BOUND_VARIABLE)
+      {
+        if (!expr::hasSubterm(n[1 - i], n[i]))
         {
           return true;
         }
@@ -874,8 +877,9 @@ Node QuantifiersRewriter::computeCondSplit( Node body, QAttributes& qa ){
   return body;
 }
 
-bool QuantifiersRewriter::isVariableElim( Node v, Node s ) {
-  return !s.hasSubterm(v) && s.getType().isSubtypeOf(v.getType());
+bool QuantifiersRewriter::isVariableElim(Node v, Node s)
+{
+  return !expr::hasSubterm(s, v) && s.getType().isSubtypeOf(v.getType());
 }
 
 void QuantifiersRewriter::isVariableBoundElig( Node n, std::map< Node, int >& exclude, std::map< Node, std::map< int, bool > >& visited, bool hasPol, bool pol, 
@@ -1112,7 +1116,7 @@ bool QuantifiersRewriter::computeVariableElimLit(
       Trace("var-elim-quant")
           << "Variable eliminate based on bit-vector inversion : " << var
           << " -> " << slv << std::endl;
-      Assert(!slv.hasSubterm(var));
+      Assert(!expr::hasSubterm(slv, var));
       Assert(slv.getType().isSubtypeOf(var.getType()));
       vars.push_back(var);
       subs.push_back(slv);
index 6a7eb81976749da8fee92943978b793e62784e7e..5f5a84a6bd42d49baef1cbd1a2f51060edaa2b22 100644 (file)
@@ -14,6 +14,7 @@
  **/
 #include "theory/quantifiers/sygus/ce_guided_single_inv.h"
 
+#include "expr/node_algorithm.h"
 #include "options/quantifiers_options.h"
 #include "theory/arith/arith_msum.h"
 #include "theory/quantifiers/sygus/sygus_grammar_cons.h"
@@ -726,12 +727,14 @@ void TransitionInference::getConstantSubstitution( std::vector< Node >& vars, st
       // check if it is a variable equality
       TNode v;
       Node s;
-      for( unsigned r=0; r<2; r++ ){
-        if( std::find( vars.begin(), vars.end(), slit[r] )!=vars.end() ){
-          if (!slit[1 - r].hasSubterm(slit[r]))
+      for (unsigned r = 0; r < 2; r++)
+      {
+        if (std::find(vars.begin(), vars.end(), slit[r]) != vars.end())
+        {
+          if (!expr::hasSubterm(slit[1 - r], slit[r]))
           {
             v = slit[r];
-            s = slit[1-r];
+            s = slit[1 - r];
             break;
           }
         }
@@ -741,13 +744,18 @@ void TransitionInference::getConstantSubstitution( std::vector< Node >& vars, st
         std::map< Node, Node > msum;
         if (ArithMSum::getMonomialSumLit(slit, msum))
         {
-          for( std::map< Node, Node >::iterator itm = msum.begin(); itm != msum.end(); ++itm ){
-            if( std::find( vars.begin(), vars.end(), itm->first )!=vars.end() ){  
+          for (std::map<Node, Node>::iterator itm = msum.begin();
+               itm != msum.end();
+               ++itm)
+          {
+            if (std::find(vars.begin(), vars.end(), itm->first) != vars.end())
+            {
               Node veq_c;
               Node val;
               int ires =
                   ArithMSum::isolate(itm->first, msum, veq_c, val, EQUAL);
-              if (ires != 0 && veq_c.isNull() && !val.hasSubterm(itm->first))
+              if (ires != 0 && veq_c.isNull()
+                  && !expr::hasSubterm(val, itm->first))
               {
                 v = itm->first;
                 s = val;
@@ -859,7 +867,8 @@ void TransitionInference::process( Node n ) {
         }else{
           res = NodeManager::currentNM()->mkNode( kind::OR, disjuncts );
         }
-        if( !res.hasBoundVar() ){
+        if (!expr::hasBoundVar(res))
+        {
           Trace("cegqi-inv") << "*** inferred " << ( comp_num==1 ? "pre" : ( comp_num==-1 ? "post" : "trans" ) ) << "-condition : " << res << std::endl;
           d_com[comp_num].d_conjuncts.push_back( res );
           if( !const_var.empty() ){
@@ -1076,4 +1085,3 @@ Node TransitionInference::constructFormulaTrace( DetTrace& dt ) {
 }
   
 } //namespace CVC4
-
index 44835cc26babfb1a22af3b9548ba59ced56d07ec..2ee120211ff45f43837393713ad32fb9f4bcc276 100644 (file)
 #include "theory/quantifiers/sygus/ce_guided_single_inv_sol.h"
 
 #include "expr/datatype.h"
+#include "expr/node_algorithm.h"
 #include "options/quantifiers_options.h"
-#include "theory/quantifiers/sygus/ce_guided_instantiation.h"
-#include "theory/quantifiers/sygus/ce_guided_single_inv.h"
+#include "theory/quantifiers/ematching/trigger.h"
 #include "theory/quantifiers/first_order_model.h"
 #include "theory/quantifiers/quantifiers_attributes.h"
+#include "theory/quantifiers/sygus/ce_guided_instantiation.h"
+#include "theory/quantifiers/sygus/ce_guided_single_inv.h"
 #include "theory/quantifiers/sygus/term_database_sygus.h"
 #include "theory/quantifiers/term_enumeration.h"
 #include "theory/quantifiers/term_util.h"
-#include "theory/quantifiers/ematching/trigger.h"
 #include "theory/theory_engine.h"
 
 using namespace CVC4::kind;
@@ -294,11 +295,12 @@ bool CegConjectureSingleInvSol::getAssignEquality( Node eq, std::vector< Node >&
       Assert( std::find( vars.begin(), vars.end(), eq[r] )==vars.end() );
       if( std::find( new_vars.begin(), new_vars.end(), eq[r] )==new_vars.end() ){
         Node eqro = eq[r==0 ? 1 : 0 ];
-        if (!eqro.hasSubterm(eq[r]))
+        if (!expr::hasSubterm(eqro, eq[r]))
         {
-          Trace("csi-simp-debug") << "---equality " << eq[r] << " = " << eqro << std::endl;
-          new_vars.push_back( eq[r] );
-          new_subs.push_back( eqro );
+          Trace("csi-simp-debug")
+              << "---equality " << eq[r] << " = " << eqro << std::endl;
+          new_vars.push_back(eq[r]);
+          new_subs.push_back(eqro);
           return true;
         }
       }
index cf06dfa453dc2ee286b1fd3a2bd25ac554c1c8a7..7d91e98121e16c5a53c897f7125fa0a7d74d43b7 100644 (file)
@@ -15,6 +15,7 @@
 #include "theory/quantifiers/term_util.h"
 
 #include "expr/datatype.h"
+#include "expr/node_algorithm.h"
 #include "options/base_options.h"
 #include "options/datatypes_options.h"
 #include "options/quantifiers_options.h"
@@ -582,7 +583,7 @@ Node TermUtil::rewriteVtsSymbols( Node n ) {
     //rewriting infinity always takes precedence over rewriting delta
     for( unsigned r=0; r<2; r++ ){
       Node inf = getVtsInfinityIndex( r, false, false );
-      if (!inf.isNull() && n.hasSubterm(inf))
+      if (!inf.isNull() && expr::hasSubterm(n, inf))
       {
         if( rew_vts_inf.isNull() ){
           rew_vts_inf = inf;
@@ -595,16 +596,17 @@ Node TermUtil::rewriteVtsSymbols( Node n ) {
           subs_lhs.push_back( rew_vts_inf );
           n = n.substitute( subs_lhs.begin(), subs_lhs.end(), subs_rhs.begin(), subs_rhs.end() );
           n = Rewriter::rewrite( n );
-          //may have cancelled
-          if (!n.hasSubterm(rew_vts_inf))
+          // may have cancelled
+          if (!expr::hasSubterm(n, rew_vts_inf))
           {
             rew_vts_inf = Node::null();
           }
         }
       }
     }
-    if( rew_vts_inf.isNull() ){
-      if (!d_vts_delta.isNull() && n.hasSubterm(d_vts_delta))
+    if (rew_vts_inf.isNull())
+    {
+      if (!d_vts_delta.isNull() && expr::hasSubterm(n, d_vts_delta))
       {
         rew_delta = true;
       }
index 49954c11106535924be0b27be47d4db580114b39..9346970d1fe50ebfbb17daeb95cac499ff5bfee6 100644 (file)
 #include "theory/sets/theory_sets_private.h"
 
 #include "expr/emptyset.h"
+#include "expr/node_algorithm.h"
 #include "options/sets_options.h"
 #include "smt/smt_statistics_registry.h"
-#include "theory/sets/theory_sets.h"
+#include "theory/quantifiers/term_database.h"
 #include "theory/sets/normal_form.h"
+#include "theory/sets/theory_sets.h"
 #include "theory/theory_model.h"
 #include "util/result.h"
-#include "theory/quantifiers/term_database.h"
 
 #define AJR_IMPLEMENTATION
 
@@ -2200,28 +2201,37 @@ Theory::PPAssertStatus TheorySetsPrivate::ppAssert(TNode in, SubstitutionMap& ou
   
   //this is based off of Theory::ppAssert
   Node var;
-  if (in.getKind() == kind::EQUAL) {
-    if (in[0].isVar() && !in[1].hasSubterm(in[0]) &&
-        (in[1].getType()).isSubtypeOf(in[0].getType()) ){
-      if( !in[0].getType().isSet() || !options::setsExt() ){
+  if (in.getKind() == kind::EQUAL)
+  {
+    if (in[0].isVar() && !expr::hasSubterm(in[1], in[0])
+        && (in[1].getType()).isSubtypeOf(in[0].getType()))
+    {
+      if (!in[0].getType().isSet() || !options::setsExt())
+      {
         outSubstitutions.addSubstitution(in[0], in[1]);
         var = in[0];
         status = Theory::PP_ASSERT_STATUS_SOLVED;
       }
-    }else if (in[1].isVar() && !in[0].hasSubterm(in[1]) &&
-        (in[0].getType()).isSubtypeOf(in[1].getType())){
-      if( !in[1].getType().isSet() || !options::setsExt() ){
+    }
+    else if (in[1].isVar() && !expr::hasSubterm(in[0], in[1])
+             && (in[0].getType()).isSubtypeOf(in[1].getType()))
+    {
+      if (!in[1].getType().isSet() || !options::setsExt())
+      {
         outSubstitutions.addSubstitution(in[1], in[0]);
         var = in[1];
         status = Theory::PP_ASSERT_STATUS_SOLVED;
       }
-    }else if (in[0].isConst() && in[1].isConst()) {
-      if (in[0] != in[1]) {
+    }
+    else if (in[0].isConst() && in[1].isConst())
+    {
+      if (in[0] != in[1])
+      {
         status = Theory::PP_ASSERT_STATUS_CONFLICT;
       }
     }
   }
-  
+
   if( status==Theory::PP_ASSERT_STATUS_SOLVED ){
     Trace("sets-var-elim") << "Sets : ppAssert variable eliminated : " << in << ", var = " << var << std::endl;
     /*
index 2585d1ee3473f0f3d6c81d38bb94fad8b8722aa6..036bb4ada913329bc8c927de8dc1205c1ac96daf 100644 (file)
@@ -15,6 +15,7 @@
  **/
 
 #include "theory/substitutions.h"
+#include "expr/node_algorithm.h"
 #include "theory/rewriter.h"
 
 using namespace std;
@@ -209,15 +210,18 @@ void SubstitutionMap::addSubstitutions(SubstitutionMap& subMap, bool invalidateC
   }
 }
 
-
-static bool check(TNode node, const SubstitutionMap::NodeMap& substitutions) CVC4_UNUSED;
-static bool check(TNode node, const SubstitutionMap::NodeMap& substitutions) {
+static bool check(TNode node,
+                  const SubstitutionMap::NodeMap& substitutions) CVC4_UNUSED;
+static bool check(TNode node, const SubstitutionMap::NodeMap& substitutions)
+{
   SubstitutionMap::NodeMap::const_iterator it = substitutions.begin();
   SubstitutionMap::NodeMap::const_iterator it_end = substitutions.end();
   Debug("substitution") << "checking " << node << endl;
-  for (; it != it_end; ++ it) {
+  for (; it != it_end; ++it)
+  {
     Debug("substitution") << "-- hasSubterm( " << (*it).first << " ) ?" << endl;
-    if (node.hasSubterm((*it).first)) {
+    if (expr::hasSubterm(node, (*it).first))
+    {
       Debug("substitution") << "-- FAIL" << endl;
       return false;
     }
index 31177669349f75367b966a76699d777ada4bc596..eedf0ff526d959847f8bf583a9e8880719d2db5e 100644 (file)
@@ -22,6 +22,7 @@
 #include <string>
 
 #include "base/cvc4_assert.h"
+#include "expr/node_algorithm.h"
 #include "smt/smt_statistics_registry.h"
 #include "theory/ext_theory.h"
 #include "theory/quantifiers_engine.h"
@@ -283,27 +284,31 @@ void Theory::computeRelevantTerms(set<Node>& termSet,
   }
 }
 
-
 Theory::PPAssertStatus Theory::ppAssert(TNode in,
                                         SubstitutionMap& outSubstitutions)
 {
-  if (in.getKind() == kind::EQUAL) {
+  if (in.getKind() == kind::EQUAL)
+  {
     // (and (= x t) phi) can be replaced by phi[x/t] if
     // 1) x is a variable
     // 2) x is not in the term t
     // 3) x : T and t : S, then S <: T
-    if (in[0].isVar() && !in[1].hasSubterm(in[0]) &&
-        (in[1].getType()).isSubtypeOf(in[0].getType()) ){
+    if (in[0].isVar() && !expr::hasSubterm(in[1], in[0])
+        && (in[1].getType()).isSubtypeOf(in[0].getType()))
+    {
       outSubstitutions.addSubstitution(in[0], in[1]);
       return PP_ASSERT_STATUS_SOLVED;
     }
-    if (in[1].isVar() && !in[0].hasSubterm(in[1]) &&
-        (in[0].getType()).isSubtypeOf(in[1].getType())){
+    if (in[1].isVar() && !expr::hasSubterm(in[0], in[1])
+        && (in[0].getType()).isSubtypeOf(in[1].getType()))
+    {
       outSubstitutions.addSubstitution(in[1], in[0]);
       return PP_ASSERT_STATUS_SOLVED;
     }
-    if (in[0].isConst() && in[1].isConst()) {
-      if (in[0] != in[1]) {
+    if (in[0].isConst() && in[1].isConst())
+    {
+      if (in[0] != in[1])
+      {
         return PP_ASSERT_STATUS_CONFLICT;
       }
     }
index 4aed35e75161c9dae451121cb8490f3d0a692ce4..cedeb640f77b2e923238d8f7e480a0a0813a9d20 100644 (file)
@@ -22,6 +22,7 @@
 #include "decision/decision_engine.h"
 #include "expr/attribute.h"
 #include "expr/node.h"
+#include "expr/node_algorithm.h"
 #include "expr/node_builder.h"
 #include "options/bv_options.h"
 #include "options/options.h"
@@ -31,8 +32,8 @@
 #include "proof/lemma_proof.h"
 #include "proof/proof_manager.h"
 #include "proof/theory_proof.h"
-#include "smt/term_formula_removal.h"
 #include "smt/logic_exception.h"
+#include "smt/term_formula_removal.h"
 #include "smt_util/lemma_output_channel.h"
 #include "smt_util/node_visitor.h"
 #include "theory/arith/arith_ite_utils.h"
@@ -396,7 +397,7 @@ void TheoryEngine::preRegister(TNode preprocessed) {
       // the atom should not have free variables
       Debug("theory") << "TheoryEngine::preRegister: " << preprocessed
                       << std::endl;
-      Assert(!preprocessed.hasFreeVar());
+      Assert(!expr::hasFreeVar(preprocessed));
       // Pre-register the terms in the atom
       Theory::Set theories = NodeVisitor<PreRegisterVisitor>::run(d_preRegistrationVisitor, preprocessed);
       theories = Theory::setRemove(THEORY_BOOL, theories);