void ExprManager::checkResolvedDatatype(DatatypeType dtt) const { const Datatype& dt = dtt.getDatatype(); AssertArgument(dt.isResolved(), dtt, "datatype should have been resolved"); // for all constructors... for(Datatype::const_iterator i = dt.begin(), i_end = dt.end(); i != i_end; ++i) { const DatatypeConstructor& c = *i; Type testerType CVC4_UNUSED = c.getTester().getType(); Assert(c.isResolved() && testerType.isTester() && TesterType(testerType).getDomain() == dtt && TesterType(testerType).getRangeType() == booleanType(), "malformed tester in datatype post-resolution"); Type ctorType CVC4_UNUSED = c.getConstructor().getType(); Assert(ctorType.isConstructor() && ConstructorType(ctorType).getArity() == c.getNumArgs() && ConstructorType(ctorType).getRangeType() == dtt, "malformed constructor in datatype post-resolution"); // for all selectors... for(DatatypeConstructor::const_iterator j = c.begin(), j_end = c.end(); j != j_end; ++j) { const DatatypeConstructorArg& a = *j; Type selectorType = a.getSelector().getType(); Assert(a.isResolved() && selectorType.isSelector() && SelectorType(selectorType).getDomain() == dtt, "malformed selector in datatype post-resolution"); // This next one's a "hard" check, performed in non-debug builds // as well; the other ones should all be guaranteed by the // CVC4::Datatype class, but this actually needs to be checked. AlwaysAssert(!SelectorType(selectorType).getRangeType().d_typeNode->isFunctionLike(), "cannot put function-like things in datatypes"); } } }
std::vector<DatatypeType> Parser::mkMutualDatatypeTypes( std::vector<Datatype>& datatypes) { try { std::vector<DatatypeType> types = d_exprManager->mkMutualDatatypeTypes(datatypes, d_unresolved); assert(datatypes.size() == types.size()); for (unsigned i = 0; i < datatypes.size(); ++i) { DatatypeType t = types[i]; const Datatype& dt = t.getDatatype(); const std::string& name = dt.getName(); Debug("parser-idt") << "define " << name << " as " << t << std::endl; if (isDeclared(name, SYM_SORT)) { throw ParserException(name + " already declared"); } if (t.isParametric()) { std::vector<Type> paramTypes = t.getParamTypes(); defineType(name, paramTypes, t); } else { defineType(name, t); } for (Datatype::const_iterator j = dt.begin(), j_end = dt.end(); j != j_end; ++j) { const DatatypeConstructor& ctor = *j; expr::ExprPrintTypes::Scope pts(Debug("parser-idt"), true); Expr constructor = ctor.getConstructor(); Debug("parser-idt") << "+ define " << constructor << std::endl; string constructorName = ctor.getName(); if (isDeclared(constructorName, SYM_VARIABLE)) { throw ParserException(constructorName + " already declared"); } defineVar(constructorName, constructor); Expr tester = ctor.getTester(); Debug("parser-idt") << "+ define " << tester << std::endl; string testerName = ctor.getTesterName(); if (isDeclared(testerName, SYM_VARIABLE)) { throw ParserException(testerName + " already declared"); } defineVar(testerName, tester); for (DatatypeConstructor::const_iterator k = ctor.begin(), k_end = ctor.end(); k != k_end; ++k) { Expr selector = (*k).getSelector(); Debug("parser-idt") << "+++ define " << selector << std::endl; string selectorName = (*k).getName(); if (isDeclared(selectorName, SYM_VARIABLE)) { throw ParserException(selectorName + " already declared"); } defineVar(selectorName, selector); } } } // These are no longer used, and the ExprManager would have // complained of a bad substitution if anything is left unresolved. // Clear out the set. d_unresolved.clear(); // throw exception if any datatype is not well-founded for (unsigned i = 0; i < datatypes.size(); ++i) { const Datatype& dt = types[i].getDatatype(); if (!dt.isCodatatype() && !dt.isWellFounded()) { throw ParserException(dt.getName() + " is not well-founded"); } } return types; } catch (IllegalArgumentException& ie) { throw ParserException(ie.getMessage()); } }