/********************* */ /*! \file type.cpp ** \verbatim ** Original author: Christopher L. Conway ** Major contributors: Dejan Jovanovic, Morgan Deters ** Minor contributors (to current version): Kshitij Bansal, Andrew Reynolds ** This file is part of the CVC4 project. ** Copyright (c) 2009-2014 New York University and The University of Iowa ** See the file COPYING in the top-level source directory for licensing ** information.\endverbatim ** ** \brief Implementation of expression types ** ** Implementation of expression types. **/ #include "expr/type.h" #include #include #include #include "base/exception.h" #include "expr/node_manager.h" #include "expr/node_manager_attributes.h" #include "expr/type_node.h" using namespace std; namespace CVC4 { ostream& operator<<(ostream& out, const Type& t) { NodeManagerScope nms(t.d_nodeManager); return out << *Type::getTypeNode(t); } Type Type::makeType(const TypeNode& typeNode) const { return Type(d_nodeManager, new TypeNode(typeNode)); } Type::Type(NodeManager* nm, TypeNode* node) : d_typeNode(node), d_nodeManager(nm) { } Type::~Type() { NodeManagerScope nms(d_nodeManager); delete d_typeNode; } Type::Type() : d_typeNode(new TypeNode), d_nodeManager(NULL) { } Type::Type(const Type& t) : d_typeNode(new TypeNode(*t.d_typeNode)), d_nodeManager(t.d_nodeManager) { } bool Type::isNull() const { return d_typeNode->isNull(); } Cardinality Type::getCardinality() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->getCardinality(); } bool Type::isWellFounded() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isWellFounded(); } Expr Type::mkGroundTerm() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->mkGroundTerm().toExpr(); } bool Type::isSubtypeOf(Type t) const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isSubtypeOf(*t.d_typeNode); } bool Type::isComparableTo(Type t) const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isComparableTo(*t.d_typeNode); } Type Type::getBaseType() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->getBaseType().toType(); } Type& Type::operator=(const Type& t) { CheckArgument(d_typeNode != NULL, this, "Unexpected NULL typenode pointer!"); CheckArgument(t.d_typeNode != NULL, t, "Unexpected NULL typenode pointer!"); if(this != &t) { if(d_nodeManager == t.d_nodeManager) { NodeManagerScope nms(d_nodeManager); *d_typeNode = *t.d_typeNode; } else { // This happens more than you think---every time you set to or // from the null Type. It's tricky because each node manager // must be in play at the right time. NodeManagerScope nms1(d_nodeManager); *d_typeNode = TypeNode::null(); NodeManagerScope nms2(t.d_nodeManager); *d_typeNode = *t.d_typeNode; d_nodeManager = t.d_nodeManager; } } return *this; } bool Type::operator==(const Type& t) const { NodeManagerScope nms(d_nodeManager); return *d_typeNode == *t.d_typeNode; } bool Type::operator!=(const Type& t) const { NodeManagerScope nms(d_nodeManager); return *d_typeNode != *t.d_typeNode; } bool Type::operator<(const Type& t) const { NodeManagerScope nms(d_nodeManager); return *d_typeNode < *t.d_typeNode; } bool Type::operator<=(const Type& t) const { NodeManagerScope nms(d_nodeManager); return *d_typeNode <= *t.d_typeNode; } bool Type::operator>(const Type& t) const { NodeManagerScope nms(d_nodeManager); return *d_typeNode > *t.d_typeNode; } bool Type::operator>=(const Type& t) const { NodeManagerScope nms(d_nodeManager); return *d_typeNode >= *t.d_typeNode; } Type Type::substitute(const Type& type, const Type& replacement) const { NodeManagerScope nms(d_nodeManager); return makeType(d_typeNode->substitute(*type.d_typeNode, *replacement.d_typeNode)); } Type Type::substitute(const std::vector& types, const std::vector& replacements) const { NodeManagerScope nms(d_nodeManager); vector typesNodes, replacementsNodes; for(vector::const_iterator i = types.begin(), iend = types.end(); i != iend; ++i) { typesNodes.push_back(*(*i).d_typeNode); } for(vector::const_iterator i = replacements.begin(), iend = replacements.end(); i != iend; ++i) { replacementsNodes.push_back(*(*i).d_typeNode); } return makeType(d_typeNode->substitute(typesNodes.begin(), typesNodes.end(), replacementsNodes.begin(), replacementsNodes.end())); } ExprManager* Type::getExprManager() const { return d_nodeManager->toExprManager(); } Type Type::exportTo(ExprManager* exprManager, ExprManagerMapCollection& vmap) const { return ExprManager::exportType(*this, exprManager, vmap); } void Type::toStream(std::ostream& out) const { NodeManagerScope nms(d_nodeManager); out << *d_typeNode; return; } string Type::toString() const { NodeManagerScope nms(d_nodeManager); stringstream ss; ss << *d_typeNode; return ss.str(); } /** Is this the Boolean type? */ bool Type::isBoolean() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isBoolean(); } /** Is this the integer type? */ bool Type::isInteger() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isInteger(); } /** Is this the real type? */ bool Type::isReal() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isReal(); } /** Is this the string type? */ bool Type::isString() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isString(); } /** Is this the rounding mode type? */ bool Type::isRoundingMode() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isRoundingMode(); } /** Is this the bit-vector type? */ bool Type::isBitVector() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isBitVector(); } /** Is this the floating-point type? */ bool Type::isFloatingPoint() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isFloatingPoint(); } /** Is this a datatype type? */ bool Type::isDatatype() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isDatatype() || d_typeNode->isParametricDatatype(); } /** Is this the Constructor type? */ bool Type::isConstructor() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isConstructor(); } /** Is this the Selector type? */ bool Type::isSelector() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isSelector(); } /** Is this the Tester type? */ bool Type::isTester() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isTester(); } /** Is this a function type? */ bool Type::isFunction() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isFunction(); } /** * Is this a predicate type? NOTE: all predicate types are also * function types. */ bool Type::isPredicate() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isPredicate(); } /** Is this a tuple type? */ bool Type::isTuple() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isTuple(); } /** Is this a record type? */ bool Type::isRecord() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isRecord(); } /** Is this a symbolic expression type? */ bool Type::isSExpr() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isSExpr(); } /** Is this an array type? */ bool Type::isArray() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isArray(); } /** Is this a Set type? */ bool Type::isSet() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isSet(); } /** Is this a sort kind */ bool Type::isSort() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isSort(); } /** Cast to a sort type */ bool Type::isSortConstructor() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isSortConstructor(); } /** Is this a predicate subtype */ /* - not in release 1.0 bool Type::isPredicateSubtype() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isPredicateSubtype(); } */ /** Is this an integer subrange */ bool Type::isSubrange() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->isSubrange(); } size_t FunctionType::getArity() const { return d_typeNode->getNumChildren() - 1; } vector FunctionType::getArgTypes() const { NodeManagerScope nms(d_nodeManager); vector args; vector argNodes = d_typeNode->getArgTypes(); vector::iterator it = argNodes.begin(); vector::iterator it_end = argNodes.end(); for(; it != it_end; ++ it) { args.push_back(makeType(*it)); } return args; } Type FunctionType::getRangeType() const { NodeManagerScope nms(d_nodeManager); CheckArgument(isNull() || isFunction(), this); return makeType(d_typeNode->getRangeType()); } size_t TupleType::getLength() const { return d_typeNode->getTupleLength(); } vector TupleType::getTypes() const { NodeManagerScope nms(d_nodeManager); vector types; vector typeNodes = d_typeNode->getTupleTypes(); vector::iterator it = typeNodes.begin(); vector::iterator it_end = typeNodes.end(); for(; it != it_end; ++ it) { types.push_back(makeType(*it)); } return types; } const Record& RecordType::getRecord() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->getRecord(); } vector SExprType::getTypes() const { NodeManagerScope nms(d_nodeManager); vector types; vector typeNodes = d_typeNode->getSExprTypes(); vector::iterator it = typeNodes.begin(); vector::iterator it_end = typeNodes.end(); for(; it != it_end; ++ it) { types.push_back(makeType(*it)); } return types; } string SortType::getName() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->getAttribute(expr::VarNameAttr()); } bool SortType::isParameterized() const { return false; } /** Get the parameter types */ std::vector SortType::getParamTypes() const { vector params; return params; } string SortConstructorType::getName() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->getAttribute(expr::VarNameAttr()); } size_t SortConstructorType::getArity() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->getAttribute(expr::SortArityAttr()); } SortType SortConstructorType::instantiate(const std::vector& params) const { NodeManagerScope nms(d_nodeManager); vector paramsNodes; for(vector::const_iterator i = params.begin(), iend = params.end(); i != iend; ++i) { paramsNodes.push_back(*getTypeNode(*i)); } return SortType(makeType(d_nodeManager->mkSort(*d_typeNode, paramsNodes))); } BooleanType::BooleanType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isBoolean(), this); } IntegerType::IntegerType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isInteger(), this); } RealType::RealType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isReal(), this); } StringType::StringType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isString(), this); } RoundingModeType::RoundingModeType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isRoundingMode(), this); } BitVectorType::BitVectorType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isBitVector(), this); } FloatingPointType::FloatingPointType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isFloatingPoint(), this); } DatatypeType::DatatypeType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isDatatype(), this); } ConstructorType::ConstructorType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isConstructor(), this); } SelectorType::SelectorType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isSelector(), this); } TesterType::TesterType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isTester(), this); } FunctionType::FunctionType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isFunction(), this); } TupleType::TupleType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isTuple(), this); } RecordType::RecordType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isRecord(), this); } SExprType::SExprType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isSExpr(), this); } ArrayType::ArrayType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isArray(), this); } SetType::SetType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isSet(), this); } SortType::SortType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isSort(), this); } SortConstructorType::SortConstructorType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isSortConstructor(), this); } /* - not in release 1.0 PredicateSubtype::PredicateSubtype(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isPredicateSubtype(), this); } */ SubrangeType::SubrangeType(const Type& t) throw(IllegalArgumentException) : Type(t) { CheckArgument(isNull() || isSubrange(), this); } unsigned BitVectorType::getSize() const { return d_typeNode->getBitVectorSize(); } unsigned FloatingPointType::getExponentSize() const { return d_typeNode->getFloatingPointExponentSize(); } unsigned FloatingPointType::getSignificandSize() const { return d_typeNode->getFloatingPointSignificandSize(); } Type ArrayType::getIndexType() const { return makeType(d_typeNode->getArrayIndexType()); } Type ArrayType::getConstituentType() const { return makeType(d_typeNode->getArrayConstituentType()); } Type SetType::getElementType() const { return makeType(d_typeNode->getSetElementType()); } DatatypeType ConstructorType::getRangeType() const { return DatatypeType(makeType(d_typeNode->getConstructorRangeType())); } size_t ConstructorType::getArity() const { return d_typeNode->getNumChildren() - 1; } std::vector ConstructorType::getArgTypes() const { NodeManagerScope nms(d_nodeManager); vector args; vector argNodes = d_typeNode->getArgTypes(); vector::iterator it = argNodes.begin(); vector::iterator it_end = argNodes.end(); for(; it != it_end; ++ it) { args.push_back(makeType(*it)); } return args; } const Datatype& DatatypeType::getDatatype() const { NodeManagerScope nms(d_nodeManager); if( d_typeNode->isParametricDatatype() ) { CheckArgument( (*d_typeNode)[0].getKind() == kind::DATATYPE_TYPE, this); const Datatype& dt = (*d_typeNode)[0].getConst(); return dt; } else { return d_typeNode->getDatatype(); } } bool DatatypeType::isParametric() const { return d_typeNode->isParametricDatatype(); } Expr DatatypeType::getConstructor(std::string name) const { return getDatatype().getConstructor(name); } 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; } std::vector DatatypeType::getParamTypes() const { NodeManagerScope nms(d_nodeManager); vector params; vector paramNodes = d_typeNode->getParamTypes(); vector::iterator it = paramNodes.begin(); vector::iterator it_end = paramNodes.end(); for(; it != it_end; ++it) { params.push_back(makeType(*it)); } return params; } DatatypeType DatatypeType::instantiate(const std::vector& params) const { NodeManagerScope nms(d_nodeManager); TypeNode cons = d_nodeManager->mkTypeConst( getDatatype() ); vector paramsNodes; paramsNodes.push_back( cons ); for(vector::const_iterator i = params.begin(), iend = params.end(); i != iend; ++i) { paramsNodes.push_back(*getTypeNode(*i)); } return DatatypeType(makeType(d_nodeManager->mkTypeNode(kind::PARAMETRIC_DATATYPE, paramsNodes))); } DatatypeType SelectorType::getDomain() const { return DatatypeType(makeType((*d_typeNode)[0])); } Type SelectorType::getRangeType() const { return makeType((*d_typeNode)[1]); } DatatypeType TesterType::getDomain() const { return DatatypeType(makeType((*d_typeNode)[0])); } BooleanType TesterType::getRangeType() const { return BooleanType(makeType(d_nodeManager->booleanType())); } /* - not in release 1.0 Expr PredicateSubtype::getPredicate() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->getSubtypePredicate().toExpr(); } Type PredicateSubtype::getParentType() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->getSubtypeParentType().toType(); } */ SubrangeBounds SubrangeType::getSubrangeBounds() const { NodeManagerScope nms(d_nodeManager); return d_typeNode->getSubrangeBounds(); } size_t TypeHashFunction::operator()(const Type& t) const { return TypeNodeHashFunction()(NodeManager::fromType(t)); } }/* CVC4 namespace */