summaryrefslogtreecommitdiff
path: root/src/parser/smt2/Smt2.g
diff options
context:
space:
mode:
Diffstat (limited to 'src/parser/smt2/Smt2.g')
-rw-r--r--src/parser/smt2/Smt2.g225
1 files changed, 184 insertions, 41 deletions
diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g
index 3d57eebff..9281b19f2 100644
--- a/src/parser/smt2/Smt2.g
+++ b/src/parser/smt2/Smt2.g
@@ -234,20 +234,22 @@ command returns [CVC4::Command* cmd = NULL]
}
PARSER_STATE->setLogic(name);
$cmd = new SetBenchmarkLogicCommand(name); }
- | SET_INFO_TOK KEYWORD symbolicExpr[sexpr]
- { name = AntlrInput::tokenText($KEYWORD);
- if(name == ":cvc4-logic" || name == ":cvc4_logic") {
- PARSER_STATE->setLogic(sexpr.getValue());
- }
- PARSER_STATE->setInfo(name.c_str() + 1, sexpr);
- cmd = new SetInfoCommand(name.c_str() + 1, sexpr); }
+ | /* set-info */
+ SET_INFO_TOK metaInfoInternal[cmd]
| /* get-info */
GET_INFO_TOK KEYWORD
{ cmd = new GetInfoCommand(AntlrInput::tokenText($KEYWORD).c_str() + 1); }
| /* set-option */
SET_OPTION_TOK keyword[name] symbolicExpr[sexpr]
{ PARSER_STATE->setOption(name.c_str() + 1, sexpr);
- cmd = new SetOptionCommand(name.c_str() + 1, sexpr); }
+ cmd = new SetOptionCommand(name.c_str() + 1, sexpr);
+ // Ugly that this changes the state of the parser; but
+ // global-declarations affects parsing, so we can't hold off
+ // on this until some SmtEngine eventually (if ever) executes it.
+ if(name == ":global-declarations") {
+ PARSER_STATE->setGlobalDeclarations(sexpr.getValue() == "true");
+ }
+ }
| /* get-option */
GET_OPTION_TOK KEYWORD
{ cmd = new GetOptionCommand(AntlrInput::tokenText($KEYWORD).c_str() + 1); }
@@ -443,9 +445,18 @@ command returns [CVC4::Command* cmd = NULL]
cmd = new PopCommand();
}
} )
+
+ /* exit */
| EXIT_TOK
{ cmd = new QuitCommand(); }
+ /* New SMT-LIB 2.5 command set */
+ | smt25Command[cmd]
+ { if(PARSER_STATE->v2_0() && PARSER_STATE->strictModeEnabled()) {
+ PARSER_STATE->parseError("SMT-LIB 2.5 commands are not permitted while operating in strict compliance mode and in SMT-LIB 2.0 mode.");
+ }
+ }
+
/* CVC4-extended SMT-LIB commands */
| extendedCommand[cmd]
{ if(PARSER_STATE->strictModeEnabled()) {
@@ -464,25 +475,56 @@ command returns [CVC4::Command* cmd = NULL]
}
;
-extendedCommand[CVC4::Command*& cmd]
+// Separate this into its own rule (can be invoked by set-info or meta-info)
+metaInfoInternal[CVC4::Command*& cmd]
@declarations {
- std::vector<CVC4::Datatype> dts;
- Type t;
- Expr e, e2;
+ std::string name;
SExpr sexpr;
+}
+ : KEYWORD symbolicExpr[sexpr]
+ { name = AntlrInput::tokenText($KEYWORD);
+ if(name == ":cvc4-logic" || name == ":cvc4_logic") {
+ PARSER_STATE->setLogic(sexpr.getValue());
+ } else if(name == ":smt-lib-version") {
+ // if we don't recognize the revision name, just keep the current mode
+ if( (sexpr.isRational() && sexpr.getRationalValue() == Rational(2)) ||
+ sexpr.getValue() == "2" ||
+ sexpr.getValue() == "2.0" ) {
+ PARSER_STATE->setLanguage(language::input::LANG_SMTLIB_V2_0);
+ } else if( (sexpr.isRational() && sexpr.getRationalValue() == Rational(5, 2)) ||
+ sexpr.getValue() == "2.5" ) {
+ PARSER_STATE->setLanguage(language::input::LANG_SMTLIB_V2_5);
+ }
+ }
+ PARSER_STATE->setInfo(name.c_str() + 1, sexpr);
+ cmd = new SetInfoCommand(name.c_str() + 1, sexpr);
+ }
+ ;
+
+smt25Command[CVC4::Command*& cmd]
+@declarations {
std::string name;
- std::vector<std::string> names;
- std::vector<Expr> terms;
- std::vector<Type> sorts;
+ Expr expr, expr2;
std::vector<std::pair<std::string, Type> > sortedVarNames;
+ SExpr sexpr;
+ Type t;
}
- /* Extended SMT-LIB set of commands syntax, not permitted in
- * --smtlib2 compliance mode. */
- : DECLARE_DATATYPES_TOK datatypesDefCommand[false, cmd]
- | DECLARE_CODATATYPES_TOK datatypesDefCommand[true, cmd]
- | /* get model */
- GET_MODEL_TOK { PARSER_STATE->checkThatLogicIsSet(); }
+ /* meta-info */
+ : META_INFO_TOK metaInfoInternal[cmd]
+
+ /* declare-const */
+ | DECLARE_CONST_TOK { PARSER_STATE->checkThatLogicIsSet(); }
+ symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
+ { PARSER_STATE->checkUserSymbol(name); }
+ sortSymbol[t,CHECK_DECLARED]
+ { Expr c = PARSER_STATE->mkVar(name, t);
+ $cmd = new DeclareFunctionCommand(name, c, t); }
+
+ /* get model */
+ | GET_MODEL_TOK { PARSER_STATE->checkThatLogicIsSet(); }
{ cmd = new GetModelCommand(); }
+
+ /* echo */
| ECHO_TOK
( simpleSymbolicExpr[sexpr]
{ std::stringstream ss;
@@ -491,17 +533,77 @@ extendedCommand[CVC4::Command*& cmd]
}
| { cmd = new EchoCommand(); }
)
+
+ /* reset: reset everything, returning solver to initial state.
+ * Logic and options must be set again. */
+ | RESET_TOK
+ { cmd = new ResetCommand();
+ PARSER_STATE->reset();
+ }
+ /* reset-assertions: reset assertions, assertion stack, declarations,
+ * etc., but the logic and options remain as they were. */
+ | RESET_ASSERTIONS_TOK
+ { cmd = new ResetAssertionsCommand();
+ PARSER_STATE->resetAssertions();
+ }
+
+ | /* recursive function definition */
+ DEFINE_FUN_REC_TOK { PARSER_STATE->checkThatLogicIsSet(); } LPAREN_TOK
+ { PARSER_STATE->pushScope(true); }
+ ( LPAREN_TOK symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
+ { PARSER_STATE->checkUserSymbol(name); }
+ LPAREN_TOK sortedVarList[sortedVarNames] RPAREN_TOK
+ sortSymbol[t,CHECK_DECLARED]
+ { /* add variables to parser state before parsing term */
+ Debug("parser") << "define fun rec: '" << name << "'" << std::endl;
+ if( sortedVarNames.size() > 0 ) {
+ std::vector<CVC4::Type> sorts;
+ sorts.reserve(sortedVarNames.size());
+ for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
+ sortedVarNames.begin(), iend = sortedVarNames.end();
+ i != iend;
+ ++i) {
+ sorts.push_back((*i).second);
+ }
+ t = EXPR_MANAGER->mkFunctionType(sorts, t);
+ }
+ PARSER_STATE->mkFunction(name, t, ExprManager::VAR_FLAG_DEFINED);
+ PARSER_STATE->pushScope(true);
+ for(std::vector<std::pair<std::string, CVC4::Type> >::const_iterator i =
+ sortedVarNames.begin(), iend = sortedVarNames.end();
+ i != iend;
+ ++i) {
+ PARSER_STATE->mkBoundVar((*i).first, (*i).second);
+ }
+ }
+ term[expr, expr2]
+ { PARSER_STATE->popScope(); }
+ RPAREN_TOK )+ RPAREN_TOK
+ { PARSER_STATE->popScope(); }
+
+ // CHECK_SAT_ASSUMING still being discussed
+ // GET_UNSAT_ASSUMPTIONS
+ ;
+
+extendedCommand[CVC4::Command*& cmd]
+@declarations {
+ std::vector<CVC4::Datatype> dts;
+ Expr e, e2;
+ Type t;
+ std::string name;
+ std::vector<std::string> names;
+ std::vector<Expr> terms;
+ std::vector<Type> sorts;
+ std::vector<std::pair<std::string, Type> > sortedVarNames;
+}
+ /* Extended SMT-LIB set of commands syntax, not permitted in
+ * --smtlib2 compliance mode. */
+ : DECLARE_DATATYPES_TOK datatypesDefCommand[false, cmd]
+ | DECLARE_CODATATYPES_TOK datatypesDefCommand[true, cmd]
| rewriterulesCommand[cmd]
/* Support some of Z3's extended SMT-LIB commands */
- | DECLARE_CONST_TOK { PARSER_STATE->checkThatLogicIsSet(); }
- symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
- { PARSER_STATE->checkUserSymbol(name); }
- sortSymbol[t,CHECK_DECLARED]
- { Expr c = PARSER_STATE->mkVar(name, t);
- $cmd = new DeclareFunctionCommand(name, c, t); }
-
| DECLARE_SORTS_TOK { PARSER_STATE->checkThatLogicIsSet(); }
{ if(!PARSER_STATE->isTheoryEnabled(Smt2::THEORY_UF) &&
!PARSER_STATE->isTheoryEnabled(Smt2::THEORY_ARRAYS) &&
@@ -799,11 +901,11 @@ simpleSymbolicExprNoKeyword[CVC4::SExpr& sexpr]
// }
| symbol[s,CHECK_NONE,SYM_SORT]
{ sexpr = SExpr(SExpr::Keyword(s)); }
- | tok=(ASSERT_TOK | CHECKSAT_TOK | DECLARE_FUN_TOK | DECLARE_SORT_TOK | DEFINE_FUN_TOK | DEFINE_SORT_TOK | GET_VALUE_TOK | GET_ASSIGNMENT_TOK | GET_ASSERTIONS_TOK | GET_PROOF_TOK | GET_UNSAT_CORE_TOK | EXIT_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)
+ | 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)
{ sexpr = SExpr(SExpr::Keyword(AntlrInput::tokenText($tok))); }
| builtinOp[k]
{ std::stringstream ss;
- ss << Expr::setlanguage(CVC4::language::output::LANG_SMTLIB_V2) << EXPR_MANAGER->mkConst(k);
+ ss << Expr::setlanguage(CVC4::language::output::LANG_SMTLIB_V2_5) << EXPR_MANAGER->mkConst(k);
sexpr = SExpr(ss.str());
}
;
@@ -1328,15 +1430,15 @@ termList[std::vector<CVC4::Expr>& formulas, CVC4::Expr& expr]
* Matches a string, and strips off the quotes.
*/
str[std::string& s, bool fsmtlib]
- : STRING_LITERAL
- { s = AntlrInput::tokenText($STRING_LITERAL);
+ : STRING_LITERAL_2_0
+ { s = AntlrInput::tokenText($STRING_LITERAL_2_0);
/* strip off the quotes */
s = s.substr(1, s.size() - 2);
- for(size_t i=0; i<s.size(); i++) {
- if((unsigned)s[i] > 127) {
- PARSER_STATE->parseError("Extended characters are not part of SMT-LIB, and they must be encoded as esacped sequences");
- }
- }
+ for(size_t i=0; i<s.size(); i++) {
+ if((unsigned)s[i] > 127) {
+ PARSER_STATE->parseError("Extended characters are not part of SMT-LIB, and they must be encoded as esacped sequences");
+ }
+ }
if(fsmtlib) {
/* handle SMT-LIB standard escapes '\\' and '\"' */
char* p_orig = strdup(s.c_str());
@@ -1360,6 +1462,29 @@ str[std::string& s, bool fsmtlib]
free(p_orig);
}
}
+ | STRING_LITERAL_2_5
+ { s = AntlrInput::tokenText($STRING_LITERAL_2_5);
+ /* strip off the quotes */
+ s = s.substr(1, s.size() - 2);
+ for(size_t i=0; i<s.size(); i++) {
+ if((unsigned)s[i] > 127) {
+ PARSER_STATE->parseError("Extended characters are not part of SMT-LIB, and they must be encoded as esacped sequences");
+ }
+ }
+ // In the 2.5 version, always handle escapes (regardless of fsmtlib flag).
+ char* p_orig = strdup(s.c_str());
+ char *p = p_orig, *q = p_orig;
+ while(*q != '\0') {
+ if(*q == '"') {
+ ++q;
+ assert(*q == '"');
+ }
+ *p++ = *q++;
+ }
+ *p = '\0';
+ s = p_orig;
+ free(p_orig);
+ }
;
/**
@@ -1718,6 +1843,7 @@ CHECKSAT_TOK : 'check-sat';
DECLARE_FUN_TOK : 'declare-fun';
DECLARE_SORT_TOK : 'declare-sort';
DEFINE_FUN_TOK : 'define-fun';
+DEFINE_FUN_REC_TOK : 'define-fun-rec';
DEFINE_SORT_TOK : 'define-sort';
GET_VALUE_TOK : 'get-value';
GET_ASSIGNMENT_TOK : 'get-assignment';
@@ -1725,6 +1851,8 @@ GET_ASSERTIONS_TOK : 'get-assertions';
GET_PROOF_TOK : 'get-proof';
GET_UNSAT_CORE_TOK : 'get-unsat-core';
EXIT_TOK : 'exit';
+RESET_TOK : 'reset';
+RESET_ASSERTIONS_TOK : 'reset-assertions';
ITE_TOK : 'ite';
LET_TOK : 'let';
ATTRIBUTE_TOK : '!';
@@ -1733,6 +1861,7 @@ RPAREN_TOK : ')';
INDEX_TOK : '_';
SET_LOGIC_TOK : 'set-logic';
SET_INFO_TOK : 'set-info';
+META_INFO_TOK : 'meta-info';
GET_INFO_TOK : 'get-info';
SET_OPTION_TOK : 'set-option';
GET_OPTION_TOK : 'get-option';
@@ -1960,14 +2089,28 @@ BINARY_LITERAL
;
/**
- * Matches a double quoted string literal. Escaping is supported, and
- * escape character '\' has to be escaped.
+ * Matches a double-quoted string literal from SMT-LIB 2.0.
+ * Escaping is supported, and * escape character '\' has to be escaped.
+ *
+ * You shouldn't generally use this in parser rules, as the quotes
+ * will be part of the token text. Use the str[] parser rule instead.
+ */
+STRING_LITERAL_2_0
+ : { PARSER_STATE->v2_0() }?=>
+ '"' ('\\' . | ~('\\' | '"'))* '"'
+ ;
+
+/**
+ * Matches a double-quoted string literal from SMT-LIB 2.5.
+ * You escape a double-quote inside the string with "", e.g.,
+ * "This is a string literal with "" a single, embedded double quote."
*
* You shouldn't generally use this in parser rules, as the quotes
* will be part of the token text. Use the str[] parser rule instead.
*/
-STRING_LITERAL
- : '"' ('\\' . | ~('\\' | '"'))* '"'
+STRING_LITERAL_2_5
+ : { PARSER_STATE->v2_5() }?=>
+ '"' (~('"') | '""')* '"'
;
/**
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback