예제 #1
0
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;
}
예제 #2
0
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;
}