}/* NodeManager::reclaimZombies() */
TypeNode NodeManager::computeType(TNode n, bool check)
- throw (TypeCheckingExceptionPrivate, AssertionException) {
+ throw (TypeCheckingExceptionPrivate, AssertionException) {
TypeNode typeNode;
// Infer the type
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());
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;
/** 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;
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;
/** 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;
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]
@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());
- //}
- }
;
/**
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(){}
}
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{
}
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;
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");
}
}
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) {
#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"
}/* CVC4 namespace */
-#endif /* __CVC4__TYPE_ASCRIPTION_H */
-
+#endif /* __CVC4__ASCRIPTION_TYPE_H */
/** 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 */