1 /* ******************* */
4 ** Original author: Christopher L. Conway
5 ** Major contributors: Morgan Deters
6 ** Minor contributors (to current version): Dejan Jovanovic, Kshitij Bansal, Tianyi Liang, Francois Bobot, Andrew Reynolds
7 ** This file is part of the CVC4 project.
8 ** Copyright (c) 2009-2014 New York University and The University of Iowa
9 ** See the file COPYING in the top-level source directory for licensing
10 ** information.\endverbatim
12 ** \brief Parser for SMT-LIB v2 input language
14 ** Parser for SMT-LIB v2 input language.
23 // Skip the default error handling, just break with exceptions
24 // defaultErrorHandler = false;
26 // Only lookahead of <= k requested (disable for LL* parsing)
27 // Note that CVC4's BoundedTokenBuffer requires a fixed k !
28 // If you change this k, change it also in smt2_input.cpp !
34 ** This file is part of CVC4.
35 ** Copyright (c) 2009-2014 New York University and The University of Iowa
36 ** See the file COPYING in the top-level source directory for licensing
43 /** This suppresses warnings about the redefinition of token symbols between
44 * different parsers. The redefinitions should be harmless as long as no
45 * client: (a) #include's the lexer headers for two grammars AND (b) uses the
46 * token symbol definitions.
48 #pragma GCC system_header
50 #if defined(CVC4_COMPETITION_MODE) && !defined(CVC4_SMTCOMP_APPLICATION_TRACK)
51 /* This improves performance by ~10 percent on big inputs.
52 * This option is only valid if we know the input is ASCII (or some 8-bit encoding).
53 * If we know the input is UTF-16, we can use ANTLR3_INLINE_INPUT_UTF16.
54 * Otherwise, we have to let the lexer detect the encoding at runtime.
56 # define ANTLR3_INLINE_INPUT_ASCII
57 # define ANTLR3_INLINE_INPUT_8BIT
58 #endif /* CVC4_COMPETITION_MODE && !CVC4_SMTCOMP_APPLICATION_TRACK */
60 #include "parser/antlr_tracing.h"
62 }/* @lexer::includes */
67 #include "parser/smt2/smt2.h"
68 #include "parser/antlr_input.h"
71 using namespace CVC4::parser;
74 #define PARSER_STATE ((Smt2*)LEXER->super)
75 }/* @lexer::postinclude */
78 #include "expr/command.h"
79 #include "parser/parser.h"
80 #include "parser/antlr_tracing.h"
88 * Just exists to provide the uintptr_t constructor that ANTLR
91 struct myExpr : public CVC4::Expr {
92 myExpr() : CVC4::Expr() {}
93 myExpr(void*) : CVC4::Expr() {}
94 myExpr(const Expr& e) : CVC4::Expr(e) {}
95 myExpr(const myExpr& e) : CVC4::Expr(e) {}
97 }/* CVC4::parser::smt2 namespace */
98 }/* CVC4::parser namespace */
101 }/* @parser::includes */
103 @parser::postinclude {
105 #include "expr/expr.h"
106 #include "expr/kind.h"
107 #include "expr/type.h"
108 #include "parser/antlr_input.h"
109 #include "parser/parser.h"
110 #include "parser/smt2/smt2.h"
111 #include "util/integer.h"
112 #include "util/output.h"
113 #include "util/rational.h"
114 #include "util/hash.h"
115 #include "util/floatingpoint.h"
120 // \todo Review the need for this header
123 using namespace CVC4;
124 using namespace CVC4::parser;
126 /* These need to be macros so they can refer to the PARSER macro, which
127 * will be defined by ANTLR *after* this section. (If they were functions,
128 * PARSER would be undefined.) */
130 #define PARSER_STATE ((Smt2*)PARSER->super)
132 #define EXPR_MANAGER PARSER_STATE->getExprManager()
134 #define MK_EXPR EXPR_MANAGER->mkExpr
136 #define MK_CONST EXPR_MANAGER->mkConst
137 #define UNSUPPORTED PARSER_STATE->unimplementedFeature
139 static bool isClosed(const Expr& e, std::set<Expr>& free, std::hash_set<Expr, ExprHashFunction>& closedCache) {
140 if(closedCache.find(e) != closedCache.end()) {
144 if(e.getKind() == kind::FORALL || e.getKind() == kind::EXISTS || e.getKind() == kind::LAMBDA) {
145 isClosed(e[1], free, closedCache);
146 for(Expr::const_iterator i = e[0].begin(); i != e[0].end(); ++i) {
149 } else if(e.getKind() == kind::BOUND_VARIABLE) {
153 if(e.hasOperator()) {
154 isClosed(e.getOperator(), free, closedCache);
156 for(Expr::const_iterator i = e.begin(); i != e.end(); ++i) {
157 isClosed(*i, free, closedCache);
162 closedCache.insert(e);
169 static inline bool isClosed(const Expr& e, std::set<Expr>& free) {
170 std::hash_set<Expr, ExprHashFunction> cache;
171 return isClosed(e, free, cache);
174 }/* parser::postinclude */
177 * Parses an expression.
178 * @return the parsed expression, or the Null Expr if we've reached the
181 parseExpr returns [CVC4::parser::smt2::myExpr expr]
191 * @return the parsed command, or NULL if we've reached the end of the input
193 parseCommand returns [CVC4::Command* cmd = NULL]
197 : LPAREN_TOK c = command RPAREN_TOK { $cmd = c; }
199 /* This extended command has to be in the outermost production so that
200 * the RPAREN_TOK is properly eaten and we are in a good state to read
201 * the included file's tokens. */
202 | LPAREN_TOK INCLUDE_TOK str[name,true] RPAREN_TOK
203 { if(!PARSER_STATE->canIncludeFile()) {
204 PARSER_STATE->parseError("include-file feature was disabled for this run.");
206 if(PARSER_STATE->strictModeEnabled()) {
207 PARSER_STATE->parseError("Extended commands are not permitted while operating in strict compliance mode.");
209 PARSER_STATE->includeFile(name);
210 // The command of the included file will be produced at the next parseCommand() call
211 cmd = new EmptyCommand("include::" + name);
218 * Parse the internal portion of the command, ignoring the surrounding
221 command returns [CVC4::Command* cmd = NULL]
224 std::vector<std::string> names;
227 std::vector<Expr> terms;
228 std::vector<Type> sorts;
229 std::vector<std::pair<std::string, Type> > sortedVarNames;
231 : /* set the logic */
232 SET_LOGIC_TOK symbol[name,CHECK_NONE,SYM_SORT]
233 { Debug("parser") << "set logic: '" << name << "'" << std::endl;
234 if( PARSER_STATE->logicIsSet() ) {
235 PARSER_STATE->parseError("Only one set-logic is allowed.");
237 PARSER_STATE->setLogic(name);
238 $cmd = new SetBenchmarkLogicCommand(name); }
240 SET_INFO_TOK metaInfoInternal[cmd]
243 { cmd = new GetInfoCommand(AntlrInput::tokenText($KEYWORD).c_str() + 1); }
245 SET_OPTION_TOK setOptionInternal[cmd]
247 GET_OPTION_TOK KEYWORD
248 { cmd = new GetOptionCommand(AntlrInput::tokenText($KEYWORD).c_str() + 1); }
249 | /* sort declaration */
250 DECLARE_SORT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
251 { if(!PARSER_STATE->isTheoryEnabled(Smt2::THEORY_UF) &&
252 !PARSER_STATE->isTheoryEnabled(Smt2::THEORY_ARRAYS) &&
253 !PARSER_STATE->isTheoryEnabled(Smt2::THEORY_DATATYPES) &&
254 !PARSER_STATE->isTheoryEnabled(Smt2::THEORY_SETS)) {
255 PARSER_STATE->parseError(std::string("Free sort symbols not allowed in ") + PARSER_STATE->getLogic().getLogicString());
258 symbol[name,CHECK_UNDECLARED,SYM_SORT]
259 { PARSER_STATE->checkUserSymbol(name); }
261 { Debug("parser") << "declare sort: '" << name
262 << "' arity=" << n << std::endl;
263 unsigned arity = AntlrInput::tokenToUnsigned(n);
265 Type type = PARSER_STATE->mkSort(name);
266 $cmd = new DeclareTypeCommand(name, 0, type);
268 Type type = PARSER_STATE->mkSortConstructor(name, arity);
269 $cmd = new DeclareTypeCommand(name, arity, type);
272 | /* sort definition */
273 DEFINE_SORT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
274 symbol[name,CHECK_UNDECLARED,SYM_SORT]
275 { PARSER_STATE->checkUserSymbol(name); }
276 LPAREN_TOK symbolList[names,CHECK_NONE,SYM_SORT] RPAREN_TOK
277 { PARSER_STATE->pushScope(true);
278 for(std::vector<std::string>::const_iterator i = names.begin(),
282 sorts.push_back(PARSER_STATE->mkSort(*i));
285 sortSymbol[t,CHECK_DECLARED]
286 { PARSER_STATE->popScope();
287 // Do NOT call mkSort, since that creates a new sort!
288 // This name is not its own distinct sort, it's an alias.
289 PARSER_STATE->defineParameterizedType(name, sorts, t);
290 $cmd = new DefineTypeCommand(name, sorts, t);
292 | /* function declaration */
293 DECLARE_FUN_TOK { PARSER_STATE->checkThatLogicIsSet(); }
294 symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
295 { PARSER_STATE->checkUserSymbol(name); }
296 LPAREN_TOK sortList[sorts] RPAREN_TOK
297 sortSymbol[t,CHECK_DECLARED]
298 { Debug("parser") << "declare fun: '" << name << "'" << std::endl;
299 if( sorts.size() > 0 ) {
300 if(!PARSER_STATE->isTheoryEnabled(Smt2::THEORY_UF)) {
301 PARSER_STATE->parseError(std::string("Functions (of non-zero arity) cannot be declared in logic ") + PARSER_STATE->getLogic().getLogicString());
303 t = EXPR_MANAGER->mkFunctionType(sorts, t);
305 Expr func = PARSER_STATE->mkVar(name, t);
306 $cmd = new DeclareFunctionCommand(name, func, t); }
307 | /* function definition */
308 DEFINE_FUN_TOK { PARSER_STATE->checkThatLogicIsSet(); }
309 symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
310 { PARSER_STATE->checkUserSymbol(name); }
311 LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK
312 sortSymbol[t,CHECK_DECLARED]
313 { /* add variables to parser state before parsing term */
314 Debug("parser") << "define fun: '" << name << "'" << std::endl;
315 if( sortedVarNames.size() > 0 ) {
316 std::vector<CVC4::Type> sorts;
317 sorts.reserve(sortedVarNames.size());
318 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
319 sortedVarNames.begin(), iend = sortedVarNames.end();
322 sorts.push_back((*i).second);
324 t = EXPR_MANAGER->mkFunctionType(sorts, t);
326 PARSER_STATE->pushScope(true);
327 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
328 sortedVarNames.begin(), iend = sortedVarNames.end();
331 terms.push_back(PARSER_STATE->mkBoundVar((*i).first, (*i).second));
335 { PARSER_STATE->popScope();
336 // declare the name down here (while parsing term, signature
337 // must not be extended with the name itself; no recursion
339 Expr func = PARSER_STATE->mkFunction(name, t, ExprManager::VAR_FLAG_DEFINED);
340 $cmd = new DefineFunctionCommand(name, func, terms, expr);
343 GET_VALUE_TOK { PARSER_STATE->checkThatLogicIsSet(); }
344 ( LPAREN_TOK termList[terms,expr] RPAREN_TOK
345 { $cmd = new GetValueCommand(terms); }
347 { PARSER_STATE->parseError("The get-value command expects a list of terms. Perhaps you forgot a pair of parentheses?"); } )
348 | /* get-assignment */
349 GET_ASSIGNMENT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
350 { cmd = new GetAssignmentCommand(); }
352 ASSERT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
353 { PARSER_STATE->clearLastNamedTerm(); }
355 { bool inUnsatCore = PARSER_STATE->lastNamedTerm().first == expr;
356 cmd = new AssertCommand(expr, inUnsatCore);
358 PARSER_STATE->registerUnsatCoreName(PARSER_STATE->lastNamedTerm());
362 CHECKSAT_TOK { PARSER_STATE->checkThatLogicIsSet(); }
364 { if(PARSER_STATE->strictModeEnabled()) {
365 PARSER_STATE->parseError("Extended commands (such as check-sat with an argument) are not permitted while operating in strict compliance mode.");
368 | { expr = MK_CONST(bool(true)); } )
369 { cmd = new CheckSatCommand(expr); }
370 | /* get-assertions */
371 GET_ASSERTIONS_TOK { PARSER_STATE->checkThatLogicIsSet(); }
372 { cmd = new GetAssertionsCommand(); }
374 GET_PROOF_TOK { PARSER_STATE->checkThatLogicIsSet(); }
375 { cmd = new GetProofCommand(); }
376 | /* get-unsat-core */
377 GET_UNSAT_CORE_TOK { PARSER_STATE->checkThatLogicIsSet(); }
378 { cmd = new GetUnsatCoreCommand(PARSER_STATE->getUnsatCoreNames()); }
380 PUSH_TOK { PARSER_STATE->checkThatLogicIsSet(); }
382 { unsigned n = AntlrInput::tokenToUnsigned(k);
384 cmd = new EmptyCommand();
386 PARSER_STATE->pushScope();
387 PARSER_STATE->pushUnsatCoreNameScope();
388 cmd = new PushCommand();
390 CommandSequence* seq = new CommandSequence();
392 PARSER_STATE->pushScope();
393 PARSER_STATE->pushUnsatCoreNameScope();
394 Command* c = new PushCommand();
401 | { if(PARSER_STATE->strictModeEnabled()) {
402 PARSER_STATE->parseError("Strict compliance mode demands an integer to be provided to PUSH. Maybe you want (push 1)?");
404 PARSER_STATE->pushScope();
405 PARSER_STATE->pushUnsatCoreNameScope();
406 cmd = new PushCommand();
409 | POP_TOK { PARSER_STATE->checkThatLogicIsSet(); }
411 { unsigned n = AntlrInput::tokenToUnsigned(k);
412 if(n > PARSER_STATE->scopeLevel()) {
413 PARSER_STATE->parseError("Attempted to pop above the top stack frame.");
416 cmd = new EmptyCommand();
418 PARSER_STATE->popUnsatCoreNameScope();
419 PARSER_STATE->popScope();
420 cmd = new PopCommand();
422 CommandSequence* seq = new CommandSequence();
424 PARSER_STATE->popUnsatCoreNameScope();
425 PARSER_STATE->popScope();
426 Command* c = new PopCommand();
433 | { if(PARSER_STATE->strictModeEnabled()) {
434 PARSER_STATE->parseError("Strict compliance mode demands an integer to be provided to POP. Maybe you want (pop 1)?");
436 PARSER_STATE->popUnsatCoreNameScope();
437 PARSER_STATE->popScope();
438 cmd = new PopCommand();
444 { cmd = new QuitCommand(); }
446 /* New SMT-LIB 2.5 command set */
448 { if(PARSER_STATE->v2_0() && PARSER_STATE->strictModeEnabled()) {
449 PARSER_STATE->parseError("SMT-LIB 2.5 commands are not permitted while operating in strict compliance mode and in SMT-LIB 2.0 mode.");
453 /* CVC4-extended SMT-LIB commands */
454 | extendedCommand[cmd]
455 { if(PARSER_STATE->strictModeEnabled()) {
456 PARSER_STATE->parseError("Extended commands are not permitted while operating in strict compliance mode.");
462 { std::string id = AntlrInput::tokenText($SIMPLE_SYMBOL);
463 if(id == "benchmark") {
464 PARSER_STATE->parseError("In SMT-LIBv2 mode, but got something that looks like SMT-LIBv1. Use --lang smt1 for SMT-LIBv1.");
466 PARSER_STATE->parseError("expected SMT-LIBv2 command, got `" + id + "'.");
471 // Separate this into its own rule (can be invoked by set-info or meta-info)
472 metaInfoInternal[CVC4::Command*& cmd]
477 : KEYWORD symbolicExpr[sexpr]
478 { name = AntlrInput::tokenText($KEYWORD);
479 if(name == ":cvc4-logic" || name == ":cvc4_logic") {
480 PARSER_STATE->setLogic(sexpr.getValue());
481 } else if(name == ":smt-lib-version") {
482 // if we don't recognize the revision name, just keep the current mode
483 if( (sexpr.isRational() && sexpr.getRationalValue() == Rational(2)) ||
484 sexpr.getValue() == "2" ||
485 sexpr.getValue() == "2.0" ) {
486 PARSER_STATE->setLanguage(language::input::LANG_SMTLIB_V2_0);
487 } else if( (sexpr.isRational() && sexpr.getRationalValue() == Rational(5, 2)) ||
488 sexpr.getValue() == "2.5" ) {
489 PARSER_STATE->setLanguage(language::input::LANG_SMTLIB_V2_5);
492 PARSER_STATE->setInfo(name.c_str() + 1, sexpr);
493 cmd = new SetInfoCommand(name.c_str() + 1, sexpr);
497 setOptionInternal[CVC4::Command*& cmd]
502 : keyword[name] symbolicExpr[sexpr]
503 { PARSER_STATE->setOption(name.c_str() + 1, sexpr);
504 cmd = new SetOptionCommand(name.c_str() + 1, sexpr);
505 // Ugly that this changes the state of the parser; but
506 // global-declarations affects parsing, so we can't hold off
507 // on this until some SmtEngine eventually (if ever) executes it.
508 if(name == ":global-declarations") {
509 PARSER_STATE->setGlobalDeclarations(sexpr.getValue() == "true");
514 smt25Command[CVC4::Command*& cmd]
518 std::vector<std::pair<std::string, Type> > sortedVarNames;
523 : META_INFO_TOK metaInfoInternal[cmd]
526 | DECLARE_CONST_TOK { PARSER_STATE->checkThatLogicIsSet(); }
527 symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
528 { PARSER_STATE->checkUserSymbol(name); }
529 sortSymbol[t,CHECK_DECLARED]
530 { Expr c = PARSER_STATE->mkVar(name, t);
531 $cmd = new DeclareFunctionCommand(name, c, t); }
534 | GET_MODEL_TOK { PARSER_STATE->checkThatLogicIsSet(); }
535 { cmd = new GetModelCommand(); }
539 ( simpleSymbolicExpr[sexpr]
540 { std::stringstream ss;
542 cmd = new EchoCommand(ss.str());
544 | { cmd = new EchoCommand(); }
547 /* reset: reset everything, returning solver to initial state.
548 * Logic and options must be set again. */
550 { cmd = new ResetCommand();
551 PARSER_STATE->reset();
553 /* reset-assertions: reset assertions, assertion stack, declarations,
554 * etc., but the logic and options remain as they were. */
555 | RESET_ASSERTIONS_TOK
556 { cmd = new ResetAssertionsCommand();
557 PARSER_STATE->resetAssertions();
560 | /* recursive function definition */
561 DEFINE_FUN_REC_TOK { PARSER_STATE->checkThatLogicIsSet(); } LPAREN_TOK
562 { PARSER_STATE->pushScope(true); }
563 ( LPAREN_TOK symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
564 { PARSER_STATE->checkUserSymbol(name); }
565 LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK
566 sortSymbol[t,CHECK_DECLARED]
567 { /* add variables to parser state before parsing term */
568 Debug("parser") << "define fun rec: '" << name << "'" << std::endl;
569 if( sortedVarNames.size() > 0 ) {
570 std::vector<CVC4::Type> sorts;
571 sorts.reserve(sortedVarNames.size());
572 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
573 sortedVarNames.begin(), iend = sortedVarNames.end();
576 sorts.push_back((*i).second);
578 t = EXPR_MANAGER->mkFunctionType(sorts, t);
580 PARSER_STATE->mkFunction(name, t, ExprManager::VAR_FLAG_DEFINED);
581 PARSER_STATE->pushScope(true);
582 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
583 sortedVarNames.begin(), iend = sortedVarNames.end();
586 PARSER_STATE->mkBoundVar((*i).first, (*i).second);
590 { PARSER_STATE->popScope(); }
591 RPAREN_TOK )+ RPAREN_TOK
592 { PARSER_STATE->popScope(); }
594 // CHECK_SAT_ASSUMING still being discussed
595 // GET_UNSAT_ASSUMPTIONS
598 extendedCommand[CVC4::Command*& cmd]
600 std::vector<CVC4::Datatype> dts;
604 std::vector<std::string> names;
605 std::vector<Expr> terms;
606 std::vector<Type> sorts;
607 std::vector<std::pair<std::string, Type> > sortedVarNames;
609 /* Extended SMT-LIB set of commands syntax, not permitted in
610 * --smtlib2 compliance mode. */
611 : DECLARE_DATATYPES_TOK datatypesDefCommand[false, cmd]
612 | DECLARE_CODATATYPES_TOK datatypesDefCommand[true, cmd]
613 | rewriterulesCommand[cmd]
615 /* Support some of Z3's extended SMT-LIB commands */
617 | DECLARE_SORTS_TOK { PARSER_STATE->checkThatLogicIsSet(); }
618 { if(!PARSER_STATE->isTheoryEnabled(Smt2::THEORY_UF) &&
619 !PARSER_STATE->isTheoryEnabled(Smt2::THEORY_ARRAYS) &&
620 !PARSER_STATE->isTheoryEnabled(Smt2::THEORY_DATATYPES) &&
621 !PARSER_STATE->isTheoryEnabled(Smt2::THEORY_SETS)) {
622 PARSER_STATE->parseError(std::string("Free sort symbols not allowed in ") + PARSER_STATE->getLogic().getLogicString());
625 { $cmd = new CommandSequence(); }
627 ( symbol[name,CHECK_UNDECLARED,SYM_SORT]
628 { PARSER_STATE->checkUserSymbol(name);
629 Type type = PARSER_STATE->mkSort(name);
630 static_cast<CommandSequence*>($cmd)->addCommand(new DeclareTypeCommand(name, 0, type));
635 | DECLARE_FUNS_TOK { PARSER_STATE->checkThatLogicIsSet(); }
636 { $cmd = new CommandSequence(); }
638 ( LPAREN_TOK symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
639 { PARSER_STATE->checkUserSymbol(name); }
640 nonemptySortList[sorts] RPAREN_TOK
642 if(sorts.size() > 1) {
643 if(!PARSER_STATE->isTheoryEnabled(Smt2::THEORY_UF)) {
644 PARSER_STATE->parseError(std::string("Functions (of non-zero arity) cannot be declared in logic ") + PARSER_STATE->getLogic().getLogicString());
646 t = EXPR_MANAGER->mkFunctionType(sorts);
650 Expr func = PARSER_STATE->mkVar(name, t);
651 static_cast<CommandSequence*>($cmd)->addCommand(new DeclareFunctionCommand(name, func, t));
656 | DECLARE_PREDS_TOK { PARSER_STATE->checkThatLogicIsSet(); }
657 { $cmd = new CommandSequence(); }
659 ( LPAREN_TOK symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
660 { PARSER_STATE->checkUserSymbol(name); }
661 sortList[sorts] RPAREN_TOK
662 { Type t = EXPR_MANAGER->booleanType();
663 if(sorts.size() > 0) {
664 if(!PARSER_STATE->isTheoryEnabled(Smt2::THEORY_UF)) {
665 PARSER_STATE->parseError(std::string("Predicates (of non-zero arity) cannot be declared in logic ") + PARSER_STATE->getLogic().getLogicString());
667 t = EXPR_MANAGER->mkFunctionType(sorts, t);
669 Expr func = PARSER_STATE->mkVar(name, t);
670 static_cast<CommandSequence*>($cmd)->addCommand(new DeclareFunctionCommand(name, func, t));
675 | DEFINE_TOK { PARSER_STATE->checkThatLogicIsSet(); }
676 ( symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
677 { PARSER_STATE->checkUserSymbol(name); }
679 { Expr func = PARSER_STATE->mkFunction(name, e.getType(), ExprManager::VAR_FLAG_DEFINED);
680 $cmd = new DefineFunctionCommand(name, func, e);
683 symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
684 { PARSER_STATE->checkUserSymbol(name); }
685 sortedVarList[sortedVarNames] RPAREN_TOK
686 { /* add variables to parser state before parsing term */
687 Debug("parser") << "define fun: '" << name << "'" << std::endl;
688 PARSER_STATE->pushScope(true);
689 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
690 sortedVarNames.begin(), iend = sortedVarNames.end();
693 terms.push_back(PARSER_STATE->mkBoundVar((*i).first, (*i).second));
697 { PARSER_STATE->popScope();
698 // declare the name down here (while parsing term, signature
699 // must not be extended with the name itself; no recursion
701 Type t = e.getType();
702 if( sortedVarNames.size() > 0 ) {
703 std::vector<CVC4::Type> sorts;
704 sorts.reserve(sortedVarNames.size());
705 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
706 sortedVarNames.begin(), iend = sortedVarNames.end();
709 sorts.push_back((*i).second);
711 t = EXPR_MANAGER->mkFunctionType(sorts, t);
713 Expr func = PARSER_STATE->mkFunction(name, t, ExprManager::VAR_FLAG_DEFINED);
714 $cmd = new DefineFunctionCommand(name, func, terms, e);
717 | DEFINE_CONST_TOK { PARSER_STATE->checkThatLogicIsSet(); }
718 symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
719 { PARSER_STATE->checkUserSymbol(name); }
720 sortSymbol[t,CHECK_DECLARED]
721 { /* add variables to parser state before parsing term */
722 Debug("parser") << "define const: '" << name << "'" << std::endl;
723 PARSER_STATE->pushScope(true);
724 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
725 sortedVarNames.begin(), iend = sortedVarNames.end();
728 terms.push_back(PARSER_STATE->mkBoundVar((*i).first, (*i).second));
732 { PARSER_STATE->popScope();
733 // declare the name down here (while parsing term, signature
734 // must not be extended with the name itself; no recursion
736 Expr func = PARSER_STATE->mkFunction(name, t, ExprManager::VAR_FLAG_DEFINED);
737 $cmd = new DefineFunctionCommand(name, func, terms, e);
740 | SIMPLIFY_TOK { PARSER_STATE->checkThatLogicIsSet(); }
742 { cmd = new SimplifyCommand(e); }
746 datatypesDefCommand[bool isCo, CVC4::Command*& cmd]
748 std::vector<CVC4::Datatype> dts;
750 std::vector<Type> sorts;
752 : { PARSER_STATE->checkThatLogicIsSet();
753 /* open a scope to keep the UnresolvedTypes contained */
754 PARSER_STATE->pushScope(true); }
755 LPAREN_TOK /* parametric sorts */
756 ( symbol[name,CHECK_UNDECLARED,SYM_SORT] {
757 sorts.push_back( PARSER_STATE->mkSort(name) ); }
760 LPAREN_TOK ( LPAREN_TOK datatypeDef[isCo, dts, sorts] RPAREN_TOK )+ RPAREN_TOK
761 { PARSER_STATE->popScope();
762 cmd = new DatatypeDeclarationCommand(PARSER_STATE->mkMutualDatatypeTypes(dts)); }
765 rewriterulesCommand[CVC4::Command*& cmd]
767 std::vector<std::pair<std::string, Type> > sortedVarNames;
768 std::vector<Expr> args, guards, heads, triggers;
769 Expr head, body, expr, expr2, bvl;
772 : /* rewrite rules */
774 LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK
776 kind = CVC4::kind::RR_REWRITE;
777 PARSER_STATE->pushScope(true);
778 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
779 sortedVarNames.begin(), iend = sortedVarNames.end();
782 args.push_back(PARSER_STATE->mkBoundVar((*i).first, (*i).second));
784 bvl = MK_EXPR(kind::BOUND_VAR_LIST, args);
786 LPAREN_TOK ( pattern[expr] { triggers.push_back( expr ); } )* RPAREN_TOK
787 LPAREN_TOK (termList[guards,expr])? RPAREN_TOK
788 term[head, expr2] term[body, expr2]
791 args.push_back(head);
792 args.push_back(body);
794 if( !triggers.empty() ){
795 expr2 = MK_EXPR(kind::INST_PATTERN_LIST, triggers);
796 args.push_back(expr2);
798 expr = MK_EXPR(kind, args);
802 switch( guards.size() ){
804 args.push_back(MK_CONST(bool(true))); break;
806 args.push_back(guards[0]); break;
808 expr2 = MK_EXPR(kind::AND, guards);
809 args.push_back(expr2); break;
811 args.push_back(expr);
812 expr = MK_EXPR(CVC4::kind::REWRITE_RULE, args);
813 cmd = new AssertCommand(expr, false); }
814 /* propagation rule */
815 | rewritePropaKind[kind]
816 LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK
818 PARSER_STATE->pushScope(true);
819 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
820 sortedVarNames.begin(), iend = sortedVarNames.end();
823 args.push_back(PARSER_STATE->mkBoundVar((*i).first, (*i).second));
825 bvl = MK_EXPR(kind::BOUND_VAR_LIST, args);
827 LPAREN_TOK ( pattern[expr] { triggers.push_back( expr ); } )* RPAREN_TOK
828 LPAREN_TOK (termList[guards,expr])? RPAREN_TOK
829 LPAREN_TOK (termList[heads,expr])? RPAREN_TOK
834 switch( heads.size() ){
836 args.push_back(MK_CONST(bool(true))); break;
838 args.push_back(heads[0]); break;
840 expr2 = MK_EXPR(kind::AND, heads);
841 args.push_back(expr2); break;
843 args.push_back(body);
845 if( !triggers.empty() ){
846 expr2 = MK_EXPR(kind::INST_PATTERN_LIST, triggers);
847 args.push_back(expr2);
849 expr = MK_EXPR(kind, args);
853 switch( guards.size() ){
855 args.push_back(MK_CONST(bool(true))); break;
857 args.push_back(guards[0]); break;
859 expr2 = MK_EXPR(kind::AND, guards);
860 args.push_back(expr2); break;
862 args.push_back(expr);
863 expr = MK_EXPR(CVC4::kind::REWRITE_RULE, args);
864 cmd = new AssertCommand(expr, false); }
867 rewritePropaKind[CVC4::Kind& kind]
868 : REDUCTION_RULE_TOK { $kind = CVC4::kind::RR_REDUCTION; }
869 | PROPAGATION_RULE_TOK { $kind = CVC4::kind::RR_DEDUCTION; }
872 pattern[CVC4::Expr& expr]
874 std::vector<Expr> patexpr;
876 : LPAREN_TOK termList[patexpr,expr] RPAREN_TOK
878 expr = MK_EXPR(kind::INST_PATTERN, patexpr);
882 simpleSymbolicExprNoKeyword[CVC4::SExpr& sexpr]
886 std::vector<unsigned int> s_vec;
889 { sexpr = SExpr(Integer(AntlrInput::tokenText($INTEGER_LITERAL))); }
891 { sexpr = SExpr(AntlrInput::tokenToRational($DECIMAL_LITERAL)); }
893 { assert( AntlrInput::tokenText($HEX_LITERAL).find("#x") == 0 );
894 std::string hexString = AntlrInput::tokenTextSubstr($HEX_LITERAL, 2);
895 sexpr = Integer(hexString, 16);
898 { assert( AntlrInput::tokenText($BINARY_LITERAL).find("#b") == 0 );
899 std::string binString = AntlrInput::tokenTextSubstr($BINARY_LITERAL, 2);
900 sexpr = Integer(binString, 2);
903 { sexpr = SExpr(s); }
904 // | LPAREN_TOK STRCST_TOK
905 // ( INTEGER_LITERAL {
906 // s_vec.push_back( atoi( AntlrInput::tokenText($INTEGER_LITERAL) ) + 65 );
909 // sexpr = SExpr( MK_CONST( ::CVC4::String(s_vec) ) );
911 | symbol[s,CHECK_NONE,SYM_SORT]
912 { sexpr = SExpr(SExpr::Keyword(s)); }
913 | tok=(ASSERT_TOK | CHECKSAT_TOK | DECLARE_FUN_TOK | DECLARE_SORT_TOK | DEFINE_FUN_TOK | DEFINE_FUN_REC_TOK | DEFINE_SORT_TOK | GET_VALUE_TOK | GET_ASSIGNMENT_TOK | GET_ASSERTIONS_TOK | GET_PROOF_TOK | GET_UNSAT_CORE_TOK | EXIT_TOK | RESET_TOK | RESET_ASSERTIONS_TOK | SET_LOGIC_TOK | SET_INFO_TOK | GET_INFO_TOK | SET_OPTION_TOK | GET_OPTION_TOK | PUSH_TOK | POP_TOK | DECLARE_DATATYPES_TOK | GET_MODEL_TOK | ECHO_TOK | REWRITE_RULE_TOK | REDUCTION_RULE_TOK | PROPAGATION_RULE_TOK | SIMPLIFY_TOK)
914 { sexpr = SExpr(SExpr::Keyword(AntlrInput::tokenText($tok))); }
916 { std::stringstream ss;
917 ss << Expr::setlanguage(CVC4::language::output::LANG_SMTLIB_V2_5) << EXPR_MANAGER->mkConst(k);
918 sexpr = SExpr(ss.str());
922 keyword[std::string& s]
924 { s = AntlrInput::tokenText($KEYWORD); }
927 simpleSymbolicExpr[CVC4::SExpr& sexpr]
928 : simpleSymbolicExprNoKeyword[sexpr]
930 { sexpr = SExpr(AntlrInput::tokenText($KEYWORD)); }
933 symbolicExpr[CVC4::SExpr& sexpr]
935 std::vector<SExpr> children;
937 : simpleSymbolicExpr[sexpr]
939 ( symbolicExpr[sexpr] { children.push_back(sexpr); } )* RPAREN_TOK
940 { sexpr = SExpr(children); }
945 * @return the expression representing the formula
947 term[CVC4::Expr& expr, CVC4::Expr& expr2]
949 Debug("parser") << "term: " << AntlrInput::tokenText(LT(1)) << std::endl;
950 Kind kind = kind::NULL_EXPR;
953 std::vector<Expr> args;
954 std::vector< std::pair<std::string, Type> > sortedVarNames;
958 std::vector<Expr> patexprs;
959 std::hash_set<std::string, StringHashFunction> names;
960 std::vector< std::pair<std::string, Expr> > binders;
963 bool isBuiltinOperator = false;
965 : /* a built-in operator application */
966 LPAREN_TOK builtinOp[kind] termList[args,expr] RPAREN_TOK
968 if( kind == CVC4::kind::EQUAL &&
970 args[0].getType() == EXPR_MANAGER->booleanType() ) {
971 /* Use IFF for boolean equalities. */
972 kind = CVC4::kind::IFF;
975 if( !PARSER_STATE->strictModeEnabled() &&
976 (kind == CVC4::kind::AND || kind == CVC4::kind::OR) &&
978 /* Unary AND/OR can be replaced with the argument.
979 * It just so happens expr should already be the only argument. */
980 assert( expr == args[0] );
981 } else if( CVC4::kind::isAssociative(kind) &&
982 args.size() > EXPR_MANAGER->maxArity(kind) ) {
983 /* Special treatment for associative operators with lots of children */
984 expr = EXPR_MANAGER->mkAssociative(kind, args);
985 } else if( kind == CVC4::kind::MINUS && args.size() == 1 ) {
986 expr = MK_EXPR(CVC4::kind::UMINUS, args[0]);
987 } else if( ( kind == CVC4::kind::XOR || kind == CVC4::kind::MINUS ) &&
989 /* left-associative, but CVC4 internally only supports 2 args */
991 for(size_t i = 1; i < args.size(); ++i) {
992 expr = MK_EXPR(kind, expr, args[i]);
994 } else if( kind == CVC4::kind::IMPLIES && args.size() > 2 ) {
995 /* right-associative, but CVC4 internally only supports 2 args */
996 expr = args[args.size() - 1];
997 for(size_t i = args.size() - 1; i > 0;) {
998 expr = MK_EXPR(kind, args[--i], expr);
1000 } else if( ( kind == CVC4::kind::IFF || kind == CVC4::kind::EQUAL ||
1001 kind == CVC4::kind::LT || kind == CVC4::kind::GT ||
1002 kind == CVC4::kind::LEQ || kind == CVC4::kind::GEQ ) &&
1004 /* "chainable", but CVC4 internally only supports 2 args */
1005 expr = MK_EXPR(MK_CONST(Chain(kind)), args);
1006 } else if( PARSER_STATE->strictModeEnabled() && kind == CVC4::kind::ABS &&
1007 args.size() == 1 && !args[0].getType().isInteger() ) {
1008 /* first, check that ABS is even defined in this logic */
1009 PARSER_STATE->checkOperator(kind, args.size());
1010 PARSER_STATE->parseError("abs can only be applied to Int, not Real, while in strict SMT-LIB compliance mode");
1012 PARSER_STATE->checkOperator(kind, args.size());
1013 expr = MK_EXPR(kind, args);
1016 | LPAREN_TOK AS_TOK term[f, f2] sortSymbol[type, CHECK_DECLARED] RPAREN_TOK
1018 if(f.getKind() == CVC4::kind::APPLY_CONSTRUCTOR && type.isDatatype()) {
1019 std::vector<CVC4::Expr> v;
1020 Expr e = f.getOperator();
1021 const DatatypeConstructor& dtc = Datatype::datatypeOf(e)[Datatype::indexOf(e)];
1022 v.push_back(MK_EXPR( CVC4::kind::APPLY_TYPE_ASCRIPTION,
1023 MK_CONST(AscriptionType(dtc.getSpecializedConstructorType(type))), f.getOperator() ));
1024 v.insert(v.end(), f.begin(), f.end());
1025 expr = MK_EXPR(CVC4::kind::APPLY_CONSTRUCTOR, v);
1026 } else if(f.getKind() == CVC4::kind::EMPTYSET) {
1027 Debug("parser") << "Empty set encountered: " << f << " "
1028 << f2 << " " << type << std::endl;
1029 expr = MK_CONST( ::CVC4::EmptySet(type) );
1031 if(f.getType() != type) {
1032 PARSER_STATE->parseError("Type ascription not satisfied.");
1036 | LPAREN_TOK quantOp[kind]
1037 LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK
1039 PARSER_STATE->pushScope(true);
1040 for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
1041 sortedVarNames.begin(), iend = sortedVarNames.end();
1044 args.push_back(PARSER_STATE->mkBoundVar((*i).first, (*i).second));
1046 Expr bvl = MK_EXPR(kind::BOUND_VAR_LIST, args);
1048 args.push_back(bvl);
1050 term[f, f2] RPAREN_TOK
1052 PARSER_STATE->popScope();
1053 switch(f.getKind()) {
1054 case CVC4::kind::RR_REWRITE:
1055 case CVC4::kind::RR_REDUCTION:
1056 case CVC4::kind::RR_DEDUCTION:
1057 if(kind == CVC4::kind::EXISTS) {
1058 PARSER_STATE->parseError("Use Exists instead of Forall for a rewrite rule.");
1060 args.push_back(f2); // guards
1061 args.push_back(f); // rule
1062 expr = MK_EXPR(CVC4::kind::REWRITE_RULE, args);
1069 expr = MK_EXPR(kind, args);
1072 | LPAREN_TOK functionName[name, CHECK_NONE]
1073 { isBuiltinOperator = PARSER_STATE->isOperatorEnabled(name);
1074 if(isBuiltinOperator) {
1075 /* A built-in operator not already handled by the lexer */
1076 kind = PARSER_STATE->getOperatorKind(name);
1078 /* A non-built-in function application */
1079 PARSER_STATE->checkDeclaration(name, CHECK_DECLARED, SYM_VARIABLE);
1080 PARSER_STATE->checkFunctionLike(name);
1081 const bool isDefinedFunction =
1082 PARSER_STATE->isDefinedFunction(name);
1083 if(isDefinedFunction) {
1084 expr = PARSER_STATE->getFunction(name);
1085 kind = CVC4::kind::APPLY;
1087 expr = PARSER_STATE->getVariable(name);
1088 Type t = expr.getType();
1089 if(t.isConstructor()) {
1090 kind = CVC4::kind::APPLY_CONSTRUCTOR;
1091 } else if(t.isSelector()) {
1092 kind = CVC4::kind::APPLY_SELECTOR;
1093 } else if(t.isTester()) {
1094 kind = CVC4::kind::APPLY_TESTER;
1096 kind = CVC4::kind::APPLY_UF;
1099 args.push_back(expr);
1102 termList[args,expr] RPAREN_TOK
1103 { Debug("parser") << "args has size " << args.size() << std::endl << "expr is " << expr << std::endl;
1104 for(std::vector<Expr>::iterator i = args.begin(); i != args.end(); ++i) {
1105 Debug("parser") << "++ " << *i << std::endl;
1107 if(isBuiltinOperator) {
1108 PARSER_STATE->checkOperator(kind, args.size());
1110 expr = MK_EXPR(kind, args); }
1113 ( /* An indexed function application */
1114 indexedFunctionName[op] termList[args,expr] RPAREN_TOK
1115 { expr = MK_EXPR(op, args);
1116 PARSER_STATE->checkOperator(expr.getKind(), args.size());
1118 | /* Array constant (in Z3 syntax) */
1119 LPAREN_TOK AS_TOK CONST_TOK sortSymbol[type, CHECK_DECLARED]
1120 RPAREN_TOK term[f, f2] RPAREN_TOK
1122 if(!type.isArray()) {
1123 std::stringstream ss;
1124 ss << "expected array constant term, but cast is not of array type" << std::endl
1125 << "cast type: " << type;
1126 PARSER_STATE->parseError(ss.str());
1129 std::stringstream ss;
1130 ss << "expected constant term inside array constant, but found "
1131 << "nonconstant term:" << std::endl
1132 << "the term: " << f;
1133 PARSER_STATE->parseError(ss.str());
1135 if(!ArrayType(type).getConstituentType().isComparableTo(f.getType())) {
1136 std::stringstream ss;
1137 ss << "type mismatch inside array constant term:" << std::endl
1138 << "array type: " << type << std::endl
1139 << "expected const type: " << ArrayType(type).getConstituentType() << std::endl
1140 << "computed const type: " << f.getType();
1141 PARSER_STATE->parseError(ss.str());
1143 expr = MK_CONST( ::CVC4::ArrayStoreAll(type, f) );
1146 | /* a let binding */
1147 LPAREN_TOK LET_TOK LPAREN_TOK
1148 { PARSER_STATE->pushScope(true); }
1149 ( LPAREN_TOK symbol[name,CHECK_NONE,SYM_VARIABLE] term[expr, f2] RPAREN_TOK
1150 // this is a parallel let, so we have to save up all the contributions
1151 // of the let and define them only later on
1152 { if(names.count(name) == 1) {
1153 std::stringstream ss;
1154 ss << "warning: symbol `" << name << "' bound multiple times by let; the last binding will be used, shadowing earlier ones";
1155 PARSER_STATE->warning(ss.str());
1159 binders.push_back(std::make_pair(name, expr)); } )+
1160 { // now implement these bindings
1161 for(std::vector< std::pair<std::string, Expr> >::iterator i = binders.begin(); i != binders.end(); ++i) {
1162 PARSER_STATE->defineVar((*i).first, (*i).second);
1168 { PARSER_STATE->popScope(); }
1171 | symbol[name,CHECK_DECLARED,SYM_VARIABLE]
1172 { const bool isDefinedFunction =
1173 PARSER_STATE->isDefinedFunction(name);
1174 if(PARSER_STATE->isAbstractValue(name)) {
1175 expr = PARSER_STATE->mkAbstractValue(name);
1176 } else if(isDefinedFunction) {
1177 expr = MK_EXPR(CVC4::kind::APPLY,
1178 PARSER_STATE->getFunction(name));
1180 expr = PARSER_STATE->getVariable(name);
1181 Type t = PARSER_STATE->getType(name);
1182 if(t.isConstructor() && ConstructorType(t).getArity() == 0) {
1183 // don't require parentheses, immediately turn it into an apply
1184 expr = MK_EXPR(CVC4::kind::APPLY_CONSTRUCTOR, expr);
1189 /* attributed expressions */
1190 | LPAREN_TOK ATTRIBUTE_TOK term[expr, f2]
1191 ( attribute[expr, attexpr, attr]
1192 { if( ! attexpr.isNull()) {
1193 patexprs.push_back( attexpr );
1198 if(attr == ":rewrite-rule") {
1201 if(expr[1].getKind() == kind::IMPLIES ||
1202 expr[1].getKind() == kind::IFF ||
1203 expr[1].getKind() == kind::EQUAL) {
1207 guard = MK_CONST(bool(true));
1211 args.push_back(body[0]);
1212 args.push_back(body[1]);
1217 if ( body.getKind()==kind::IMPLIES ) kind = kind::RR_DEDUCTION;
1218 else if( body.getKind()==kind::IFF ) kind = kind::RR_REDUCTION;
1219 else if( body.getKind()==kind::EQUAL ) kind = kind::RR_REWRITE;
1220 else PARSER_STATE->parseError("Error parsing rewrite rule.");
1222 expr = MK_EXPR( kind, args );
1223 } else if(! patexprs.empty()) {
1224 if( !f2.isNull() && f2.getKind()==kind::INST_PATTERN_LIST ){
1225 for( size_t i=0; i<f2.getNumChildren(); i++ ){
1226 if( f2[i].getKind()==kind::INST_PATTERN ){
1227 patexprs.push_back( f2[i] );
1229 std::stringstream ss;
1230 ss << "warning: rewrite rules do not support " << f2[i] << " within instantiation pattern list";
1231 PARSER_STATE->warning(ss.str());
1235 expr2 = MK_EXPR(kind::INST_PATTERN_LIST, patexprs);
1242 { expr = MK_CONST( AntlrInput::tokenToInteger($INTEGER_LITERAL) ); }
1245 { // FIXME: This doesn't work because an SMT rational is not a
1246 // valid GMP rational string
1247 expr = MK_CONST( AntlrInput::tokenToRational($DECIMAL_LITERAL) ); }
1249 | LPAREN_TOK INDEX_TOK
1250 ( bvLit=SIMPLE_SYMBOL size=INTEGER_LITERAL
1251 { if(AntlrInput::tokenText($bvLit).find("bv") == 0) {
1252 expr = MK_CONST( AntlrInput::tokenToBitvector($bvLit, $size) );
1254 PARSER_STATE->parseError("Unexpected symbol `" + AntlrInput::tokenText($bvLit) + "'");
1257 | FP_PINF_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1258 { expr = MK_CONST(FloatingPoint(AntlrInput::tokenToUnsigned($eb),
1259 AntlrInput::tokenToUnsigned($sb),
1261 | FP_NINF_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1262 { expr = MK_CONST(FloatingPoint(AntlrInput::tokenToUnsigned($eb),
1263 AntlrInput::tokenToUnsigned($sb),
1265 | FP_NAN_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1266 { expr = MK_CONST(FloatingPoint(AntlrInput::tokenToUnsigned($eb),
1267 AntlrInput::tokenToUnsigned($sb),
1269 // NOTE: Theory parametric constants go here
1275 { assert( AntlrInput::tokenText($HEX_LITERAL).find("#x") == 0 );
1276 std::string hexString = AntlrInput::tokenTextSubstr($HEX_LITERAL, 2);
1277 expr = MK_CONST( BitVector(hexString, 16) ); }
1280 { assert( AntlrInput::tokenText($BINARY_LITERAL).find("#b") == 0 );
1281 std::string binString = AntlrInput::tokenTextSubstr($BINARY_LITERAL, 2);
1282 expr = MK_CONST( BitVector(binString, 2) ); }
1285 { expr = MK_CONST( ::CVC4::String(s) ); }
1286 | FP_RNE_TOK { expr = MK_CONST(roundNearestTiesToEven); }
1287 | FP_RNA_TOK { expr = MK_CONST(roundNearestTiesToAway); }
1288 | FP_RTP_TOK { expr = MK_CONST(roundTowardPositive); }
1289 | FP_RTN_TOK { expr = MK_CONST(roundTowardNegative); }
1290 | FP_RTZ_TOK { expr = MK_CONST(roundTowardZero); }
1291 | FP_RNE_FULL_TOK { expr = MK_CONST(roundNearestTiesToEven); }
1292 | FP_RNA_FULL_TOK { expr = MK_CONST(roundNearestTiesToAway); }
1293 | FP_RTP_FULL_TOK { expr = MK_CONST(roundTowardPositive); }
1294 | FP_RTN_FULL_TOK { expr = MK_CONST(roundTowardNegative); }
1295 | FP_RTZ_FULL_TOK { expr = MK_CONST(roundTowardZero); }
1298 { std::vector< Expr > nvec; expr = MK_EXPR( CVC4::kind::REGEXP_EMPTY, nvec ); }
1301 { std::vector< Expr > nvec; expr = MK_EXPR( CVC4::kind::REGEXP_SIGMA, nvec ); }
1304 { expr = MK_CONST( ::CVC4::EmptySet(Type())); }
1306 // NOTE: Theory constants go here
1312 attribute[CVC4::Expr& expr,CVC4::Expr& retExpr, std::string& attr]
1316 std::vector<Expr> patexprs;
1318 bool hasValue = false;
1320 : KEYWORD ( simpleSymbolicExprNoKeyword[sexpr] { hasValue = true; } )?
1322 attr = AntlrInput::tokenText($KEYWORD);
1323 // EXPR_MANAGER->setNamedAttribute( expr, attr );
1324 if(attr == ":rewrite-rule") {
1326 std::stringstream ss;
1327 ss << "warning: Attribute " << attr << " does not take a value (ignoring)";
1328 PARSER_STATE->warning(ss.str());
1331 } else if(attr==":axiom" || attr==":conjecture" || attr==":fun-def" || attr==":sygus" || attr==":synthesis") {
1333 std::stringstream ss;
1334 ss << "warning: Attribute " << attr << " does not take a value (ignoring)";
1335 PARSER_STATE->warning(ss.str());
1337 bool success = true;
1338 if( attr==":fun-def" ){
1339 if( ( expr.getKind()!=kind::EQUAL && expr.getKind()!=kind::IFF ) || expr[0].getKind()!=kind::APPLY_UF ){
1342 FunctionType t = (FunctionType)expr[0].getOperator().getType();
1343 for( unsigned i=0; i<expr[0].getNumChildren(); i++ ){
1344 if( expr[0][i].getKind()!=kind::BOUND_VARIABLE || expr[0][i].getType()!=t.getArgTypes()[i] ){
1348 for( unsigned j=0; j<i; j++ ){
1349 if( expr[0][j]==expr[0][i] ){
1358 std::stringstream ss;
1359 ss << "warning: Function definition should be an equality whose LHS is an uninterpreted function applied to unique variables.";
1360 PARSER_STATE->warning(ss.str());
1364 std::string attr_name = attr;
1365 attr_name.erase( attr_name.begin() );
1366 //will set the attribute on auxiliary var (preserves attribute on formula through rewriting)
1367 Type t = EXPR_MANAGER->booleanType();
1368 Expr avar = PARSER_STATE->mkVar(attr_name, t);
1369 retExpr = MK_EXPR(kind::INST_ATTRIBUTE, avar);
1370 Command* c = new SetUserAttributeCommand( attr_name, avar );
1372 PARSER_STATE->preemptCommand(c);
1375 PARSER_STATE->attributeNotSupported(attr);
1378 | ATTRIBUTE_PATTERN_TOK LPAREN_TOK ( term[patexpr, e2] { patexprs.push_back( patexpr ); } )+ RPAREN_TOK
1380 attr = std::string(":pattern");
1381 retExpr = MK_EXPR(kind::INST_PATTERN, patexprs);
1383 | ATTRIBUTE_NO_PATTERN_TOK term[patexpr, e2]
1385 attr = std::string(":no-pattern");
1386 retExpr = MK_EXPR(kind::INST_NO_PATTERN, patexpr);
1388 | tok=( ATTRIBUTE_INST_LEVEL | ATTRIBUTE_RR_PRIORITY ) INTEGER_LITERAL
1390 Expr n = MK_CONST( AntlrInput::tokenToInteger($INTEGER_LITERAL) );
1391 std::vector<Expr> values;
1392 values.push_back( n );
1393 std::string attr_name(AntlrInput::tokenText($tok));
1394 attr_name.erase( attr_name.begin() );
1395 Type t = EXPR_MANAGER->booleanType();
1396 Expr avar = PARSER_STATE->mkVar(attr_name, t);
1397 retExpr = MK_EXPR(kind::INST_ATTRIBUTE, avar);
1398 Command* c = new SetUserAttributeCommand( attr_name, avar, values );
1400 PARSER_STATE->preemptCommand(c);
1402 | ATTRIBUTE_NAMED_TOK symbolicExpr[sexpr]
1404 attr = std::string(":named");
1405 if(!sexpr.isKeyword()) {
1406 PARSER_STATE->parseError("improperly formed :named annotation");
1408 std::string name = sexpr.getValue();
1409 PARSER_STATE->checkUserSymbol(name);
1410 // ensure expr is a closed subterm
1411 std::set<Expr> freeVars;
1412 if(!isClosed(expr, freeVars)) {
1413 assert(!freeVars.empty());
1414 std::stringstream ss;
1415 ss << ":named annotations can only name terms that are closed; this one contains free variables:";
1416 for(std::set<Expr>::const_iterator i = freeVars.begin(); i != freeVars.end(); ++i) {
1419 PARSER_STATE->parseError(ss.str());
1421 // check that sexpr is a fresh function symbol, and reserve it
1422 PARSER_STATE->reserveSymbolAtAssertionLevel(name);
1424 Expr func = PARSER_STATE->mkFunction(name, expr.getType());
1425 // remember the last term to have been given a :named attribute
1426 PARSER_STATE->setLastNamedTerm(expr, name);
1427 // bind name to expr with define-fun
1429 new DefineNamedFunctionCommand(name, func, std::vector<Expr>(), expr);
1431 PARSER_STATE->preemptCommand(c);
1436 * Matches a bit-vector operator (the ones parametrized by numbers)
1438 indexedFunctionName[CVC4::Expr& op]
1439 : LPAREN_TOK INDEX_TOK
1440 ( 'extract' n1=INTEGER_LITERAL n2=INTEGER_LITERAL
1441 { op = MK_CONST(BitVectorExtract(AntlrInput::tokenToUnsigned($n1),
1442 AntlrInput::tokenToUnsigned($n2))); }
1443 | 'repeat' n=INTEGER_LITERAL
1444 { op = MK_CONST(BitVectorRepeat(AntlrInput::tokenToUnsigned($n))); }
1445 | 'zero_extend' n=INTEGER_LITERAL
1446 { op = MK_CONST(BitVectorZeroExtend(AntlrInput::tokenToUnsigned($n))); }
1447 | 'sign_extend' n=INTEGER_LITERAL
1448 { op = MK_CONST(BitVectorSignExtend(AntlrInput::tokenToUnsigned($n))); }
1449 | 'rotate_left' n=INTEGER_LITERAL
1450 { op = MK_CONST(BitVectorRotateLeft(AntlrInput::tokenToUnsigned($n))); }
1451 | 'rotate_right' n=INTEGER_LITERAL
1452 { op = MK_CONST(BitVectorRotateRight(AntlrInput::tokenToUnsigned($n))); }
1453 | DIVISIBLE_TOK n=INTEGER_LITERAL
1454 { op = MK_CONST(Divisible(AntlrInput::tokenToUnsigned($n))); }
1455 | INT2BV_TOK n=INTEGER_LITERAL
1456 { op = MK_CONST(IntToBitVector(AntlrInput::tokenToUnsigned($n)));
1457 if(PARSER_STATE->strictModeEnabled()) {
1458 PARSER_STATE->parseError("bv2nat and int2bv are not part of SMT-LIB, and aren't available in SMT-LIB strict compliance mode");
1460 | FP_PINF_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1461 { op = MK_CONST(FloatingPoint(AntlrInput::tokenToUnsigned($eb),
1462 AntlrInput::tokenToUnsigned($sb),
1464 | FP_NINF_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1465 { op = MK_CONST(FloatingPoint(AntlrInput::tokenToUnsigned($eb),
1466 AntlrInput::tokenToUnsigned($sb),
1468 | FP_NAN_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1469 { op = MK_CONST(FloatingPoint(AntlrInput::tokenToUnsigned($eb),
1470 AntlrInput::tokenToUnsigned($sb),
1472 | FP_PZERO_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1473 { op = MK_CONST(FloatingPoint(AntlrInput::tokenToUnsigned($eb),
1474 AntlrInput::tokenToUnsigned($sb),
1476 | FP_NZERO_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1477 { op = MK_CONST(FloatingPoint(AntlrInput::tokenToUnsigned($eb),
1478 AntlrInput::tokenToUnsigned($sb),
1480 | FP_TO_FP_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1481 { op = MK_CONST(FloatingPointToFPGeneric(AntlrInput::tokenToUnsigned($eb),
1482 AntlrInput::tokenToUnsigned($sb))); }
1483 | FP_TO_FPBV_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1484 { op = MK_CONST(FloatingPointToFPIEEEBitVector(AntlrInput::tokenToUnsigned($eb),
1485 AntlrInput::tokenToUnsigned($sb))); }
1486 | FP_TO_FPFP_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1487 { op = MK_CONST(FloatingPointToFPFloatingPoint(AntlrInput::tokenToUnsigned($eb),
1488 AntlrInput::tokenToUnsigned($sb))); }
1489 | FP_TO_FPR_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1490 { op = MK_CONST(FloatingPointToFPReal(AntlrInput::tokenToUnsigned($eb),
1491 AntlrInput::tokenToUnsigned($sb))); }
1492 | FP_TO_FPS_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1493 { op = MK_CONST(FloatingPointToFPSignedBitVector(AntlrInput::tokenToUnsigned($eb),
1494 AntlrInput::tokenToUnsigned($sb))); }
1495 | FP_TO_FPU_TOK eb=INTEGER_LITERAL sb=INTEGER_LITERAL
1496 { op = MK_CONST(FloatingPointToFPUnsignedBitVector(AntlrInput::tokenToUnsigned($eb),
1497 AntlrInput::tokenToUnsigned($sb))); }
1498 | FP_TO_UBV_TOK m=INTEGER_LITERAL
1499 { op = MK_CONST(FloatingPointToUBV(AntlrInput::tokenToUnsigned($m))); }
1500 | FP_TO_SBV_TOK m=INTEGER_LITERAL
1501 { op = MK_CONST(FloatingPointToSBV(AntlrInput::tokenToUnsigned($m))); }
1502 | badIndexedFunctionName
1508 * Matches an erroneous indexed function name (and args) for better
1511 badIndexedFunctionName
1515 : id=(SIMPLE_SYMBOL | QUOTED_SYMBOL | UNTERMINATED_QUOTED_SYMBOL)
1516 { PARSER_STATE->parseError(std::string("Unknown indexed function `") + AntlrInput::tokenText($id) + "'"); }
1520 * Matches a sequence of terms and puts them into the formulas
1522 * @param formulas the vector to fill with terms
1523 * @param expr an Expr reference for the elements of the sequence
1525 /* NOTE: We pass an Expr in here just to avoid allocating a fresh Expr every
1526 * time through this rule. */
1527 termList[std::vector<CVC4::Expr>& formulas, CVC4::Expr& expr]
1531 : ( term[expr, expr2] { formulas.push_back(expr); } )+
1535 * Matches a string, and strips off the quotes.
1537 str[std::string& s, bool fsmtlib]
1538 : STRING_LITERAL_2_0
1539 { s = AntlrInput::tokenText($STRING_LITERAL_2_0);
1540 /* strip off the quotes */
1541 s = s.substr(1, s.size() - 2);
1542 for(size_t i=0; i<s.size(); i++) {
1543 if((unsigned)s[i] > 127 && !isprint(s[i])) {
1544 PARSER_STATE->parseError("Extended/unprintable characters are not part of SMT-LIB, and they must be encoded as escape sequences");
1548 /* handle SMT-LIB standard escapes '\\' and '\"' */
1549 char* p_orig = strdup(s.c_str());
1550 char *p = p_orig, *q = p_orig;
1554 if(*q == '\\' || *q == '"') {
1570 | STRING_LITERAL_2_5
1571 { s = AntlrInput::tokenText($STRING_LITERAL_2_5);
1572 /* strip off the quotes */
1573 s = s.substr(1, s.size() - 2);
1574 for(size_t i=0; i<s.size(); i++) {
1575 if((unsigned)s[i] > 127 && !isprint(s[i])) {
1576 PARSER_STATE->parseError("Extended/unprintable characters are not part of SMT-LIB, and they must be encoded as escape sequences");
1579 // In the 2.5 version, always handle escapes (regardless of fsmtlib flag).
1580 char* p_orig = strdup(s.c_str());
1581 char *p = p_orig, *q = p_orig;
1596 * Matches a builtin operator symbol and sets kind to its associated Expr kind.
1598 builtinOp[CVC4::Kind& kind]
1600 Debug("parser") << "builtin: " << AntlrInput::tokenText(LT(1)) << std::endl;
1602 : NOT_TOK { $kind = CVC4::kind::NOT; }
1603 | IMPLIES_TOK { $kind = CVC4::kind::IMPLIES; }
1604 | AND_TOK { $kind = CVC4::kind::AND; }
1605 | OR_TOK { $kind = CVC4::kind::OR; }
1606 | XOR_TOK { $kind = CVC4::kind::XOR; }
1607 | EQUAL_TOK { $kind = CVC4::kind::EQUAL; }
1608 | DISTINCT_TOK { $kind = CVC4::kind::DISTINCT; }
1609 | ITE_TOK { $kind = CVC4::kind::ITE; }
1611 { $kind = CVC4::kind::GT; }
1612 | GREATER_THAN_EQUAL_TOK
1613 { $kind = CVC4::kind::GEQ; }
1614 | LESS_THAN_EQUAL_TOK
1615 { $kind = CVC4::kind::LEQ; }
1617 { $kind = CVC4::kind::LT; }
1618 | PLUS_TOK { $kind = CVC4::kind::PLUS; }
1619 | MINUS_TOK { $kind = CVC4::kind::MINUS; }
1620 | STAR_TOK { $kind = CVC4::kind::MULT; }
1621 | DIV_TOK { $kind = CVC4::kind::DIVISION; }
1622 | INTS_DIV_TOK { $kind = CVC4::kind::INTS_DIVISION; }
1623 | INTS_MOD_TOK { $kind = CVC4::kind::INTS_MODULUS; }
1624 | ABS_TOK { $kind = CVC4::kind::ABS; }
1625 | IS_INT_TOK { $kind = CVC4::kind::IS_INTEGER; }
1626 | TO_INT_TOK { $kind = CVC4::kind::TO_INTEGER; }
1627 | TO_REAL_TOK { $kind = CVC4::kind::TO_REAL; }
1629 | SELECT_TOK { $kind = CVC4::kind::SELECT; }
1630 | STORE_TOK { $kind = CVC4::kind::STORE; }
1632 | CONCAT_TOK { $kind = CVC4::kind::BITVECTOR_CONCAT; }
1633 | BVNOT_TOK { $kind = CVC4::kind::BITVECTOR_NOT; }
1634 | BVAND_TOK { $kind = CVC4::kind::BITVECTOR_AND; }
1635 | BVOR_TOK { $kind = CVC4::kind::BITVECTOR_OR; }
1636 | BVNEG_TOK { $kind = CVC4::kind::BITVECTOR_NEG; }
1637 | BVADD_TOK { $kind = CVC4::kind::BITVECTOR_PLUS; }
1638 | BVMUL_TOK { $kind = CVC4::kind::BITVECTOR_MULT; }
1639 | BVUDIV_TOK { $kind = CVC4::kind::BITVECTOR_UDIV; }
1640 | BVUREM_TOK { $kind = CVC4::kind::BITVECTOR_UREM; }
1641 | BVSHL_TOK { $kind = CVC4::kind::BITVECTOR_SHL; }
1642 | BVLSHR_TOK { $kind = CVC4::kind::BITVECTOR_LSHR; }
1643 | BVULT_TOK { $kind = CVC4::kind::BITVECTOR_ULT; }
1644 | BVNAND_TOK { $kind = CVC4::kind::BITVECTOR_NAND; }
1645 | BVNOR_TOK { $kind = CVC4::kind::BITVECTOR_NOR; }
1646 | BVXOR_TOK { $kind = CVC4::kind::BITVECTOR_XOR; }
1647 | BVXNOR_TOK { $kind = CVC4::kind::BITVECTOR_XNOR; }
1648 | BVCOMP_TOK { $kind = CVC4::kind::BITVECTOR_COMP; }
1649 | BVSUB_TOK { $kind = CVC4::kind::BITVECTOR_SUB; }
1650 | BVSDIV_TOK { $kind = CVC4::kind::BITVECTOR_SDIV; }
1651 | BVSREM_TOK { $kind = CVC4::kind::BITVECTOR_SREM; }
1652 | BVSMOD_TOK { $kind = CVC4::kind::BITVECTOR_SMOD; }
1653 | BVASHR_TOK { $kind = CVC4::kind::BITVECTOR_ASHR; }
1654 | BVULE_TOK { $kind = CVC4::kind::BITVECTOR_ULE; }
1655 | BVUGT_TOK { $kind = CVC4::kind::BITVECTOR_UGT; }
1656 | BVUGE_TOK { $kind = CVC4::kind::BITVECTOR_UGE; }
1657 | BVSLT_TOK { $kind = CVC4::kind::BITVECTOR_SLT; }
1658 | BVSLE_TOK { $kind = CVC4::kind::BITVECTOR_SLE; }
1659 | BVSGT_TOK { $kind = CVC4::kind::BITVECTOR_SGT; }
1660 | BVSGE_TOK { $kind = CVC4::kind::BITVECTOR_SGE; }
1662 | BV2NAT_TOK { $kind = CVC4::kind::BITVECTOR_TO_NAT;
1663 if(PARSER_STATE->strictModeEnabled()) {
1664 PARSER_STATE->parseError("bv2nat and int2bv are not part of SMT-LIB, and aren't available in SMT-LIB strict compliance mode");
1666 | STRCON_TOK { $kind = CVC4::kind::STRING_CONCAT; }
1667 | STRLEN_TOK { $kind = CVC4::kind::STRING_LENGTH; }
1668 | STRSUB_TOK { $kind = CVC4::kind::STRING_SUBSTR; }
1669 | STRCTN_TOK { $kind = CVC4::kind::STRING_STRCTN; }
1670 | STRCAT_TOK { $kind = CVC4::kind::STRING_CHARAT; }
1671 | STRIDOF_TOK { $kind = CVC4::kind::STRING_STRIDOF; }
1672 | STRREPL_TOK { $kind = CVC4::kind::STRING_STRREPL; }
1673 | STRPREF_TOK { $kind = CVC4::kind::STRING_PREFIX; }
1674 | STRSUFF_TOK { $kind = CVC4::kind::STRING_SUFFIX; }
1675 | STRITOS_TOK { $kind = CVC4::kind::STRING_ITOS; }
1676 | STRSTOI_TOK { $kind = CVC4::kind::STRING_STOI; }
1677 | STRU16TOS_TOK { $kind = CVC4::kind::STRING_U16TOS; }
1678 | STRSTOU16_TOK { $kind = CVC4::kind::STRING_STOU16; }
1679 | STRU32TOS_TOK { $kind = CVC4::kind::STRING_U32TOS; }
1680 | STRSTOU32_TOK { $kind = CVC4::kind::STRING_STOU32; }
1681 | STRINRE_TOK { $kind = CVC4::kind::STRING_IN_REGEXP; }
1682 | STRTORE_TOK { $kind = CVC4::kind::STRING_TO_REGEXP; }
1683 | RECON_TOK { $kind = CVC4::kind::REGEXP_CONCAT; }
1684 | REUNION_TOK { $kind = CVC4::kind::REGEXP_UNION; }
1685 | REINTER_TOK { $kind = CVC4::kind::REGEXP_INTER; }
1686 | RESTAR_TOK { $kind = CVC4::kind::REGEXP_STAR; }
1687 | REPLUS_TOK { $kind = CVC4::kind::REGEXP_PLUS; }
1688 | REOPT_TOK { $kind = CVC4::kind::REGEXP_OPT; }
1689 | RERANGE_TOK { $kind = CVC4::kind::REGEXP_RANGE; }
1690 | RELOOP_TOK { $kind = CVC4::kind::REGEXP_LOOP; }
1692 | DTSIZE_TOK { $kind = CVC4::kind::DT_SIZE; }
1694 | FMFCARD_TOK { $kind = CVC4::kind::CARDINALITY_CONSTRAINT; }
1696 | INST_CLOSURE_TOK { $kind = CVC4::kind::INST_CLOSURE; }
1698 | FP_TOK { $kind = CVC4::kind::FLOATINGPOINT_FP; }
1699 | FP_EQ_TOK { $kind = CVC4::kind::FLOATINGPOINT_EQ; }
1700 | FP_ABS_TOK { $kind = CVC4::kind::FLOATINGPOINT_ABS; }
1701 | FP_NEG_TOK { $kind = CVC4::kind::FLOATINGPOINT_NEG; }
1702 | FP_PLUS_TOK { $kind = CVC4::kind::FLOATINGPOINT_PLUS; }
1703 | FP_SUB_TOK { $kind = CVC4::kind::FLOATINGPOINT_SUB; }
1704 | FP_MUL_TOK { $kind = CVC4::kind::FLOATINGPOINT_MULT; }
1705 | FP_DIV_TOK { $kind = CVC4::kind::FLOATINGPOINT_DIV; }
1706 | FP_FMA_TOK { $kind = CVC4::kind::FLOATINGPOINT_FMA; }
1707 | FP_SQRT_TOK { $kind = CVC4::kind::FLOATINGPOINT_SQRT; }
1708 | FP_REM_TOK { $kind = CVC4::kind::FLOATINGPOINT_REM; }
1709 | FP_RTI_TOK { $kind = CVC4::kind::FLOATINGPOINT_RTI; }
1710 | FP_MIN_TOK { $kind = CVC4::kind::FLOATINGPOINT_MIN; }
1711 | FP_MAX_TOK { $kind = CVC4::kind::FLOATINGPOINT_MAX; }
1712 | FP_LEQ_TOK { $kind = CVC4::kind::FLOATINGPOINT_LEQ; }
1713 | FP_LT_TOK { $kind = CVC4::kind::FLOATINGPOINT_LT; }
1714 | FP_GEQ_TOK { $kind = CVC4::kind::FLOATINGPOINT_GEQ; }
1715 | FP_GT_TOK { $kind = CVC4::kind::FLOATINGPOINT_GT; }
1716 | FP_ISN_TOK { $kind = CVC4::kind::FLOATINGPOINT_ISN; }
1717 | FP_ISSN_TOK { $kind = CVC4::kind::FLOATINGPOINT_ISSN; }
1718 | FP_ISZ_TOK { $kind = CVC4::kind::FLOATINGPOINT_ISZ; }
1719 | FP_ISINF_TOK { $kind = CVC4::kind::FLOATINGPOINT_ISINF; }
1720 | FP_ISNAN_TOK { $kind = CVC4::kind::FLOATINGPOINT_ISNAN; }
1721 | FP_ISNEG_TOK { $kind = CVC4::kind::FLOATINGPOINT_ISNEG; }
1722 | FP_ISPOS_TOK { $kind = CVC4::kind::FLOATINGPOINT_ISPOS; }
1723 | FP_TO_REAL_TOK {$kind = CVC4::kind::FLOATINGPOINT_TO_REAL; }
1724 // NOTE: Theory operators go here
1727 quantOp[CVC4::Kind& kind]
1729 Debug("parser") << "quant: " << AntlrInput::tokenText(LT(1)) << std::endl;
1731 : EXISTS_TOK { $kind = CVC4::kind::EXISTS; }
1732 | FORALL_TOK { $kind = CVC4::kind::FORALL; }
1736 * Matches a (possibly undeclared) function symbol (returning the string)
1737 * @param check what kind of check to do with the symbol
1739 functionName[std::string& name, CVC4::parser::DeclarationCheck check]
1740 : symbol[name,check,SYM_VARIABLE]
1744 * Matches a sequence of sort symbols and fills them into the given
1747 sortList[std::vector<CVC4::Type>& sorts]
1751 : ( sortSymbol[t,CHECK_DECLARED] { sorts.push_back(t); } )*
1754 nonemptySortList[std::vector<CVC4::Type>& sorts]
1758 : ( sortSymbol[t,CHECK_DECLARED] { sorts.push_back(t); } )+
1762 * Matches a sequence of (variable,sort) symbol pairs and fills them
1763 * into the given vector.
1765 sortedVarList[std::vector<std::pair<std::string, CVC4::Type> >& sortedVars]
1770 : ( LPAREN_TOK symbol[name,CHECK_NONE,SYM_VARIABLE] sortSymbol[t,CHECK_DECLARED] RPAREN_TOK
1771 { sortedVars.push_back(make_pair(name, t)); }
1776 * Matches the sort symbol, which can be an arbitrary symbol.
1777 * @param check the check to perform on the name
1779 sortName[std::string& name, CVC4::parser::DeclarationCheck check]
1780 : symbol[name,check,SYM_SORT]
1783 sortSymbol[CVC4::Type& t, CVC4::parser::DeclarationCheck check]
1786 std::vector<CVC4::Type> args;
1787 std::vector<uint64_t> numerals;
1789 : sortName[name,CHECK_NONE]
1791 if( check == CHECK_DECLARED || PARSER_STATE->isDeclared(name, SYM_SORT) ) {
1792 t = PARSER_STATE->getSort(name);
1794 t = PARSER_STATE->mkUnresolvedType(name);
1797 | LPAREN_TOK INDEX_TOK symbol[name,CHECK_NONE,SYM_SORT] nonemptyNumeralList[numerals] RPAREN_TOK
1799 if( name == "BitVec" ) {
1800 if( numerals.size() != 1 ) {
1801 PARSER_STATE->parseError("Illegal bitvector type.");
1803 if(numerals.front() == 0) {
1804 PARSER_STATE->parseError("Illegal bitvector size: 0");
1806 t = EXPR_MANAGER->mkBitVectorType(numerals.front());
1807 } else if ( name == "FloatingPoint" ) {
1808 if( numerals.size() != 2 ) {
1809 PARSER_STATE->parseError("Illegal floating-point type.");
1811 if(!validExponentSize(numerals[0])) {
1812 PARSER_STATE->parseError("Illegal floating-point exponent size");
1814 if(!validSignificandSize(numerals[1])) {
1815 PARSER_STATE->parseError("Illegal floating-point significand size");
1817 t = EXPR_MANAGER->mkFloatingPointType(numerals[0],numerals[1]);
1819 std::stringstream ss;
1820 ss << "unknown indexed symbol `" << name << "'";
1821 PARSER_STATE->parseError(ss.str());
1824 | LPAREN_TOK symbol[name,CHECK_NONE,SYM_SORT] sortList[args] RPAREN_TOK
1827 PARSER_STATE->parseError("Extra parentheses around sort name not permitted in SMT-LIB");
1828 } else if(name == "Array" &&
1829 PARSER_STATE->isTheoryEnabled(Smt2::THEORY_ARRAYS) ) {
1830 if(args.size() != 2) {
1831 PARSER_STATE->parseError("Illegal array type.");
1833 t = EXPR_MANAGER->mkArrayType( args[0], args[1] );
1834 } else if(name == "Set" &&
1835 PARSER_STATE->isTheoryEnabled(Smt2::THEORY_SETS) ) {
1836 if(args.size() != 1) {
1837 PARSER_STATE->parseError("Illegal set type.");
1839 t = EXPR_MANAGER->mkSetType( args[0] );
1840 } else if(check == CHECK_DECLARED ||
1841 PARSER_STATE->isDeclared(name, SYM_SORT)) {
1842 t = PARSER_STATE->getSort(name, args);
1844 // make unresolved type
1846 t = PARSER_STATE->mkUnresolvedType(name);
1847 Debug("parser-param") << "param: make unres type " << name << std::endl;
1849 t = PARSER_STATE->mkUnresolvedTypeConstructor(name,args);
1850 t = SortConstructorType(t).instantiate( args );
1851 Debug("parser-param") << "param: make unres param type " << name << " " << args.size() << " "
1852 << PARSER_STATE->getArity( name ) << std::endl;
1859 * Matches a list of symbols, with check and type arguments as for the
1860 * symbol[] rule below.
1862 symbolList[std::vector<std::string>& names,
1863 CVC4::parser::DeclarationCheck check,
1864 CVC4::parser::SymbolType type]
1868 : ( symbol[id,check,type] { names.push_back(id); } )*
1872 * Matches an symbol and sets the string reference parameter id.
1873 * @param id string to hold the symbol
1874 * @param check what kinds of check to do on the symbol
1875 * @param type the intended namespace for the symbol
1877 symbol[std::string& id,
1878 CVC4::parser::DeclarationCheck check,
1879 CVC4::parser::SymbolType type]
1881 { id = AntlrInput::tokenText($SIMPLE_SYMBOL);
1882 if(!PARSER_STATE->isAbstractValue(id)) {
1883 // if an abstract value, SmtEngine handles declaration
1884 PARSER_STATE->checkDeclaration(id, check, type);
1889 PARSER_STATE->checkDeclaration(id, check, type);
1892 { id = AntlrInput::tokenText($QUOTED_SYMBOL);
1893 /* strip off the quotes */
1894 id = id.substr(1, id.size() - 2);
1895 if(!PARSER_STATE->isAbstractValue(id)) {
1896 // if an abstract value, SmtEngine handles declaration
1897 PARSER_STATE->checkDeclaration(id, check, type);
1900 | UNTERMINATED_QUOTED_SYMBOL
1902 { PARSER_STATE->unexpectedEOF("unterminated |quoted| symbol"); }
1904 { PARSER_STATE->unexpectedEOF("backslash not permitted in |quoted| symbol"); }
1909 * Matches a nonempty list of numerals.
1910 * @param numerals the (empty) vector to house the numerals.
1912 nonemptyNumeralList[std::vector<uint64_t>& numerals]
1914 { numerals.push_back(AntlrInput::tokenToUnsigned($INTEGER_LITERAL)); }
1919 * Parses a datatype definition
1921 datatypeDef[bool isCo, std::vector<CVC4::Datatype>& datatypes, std::vector< CVC4::Type >& params]
1925 /* This really needs to be CHECK_NONE, or mutually-recursive
1926 * datatypes won't work, because this type will already be
1927 * "defined" as an unresolved type; don't worry, we check
1929 : symbol[id,CHECK_NONE,SYM_SORT] { PARSER_STATE->pushScope(true); }
1930 /* ( '[' symbol[id2,CHECK_UNDECLARED,SYM_SORT] {
1931 t = PARSER_STATE->mkSort(id2);
1932 params.push_back( t );
1934 ( symbol[id2,CHECK_UNDECLARED,SYM_SORT] {
1935 t = PARSER_STATE->mkSort(id2);
1936 params.push_back( t ); }
1938 )?*/ //AJR: this isn't necessary if we use z3's style
1939 { datatypes.push_back(Datatype(id,params,isCo));
1940 if(!PARSER_STATE->isUnresolvedType(id)) {
1941 // if not unresolved, must be undeclared
1942 PARSER_STATE->checkDeclaration(id, CHECK_UNDECLARED, SYM_SORT);
1945 ( LPAREN_TOK constructorDef[datatypes.back()] RPAREN_TOK )+
1946 { PARSER_STATE->popScope(); }
1950 * Parses a constructor defintion for type
1952 constructorDef[CVC4::Datatype& type]
1955 CVC4::DatatypeConstructor* ctor = NULL;
1957 : symbol[id,CHECK_UNDECLARED,SYM_SORT]
1958 { // make the tester
1959 std::string testerId("is-");
1960 testerId.append(id);
1961 PARSER_STATE->checkDeclaration(testerId, CHECK_UNDECLARED, SYM_SORT);
1962 ctor = new CVC4::DatatypeConstructor(id, testerId);
1964 ( LPAREN_TOK selector[*ctor] RPAREN_TOK )*
1965 { // make the constructor
1966 type.addConstructor(*ctor);
1967 Debug("parser-idt") << "constructor: " << id.c_str() << std::endl;
1972 selector[CVC4::DatatypeConstructor& ctor]
1977 : symbol[id,CHECK_UNDECLARED,SYM_SORT] sortSymbol[t,CHECK_NONE]
1978 { ctor.addArg(id, t);
1979 Debug("parser-idt") << "selector: " << id.c_str()
1980 << " of type " << t << std::endl;
1984 // Base SMT-LIB tokens
1985 ASSERT_TOK : 'assert';
1986 CHECKSAT_TOK : 'check-sat';
1987 DECLARE_FUN_TOK : 'declare-fun';
1988 DECLARE_SORT_TOK : 'declare-sort';
1989 DEFINE_FUN_TOK : 'define-fun';
1990 DEFINE_FUN_REC_TOK : 'define-fun-rec';
1991 DEFINE_SORT_TOK : 'define-sort';
1992 GET_VALUE_TOK : 'get-value';
1993 GET_ASSIGNMENT_TOK : 'get-assignment';
1994 GET_ASSERTIONS_TOK : 'get-assertions';
1995 GET_PROOF_TOK : 'get-proof';
1996 GET_UNSAT_CORE_TOK : 'get-unsat-core';
1998 RESET_TOK : { PARSER_STATE->v2_5() }? 'reset';
1999 RESET_ASSERTIONS_TOK : 'reset-assertions';
2002 ATTRIBUTE_TOK : '!';
2006 SET_LOGIC_TOK : 'set-logic';
2007 SET_INFO_TOK : 'set-info';
2008 META_INFO_TOK : 'meta-info';
2009 GET_INFO_TOK : 'get-info';
2010 SET_OPTION_TOK : 'set-option';
2011 GET_OPTION_TOK : 'get-option';
2015 CONST_TOK : 'const';
2017 // extended commands
2018 DECLARE_DATATYPES_TOK : 'declare-datatypes';
2019 DECLARE_CODATATYPES_TOK : 'declare-codatatypes';
2020 GET_MODEL_TOK : 'get-model';
2022 REWRITE_RULE_TOK : 'assert-rewrite';
2023 REDUCTION_RULE_TOK : 'assert-reduction';
2024 PROPAGATION_RULE_TOK : 'assert-propagation';
2025 DECLARE_SORTS_TOK : 'declare-sorts';
2026 DECLARE_FUNS_TOK : 'declare-funs';
2027 DECLARE_PREDS_TOK : 'declare-preds';
2028 DEFINE_TOK : 'define';
2029 DECLARE_CONST_TOK : 'declare-const';
2030 DEFINE_CONST_TOK : 'define-const';
2031 SIMPLIFY_TOK : 'simplify';
2032 INCLUDE_TOK : 'include';
2035 ATTRIBUTE_PATTERN_TOK : ':pattern';
2036 ATTRIBUTE_NO_PATTERN_TOK : ':no-pattern';
2037 ATTRIBUTE_NAMED_TOK : ':named';
2038 ATTRIBUTE_INST_LEVEL : ':quant-inst-max-level';
2039 ATTRIBUTE_RR_PRIORITY : ':rr-priority';
2041 // operators (NOTE: theory symbols go here)
2042 AMPERSAND_TOK : '&';
2045 DISTINCT_TOK : 'distinct';
2048 EXISTS_TOK : 'exists';
2049 FORALL_TOK : 'forall';
2050 GREATER_THAN_TOK : '>';
2051 GREATER_THAN_EQUAL_TOK : '>=';
2053 IS_INT_TOK : 'is_int';
2054 LESS_THAN_TOK : '<';
2055 LESS_THAN_EQUAL_TOK : '<=';
2059 // PERCENT_TOK : '%';
2062 SELECT_TOK : 'select';
2064 STORE_TOK : 'store';
2066 TO_INT_TOK : 'to_int';
2067 TO_REAL_TOK : 'to_real';
2070 INTS_DIV_TOK : 'div';
2071 INTS_MOD_TOK : 'mod';
2074 DIVISIBLE_TOK : 'divisible';
2076 CONCAT_TOK : 'concat';
2077 BVNOT_TOK : 'bvnot';
2078 BVAND_TOK : 'bvand';
2080 BVNEG_TOK : 'bvneg';
2081 BVADD_TOK : 'bvadd';
2082 BVMUL_TOK : 'bvmul';
2083 BVUDIV_TOK : 'bvudiv';
2084 BVUREM_TOK : 'bvurem';
2085 BVSHL_TOK : 'bvshl';
2086 BVLSHR_TOK : 'bvlshr';
2087 BVULT_TOK : 'bvult';
2088 BVNAND_TOK : 'bvnand';
2089 BVNOR_TOK : 'bvnor';
2090 BVXOR_TOK : 'bvxor';
2091 BVXNOR_TOK : 'bvxnor';
2092 BVCOMP_TOK : 'bvcomp';
2093 BVSUB_TOK : 'bvsub';
2094 BVSDIV_TOK : 'bvsdiv';
2095 BVSREM_TOK : 'bvsrem';
2096 BVSMOD_TOK : 'bvsmod';
2097 BVASHR_TOK : 'bvashr';
2098 BVULE_TOK : 'bvule';
2099 BVUGT_TOK : 'bvugt';
2100 BVUGE_TOK : 'bvuge';
2101 BVSLT_TOK : 'bvslt';
2102 BVSLE_TOK : 'bvsle';
2103 BVSGT_TOK : 'bvsgt';
2104 BVSGE_TOK : 'bvsge';
2105 BV2NAT_TOK : 'bv2nat';
2106 INT2BV_TOK : 'int2bv';
2108 STRCON_TOK : 'str.++';
2109 STRLEN_TOK : 'str.len';
2110 STRSUB_TOK : 'str.substr' ;
2111 STRCTN_TOK : 'str.contains' ;
2112 STRCAT_TOK : 'str.at' ;
2113 STRIDOF_TOK : 'str.indexof' ;
2114 STRREPL_TOK : 'str.replace' ;
2115 STRPREF_TOK : 'str.prefixof' ;
2116 STRSUFF_TOK : 'str.suffixof' ;
2117 STRITOS_TOK : 'int.to.str' ;
2118 STRSTOI_TOK : 'str.to.int' ;
2119 STRU16TOS_TOK : 'u16.to.str' ;
2120 STRSTOU16_TOK : 'str.to.u16' ;
2121 STRU32TOS_TOK : 'u32.to.str' ;
2122 STRSTOU32_TOK : 'str.to.u32' ;
2123 STRINRE_TOK : 'str.in.re';
2124 STRTORE_TOK : 'str.to.re';
2125 RECON_TOK : 're.++';
2126 REUNION_TOK : 're.union';
2127 REINTER_TOK : 're.inter';
2128 RESTAR_TOK : 're.*';
2129 REPLUS_TOK : 're.+';
2130 REOPT_TOK : 're.opt';
2131 RERANGE_TOK : 're.range';
2132 RELOOP_TOK : 're.loop';
2133 RENOSTR_TOK : 're.nostr';
2134 REALLCHAR_TOK : 're.allchar';
2136 DTSIZE_TOK : 'dt.size';
2138 FMFCARD_TOK : 'fmf.card';
2140 INST_CLOSURE_TOK : 'inst-closure';
2142 EMPTYSET_TOK: { PARSER_STATE->isTheoryEnabled(Smt2::THEORY_SETS) }? 'emptyset';
2143 // Other set theory operators are not
2144 // tokenized and handled directly when
2145 // processing a term
2148 FP_PINF_TOK : '+oo';
2149 FP_NINF_TOK : '-oo';
2150 FP_PZERO_TOK : '+zero';
2151 FP_NZERO_TOK : '-zero';
2153 FP_EQ_TOK : 'fp.eq';
2154 FP_ABS_TOK : 'fp.abs';
2155 FP_NEG_TOK : 'fp.neg';
2156 FP_PLUS_TOK : 'fp.add';
2157 FP_SUB_TOK : 'fp.sub';
2158 FP_MUL_TOK : 'fp.mul';
2159 FP_DIV_TOK : 'fp.div';
2160 FP_FMA_TOK : 'fp.fma';
2161 FP_SQRT_TOK : 'fp.sqrt';
2162 FP_REM_TOK : 'fp.rem';
2163 FP_RTI_TOK : 'fp.roundToIntegral';
2164 FP_MIN_TOK : 'fp.min';
2165 FP_MAX_TOK : 'fp.max';
2166 FP_LEQ_TOK : 'fp.leq';
2167 FP_LT_TOK : 'fp.lt';
2168 FP_GEQ_TOK : 'fp.geq';
2169 FP_GT_TOK : 'fp.gt';
2170 FP_ISN_TOK : 'fp.isNormal';
2171 FP_ISSN_TOK : 'fp.isSubnormal';
2172 FP_ISZ_TOK : 'fp.isZero';
2173 FP_ISINF_TOK : 'fp.isInfinite';
2174 FP_ISNAN_TOK : 'fp.isNaN';
2175 FP_ISNEG_TOK : 'fp.isNegative';
2176 FP_ISPOS_TOK : 'fp.isPositive';
2177 FP_TO_FP_TOK : 'to_fp';
2178 FP_TO_FPBV_TOK : 'to_fp_bv';
2179 FP_TO_FPFP_TOK : 'to_fp_fp';
2180 FP_TO_FPR_TOK : 'to_fp_real';
2181 FP_TO_FPS_TOK : 'to_fp_signed';
2182 FP_TO_FPU_TOK : 'to_fp_unsigned';
2183 FP_TO_UBV_TOK : 'fp.to_ubv';
2184 FP_TO_SBV_TOK : 'fp.to_sbv';
2185 FP_TO_REAL_TOK : 'fp.to_real';
2191 FP_RNE_FULL_TOK : 'roundNearestTiesToEven';
2192 FP_RNA_FULL_TOK : 'roundNearestTiesToAway';
2193 FP_RTP_FULL_TOK : 'roundTowardPositive';
2194 FP_RTN_FULL_TOK : 'roundTowardNegative';
2195 FP_RTZ_FULL_TOK : 'roundTowardZero';
2198 * A sequence of printable ASCII characters (except backslash) that starts
2199 * and ends with | and does not otherwise contain |.
2201 * You shouldn't generally use this in parser rules, as the |quoting|
2202 * will be part of the token text. Use the symbol[] parser rule instead.
2205 : '|' ~('|' | '\\')* '|'
2207 UNTERMINATED_QUOTED_SYMBOL
2208 : '|' ~('|' | '\\')*
2212 * Matches a keyword from the input. A keyword is a simple symbol prefixed
2216 : ':' (ALPHA | DIGIT | SYMBOL_CHAR)+
2220 * Matches a "simple" symbol: a non-empty sequence of letters, digits and
2221 * the characters + - / * = % ? ! . $ ~ & ^ < > @ that does not start with a
2222 * digit, and is not the special reserved symbols '!' or '_'.
2225 : (ALPHA | SYMBOL_CHAR) (ALPHA | DIGIT | SYMBOL_CHAR)+
2227 | SYMBOL_CHAR_NOUNDERSCORE_NOATTRIBUTE
2231 * Matches and skips whitespace in the input.
2234 : (' ' | '\t' | '\f' | '\r' | '\n')+ { SKIP(); }
2238 * Matches an integer constant from the input (non-empty sequence of
2239 * digits, with no leading zeroes).
2246 * Match an integer constant. In non-strict mode, this is any sequence
2247 * of digits. In strict mode, non-zero integers can't have leading
2252 char *start = (char*) GETCHARINDEX();
2255 { Debug("parser-extra") << "NUMERAL: "
2256 << (uintptr_t)start << ".." << GETCHARINDEX()
2257 << " strict? " << (bool)(PARSER_STATE->strictModeEnabled())
2258 << " ^0? " << (bool)(*start == '0')
2259 << " len>1? " << (bool)(start < (char*)(GETCHARINDEX() - 1))
2261 { !PARSER_STATE->strictModeEnabled() ||
2263 start == (char*)(GETCHARINDEX() - 1) }?
2267 * Matches a decimal constant from the input.
2270 : NUMERAL '.' DIGIT+
2274 * Matches a hexadecimal constant.
2281 * Matches a binary constant.
2288 * Matches a double-quoted string literal from SMT-LIB 2.0.
2289 * Escaping is supported, and * escape character '\' has to be escaped.
2291 * You shouldn't generally use this in parser rules, as the quotes
2292 * will be part of the token text. Use the str[] parser rule instead.
2295 : { PARSER_STATE->v2_0() }?=>
2296 '"' ('\\' . | ~('\\' | '"'))* '"'
2300 * Matches a double-quoted string literal from SMT-LIB 2.5.
2301 * You escape a double-quote inside the string with "", e.g.,
2302 * "This is a string literal with "" a single, embedded double quote."
2304 * You shouldn't generally use this in parser rules, as the quotes
2305 * will be part of the token text. Use the str[] parser rule instead.
2308 : { PARSER_STATE->v2_5() }?=>
2309 '"' (~('"') | '""')* '"'
2313 * Matches the comments and ignores them
2316 : ';' (~('\n' | '\r'))* { SKIP(); }
2320 * Matches any letter ('a'-'z' and 'A'-'Z').
2329 * Matches the digits (0-9)
2331 fragment DIGIT : '0'..'9';
2333 fragment HEX_DIGIT : DIGIT | 'a'..'f' | 'A'..'F';
2336 * Matches the characters that may appear as a one-character "symbol"
2337 * (which excludes _ and !, which are reserved words in SMT-LIB).
2339 fragment SYMBOL_CHAR_NOUNDERSCORE_NOATTRIBUTE
2340 : '+' | '-' | '/' | '*' | '=' | '%' | '?' | '.' | '$' | '~'
2341 | '&' | '^' | '<' | '>' | '@'
2345 * Matches the characters that may appear in a "symbol" (i.e., an identifier)
2347 fragment SYMBOL_CHAR
2348 : SYMBOL_CHAR_NOUNDERSCORE_NOATTRIBUTE | '_' | '!'