Updates to dtype constructor in preparation for eliminating Expr-level datatype ...
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>
Sun, 2 Aug 2020 13:50:57 +0000 (08:50 -0500)
committerGitHub <noreply@github.com>
Sun, 2 Aug 2020 13:50:57 +0000 (08:50 -0500)
src/expr/dtype_cons.cpp
src/expr/dtype_cons.h
src/theory/datatypes/theory_datatypes_type_rules.h

index b2e3fbd43213a592dd50df09feae8c11807d168a..85e07866bc97494c7b35f31f19802b981b22d3ec 100644 (file)
@@ -51,7 +51,7 @@ void DTypeConstructor::addArg(std::string selectorName, TypeNode selectorType)
       selectorType,
       "is an unresolved selector type placeholder",
       NodeManager::SKOLEM_EXACT_NAME | NodeManager::SKOLEM_NO_NOTIFY);
-  Trace("datatypes") << type << std::endl;
+  Trace("datatypes") << "DTypeConstructor::addArg: " << type << std::endl;
   std::shared_ptr<DTypeSelector> a =
       std::make_shared<DTypeSelector>(selectorName, type);
   addArg(a);
@@ -62,6 +62,14 @@ void DTypeConstructor::addArg(std::shared_ptr<DTypeSelector> a)
   d_args.push_back(a);
 }
 
+void DTypeConstructor::addArgSelf(std::string selectorName)
+{
+  Trace("datatypes") << "DTypeConstructor::addArgSelf" << std::endl;
+  std::shared_ptr<DTypeSelector> a =
+      std::make_shared<DTypeSelector>(selectorName, Node::null());
+  addArg(a);
+}
+
 std::string DTypeConstructor::getName() const { return d_name; }
 
 Node DTypeConstructor::getConstructor() const
@@ -276,6 +284,18 @@ int DTypeConstructor::getSelectorIndexInternal(Node sel) const
   return -1;
 }
 
+int DTypeConstructor::getSelectorIndexForName(const std::string& name) const
+{
+  for (size_t i = 0, nargs = getNumArgs(); i < nargs; i++)
+  {
+    if (d_args[i]->getName() == name)
+    {
+      return i;
+    }
+  }
+  return -1;
+}
+
 bool DTypeConstructor::involvesExternalType() const
 {
   for (size_t i = 0, nargs = getNumArgs(); i < nargs; i++)
index d89ed6af7321a72e549a28f66485aefdc04a95ed..2553309f15d75fbf10c48e1040505639b4d6d181 100644 (file)
@@ -26,8 +26,6 @@
 
 namespace CVC4 {
 
-class DatatypeConstructor;
-
 /**
  * The Node-level representation of a constructor for a datatype, which
  * currently resides in the Expr-level DatatypeConstructor class
@@ -35,7 +33,6 @@ class DatatypeConstructor;
  */
 class DTypeConstructor
 {
-  friend class DatatypeConstructor;
   friend class DType;
 
  public:
@@ -63,6 +60,20 @@ class DTypeConstructor
    * Add an argument, given a pointer to a selector object.
    */
   void addArg(std::shared_ptr<DTypeSelector> a);
+  /**
+   * Add a self-referential (i.e., a data field) of the given name
+   * to this Datatype constructor that refers to the enclosing
+   * Datatype.  For example, using the familiar "nat" Datatype, to
+   * create the "pred" field for "succ" constructor, one uses
+   * succ::addArgSelf("pred")---the actual Type
+   * cannot be passed because the Datatype is still under
+   * construction.  Selector names need not be unique; they are for
+   * convenience and pretty-printing only.
+   *
+   * This is a special case of
+   * DTypeConstructor::addArg(std::string).
+   */
+  void addArgSelf(std::string selectorName);
 
   /** Get the name of this constructor. */
   std::string getName() const;
@@ -195,6 +206,12 @@ class DTypeConstructor
    *   stoa(T,C,index)
    */
   int getSelectorIndexInternal(Node sel) const;
+  /** get selector index for name
+   *
+   * Returns the index of selector with the given name, or -1 if it
+   * does not exist.
+   */
+  int getSelectorIndexForName(const std::string& name) const;
 
   /** involves external type
    *
index e9df20c2e01de7e45a0bde087409d0a3daf7c36c..5c1a09805eebcea33871bda8fe624c7731199ffa 100644 (file)
@@ -282,9 +282,10 @@ struct RecordUpdateTypeRule {
         throw TypeCheckingExceptionPrivate(
             n, "Record-update expression formed over non-record");
       }
-      const Record& rec =
-          DatatypeType(recordType.toType()).getRecord();
-      if (!rec.contains(ru.getField())) {
+      const DType& dt = recordType.getDType();
+      const DTypeConstructor& recCons = dt[0];
+      if (recCons.getSelectorIndexForName(ru.getField()) == -1)
+      {
         std::stringstream ss;
         ss << "Record-update field `" << ru.getField()
            << "' is not a valid field name for the record type";