Remove dependency of `TypeNode` on `Node` (#7690)
authorAndres Noetzli <andres.noetzli@gmail.com>
Wed, 24 Nov 2021 05:53:01 +0000 (21:53 -0800)
committerGitHub <noreply@github.com>
Wed, 24 Nov 2021 05:53:01 +0000 (05:53 +0000)
This is further work towards breaking cyclic dependencies in the `expr`
folder.

23 files changed:
src/expr/CMakeLists.txt
src/expr/dtype.cpp
src/expr/dtype_cons.cpp
src/expr/node_converter.cpp
src/expr/node_manager.h
src/expr/node_manager_template.cpp
src/expr/type_node.cpp
src/expr/type_node.h
src/expr/type_properties_template.cpp [new file with mode: 0644]
src/expr/type_properties_template.h
src/theory/arrays/theory_arrays_type_rules.cpp
src/theory/datatypes/datatypes_rewriter.cpp
src/theory/datatypes/proof_checker.cpp
src/theory/datatypes/theory_datatypes.cpp
src/theory/quantifiers/candidate_rewrite_database.cpp
src/theory/quantifiers/sygus/sygus_grammar_cons.cpp
src/theory/quantifiers/sygus/sygus_reconstruct.cpp
src/theory/quantifiers/sygus/sygus_unif_strat.cpp
src/theory/smt_engine_subsolver.cpp
src/theory/strings/sequences_rewriter.cpp
src/theory/theory_model.cpp
src/theory/uf/theory_uf_type_rules.cpp
test/unit/util/datatype_black.cpp

index a6a7c04e93144c29512b217279e9418080dfd907..9a89dfbe66710c0bd126a5a37e3e520ae5ec8da9 100644 (file)
@@ -105,6 +105,7 @@ libcvc5_add_sources(GENERATED
   metakind.h
   node_manager.cpp
   type_checker.cpp
+  type_properties.cpp
   type_properties.h
 )
 
@@ -146,6 +147,16 @@ add_custom_command(
   DEPENDS mkkind type_properties_template.h ${KINDS_FILES}
 )
 
+add_custom_command(
+  OUTPUT type_properties.cpp
+  COMMAND
+    ${mkkind_script}
+    ${CMAKE_CURRENT_LIST_DIR}/type_properties_template.cpp
+    ${KINDS_FILES}
+    > ${CMAKE_CURRENT_BINARY_DIR}/type_properties.cpp
+  DEPENDS mkkind type_properties_template.cpp type_properties.h ${KINDS_FILES}
+)
+
 add_custom_command(
   OUTPUT metakind.h
   COMMAND
@@ -194,5 +205,6 @@ add_custom_target(gen-expr
     metakind.h
     node_manager.cpp
     type_checker.cpp
+    type_properties.cpp
     type_properties.h
 )
index a5719a7ff0225567c6f0b2a7f62f3e247be47387..5b2503454b543b8ac3f7a3b3199b34a96dbb892f 100644 (file)
@@ -278,7 +278,8 @@ void DType::setSygus(TypeNode st, Node bvl, bool allowConst, bool allowAll)
     if (!hasConstant)
     {
       // add an arbitrary one
-      Node op = st.mkGroundTerm();
+      NodeManager* nm = NodeManager::currentNM();
+      Node op = nm->mkGroundTerm(st);
       // use same naming convention as SygusDatatype
       std::stringstream ss;
       ss << getName() << "_" << getNumConstructors() << "_" << op;
index f23cfa4f916258ba8fbea7bb4adacd97ce28c83f..6ba3970c9696d808ba7e1ebc37742eaf43e257d2 100644 (file)
@@ -410,7 +410,7 @@ Node DTypeConstructor::computeGroundTerm(TypeNode t,
     else
     {
       // call mkGroundValue or mkGroundTerm based on isValue
-      arg = isValue ? selType.mkGroundValue() : selType.mkGroundTerm();
+      arg = isValue ? nm->mkGroundValue(selType) : nm->mkGroundTerm(selType);
     }
     if (arg.isNull())
     {
index b72aa99f66e436966fd960d262388d7450b29f2e..3b165ded8c4a0f574c48670d5ef070901ade5bfb 100644 (file)
@@ -199,7 +199,7 @@ TypeNode NodeConverter::convertType(TypeNode tn)
         if (ret.getMetaKind() == kind::metakind::PARAMETERIZED)
         {
           // push the operator
-          nb << ret.getOperator();
+          nb << NodeManager::operatorFromType(ret);
         }
         for (TypeNode::const_iterator j = ret.begin(), iend = ret.end();
              j != iend;
index 5b74b04e1e28bf0fefacc5f6e7fc940c2a40671e..6435c488a96981f9132c5780fab341b5f23965d6 100644 (file)
@@ -73,6 +73,18 @@ class NodeManager
    */
   static bool isNAryKind(Kind k);
 
+  /**
+   * Returns a node representing the operator of this `TypeNode`.
+   * PARAMETERIZED-metakinded types (the SORT_TYPE is one of these) have an
+   * operator. "Little-p parameterized" types (like Array), are OPERATORs, not
+   * PARAMETERIZEDs.
+   */
+  static Node operatorFromType(const TypeNode& tn)
+  {
+    Assert(tn.getMetaKind() == kind::metakind::PARAMETERIZED);
+    return Node(tn.d_nv->getOperator());
+  }
+
  private:
   /**
    * Instead of creating an instance using the constructor,
@@ -448,6 +460,24 @@ class NodeManager
 
   Node mkBoundVar(const TypeNode& type);
 
+  /**
+   * Construct and return a ground term of a given type. If the type is not
+   * well founded, this function throws an exception.
+   *
+   * @param tn The type
+   * @return a ground term of the type
+   */
+  Node mkGroundTerm(const TypeNode& tn);
+
+  /**
+   * Construct and return a ground value of a given type. If the type is not
+   * well founded, this function throws an exception.
+   *
+   * @param tn The type
+   * @return a ground value of the type
+   */
+  Node mkGroundValue(const TypeNode& tn);
+
   /** get the canonical bound variable list for function type tn */
   Node getBoundVarListForFunctionType( TypeNode tn );
 
index 06f5bcfb662e0a12d349ed221efab97ae0042339..a3e267d95de62c94572dd63a4bb9ba4031255204 100644 (file)
 #include "expr/node_manager_attributes.h"
 #include "expr/skolem_manager.h"
 #include "expr/type_checker.h"
+#include "expr/type_properties.h"
 #include "theory/bags/bag_make_op.h"
 #include "theory/sets/singleton_op.h"
+#include "theory/type_enumerator.h"
 #include "util/abstract_value.h"
 #include "util/bitvector.h"
 #include "util/rational.h"
@@ -1216,6 +1218,17 @@ NodeClass NodeManager::mkConstInternal(Kind k, const T& val)
   return NodeClass(nv);
 }
 
+Node NodeManager::mkGroundTerm(const TypeNode& tn)
+{
+  return kind::mkGroundTerm(tn);
+}
+
+Node NodeManager::mkGroundValue(const TypeNode& tn)
+{
+  theory::TypeEnumerator te(tn);
+  return *te;
+}
+
 bool NodeManager::safeToReclaimZombies() const
 {
   // FIXME multithreading
index e94d4733e9a1e283c2126bbe8e4680296b59a218..8358facacc1f851e65704c6514a050ac384725b6 100644 (file)
@@ -264,16 +264,6 @@ bool TypeNode::isWellFounded() const {
   return kind::isWellFounded(*this);
 }
 
-Node TypeNode::mkGroundTerm() const {
-  return kind::mkGroundTerm(*this);
-}
-
-Node TypeNode::mkGroundValue() const
-{
-  theory::TypeEnumerator te(*this);
-  return *te;
-}
-
 bool TypeNode::isStringLike() const { return isString() || isSequence(); }
 
 // !!! Note that this will change to isReal() || isInteger() when subtyping is
@@ -560,47 +550,6 @@ TypeNode TypeNode::commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast) {
   }
 }
 
-Node TypeNode::getEnsureTypeCondition( Node n, TypeNode tn ) {
-  TypeNode ntn = n.getType();
-  Assert(ntn.isComparableTo(tn));
-  if( !ntn.isSubtypeOf( tn ) ){
-    if( tn.isInteger() ){
-      if( tn.isSubtypeOf( ntn ) ){
-        return NodeManager::currentNM()->mkNode( kind::IS_INTEGER, n );
-      }
-    }else if( tn.isDatatype() && ntn.isDatatype() ){
-      if( tn.isTuple() && ntn.isTuple() ){
-        const DType& dt1 = tn.getDType();
-        const DType& dt2 = ntn.getDType();
-        NodeManager* nm = NodeManager::currentNM();
-        if( dt1[0].getNumArgs()==dt2[0].getNumArgs() ){
-          std::vector< Node > conds;
-          for( unsigned i=0; i<dt2[0].getNumArgs(); i++ ){
-            Node s = nm->mkNode(
-                kind::APPLY_SELECTOR_TOTAL, dt2[0][i].getSelector(), n);
-            Node etc = getEnsureTypeCondition(s, dt1[0][i].getRangeType());
-            if( etc.isNull() ){
-              return Node::null();
-            }else{
-              conds.push_back( etc );
-            }
-          }
-          if( conds.empty() ){
-            return nm->mkConst(true);
-          }else if( conds.size()==1 ){
-            return conds[0];
-          }else{
-            return nm->mkNode(kind::AND, conds);
-          }
-        }
-      }
-    }
-    return Node::null();
-  }else{
-    return NodeManager::currentNM()->mkConst( true );
-  }
-}
-
 /** Is this a sort kind */
 bool TypeNode::isSort() const {
   return ( getKind() == kind::SORT_TYPE && !hasAttribute(expr::SortArityAttr()) );
@@ -698,6 +647,17 @@ uint32_t TypeNode::getBitVectorSize() const
   return getConst<BitVectorSize>();
 }
 
+TypeNode TypeNode::getRangeType() const
+{
+  if (isTester())
+  {
+    return NodeManager::currentNM()->booleanType();
+  }
+  Assert(isFunction() || isConstructor() || isSelector())
+      << "Cannot get range type of " << *this;
+  return (*this)[getNumChildren() - 1];
+}
+
 }  // namespace cvc5
 
 namespace std {
index 33d698163fe088bd908e9a0d6c7d85e9802e396f..9882c7fc53b9d886e7d7e4e73dec8cb2e9baf6db 100644 (file)
@@ -217,16 +217,6 @@ private:
     return TypeNode(d_nv->getChild(i));
   }
 
-  /**
-   * PARAMETERIZED-metakinded types (the SORT_TYPE is one of these)
-   * have an operator.  "Little-p parameterized" types (like Array),
-   * are OPERATORs, not PARAMETERIZEDs.
-   */
-  inline Node getOperator() const {
-    Assert(getMetaKind() == kind::metakind::PARAMETERIZED);
-    return Node(d_nv->getOperator());
-  }
-
   /**
    * Returns the unique id of this node
    *
@@ -442,22 +432,6 @@ private:
    */
   bool isWellFounded() const;
 
-  /**
-   * Construct and return a ground term of this type.  If the type is
-   * not well founded, this function throws an exception.
-   *
-   * @return a ground term of the type
-   */
-  Node mkGroundTerm() const;
-
-  /**
-   * Construct and return a ground value of this type.  If the type is
-   * not well founded, this function throws an exception.
-   *
-   * @return a ground value of the type
-   */
-  Node mkGroundValue() const;
-
   /**
    * Is this type a subtype of the given type?
    */
@@ -699,10 +673,6 @@ private:
   static TypeNode leastCommonTypeNode(TypeNode t0, TypeNode t1);
   static TypeNode mostCommonTypeNode(TypeNode t0, TypeNode t1);
 
-  /** get ensure type condition
-   *  Return value is a condition that implies that n has type tn.
-  */
-  static Node getEnsureTypeCondition( Node n, TypeNode tn );
 private:
   static TypeNode commonTypeNode(TypeNode t0, TypeNode t1, bool isLeast);
 
@@ -975,15 +945,6 @@ inline bool TypeNode::isPredicateLike() const {
   return isFunctionLike() && getRangeType().isBoolean();
 }
 
-inline TypeNode TypeNode::getRangeType() const {
-  if(isTester()) {
-    return NodeManager::currentNM()->booleanType();
-  }
-  Assert(isFunction() || isConstructor() || isSelector())
-      << "Cannot get range type of " << *this;
-  return (*this)[getNumChildren() - 1];
-}
-
 /** Is this a floating-point type of with <code>exp</code> exponent bits
     and <code>sig</code> significand bits */
 inline bool TypeNode::isFloatingPoint(unsigned exp, unsigned sig) const {
diff --git a/src/expr/type_properties_template.cpp b/src/expr/type_properties_template.cpp
new file mode 100644 (file)
index 0000000..1ad2572
--- /dev/null
@@ -0,0 +1,51 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ *   Andres Noetzli
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 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.
+ * ****************************************************************************
+ *
+ * Template for the Type properties source file.
+ */
+
+#include "expr/type_properties.h"
+
+namespace cvc5 {
+namespace kind {
+
+Node mkGroundTerm(TypeConstant tc)
+{
+  switch (tc)
+  {
+    // clang-format off
+${type_constant_groundterms}
+      // clang-format on
+    default:
+      InternalError() << "No ground term known for type constant: " << tc;
+  }
+}
+
+Node mkGroundTerm(TypeNode typeNode)
+{
+  AssertArgument(!typeNode.isNull(), typeNode);
+  switch (Kind k = typeNode.getKind())
+  {
+    case TYPE_CONSTANT:
+      return mkGroundTerm(typeNode.getConst<TypeConstant>());
+      // clang-format off
+${type_groundterms}
+      // clang-format on
+    default:
+      InternalError() << "A theory kinds file did not provide a ground term "
+                      << "or ground term computer for type:\n"
+                      << typeNode << "\nof kind " << k;
+  }
+}
+
+}  // namespace kind
+}  // namespace cvc5
index 40ead9a5ea8301736b10a0267ff37945ff0dff5c..3ce3391dca5019c91ee83ed2c3bdc61d581979ef 100644 (file)
@@ -97,34 +97,8 @@ ${type_wellfoundednesses}
   }
 }/* isWellFounded(TypeNode) */
 
-inline Node mkGroundTerm(TypeConstant tc)
-{
-  switch (tc)
-  {
-    // clang-format off
-${type_constant_groundterms}
-      // clang-format on
-    default:
-      InternalError() << "No ground term known for type constant: " << tc;
-  }
-} /* mkGroundTerm(TypeConstant) */
-
-inline Node mkGroundTerm(TypeNode typeNode)
-{
-  AssertArgument(!typeNode.isNull(), typeNode);
-  switch (Kind k = typeNode.getKind())
-  {
-    case TYPE_CONSTANT:
-      return mkGroundTerm(typeNode.getConst<TypeConstant>());
-      // clang-format off
-${type_groundterms}
-      // clang-format on
-    default:
-      InternalError() << "A theory kinds file did not provide a ground term "
-                      << "or ground term computer for type:\n"
-                      << typeNode << "\nof kind " << k;
-  }
-} /* mkGroundTerm(TypeNode) */
+Node mkGroundTerm(TypeConstant tc);
+Node mkGroundTerm(TypeNode typeNode);
 
 }  // namespace kind
 }  // namespace cvc5
index a389c6efb66ffd3aa3bd180f02705fa15f1f51ec..7ba98000a51438a60b459a56174c77ea86afe829 100644 (file)
@@ -251,8 +251,9 @@ bool ArraysProperties::isWellFounded(TypeNode type)
 Node ArraysProperties::mkGroundTerm(TypeNode type)
 {
   Assert(type.getKind() == kind::ARRAY_TYPE);
+  NodeManager* nm = NodeManager::currentNM();
   TypeNode elemType = type.getArrayConstituentType();
-  Node elem = elemType.mkGroundTerm();
+  Node elem = nm->mkGroundTerm(elemType);
   if (elem.isConst())
   {
     return NodeManager::currentNM()->mkConst(ArrayStoreAll(type, elem));
index 4cda9f728651f28a230c72f4b6458f4b19bf7270..903a08bb4d5b44c7b56d087bfbc02d6e5b802b4f 100644 (file)
@@ -441,7 +441,8 @@ RewriteResponse DatatypesRewriter::rewriteSelector(TNode in)
     else if (k == kind::APPLY_SELECTOR_TOTAL)
     {
       // evaluates to the first ground value of type tn.
-      Node gt = tn.mkGroundValue();
+      NodeManager* nm = NodeManager::currentNM();
+      Node gt = nm->mkGroundValue(tn);
       Assert(!gt.isNull());
       if (tn.isDatatype() && !tn.isInstantiatedDatatype())
       {
index cfeb72b5c757703f509a70cdaea81a494a504f9d..69153ef005aa7300ce5891bbf391e0a605acd4d8 100644 (file)
@@ -93,7 +93,7 @@ Node DatatypesProofRuleChecker::checkInternal(PfRule id,
     const DTypeConstructor& dtc = dt[constructorIndex];
     int selectorIndex = dtc.getSelectorIndexInternal(selector);
     Node r =
-        selectorIndex < 0 ? t.getType().mkGroundTerm() : t[0][selectorIndex];
+        selectorIndex < 0 ? nm->mkGroundTerm(t.getType()) : t[0][selectorIndex];
     return t.eqNode(r);
   }
   else if (id == PfRule::DT_SPLIT)
index b19eb53afd25a84571ec1017f1a16bc304a751dd..a9f0c3198e7e47a616a80ff905d6ec0a3779b09a 100644 (file)
@@ -1007,10 +1007,11 @@ void TheoryDatatypes::collapseSelector( Node s, Node c ) {
       // uninterpreted sorts and arrays, where the solver does not fully
       // handle values of the sort. The call to mkGroundTerm does not introduce
       // values for these sorts.
-      rrs = r.getType().mkGroundTerm();
+      NodeManager* nm = NodeManager::currentNM();
+      rrs = nm->mkGroundTerm(r.getType());
       Trace("datatypes-wrong-sel")
           << "Bad apply " << r << " term = " << rrs
-          << ", value = " << r.getType().mkGroundValue() << std::endl;
+          << ", value = " << nm->mkGroundValue(r.getType()) << std::endl;
     }
     else
     {
index 5a5d970648ad40ea5e66a8c98d1bf7ba6fd64e77..5f129f3fcb4b80bac87a0b6551b17c88f1498136 100644 (file)
@@ -150,6 +150,7 @@ Node CandidateRewriteDatabase::addTerm(Node sol,
         if (r.asSatisfiabilityResult().isSat() == Result::SAT)
         {
           Trace("rr-check") << "...rewrite does not hold for: " << std::endl;
+          NodeManager* nm = NodeManager::currentNM();
           is_unique_term = true;
           std::vector<Node> vars;
           d_sampler->getVariables(vars);
@@ -166,7 +167,7 @@ Node CandidateRewriteDatabase::addTerm(Node sol,
               if (itf == d_fv_to_skolem.end())
               {
                 // not in conjecture, can use arbitrary value
-                val = v.getType().mkGroundTerm();
+                val = nm->mkGroundTerm(v.getType());
               }
               else
               {
index a05b64249bee6e3455b7a7cbc3eda9fa7cca25aa..438afbe8268f5023d15f29087a4cafb430856586 100644 (file)
@@ -437,7 +437,7 @@ void CegGrammarConstructor::mkSygusConstantsForType(TypeNode type,
   else if (type.isArray() || type.isSet())
   {
     // generate constant array over the first element of the constituent type
-    Node c = type.mkGroundTerm();
+    Node c = nm->mkGroundTerm(type);
     // note that c should never contain an uninterpreted constant
     Assert(!expr::hasSubtermKind(UNINTERPRETED_CONSTANT, c));
     ops.push_back(c);
@@ -1065,8 +1065,8 @@ void CegGrammarConstructor::mkSygusDefaultGrammar(
     {
       // if there are not constructors yet by this point, which can happen,
       // e.g. for unimplemented types that have no variables in the argument
-      // list of the function-to-synthesize, create a fresh ground term 
-      sdts[i].addConstructor(types[i].mkGroundTerm(), "", {});
+      // list of the function-to-synthesize, create a fresh ground term
+      sdts[i].addConstructor(nm->mkGroundTerm(types[i]), "", {});
     }
 
     // always add ITE
index 6167f747488eb46760d1164358f7ca8f4a12e061..bd71de283f422dcd1bdda003082893042a8ed7c8 100644 (file)
@@ -442,9 +442,10 @@ Node SygusReconstruct::mkGround(Node n) const
   std::unordered_map<TNode, TNode> subs;
 
   // generate a ground value for each one of those variables
+  NodeManager* nm = NodeManager::currentNM();
   for (const TNode& var : vars)
   {
-    subs.emplace(var, var.getType().mkGroundValue());
+    subs.emplace(var, nm->mkGroundValue(var.getType()));
   }
 
   // substitute the variables with ground values
index 6b023075b75007ce1cbf33a2d2514c16bf7b7ac8..d1f29d207727fe492fca90b880c6d5082cac410f 100644 (file)
@@ -609,7 +609,8 @@ void SygusUnifStrategy::buildStrategyGraph(TypeNode tn, NodeRole nrole)
         {
           if (sol_templ_children[j].isNull())
           {
-            sol_templ_children[j] = cop_to_sks[cop][j].getType().mkGroundTerm();
+            sol_templ_children[j] =
+                nm->mkGroundTerm(cop_to_sks[cop][j].getType());
           }
         }
         sol_templ_children.insert(sol_templ_children.begin(), cop);
index d22bde3705c6258e2aad215db6f15e203284ae8a..3e4a69dc9e441d87876ce287cc2694da6fb7ec39 100644 (file)
@@ -116,9 +116,10 @@ Result checkWithSubsolver(Node query,
     if (r.asSatisfiabilityResult().isSat() == Result::SAT)
     {
       // default model
+      NodeManager* nm = NodeManager::currentNM();
       for (const Node& v : vars)
       {
-        modelVals.push_back(v.getType().mkGroundTerm());
+        modelVals.push_back(nm->mkGroundTerm(v.getType()));
       }
     }
     return r;
index 69cd790e876e9c8e21ee4dc52f775220e4284339..1d82f9abd2bd5de8177627d815685d413501b8b1 100644 (file)
@@ -1757,7 +1757,8 @@ Node SequencesRewriter::rewriteSeqNth(Node node)
     if (node.getKind() == SEQ_NTH_TOTAL)
     {
       // return arbitrary term
-      Node ret = s.getType().getSequenceElementType().mkGroundValue();
+      NodeManager* nm = NodeManager::currentNM();
+      Node ret = nm->mkGroundValue(s.getType().getSequenceElementType());
       return returnRewrite(node, ret, Rewrite::SEQ_NTH_TOTAL_OOB);
     }
     else
index a91a185a0486c94a252b16ea789ea013fd2394af..0796831163a3337b489cca7dc05c24224cdd8827 100644 (file)
@@ -124,7 +124,8 @@ std::vector<Node> TheoryModel::getDomainElements(TypeNode tn) const
   {
     // This is called when t is a sort that does not occur in this model.
     // Sorts are always interpreted as non-empty, thus we add a single element.
-    elements.push_back(tn.mkGroundTerm());
+    NodeManager* nm = NodeManager::currentNM();
+    elements.push_back(nm->mkGroundTerm(tn));
     return elements;
   }
   return *type_refs;
index a05c76d4c37aa847fbc0e9e88e44b2761ba82c58..2c0dcd7634eb16ad9bf3658270f9d61b752d91e7 100644 (file)
@@ -264,7 +264,7 @@ Node FunctionProperties::mkGroundTerm(TypeNode type)
 {
   NodeManager* nm = NodeManager::currentNM();
   Node bvl = nm->getBoundVarListForFunctionType(type);
-  Node ret = type.getRangeType().mkGroundTerm();
+  Node ret = nm->mkGroundTerm(type.getRangeType());
   return nm->mkNode(kind::LAMBDA, bvl, ret);
 }
 
index 15dde0cc248092551c84b1a5d3e028681cab1300..336190b8ee792aba9e5694c3092a765707d255ad 100644 (file)
@@ -71,8 +71,9 @@ TEST_F(TestUtilBlackDatatype, enumeration)
   ASSERT_TRUE(colorsType.getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << colorsType.getDType().getName()
                        << std::endl
-                       << "  is " << colorsType.mkGroundTerm() << std::endl;
-  ASSERT_EQ(colorsType.mkGroundTerm().getType(), colorsType);
+                       << "  is " << d_nodeManager->mkGroundTerm(colorsType)
+                       << std::endl;
+  ASSERT_EQ(d_nodeManager->mkGroundTerm(colorsType).getType(), colorsType);
 }
 
 TEST_F(TestUtilBlackDatatype, nat)
@@ -103,8 +104,9 @@ TEST_F(TestUtilBlackDatatype, nat)
   ASSERT_TRUE(natType.getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << natType.getDType().getName()
                        << std::endl
-                       << "  is " << natType.mkGroundTerm() << std::endl;
-  ASSERT_TRUE(natType.mkGroundTerm().getType() == natType);
+                       << "  is " << d_nodeManager->mkGroundTerm(natType)
+                       << std::endl;
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(natType).getType() == natType);
 }
 
 TEST_F(TestUtilBlackDatatype, tree)
@@ -135,8 +137,9 @@ TEST_F(TestUtilBlackDatatype, tree)
   ASSERT_TRUE(treeType.getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << treeType.getDType().getName()
                        << std::endl
-                       << "  is " << treeType.mkGroundTerm() << std::endl;
-  ASSERT_TRUE(treeType.mkGroundTerm().getType() == treeType);
+                       << "  is " << d_nodeManager->mkGroundTerm(treeType)
+                       << std::endl;
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(treeType).getType() == treeType);
 }
 
 TEST_F(TestUtilBlackDatatype, list_int)
@@ -166,8 +169,9 @@ TEST_F(TestUtilBlackDatatype, list_int)
   ASSERT_TRUE(listType.getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << listType.getDType().getName()
                        << std::endl
-                       << "  is " << listType.mkGroundTerm() << std::endl;
-  ASSERT_TRUE(listType.mkGroundTerm().getType() == listType);
+                       << "  is " << d_nodeManager->mkGroundTerm(listType)
+                       << std::endl;
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(listType).getType() == listType);
 }
 
 TEST_F(TestUtilBlackDatatype, list_real)
@@ -196,8 +200,9 @@ TEST_F(TestUtilBlackDatatype, list_real)
   ASSERT_TRUE(listType.getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << listType.getDType().getName()
                        << std::endl
-                       << "  is " << listType.mkGroundTerm() << std::endl;
-  ASSERT_TRUE(listType.mkGroundTerm().getType() == listType);
+                       << "  is " << d_nodeManager->mkGroundTerm(listType)
+                       << std::endl;
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(listType).getType() == listType);
 }
 
 TEST_F(TestUtilBlackDatatype, list_boolean)
@@ -226,8 +231,9 @@ TEST_F(TestUtilBlackDatatype, list_boolean)
   ASSERT_TRUE(listType.getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << listType.getDType().getName()
                        << std::endl
-                       << "  is " << listType.mkGroundTerm() << std::endl;
-  ASSERT_TRUE(listType.mkGroundTerm().getType() == listType);
+                       << "  is " << d_nodeManager->mkGroundTerm(listType)
+                       << std::endl;
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(listType).getType() == listType);
 }
 
 TEST_F(TestUtilBlackDatatype, listIntUpdate)
@@ -248,7 +254,7 @@ TEST_F(TestUtilBlackDatatype, listIntUpdate)
   TypeNode listType = d_nodeManager->mkDatatypeType(list);
   const DType& ldt = listType.getDType();
   Node updater = ldt[0][0].getUpdater();
-  Node gt = listType.mkGroundTerm();
+  Node gt = d_nodeManager->mkGroundTerm(listType);
   Node zero = d_nodeManager->mkConst(CONST_RATIONAL, Rational(0));
   Node truen = d_nodeManager->mkConst(true);
   // construct an update term
@@ -322,8 +328,9 @@ TEST_F(TestUtilBlackDatatype, mutual_list_trees1)
   ASSERT_TRUE(dtts[0].getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << dtts[0].getDType().getName()
                        << std::endl
-                       << "  is " << dtts[0].mkGroundTerm() << std::endl;
-  ASSERT_TRUE(dtts[0].mkGroundTerm().getType() == dtts[0]);
+                       << "  is " << d_nodeManager->mkGroundTerm(dtts[0])
+                       << std::endl;
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(dtts[0]).getType() == dtts[0]);
 
   ASSERT_FALSE(dtts[1].getDType().isFinite());
   ASSERT_TRUE(dtts[1].getDType().getCardinality().compare(Cardinality::INTEGERS)
@@ -331,8 +338,9 @@ TEST_F(TestUtilBlackDatatype, mutual_list_trees1)
   ASSERT_TRUE(dtts[1].getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << dtts[1].getDType().getName()
                        << std::endl
-                       << "  is " << dtts[1].mkGroundTerm() << std::endl;
-  ASSERT_TRUE(dtts[1].mkGroundTerm().getType() == dtts[1]);
+                       << "  is " << d_nodeManager->mkGroundTerm(dtts[1])
+                       << std::endl;
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(dtts[1]).getType() == dtts[1]);
 }
 
 TEST_F(TestUtilBlackDatatype, mutual_list_trees2)
@@ -388,8 +396,9 @@ TEST_F(TestUtilBlackDatatype, mutual_list_trees2)
   ASSERT_TRUE(dtts2[0].getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << dtts2[0].getDType().getName()
                        << std::endl
-                       << "  is " << dtts2[0].mkGroundTerm() << std::endl;
-  ASSERT_TRUE(dtts2[0].mkGroundTerm().getType() == dtts2[0]);
+                       << "  is " << d_nodeManager->mkGroundTerm(dtts2[0])
+                       << std::endl;
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(dtts2[0]).getType() == dtts2[0]);
 
   ASSERT_FALSE(dtts2[1].getDType().isParametric());
   ASSERT_FALSE(dtts2[1].getDType().isFinite());
@@ -399,8 +408,9 @@ TEST_F(TestUtilBlackDatatype, mutual_list_trees2)
   ASSERT_TRUE(dtts2[1].getDType().isWellFounded());
   Debug("groundterms") << "ground term of " << dtts2[1].getDType().getName()
                        << std::endl
-                       << "  is " << dtts2[1].mkGroundTerm() << std::endl;
-  ASSERT_TRUE(dtts2[1].mkGroundTerm().getType() == dtts2[1]);
+                       << "  is " << d_nodeManager->mkGroundTerm(dtts2[1])
+                       << std::endl;
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(dtts2[1]).getType() == dtts2[1]);
 }
 
 TEST_F(TestUtilBlackDatatype, not_so_well_founded)
@@ -423,7 +433,7 @@ TEST_F(TestUtilBlackDatatype, not_so_well_founded)
       treeType.getDType().getCardinality().compare(Cardinality::INTEGERS)
       == Cardinality::EQUAL);
   ASSERT_FALSE(treeType.getDType().isWellFounded());
-  ASSERT_TRUE(treeType.mkGroundTerm().isNull());
+  ASSERT_TRUE(d_nodeManager->mkGroundTerm(treeType).isNull());
   ASSERT_TRUE(treeType.getDType().mkGroundTerm(treeType).isNull());
 }