TypeNode NodeManager::getDatatypeForTupleRecord(TypeNode t) {
Assert(t.isTuple() || t.isRecord());
+ 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;
+ for(Record::iterator i = r.begin(); i != r.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()) {
Assert(t == expectType.end());
d_nodes[current] = b;
Debug("tuprec") << "returning " << d_nodes[current] << endl;
- Assert(d_nodes[current].getType() == expectType);
+ // The assert below is too strong---we might be returning a model value but
+ // expect a type that still uses datatypes for tuples/records. If it's
+ // really not the right type we should catch it in SmtEngine anyway.
+ // Assert(d_nodes[current].getType() == expectType);
} else if(current.getType().hasAttribute(expr::DatatypeRecordAttr())) {
Assert(current.getKind() == kind::APPLY_CONSTRUCTOR);
TypeNode expectType = current.getType().getAttribute(expr::DatatypeRecordAttr());
--- /dev/null
+% EXPECT: invalid
+
+Mem_0 : TYPE = ARRAY INT OF INT;
+
+MEMORY : TYPE = [# int : Mem_0, queries : Mem_0 #];
+
+x : INT;
+
+foo : MEMORY -> MEMORY
+ = LAMBDA (x : MEMORY) : LET y = x WITH .int := x.int IN y;
+
+m : MEMORY;
+
+w : [MEMORY,INT] =
+ IF x = 0
+ THEN (foo(m),0)
+ ELSE (m, 0)
+ ENDIF;
+
+QUERY w.1 = 1;