}
/* tuple types / old-style function types */
- | LBRACKET type[t,check] { types.push_back(t); }
- ( COMMA type[t,check] { types.push_back(t); } )* RBRACKET
- { if(types.size() == 1) {
- if(types.front().isFunction()) {
- // old style function syntax [ T -> U ]
- PARSER_STATE->parseError("old-style function type syntax not supported anymore; please use the new syntax");
- } else {
- PARSER_STATE->parseError("I'm not sure what you're trying to do here; tuples must have > 1 type");
- }
+ | LBRACKET ( type[t,check] { types.push_back(t); }
+ ( COMMA type[t,check] { types.push_back(t); } )* )? RBRACKET
+ { if(types.size() == 1 && types.front().isFunction()) {
+ // old style function syntax [ T -> U ]
+ PARSER_STATE->parseError("old-style function type syntax not supported anymore; please use the new syntax");
} else {
// tuple type [ T, U, V... ]
t = EXPR_MANAGER->mkTupleType(types);
}
/* record types */
- | SQHASH identifier[id,CHECK_NONE,SYM_SORT] COLON type[t,check] { typeIds.push_back(std::make_pair(id, t)); }
- ( COMMA identifier[id,CHECK_NONE,SYM_SORT] COLON type[t,check] { typeIds.push_back(std::make_pair(id, t)); } )* HASHSQ
+ | SQHASH ( identifier[id,CHECK_NONE,SYM_SORT] COLON type[t,check] { typeIds.push_back(std::make_pair(id, t)); }
+ ( COMMA identifier[id,CHECK_NONE,SYM_SORT] COLON type[t,check] { typeIds.push_back(std::make_pair(id, t)); } )* )? HASHSQ
{ t = EXPR_MANAGER->mkRecordType(typeIds); }
/* bitvector types */
}
}
+ /* empty tuple literal */
+ | LPAREN RPAREN
+ { f = MK_EXPR(kind::TUPLE, std::vector<Expr>()); }
+
/* boolean literals */
| TRUE_TOK { f = MK_CONST(bool(true)); }
| FALSE_TOK { f = MK_CONST(bool(false)); }
# constructor applications are constant if they are applied only to constants
construle APPLY_CONSTRUCTOR ::CVC4::theory::datatypes::DatatypeConstructorTypeRule
-operator TUPLE_TYPE 1: "tuple type"
+operator TUPLE_TYPE 0: "tuple type"
cardinality TUPLE_TYPE \
"::CVC4::theory::datatypes::TupleProperties::computeCardinality(%TYPE%)" \
"theory/datatypes/theory_datatypes_type_rules.h"
"::CVC4::theory::datatypes::TupleEnumerator" \
"theory/datatypes/type_enumerator.h"
-operator TUPLE 1: "a tuple"
+operator TUPLE 0: "a tuple"
typerule TUPLE ::CVC4::theory::datatypes::TupleTypeRule
construle TUPLE ::CVC4::theory::datatypes::TupleProperties
--- /dev/null
+OPTION "incremental";
+
+a1, a2 : []; % empty tuples (a unit type)
+b1, b2 : [##]; % empty records (a unit type)
+c1, c2 : [[]]; % 1-tuples of the empty tuple (a unit type)
+d1, d2 : [#x:[[##]],y:[#z:[]#]#]; % more complicated records (still a unit type)
+
+% EXPECT: valid
+QUERY a1 = a2;
+
+% EXPECT: valid
+QUERY b1 = b2;
+
+% EXPECT: valid
+QUERY c1 = c2;
+
+% EXPECT: valid
+QUERY d1 = d2;
+
+% EXIT: 20