type ascriptions (casts) for parameterized datatypes, e.g. "nil :: list[INT]
authorMorgan Deters <mdeters@gmail.com>
Wed, 1 Jun 2011 00:49:37 +0000 (00:49 +0000)
committerMorgan Deters <mdeters@gmail.com>
Wed, 1 Jun 2011 00:49:37 +0000 (00:49 +0000)
src/expr/node_manager.cpp
src/expr/type.cpp
src/expr/type.h
src/expr/type_node.cpp
src/expr/type_node.h
src/parser/cvc/Cvc.g
src/theory/datatypes/theory_datatypes_type_rules.h
src/util/ascription_type.h
src/util/datatype.h

index 716e2a3b3e07bdd71dc14b05bd996ab69e1b3edf..4cde0c62471114364b3ad51ed86b894347578279 100644 (file)
@@ -238,7 +238,7 @@ void NodeManager::reclaimZombies() {
 }/* NodeManager::reclaimZombies() */
 
 TypeNode NodeManager::computeType(TNode n, bool check)
-  throw (TypeCheckingExceptionPrivate, AssertionException) {  
+  throw (TypeCheckingExceptionPrivate, AssertionException) {
   TypeNode typeNode;
 
   // Infer the type
@@ -444,6 +444,9 @@ TypeNode NodeManager::computeType(TNode n, bool check)
   case kind::APPLY_TESTER:
     typeNode = CVC4::theory::datatypes::DatatypeTesterTypeRule::computeType(this, n, check);
     break;
+  case kind::APPLY_TYPE_ASCRIPTION:
+    typeNode = CVC4::theory::datatypes::DatatypeAscriptionTypeRule::computeType(this, n, check);
+    break;
   default:
     Debug("getType") << "FAILURE" << std::endl;
     Unhandled(n.getKind());
index 8320a70535ba94f71fd8c9a6aa9561f36dcbd12e..077fc5ee2a030456c3157f1ba9e8e064ebfae402 100644 (file)
@@ -537,6 +537,14 @@ bool DatatypeType::isParametric() const {
   return d_typeNode->isParametricDatatype();
 }
 
+bool DatatypeType::isInstantiated() const {
+  return d_typeNode->isInstantiatedDatatype();
+}
+
+bool DatatypeType::isParameterInstantiated(unsigned n) const {
+  return d_typeNode->isParameterInstantiatedDatatype(n);
+}
+
 size_t DatatypeType::getArity() const {
   NodeManagerScope nms(d_nodeManager);
   return d_typeNode->getNumChildren() - 1;
index 4b260185b0100e04dd96d1cfaaea8edd7fa4d1c3..14ca3baf37372d59955a995a5c7b7ab763a7d62e 100644 (file)
@@ -540,9 +540,22 @@ public:
   /** Get the underlying datatype */
   const Datatype& getDatatype() const;
 
-  /** Is this this datatype parametric? */
+  /** Is this datatype parametric? */
   bool isParametric() const;
 
+  /**
+   * Has this datatype been fully instantiated ?
+   *
+   * @return true if this datatype is not parametric or, if it is, it
+   * has been fully instantiated
+   */
+  bool isInstantiated() const;
+
+  /**
+   * Has this datatype been instantiated for parameter N ?
+   */
+  bool isParameterInstantiated(unsigned n) const;
+
   /** Get the parameter types */
   std::vector<Type> getParamTypes() const;
 
index f77182d5d1f637ab5385bd8e3c06fb4fddb144cf..7376b00802c62df42cb03b4e139e0030fdb054f6 100644 (file)
@@ -199,6 +199,32 @@ bool TypeNode::isParametricDatatype() const {
   return getKind() == kind::PARAMETRIC_DATATYPE;
 }
 
+/** Is this an instantiated datatype type */
+bool TypeNode::isInstantiatedDatatype() const {
+  if(getKind() == kind::DATATYPE_TYPE) {
+    return true;
+  }
+  if(getKind() != kind::PARAMETRIC_DATATYPE) {
+    return false;
+  }
+  const Datatype& dt = (*this)[0].getConst<Datatype>();
+  unsigned n = dt.getNumParameters();
+  for(unsigned i = 0; i < n; ++i) {
+    if(TypeNode::fromType(dt.getParameter(i)) == (*this)[n + 1]) {
+      return false;
+    }
+  }
+  return true;
+}
+
+/** Is this an instantiated datatype parameter */
+bool TypeNode::isParameterInstantiatedDatatype(unsigned n) const {
+  AssertArgument(getKind() == kind::PARAMETRIC_DATATYPE, *this);
+  const Datatype& dt = (*this)[0].getConst<Datatype>();
+  AssertArgument(n < dt.getNumParameters(), *this);
+  return TypeNode::fromType(dt.getParameter(n)) != (*this)[n + 1];
+}
+
 /** Is this a constructor type */
 bool TypeNode::isConstructor() const {
   return getKind() == kind::CONSTRUCTOR_TYPE;
index 90fee7f1b5fb3053f06fa20b97d22334477c9099..0f4b122db95a4cb0408832ee068a6b30401df986 100644 (file)
@@ -488,6 +488,12 @@ public:
   /** Is this a parameterized datatype type */
   bool isParametricDatatype() const;
 
+  /** Is this a fully instantiated datatype type */
+  bool isInstantiatedDatatype() const;
+
+  /** Is this an instantiated datatype parameter */
+  bool isParameterInstantiatedDatatype(unsigned n) const;
+
   /** Is this a constructor type */
   bool isConstructor() const;
 
index 3c8d6e1ce838415c7ac45781bfaaecaacf621aff..ca006daab4c3781bcb2c6ffc8501675b9834fbe5 100644 (file)
@@ -1461,9 +1461,16 @@ postfixTerm[CVC4::Expr& f]
           f = EXPR_MANAGER->mkVar(TupleType(f.getType()).getTypes()[k]); }
       )*/
     )*
-    (typeAscription[f, t] 
-     { //f = MK_EXPR(CVC4::kind::APPLY_TYPE_ANNOTATION, MK_CONST(t), f); 
-     } )? 
+    ( typeAscription[f, t]
+      { if(t.isDatatype()) {
+          f = MK_EXPR(CVC4::kind::APPLY_TYPE_ASCRIPTION, MK_CONST(AscriptionType(t)), f);
+        } else {
+          if(f.getType() != t) {
+            PARSER_STATE->parseError("Type ascription not satisfied.");
+          }
+        }
+      }
+    )?
   ;
 
 bvTerm[CVC4::Expr& f]
@@ -1666,16 +1673,6 @@ typeAscription[const CVC4::Expr& f, CVC4::Type& t]
 @init {
 }
   : COLON COLON type[t,CHECK_DECLARED]
-    { //if(f.getType() != t) {
-      //  std::stringstream ss;
-      //  ss << Expr::setlanguage(language::output::LANG_CVC4)
-      //     << "type ascription not satisfied\n"
-      //     << "term:     " << f << '\n'
-      //     << "has type: " << f.getType() << '\n'
-      //     << "ascribed: " << t;
-      //  PARSER_STATE->parseError(ss.str());
-      //}
-    }
   ;
 
 /**
index 3fe43657f66a931288f7bb46c641ca6361c75c9e..c9c76a15b45dadc615b444b30bd9b56e568a8088 100644 (file)
@@ -41,6 +41,13 @@ public:
   Matcher( DatatypeType dt ){
     std::vector< Type > argTypes = dt.getParamTypes();
     addTypes( argTypes );
+    Debug("typecheck-idt") << "instantiating matcher for " << dt << std::endl;
+    for(unsigned i = 0; i < argTypes.size(); ++i) {
+      if(dt.isParameterInstantiated(i)) {
+        Debug("typecheck-idt") << "++ instantiate param " << i << " : " << d_types[i] << std::endl;
+        d_match[i] = d_types[i];
+      }
+    }
   }
   ~Matcher(){}
 
@@ -55,9 +62,11 @@ public:
   }
 
   bool doMatching( TypeNode base, TypeNode match ){
+    Debug("typecheck-idt") << "doMatching() : " << base << " : " << match << std::endl;
     std::vector< TypeNode >::iterator i = std::find( d_types.begin(), d_types.end(), base );
     if( i!=d_types.end() ){
       int index = i - d_types.begin();
+      Debug("typecheck-idt") << "++ match on " << index << " : " << d_match[index] << std::endl;
       if( !d_match[index].isNull() && d_match[index]!=match ){
         return false;
       }else{
@@ -79,20 +88,23 @@ public:
   }
 
   TypeNode getMatch( unsigned int i ){ return d_match[i]; }
-  void getTypes( std::vector<Type>& types ) { 
+  void getTypes( std::vector<Type>& types ) {
     types.clear();
     for( int i=0; i<(int)d_match.size(); i++ ){
       types.push_back( d_types[i].toType() );
     }
   }
-  void getMatches( std::vector<Type>& types ) { 
+  void getMatches( std::vector<Type>& types ) {
     types.clear();
     for( int i=0; i<(int)d_match.size(); i++ ){
-      Assert( !d_match[i].isNull() ); //verify that all types have been set
-      types.push_back( d_match[i].toType() );
+      if(d_match[i].isNull()) {
+        types.push_back( d_types[i].toType() );
+      } else {
+        types.push_back( d_match[i].toType() );
+      }
     }
   }
-};
+};/* class Matcher */
 
 
 typedef expr::Attribute<expr::attr::DatatypeConstructorTypeGroundTermTag, Node> GroundTermAttr;
@@ -157,6 +169,9 @@ struct DatatypeSelectorTypeRule {
       Debug("typecheck-idt") << "typecheck parameterized sel: " << n << std::endl;
       Matcher m( dt );
       TypeNode childType = n[0].getType(check);
+      if(! childType.isInstantiatedDatatype()) {
+        throw TypeCheckingExceptionPrivate(n, "Datatype type not fully instantiated");
+      }
       if( !m.doMatching( selType[0], childType ) ){
         throw TypeCheckingExceptionPrivate(n, "matching failed for selector argument of parameterized datatype");
       }
@@ -211,7 +226,36 @@ struct DatatypeTesterTypeRule {
     }
     return nodeManager->booleanType();
   }
-};/* struct DatatypeSelectorTypeRule */
+};/* struct DatatypeTesterTypeRule */
+
+struct DatatypeAscriptionTypeRule {
+  inline static TypeNode computeType(NodeManager* nodeManager, TNode n, bool check)
+    throw(TypeCheckingExceptionPrivate) {
+    Debug("typecheck-idt") << "typechecking ascription: " << n << std::endl;
+    Assert(n.getKind() == kind::APPLY_TYPE_ASCRIPTION);
+    TypeNode t = TypeNode::fromType(n.getOperator().getConst<AscriptionType>().getType());
+    if(check) {
+      TypeNode childType = n[0].getType(check);
+      if(!t.getKind() == kind::DATATYPE_TYPE) {
+        throw TypeCheckingExceptionPrivate(n, "bad type for datatype type ascription");
+      }
+      DatatypeType dt = DatatypeType(childType.toType());
+      if( dt.isParametric() ){
+        Debug("typecheck-idt") << "typecheck parameterized ascription: " << n << std::endl;
+        Matcher m( dt );
+        if( !m.doMatching( childType, t ) ){
+          throw TypeCheckingExceptionPrivate(n, "matching failed for type ascription argument of parameterized datatype");
+        }
+      }else{
+        Debug("typecheck-idt") << "typecheck test: " << n << std::endl;
+        if(t != childType) {
+          throw TypeCheckingExceptionPrivate(n, "bad type for type ascription argument");
+        }
+      }
+    }
+    return t;
+  }
+};/* struct DatatypeAscriptionTypeRule */
 
 struct ConstructorProperties {
   inline static Cardinality computeCardinality(TypeNode type) {
index 85a51d8a40def6c3548760fdeefc60ed7ab0aa48..81289572cb7da5767fc0c37c628d80b422ad1169 100644 (file)
@@ -18,8 +18,8 @@
 
 #include "cvc4_public.h"
 
-#ifndef __CVC4__TYPE_ASCRIPTION_H
-#define __CVC4__TYPE_ASCRIPTION_H
+#ifndef __CVC4__ASCRIPTION_TYPE_H
+#define __CVC4__ASCRIPTION_TYPE_H
 
 #include "expr/type.h"
 
@@ -62,5 +62,4 @@ inline std::ostream& operator<<(std::ostream& out, AscriptionType at) {
 
 }/* CVC4 namespace */
 
-#endif /* __CVC4__TYPE_ASCRIPTION_H */
-
+#endif /* __CVC4__ASCRIPTION_TYPE_H */
index 6aeb93bcf3d9d223339941ae592e3acca1d4672f..90dd8775f6b7a2aefea41e3490dbfbffb35334e6 100644 (file)
@@ -369,7 +369,7 @@ public:
   /** Get the number of constructors (so far) for this Datatype. */
   inline size_t getNumConstructors() const throw();
 
-  /** Get the nubmer of parameters */
+  /** Get the nubmer of type parameters */
   inline size_t getNumParameters() const throw();
 
   /** Get parameter */