diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/parser/smt2/Smt2.g | 58 | ||||
-rw-r--r-- | src/parser/smt2/smt2.cpp | 8 | ||||
-rw-r--r-- | src/printer/smt2/smt2_printer.cpp | 237 |
3 files changed, 215 insertions, 88 deletions
diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g index 81f62ccf4..d424fefad 100644 --- a/src/parser/smt2/Smt2.g +++ b/src/parser/smt2/Smt2.g @@ -1980,11 +1980,33 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2] | LPAREN_TOK ( /* An indexed function application */ - indexedFunctionName[op, kind] termList[args,expr] RPAREN_TOK - { - if( kind!=kind::NULL_EXPR ){ + indexedFunctionName[op, kind] termList[args,expr] RPAREN_TOK { + if(kind==CVC4::kind::APPLY_SELECTOR) { + //tuple selector case + Integer x = op.getConst<CVC4::Rational>().getNumerator(); + if (!x.fitsUnsignedInt()) { + PARSER_STATE->parseError("index of tupSel is larger than size of unsigned int"); + } + unsigned int n = x.toUnsignedInt(); + if (args.size()>1) { + PARSER_STATE->parseError("tupSel applied to more than one tuple argument"); + } + Type t = args[0].getType(); + if (!t.isTuple()) { + PARSER_STATE->parseError("tupSel applied to non-tuple"); + } + size_t length = ((DatatypeType)t).getTupleLength(); + if (n >= length) { + std::stringstream ss; + ss << "tuple is of length " << length << "; cannot access index " << n; + PARSER_STATE->parseError(ss.str()); + } + const Datatype & dt = ((DatatypeType)t).getDatatype(); + op = dt[0][n].getSelector(); + } + if (kind!=kind::NULL_EXPR) { expr = MK_EXPR( kind, op, args ); - }else{ + } else { expr = MK_EXPR(op, args); } PARSER_STATE->checkOperator(expr.getKind(), args.size()); @@ -2347,6 +2369,25 @@ termNonVariable[CVC4::Expr& expr, CVC4::Expr& expr2] { //booleanType is placeholder here since we don't have type info without type annotation expr = EXPR_MANAGER->mkNullaryOperator(EXPR_MANAGER->booleanType(), kind::SEP_NIL); } // NOTE: Theory constants go here + + | LPAREN_TOK TUPLE_CONST_TOK termList[args,expr] RPAREN_TOK + { std::vector<Type> types; + for(std::vector<Expr>::const_iterator i = args.begin(); i != args.end(); ++i) { + types.push_back((*i).getType()); + } + DatatypeType t = EXPR_MANAGER->mkTupleType(types); + const Datatype& dt = t.getDatatype(); + args.insert(args.begin(), dt[0].getConstructor()); + expr = MK_EXPR(kind::APPLY_CONSTRUCTOR, args); + } + + | TUPLE_CONST_TOK + { std::vector<Type> types; + DatatypeType t = EXPR_MANAGER->mkTupleType(types); + const Datatype& dt = t.getDatatype(); + args.insert(args.begin(), dt[0].getConstructor()); + expr = MK_EXPR(kind::APPLY_CONSTRUCTOR, args); + } ; /** @@ -2565,6 +2606,11 @@ indexedFunctionName[CVC4::Expr& op, CVC4::Kind& kind] op = Datatype::datatypeOf(expr)[Datatype::indexOf(expr)].getTester(); kind = CVC4::kind::APPLY_TESTER; } + | TUPLE_SEL_TOK m=INTEGER_LITERAL { + kind = CVC4::kind::APPLY_SELECTOR; + //put m in op so that the caller (termNonVariable) can deal with this case + op = MK_CONST(Rational(AntlrInput::tokenToUnsigned($m))); + } | badIndexedFunctionName ) RPAREN_TOK @@ -2843,6 +2889,8 @@ sortSymbol[CVC4::Type& t, CVC4::parser::DeclarationCheck check] PARSER_STATE->parseError("Illegal set type."); } t = EXPR_MANAGER->mkSetType( args[0] ); + } else if(name == "Tuple") { + t = EXPR_MANAGER->mkTupleType(args); } else if(check == CHECK_DECLARED || PARSER_STATE->isDeclared(name, SYM_SORT)) { t = PARSER_STATE->getSort(name, args); @@ -3137,6 +3185,8 @@ INST_CLOSURE_TOK : 'inst-closure'; EMPTYSET_TOK: { PARSER_STATE->isTheoryEnabled(Smt2::THEORY_SETS) }? 'emptyset'; UNIVSET_TOK: { PARSER_STATE->isTheoryEnabled(Smt2::THEORY_SETS) }? 'univset'; NILREF_TOK: { PARSER_STATE->isTheoryEnabled(Smt2::THEORY_SEP) }? 'sep.nil'; +TUPLE_CONST_TOK: { PARSER_STATE->isTheoryEnabled(Smt2::THEORY_DATATYPES) }? 'mkTuple'; +TUPLE_SEL_TOK: { PARSER_STATE->isTheoryEnabled(Smt2::THEORY_DATATYPES) }? 'tupSel'; // Other set theory operators are not // tokenized and handled directly when // processing a term diff --git a/src/parser/smt2/smt2.cpp b/src/parser/smt2/smt2.cpp index 381a60fa8..e4f6569b8 100644 --- a/src/parser/smt2/smt2.cpp +++ b/src/parser/smt2/smt2.cpp @@ -240,14 +240,22 @@ void Smt2::addTheory(Theory theory) { addOperator(kind::INSERT, "insert"); addOperator(kind::CARD, "card"); addOperator(kind::COMPLEMENT, "complement"); + addOperator(kind::JOIN, "join"); + addOperator(kind::PRODUCT, "product"); + addOperator(kind::TRANSPOSE, "transpose"); + addOperator(kind::TCLOSURE, "tclosure"); break; case THEORY_DATATYPES: + { + const std::vector<Type> types; + defineType("Tuple", getExprManager()->mkTupleType(types)); Parser::addOperator(kind::APPLY_CONSTRUCTOR); Parser::addOperator(kind::APPLY_TESTER); Parser::addOperator(kind::APPLY_SELECTOR); Parser::addOperator(kind::APPLY_SELECTOR_TOTAL); break; + } case THEORY_STRINGS: defineType("String", getExprManager()->stringType()); diff --git a/src/printer/smt2/smt2_printer.cpp b/src/printer/smt2/smt2_printer.cpp index c13c519ae..54fc10719 100644 --- a/src/printer/smt2/smt2_printer.cpp +++ b/src/printer/smt2/smt2_printer.cpp @@ -252,11 +252,32 @@ void Smt2Printer::toStream(std::ostream& out, } case kind::DATATYPE_TYPE: + { + const Datatype& dt = (NodeManager::currentNM()->getDatatypeForIndex( + n.getConst<DatatypeIndexConstant>().getIndex())); + if (dt.isTuple()) + { + unsigned int n = dt[0].getNumArgs(); + if (n == 0) + { + out << "Tuple"; + } + else + { + out << "(Tuple"; + for (unsigned int i = 0; i < n; i++) + { + out << " " << dt[0][i].getRangeType(); + } + out << ")"; + } + } + else { - const Datatype & dt = (NodeManager::currentNM()->getDatatypeForIndex( n.getConst< DatatypeIndexConstant >().getIndex() )); out << maybeQuoteSymbol(dt.getName()); } break; + } case kind::UNINTERPRETED_CONSTANT: { const UninterpretedConstant& uc = n.getConst<UninterpretedConstant>(); @@ -549,6 +570,11 @@ void Smt2Printer::toStream(std::ostream& out, case kind::INTERSECTION: case kind::SETMINUS: case kind::SUBSET: + case kind::CARD: + case kind::JOIN: + case kind::PRODUCT: + case kind::TRANSPOSE: + case kind::TCLOSURE: parametricTypeChildren = true; out << smtKindString(k) << " "; break; @@ -624,80 +650,103 @@ void Smt2Printer::toStream(std::ostream& out, return; } break; - case kind::APPLY_CONSTRUCTOR: typeChildren = true; - case kind::APPLY_TESTER: - case kind::APPLY_SELECTOR: - case kind::APPLY_SELECTOR_TOTAL: - case kind::PARAMETRIC_DATATYPE: - break; - //separation logic - case kind::SEP_EMP: - case kind::SEP_PTO: - case kind::SEP_STAR: - case kind::SEP_WAND:out << smtKindString(k) << " "; break; + case kind::APPLY_CONSTRUCTOR: + { + typeChildren = true; + const Datatype& dt = Datatype::datatypeOf(n.getOperator().toExpr()); + if (dt.isTuple()) + { + stillNeedToPrintParams = false; + out << "mkTuple" << ( dt[0].getNumArgs()==0 ? "" : " "); + } + } + + case kind::APPLY_TESTER: + case kind::APPLY_SELECTOR: + case kind::APPLY_SELECTOR_TOTAL: + case kind::PARAMETRIC_DATATYPE: break; - case kind::SEP_NIL:out << "(as sep.nil " << n.getType() << ")";break; + // separation logic + case kind::SEP_EMP: + case kind::SEP_PTO: + case kind::SEP_STAR: + case kind::SEP_WAND: out << smtKindString(k) << " "; break; - // quantifiers - case kind::FORALL: - case kind::EXISTS: - if( k==kind::FORALL ){ - out << "forall "; - }else{ - out << "exists "; - } - for( unsigned i=0; i<2; i++) { - out << n[i] << " "; - if( i==0 && n.getNumChildren()==3 ){ - out << "(! "; + case kind::SEP_NIL: + out << "(as sep.nil " << n.getType() << ")"; + break; + + // quantifiers + case kind::FORALL: + case kind::EXISTS: + if (k == kind::FORALL) + { + out << "forall "; + } + else + { + out << "exists "; + } + for (unsigned i = 0; i < 2; i++) + { + out << n[i] << " "; + if (i == 0 && n.getNumChildren() == 3) + { + out << "(! "; + } + } + if (n.getNumChildren() == 3) + { + out << n[2]; + out << ")"; } - } - if( n.getNumChildren()==3 ){ - out << n[2]; out << ")"; - } - out << ")"; - return; - break; - case kind::BOUND_VAR_LIST: - // the left parenthesis is already printed (before the switch) - for(TNode::iterator i = n.begin(), iend = n.end(); - i != iend; ) { - out << '('; - toStream(out, *i, toDepth < 0 ? toDepth : toDepth - 1, types, 0); - out << ' '; - out << (*i).getType(); - // The following code do stange things - // (*i).getType().toStream(out, toDepth < 0 ? toDepth : toDepth - 1, - // false, language::output::LANG_SMTLIB_V2_5); - out << ')'; - if(++i != iend) { + return; + break; + case kind::BOUND_VAR_LIST: + // the left parenthesis is already printed (before the switch) + for (TNode::iterator i = n.begin(), iend = n.end(); i != iend;) + { + out << '('; + toStream(out, *i, toDepth < 0 ? toDepth : toDepth - 1, types, 0); out << ' '; + out << (*i).getType(); + // The following code do stange things + // (*i).getType().toStream(out, toDepth < 0 ? toDepth : toDepth - 1, + // false, language::output::LANG_SMTLIB_V2_5); + out << ')'; + if (++i != iend) + { + out << ' '; + } } - } - out << ')'; - return; - case kind::INST_PATTERN: - break; - case kind::INST_PATTERN_LIST: - for(unsigned i=0; i<n.getNumChildren(); i++) { - if( n[i].getKind()==kind::INST_ATTRIBUTE ){ - if( n[i][0].getAttribute(theory::FunDefAttribute()) ){ - out << ":fun-def"; + out << ')'; + return; + case kind::INST_PATTERN: break; + case kind::INST_PATTERN_LIST: + for (unsigned i = 0; i < n.getNumChildren(); i++) + { + if (n[i].getKind() == kind::INST_ATTRIBUTE) + { + if (n[i][0].getAttribute(theory::FunDefAttribute())) + { + out << ":fun-def"; + } + } + else + { + out << ":pattern " << n[i]; } - }else{ - out << ":pattern " << n[i]; } - } - return; - break; + return; + break; - default: - // fall back on however the kind prints itself; this probably - // won't be SMT-LIB v2 compliant, but it will be clear from the - // output that support for the kind needs to be added here. - out << n.getKind() << ' '; + default: + // fall back on however the kind prints itself; this probably + // won't be SMT-LIB v2 compliant, but it will be clear from the + // output that support for the kind needs to be added here. + out << n.getKind() << ' '; } if( n.getMetaKind() == kind::metakind::PARAMETERIZED && stillNeedToPrintParams ) { @@ -917,6 +966,12 @@ static string smtKindString(Kind k) case kind::SINGLETON: return "singleton"; case kind::INSERT: return "insert"; case kind::COMPLEMENT: return "complement"; + case kind::CARD: return "card"; + case kind::JOIN: return "join"; + case kind::PRODUCT: return "product"; + case kind::TRANSPOSE: return "transpose"; + case kind::TCLOSURE: + return "tclosure"; // fp theory case kind::FLOATINGPOINT_FP: return "fp"; @@ -1326,7 +1381,11 @@ void Smt2Printer::toStream(std::ostream& out, } */ } else { - out << c << endl; + DatatypeDeclarationCommand* c1 = (DatatypeDeclarationCommand*)c; + const vector<DatatypeType>& datatypes = c1->getDatatypes(); + if (!datatypes[0].isTuple()) { + out << c << endl; + } } } @@ -1762,38 +1821,48 @@ static void toStream(std::ostream& out, { const vector<DatatypeType>& datatypes = c->getDatatypes(); out << "(declare-"; - Assert( !datatypes.empty() ); - if( datatypes[0].getDatatype().isCodatatype() ){ + Assert(!datatypes.empty()); + if (datatypes[0].getDatatype().isCodatatype()) + { out << "co"; } out << "datatypes"; - if(v == smt2_6_variant) { + if (v == smt2_6_variant) + { out << " ("; - for(vector<DatatypeType>::const_iterator i = datatypes.begin(), - i_end = datatypes.end(); - i != i_end; ++i) { - const Datatype & d = i->getDatatype(); + for (vector<DatatypeType>::const_iterator i = datatypes.begin(), + i_end = datatypes.end(); + i != i_end; + ++i) + { + const Datatype& d = i->getDatatype(); out << "(" << maybeQuoteSymbol(d.getName()); out << " " << d.getNumParameters() << ")"; } out << ") ("; - for(vector<DatatypeType>::const_iterator i = datatypes.begin(), - i_end = datatypes.end(); - i != i_end; ++i) { - const Datatype & d = i->getDatatype(); + for (vector<DatatypeType>::const_iterator i = datatypes.begin(), + i_end = datatypes.end(); + i != i_end; + ++i) + { + const Datatype& d = i->getDatatype(); out << "("; - toStream( out, d ); + toStream(out, d); out << ")" << endl; } out << ")"; - }else{ + } + else + { out << " () ("; - for(vector<DatatypeType>::const_iterator i = datatypes.begin(), - i_end = datatypes.end(); - i != i_end; ++i) { - const Datatype & d = i->getDatatype(); + for (vector<DatatypeType>::const_iterator i = datatypes.begin(), + i_end = datatypes.end(); + i != i_end; + ++i) + { + const Datatype& d = i->getDatatype(); out << "(" << maybeQuoteSymbol(d.getName()) << " "; - toStream( out, d ); + toStream(out, d); out << ")" << endl; } out << ")"; |