TypeNode NodeManager::getDatatypeForTupleRecord(TypeNode t) { Assert(t.isTuple() || t.isRecord()); // if the type doesn't have an associated datatype, then make one for it TypeNode& dtt = d_tupleAndRecordTypes[t]; if(dtt.isNull()) { if(t.isTuple()) { Datatype dt("__cvc4_tuple"); DatatypeConstructor c("__cvc4_tuple_ctor"); for(TypeNode::const_iterator i = t.begin(); i != t.end(); ++i) { c.addArg("__cvc4_tuple_stor", (*i).toType()); } dt.addConstructor(c); dtt = TypeNode::fromType(toExprManager()->mkDatatypeType(dt)); Debug("tuprec") << "REWROTE " << t << " to " << dtt << std::endl; dtt.setAttribute(DatatypeTupleAttr(), t); } else { const Record& rec = t.getRecord(); Datatype dt("__cvc4_record"); DatatypeConstructor c("__cvc4_record_ctor"); for(Record::const_iterator i = rec.begin(); i != rec.end(); ++i) { c.addArg((*i).first, (*i).second); } dt.addConstructor(c); dtt = TypeNode::fromType(toExprManager()->mkDatatypeType(dt)); Debug("tuprec") << "REWROTE " << t << " to " << dtt << std::endl; dtt.setAttribute(DatatypeRecordAttr(), t); } } else { Debug("tuprec") << "REUSING cached " << t << ": " << dtt << std::endl; } Assert(!dtt.isNull()); return dtt; }
TypeNode exportTypeInternal(TypeNode n, NodeManager* from, NodeManager* to, ExprManagerMapCollection& vmap) { Debug("export") << "type: " << n << " " << n.getId() << std::endl; if(theory::kindToTheoryId(n.getKind()) == theory::THEORY_DATATYPES) { throw ExportUnsupportedException ("export of types belonging to theory of DATATYPES kinds unsupported"); } if(n.getMetaKind() == kind::metakind::PARAMETERIZED && n.getKind() != kind::SORT_TYPE) { throw ExportUnsupportedException ("export of PARAMETERIZED-kinded types (other than SORT_KIND) not supported"); } if(n.getKind() == kind::TYPE_CONSTANT) { return to->mkTypeConst(n.getConst<TypeConstant>()); } else if(n.getKind() == kind::BITVECTOR_TYPE) { return to->mkBitVectorType(n.getConst<BitVectorSize>()); } else if(n.getKind() == kind::SUBRANGE_TYPE) { return to->mkSubrangeType(n.getSubrangeBounds()); } Type from_t = from->toType(n); Type& to_t = vmap.d_typeMap[from_t]; if(! to_t.isNull()) { Debug("export") << "+ mapped `" << from_t << "' to `" << to_t << "'" << std::endl; return *Type::getTypeNode(to_t); } NodeBuilder<> children(to, n.getKind()); if(n.getKind() == kind::SORT_TYPE) { Debug("export") << "type: operator: " << n.getOperator() << std::endl; // make a new sort tag in target node manager Node sortTag = NodeBuilder<0>(to, kind::SORT_TAG); children << sortTag; } for(TypeNode::iterator i = n.begin(), i_end = n.end(); i != i_end; ++i) { Debug("export") << "type: child: " << *i << std::endl; children << exportTypeInternal(*i, from, to, vmap); } TypeNode out = children.constructTypeNode();// FIXME thread safety to_t = to->toType(out); return out; }/* exportTypeInternal() */
TypeNode NodeManager::getDatatypeForTupleRecord(TypeNode t) { Assert(t.isTuple() || t.isRecord()); //AJR: not sure why .getBaseType() was used in two cases below, // disabling this, which is necessary to fix bug 605/667, // which involves records of INT which were mapped to records of REAL below. TypeNode tOrig = t; if(t.isTuple()) { vector<TypeNode> v; bool changed = false; for(size_t i = 0; i < t.getNumChildren(); ++i) { TypeNode tn = t[i]; TypeNode base; if(tn.isTuple() || tn.isRecord()) { base = getDatatypeForTupleRecord(tn); } else { base = tn;//.getBaseType(); } changed = changed || (tn != base); v.push_back(base); } if(changed) { t = mkTupleType(v); } } else { const Record& r = t.getRecord(); std::vector< std::pair<std::string, Type> > v; bool changed = false; const Record::FieldVector& fields = r.getFields(); for(Record::FieldVector::const_iterator i = fields.begin(); i != fields.end(); ++i) { Type tn = (*i).second; Type base; if(tn.isTuple() || tn.isRecord()) { base = getDatatypeForTupleRecord(TypeNode::fromType(tn)).toType(); } else { base = tn;//.getBaseType(); } changed = changed || (tn != base); v.push_back(std::make_pair((*i).first, base)); } if(changed) { t = mkRecordType(Record(v)); } } // if the type doesn't have an associated datatype, then make one for it TypeNode& dtt = d_tupleAndRecordTypes[t]; if(dtt.isNull()) { if(t.isTuple()) { Datatype dt("__cvc4_tuple"); DatatypeConstructor c("__cvc4_tuple_ctor"); for(TypeNode::const_iterator i = t.begin(); i != t.end(); ++i) { c.addArg("__cvc4_tuple_stor", (*i).toType()); } dt.addConstructor(c); dtt = TypeNode::fromType(toExprManager()->mkDatatypeType(dt)); Debug("tuprec") << "REWROTE " << t << " to " << dtt << std::endl; dtt.setAttribute(DatatypeTupleAttr(), tOrig); } else { const Record& rec = t.getRecord(); const Record::FieldVector& fields = rec.getFields(); Datatype dt("__cvc4_record"); DatatypeConstructor c("__cvc4_record_ctor"); for(Record::FieldVector::const_iterator i = fields.begin(); i != fields.end(); ++i) { c.addArg((*i).first, (*i).second); } dt.addConstructor(c); dtt = TypeNode::fromType(toExprManager()->mkDatatypeType(dt)); Debug("tuprec") << "REWROTE " << t << " to " << dtt << std::endl; dtt.setAttribute(DatatypeRecordAttr(), tOrig); } } else { Debug("tuprec") << "REUSING cached " << t << ": " << dtt << std::endl; } Assert(!dtt.isNull()); return dtt; }