* Simplification mode "incremental" no longer supported.
* Support for array constants in constraints.
* Syntax for array models have changed in some language front-ends.
+* New input/output languages supported: "smt2.0" and "smtlib2.0" to
+ force SMT-LIB v2.0; "smt2.5" and "smtlib2.5" to force SMT-LIB v2.5.
+ "smt", "smtlib", "smt2", and "smtlib2" all refer to the current standard
+ version 2.0. If an :smt-lib-version is set in the input, that overrides
+ the command line.
+* Abstract values in SMT-LIB models are now ascribed types (with "as").
* In SMT-LIB model output, real-sorted but integer-valued constants are
now printed in accordance with the standard (e.g. "1.0").
return "reset";
}
+/* class ResetAssertionsCommand */
+
+void ResetAssertionsCommand::invoke(SmtEngine* smtEngine) throw() {
+ try {
+ smtEngine->resetAssertions();
+ d_commandStatus = CommandSuccess::instance();
+ } catch(exception& e) {
+ d_commandStatus = new CommandFailure(e.what());
+ }
+}
+
+Command* ResetAssertionsCommand::exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap) {
+ return new ResetAssertionsCommand();
+}
+
+Command* ResetAssertionsCommand::clone() const {
+ return new ResetAssertionsCommand();
+}
+
+std::string ResetAssertionsCommand::getCommandName() const throw() {
+ return "reset-assertions";
+}
+
/* class QuitCommand */
void QuitCommand::invoke(SmtEngine* smtEngine) throw() {
std::string getCommandName() const throw();
};/* class ResetCommand */
+class CVC4_PUBLIC ResetAssertionsCommand : public Command {
+public:
+ ResetAssertionsCommand() throw() {}
+ ~ResetAssertionsCommand() throw() {}
+ void invoke(SmtEngine* smtEngine) throw();
+ Command* exportTo(ExprManager* exprManager, ExprManagerMapCollection& variableMap);
+ Command* clone() const;
+ std::string getCommandName() const throw();
+};/* class ResetAssertionsCommand */
+
class CVC4_PUBLIC QuitCommand : public Command {
public:
QuitCommand() throw() {}
* Use like this:
*
* // let out be an ostream, e an Expr
- * out << Expr::setlanguage(LANG_SMTLIB_V2) << e << endl;
+ * out << Expr::setlanguage(LANG_SMTLIB_V2_5) << e << endl;
*
* The setting stays permanently (until set again) with the stream.
*/
d_stats.registerStat_(&d_statLastWinner);
d_stats.registerStat_(&d_statWaitTime);
- /* Duplication, Individualisation */
+ /* Duplication, individualization */
d_exprMgrs.push_back(&d_exprMgr);
for(unsigned i = 1; i < d_numThreads; ++i) {
d_exprMgrs.push_back(new ExprManager(d_threadOptions[i]));
dynamic_cast<GetAssignmentCommand*>(cmd) != NULL ||
dynamic_cast<GetModelCommand*>(cmd) != NULL ||
dynamic_cast<GetProofCommand*>(cmd) != NULL ||
+ dynamic_cast<GetInstantiationsCommand*>(cmd) != NULL ||
dynamic_cast<GetUnsatCoreCommand*>(cmd) != NULL ||
dynamic_cast<GetAssertionsCommand*>(cmd) != NULL ||
dynamic_cast<GetInfoCommand*>(cmd) != NULL ||
#include "util/configuration.h"
#include "options/options.h"
#include "main/command_executor.h"
-# ifdef PORTFOLIO_BUILD
-# include "main/command_executor_portfolio.h"
-# endif
+
+#ifdef PORTFOLIO_BUILD
+# include "main/command_executor_portfolio.h"
+#endif
+
#include "main/options.h"
#include "smt/options.h"
#include "util/output.h"
} else {
unsigned len = strlen(filename);
if(len >= 5 && !strcmp(".smt2", filename + len - 5)) {
- opts.set(options::inputLanguage, language::input::LANG_SMTLIB_V2);
+ opts.set(options::inputLanguage, language::input::LANG_SMTLIB_V2_5);
} else if(len >= 4 && !strcmp(".smt", filename + len - 4)) {
opts.set(options::inputLanguage, language::input::LANG_SMTLIB_V1);
} else if(len >= 5 && !strcmp(".smt1", filename + len - 5)) {
}
status = pExecutor->doCommand(cmd);
needReset = true;
+ } else if(dynamic_cast<ResetCommand*>(cmd) != NULL) {
+ pExecutor->doCommand(cmd);
+ allCommands.clear();
+ allCommands.push_back(vector<Command*>());
} else {
// We shouldn't copy certain commands, because they can cause
// an error on replay since there's no associated sat/unsat check
dynamic_cast<GetValueCommand*>(cmd) == NULL &&
dynamic_cast<GetModelCommand*>(cmd) == NULL &&
dynamic_cast<GetAssignmentCommand*>(cmd) == NULL &&
- dynamic_cast<GetInstantiationsCommand*>(cmd) == NULL) {
+ dynamic_cast<GetInstantiationsCommand*>(cmd) == NULL &&
+ dynamic_cast<GetAssertionsCommand*>(cmd) == NULL &&
+ dynamic_cast<GetInfoCommand*>(cmd) == NULL &&
+ dynamic_cast<GetOptionCommand*>(cmd) == NULL) {
Command* copy = cmd->clone();
allCommands.back().push_back(copy);
}
commandsBegin = smt1_commands;
commandsEnd = smt1_commands + sizeof(smt1_commands) / sizeof(*smt1_commands);
break;
- case output::LANG_SMTLIB_V2:
+ case output::LANG_SMTLIB_V2_0:
+ case output::LANG_SMTLIB_V2_5:
d_historyFilename = string(getenv("HOME")) + "/.cvc4_history_smtlib2";
commandsBegin = smt2_commands;
commandsEnd = smt2_commands + sizeof(smt2_commands) / sizeof(*smt2_commands);
line += "\n";
goto restart;
} catch(ParserException& pe) {
- if(d_options[options::outputLanguage] == output::LANG_SMTLIB_V2) {
+ if(d_options[options::outputLanguage] == output::LANG_SMTLIB_V2_0 ||
+ d_options[options::outputLanguage] == output::LANG_SMTLIB_V2_5) {
d_out << "(error \"" << pe << "\")" << endl;
} else {
d_out << pe << endl;
#ifdef CVC4_COMPETITION_MODE
*opts[options::out] << "unknown" << endl;
#endif
- if(opts[options::outputLanguage] == output::LANG_SMTLIB_V2) {
+ if(opts[options::outputLanguage] == output::LANG_SMTLIB_V2_0 ||
+ opts[options::outputLanguage] == output::LANG_SMTLIB_V2_5) {
*opts[options::err] << "(error \"" << e << "\")" << endl;
} else {
*opts[options::err] << "CVC4 Error:" << endl << e << endl;
option incrementalParallel --incremental-parallel bool :default false :link --incremental
Use parallel solver even in incremental mode (may print 'unknown's at times)
+option interactive : --interactive bool :read-write
+ force interactive/non-interactive mode
undocumented-option interactivePrompt /--no-interactive-prompt bool :default true
turn off interactive prompting while in interactive mode
Options(const Options& options);
~Options();
+ Options& operator=(const Options& options);
+
/**
* Set the value of the given option. Use of this default
* implementation causes a compile-time error; write-able
delete d_holder;
}
+Options& Options::operator=(const Options& options) {
+ if(this != &options) {
+ delete d_holder;
+ d_holder = new options::OptionsHolder(*options.d_holder);
+ }
+ return *this;
+}
+
options::OptionsHolder::OptionsHolder() : ${all_modules_defaults}
{
}
auto attempt to automatically determine language\n\
cvc4 | presentation | pl CVC4 presentation language\n\
smt1 | smtlib1 SMT-LIB format 1.2\n\
- smt | smtlib | smt2 | smtlib2 SMT-LIB format 2.0\n\
+ smt | smtlib | smt2 |\n\
+ smt2.0 | smtlib2 | smtlib2.0 SMT-LIB format 2.0\n\
+ smt2.5 | smtlib2.5 SMT-LIB format 2.5\n\
tptp TPTP format (cnf and fof)\n\
\n\
Languages currently supported as arguments to the --output-lang option:\n\
cvc4 | presentation | pl CVC4 presentation language\n\
cvc3 CVC3 presentation language\n\
smt1 | smtlib1 SMT-LIB format 1.2\n\
- smt | smtlib | smt2 | smtlib2 SMT-LIB format 2.0\n\
+ smt | smtlib | smt2 |\n\
+ smt2.0 | smtlib2.0 | smtlib2 SMT-LIB format 2.0\n\
+ smt2.5 | smtlib2.5 SMT-LIB format 2.5\n\
z3str SMT-LIB 2.0 with Z3-str string constraints\n\
tptp TPTP format\n\
ast internal format (simple syntax trees)\n\
{ NULL, no_argument, NULL, '\0' }
};/* cmdlineOptions */
-#line 318 "${template}"
+#line 322 "${template}"
static void preemptGetopt(int& argc, char**& argv, const char* opt) {
const size_t maxoptlen = 128;
switch(c) {
${all_modules_option_handlers}
-#line 511 "${template}"
+#line 515 "${template}"
case ':':
// This can be a long or short option, and the way to get at the
static const char* smtOptions[] = {
${all_modules_smt_options},
-#line 580 "${template}"
+#line 584 "${template}"
NULL
};/* smtOptions[] */
${all_modules_get_options}
-#line 602 "${template}"
+#line 606 "${template}"
return SExpr(opts);
}
input = new Smt1Input(inputStream);
break;
- case LANG_SMTLIB_V2:
- input = new Smt2Input(inputStream);
+ case LANG_SMTLIB_V2_0:
+ case LANG_SMTLIB_V2_5:
+ input = new Smt2Input(inputStream, lang);
break;
case LANG_TPTP:
PARSER_STATE->reset();
}
+ | RESET_TOK ASSERTIONS_TOK
+ { cmd = new ResetAssertionsCommand();
+ PARSER_STATE->reset();
+ }
+
// Datatypes can be mututally-recursive if they're in the same
// definition block, separated by a comma. So we parse everything
// and then ask the ExprManager to resolve everything in one go.
option semanticChecks /--no-checking bool :default DO_SEMANTIC_CHECKS_BY_DEFAULT :link /--no-type-checking
disable ALL semantic checks, including type checks
+option globalDeclarations global-declarations bool :default false
+ force all declarations and definitions to be global
+
# this is to support security in the online version, and in other similar contexts
# (--no-include-file disables filesystem access in TPTP and SMT2 parsers)
# the name --no-include-file is legacy: it also now limits any filesystem access
#include "expr/kind.h"
#include "expr/type.h"
#include "util/output.h"
-#include "options/options.h"
using namespace std;
using namespace CVC4::kind;
d_symtabAllocated(),
d_symtab(&d_symtabAllocated),
d_assertionLevel(0),
+ d_globalDeclarations(false),
d_anonymousFunctionCount(0),
d_done(false),
d_checksEnabled(true),
Expr
Parser::mkVar(const std::string& name, const Type& type, uint32_t flags) {
+ if(d_globalDeclarations) {
+ flags |= ExprManager::VAR_FLAG_GLOBAL;
+ }
Debug("parser") << "mkVar(" << name << ", " << type << ")" << std::endl;
Expr expr = d_exprManager->mkVar(name, type, flags);
defineVar(name, expr, flags & ExprManager::VAR_FLAG_GLOBAL);
Expr
Parser::mkFunction(const std::string& name, const Type& type, uint32_t flags) {
+ if(d_globalDeclarations) {
+ flags |= ExprManager::VAR_FLAG_GLOBAL;
+ }
Debug("parser") << "mkVar(" << name << ", " << type << ")" << std::endl;
Expr expr = d_exprManager->mkVar(name, type, flags);
defineFunction(name, expr, flags & ExprManager::VAR_FLAG_GLOBAL);
Expr
Parser::mkAnonymousFunction(const std::string& prefix, const Type& type, uint32_t flags) {
+ if(d_globalDeclarations) {
+ flags |= ExprManager::VAR_FLAG_GLOBAL;
+ }
stringstream name;
name << prefix << "_anon_" << ++d_anonymousFunctionCount;
return d_exprManager->mkVar(name.str(), type, flags);
std::vector<Expr>
Parser::mkVars(const std::vector<std::string> names, const Type& type, uint32_t flags) {
+ if(d_globalDeclarations) {
+ flags |= ExprManager::VAR_FLAG_GLOBAL;
+ }
std::vector<Expr> vars;
for(unsigned i = 0; i < names.size(); ++i) {
vars.push_back(mkVar(names[i], type, flags));
SortType
Parser::mkSort(const std::string& name, uint32_t flags) {
+ if(d_globalDeclarations) {
+ flags |= ExprManager::VAR_FLAG_GLOBAL;
+ }
Debug("parser") << "newSort(" << name << ")" << std::endl;
Type type = d_exprManager->mkSort(name, flags);
defineType(name, type);
*/
size_t d_assertionLevel;
+ /**
+ * Whether we're in global declarations mode (all definitions and
+ * declarations are global).
+ */
+ bool d_globalDeclarations;
+
/**
* Maintains a list of reserved symbols at the assertion level that might
* not occur in our symbol table. This is necessary to e.g. support the
}
}
- inline void reset() {
+ virtual void reset() {
d_symtab->reset();
}
+ void setGlobalDeclarations(bool flag) {
+ d_globalDeclarations = flag;
+ }
+
/**
* Set the current symbol table used by this parser.
* From now on, this parser will perform its definitions and
case language::input::LANG_SMTLIB_V1:
parser = new Smt1(d_exprManager, input, d_strictMode, d_parseOnly);
break;
- case language::input::LANG_SMTLIB_V2:
+ case language::input::LANG_SMTLIB_V2_0:
+ case language::input::LANG_SMTLIB_V2_5:
parser = new Smt2(d_exprManager, input, d_strictMode, d_parseOnly);
break;
case language::input::LANG_TPTP:
}
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); }
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()) {
}
;
-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;
}
| { 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) &&
// }
| 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());
}
;
* 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());
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);
+ }
;
/**
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';
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 : '!';
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';
;
/**
- * 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() }?=>
+ '"' (~('"') | '""')* '"'
;
/**
return d_logicSet;
}
+void Smt2::reset() {
+ d_logicSet = false;
+ d_logic = LogicInfo();
+ operatorKindMap.clear();
+ d_lastNamedTerm = std::pair<Expr, std::string>();
+ d_unsatCoreNames = std::stack< std::map<Expr, std::string> >();
+ this->Parser::reset();
+
+ d_unsatCoreNames.push(std::map<Expr, std::string>());
+ if( !strictModeEnabled() ) {
+ addTheory(Smt2::THEORY_CORE);
+ }
+}
+
+void Smt2::resetAssertions() {
+ this->Parser::reset();
+}
+
void Smt2::setLogic(const std::string& name) {
d_logicSet = true;
if(logicIsForced()) {
#include "parser/smt1/smt1.h"
#include "theory/logic_info.h"
#include "util/abstract_value.h"
+#include "parser/smt2/smt2_input.h"
#include <string>
#include <sstream>
bool logicIsSet();
+ void reset();
+
+ void resetAssertions();
+
/**
* Sets the logic for the current benchmark. Declares any logic and
* theory symbols.
*/
const LogicInfo& getLogic() const { return d_logic; }
+ bool v2_0() const {
+ return getInput()->getLanguage() == language::input::LANG_SMTLIB_V2_0;
+ }
+ bool v2_5() const {
+ return getInput()->getLanguage() == language::input::LANG_SMTLIB_V2_5;
+ }
+
+ void setLanguage(InputLanguage lang) {
+ ((Smt2Input*) getInput())->setLanguage(lang);
+ }
+
void setInfo(const std::string& flag, const SExpr& sexpr);
void setOption(const std::string& flag, const SExpr& sexpr);
namespace parser {
/* Use lookahead=2 */
-Smt2Input::Smt2Input(AntlrInputStream& inputStream) :
+Smt2Input::Smt2Input(AntlrInputStream& inputStream, InputLanguage lang) :
AntlrInput(inputStream, 2) {
+
pANTLR3_INPUT_STREAM input = inputStream.getAntlr3InputStream();
assert( input != NULL );
}
setAntlr3Parser(d_pSmt2Parser->pParser);
-}
+ setLanguage(lang);
+}
Smt2Input::~Smt2Input() {
d_pSmt2Lexer->free(d_pSmt2Lexer);
d_pSmt2Parser->free(d_pSmt2Parser);
}
+void Smt2Input::setLanguage(InputLanguage lang) {
+ CheckArgument(lang == language::input::LANG_SMTLIB_V2_0 ||
+ lang == language::input::LANG_SMTLIB_V2_5, lang);
+ d_lang = lang;
+}
+
Command* Smt2Input::parseCommand() {
return d_pSmt2Parser->parseCommand(d_pSmt2Parser);
}
/** The ANTLR3 SMT2 parser for the input. */
pSmt2Parser d_pSmt2Parser;
+ /** Which (variant of the) input language we're using */
+ InputLanguage d_lang;
+
/**
* Initialize the class. Called from the constructors once the input
* stream is initialized.
*
* @param inputStream the input stream to use
*/
- Smt2Input(AntlrInputStream& inputStream);
+ Smt2Input(AntlrInputStream& inputStream,
+ InputLanguage lang = language::input::LANG_SMTLIB_V2_5);
/** Destructor. Frees the lexer and the parser. */
virtual ~Smt2Input();
/** Get the language that this Input is reading. */
InputLanguage getLanguage() const throw() {
- return language::input::LANG_SMTLIB_V2;
+ return d_lang;
}
+ /** Set the language that this Input is reading. */
+ void setLanguage(InputLanguage);
+
protected:
/**
tryToStream<CheckSatCommand>(out, c) ||
tryToStream<QueryCommand>(out, c) ||
tryToStream<ResetCommand>(out, c) ||
+ tryToStream<ResetAssertionsCommand>(out, c) ||
tryToStream<QuitCommand>(out, c) ||
tryToStream<DeclarationSequence>(out, c) ||
tryToStream<CommandSequence>(out, c) ||
out << "Reset()";
}
+static void toStream(std::ostream& out, const ResetAssertionsCommand* c) throw() {
+ out << "ResetAssertions()";
+}
+
static void toStream(std::ostream& out, const QuitCommand* c) throw() {
out << "Quit()";
}
tryToStream<CheckSatCommand>(out, c, d_cvc3Mode) ||
tryToStream<QueryCommand>(out, c, d_cvc3Mode) ||
tryToStream<ResetCommand>(out, c, d_cvc3Mode) ||
+ tryToStream<ResetAssertionsCommand>(out, c, d_cvc3Mode) ||
tryToStream<QuitCommand>(out, c, d_cvc3Mode) ||
tryToStream<DeclarationSequence>(out, c, d_cvc3Mode) ||
tryToStream<CommandSequence>(out, c, d_cvc3Mode) ||
out << "RESET;";
}
+static void toStream(std::ostream& out, const ResetAssertionsCommand* c, bool cvc3Mode) throw() {
+ out << "RESET ASSERTIONS;";
+}
+
static void toStream(std::ostream& out, const QuitCommand* c, bool cvc3Mode) throw() {
//out << "EXIT;";
}
case LANG_SMTLIB_V1: // TODO the printer
return new printer::smt1::Smt1Printer();
- case LANG_SMTLIB_V2:
+ case LANG_SMTLIB_V2_0:
+ return new printer::smt2::Smt2Printer(printer::smt2::smt2_0_variant);
+
+ case LANG_SMTLIB_V2_5:
return new printer::smt2::Smt2Printer();
case LANG_TPTP:
void Smt1Printer::toStream(std::ostream& out, TNode n,
int toDepth, bool types, size_t dag) const throw() {
- n.toStream(out, toDepth, types, dag, language::output::LANG_SMTLIB_V2);
+ n.toStream(out, toDepth, types, dag, language::output::LANG_SMTLIB_V2_5);
}/* Smt1Printer::toStream() */
void Smt1Printer::toStream(std::ostream& out, const Command* c,
int toDepth, bool types, size_t dag) const throw() {
- c->toStream(out, toDepth, types, dag, language::output::LANG_SMTLIB_V2);
+ c->toStream(out, toDepth, types, dag, language::output::LANG_SMTLIB_V2_5);
}/* Smt1Printer::toStream() */
void Smt1Printer::toStream(std::ostream& out, const CommandStatus* s) const throw() {
- s->toStream(out, language::output::LANG_SMTLIB_V2);
+ s->toStream(out, language::output::LANG_SMTLIB_V2_5);
}/* Smt1Printer::toStream() */
void Smt1Printer::toStream(std::ostream& out, const SExpr& sexpr) const throw() {
- Printer::getPrinter(language::output::LANG_SMTLIB_V2)->toStream(out, sexpr);
+ Printer::getPrinter(language::output::LANG_SMTLIB_V2_5)->toStream(out, sexpr);
}/* Smt1Printer::toStream() */
void Smt1Printer::toStream(std::ostream& out, const Model& m) const throw() {
- Printer::getPrinter(language::output::LANG_SMTLIB_V2)->toStream(out, m);
+ Printer::getPrinter(language::output::LANG_SMTLIB_V2_5)->toStream(out, m);
}
void Smt1Printer::toStream(std::ostream& out, const Model& m, const Command* c) const throw() {
if(types) {
// print the whole type, but not *its* type
out << ":";
- n.getType().toStream(out, language::output::LANG_SMTLIB_V2);
+ n.getType().toStream(out, language::output::LANG_SMTLIB_V2_5);
}
return;
break;
}
+ case kind::CONST_STRING: {
+ const String& s = n.getConst<String>();
+ out << '"';
+ for(size_t i = 0; i < s.size(); ++i) {
+ char c = String::convertUnsignedIntToChar(s[i]);
+ if(c == '"') {
+ if(d_variant == z3str_variant || d_variant == smt2_0_variant) {
+ out << "\\\"";
+ } else {
+ out << "\"\"";
+ }
+ } else if(c == '\\' && (d_variant == z3str_variant || d_variant == smt2_0_variant)) {
+ out << "\\\\";
+ } else {
+ out << c;
+ }
+ }
+ out << '"';
+ break;
+ }
+
case kind::STORE_ALL: {
ArrayStoreAll asa = n.getConst<ArrayStoreAll>();
out << "((as const " << asa.getType() << ") " << asa.getExpr() << ")";
out << (*i).getType();
// The following code do stange things
// (*i).getType().toStream(out, toDepth < 0 ? toDepth : toDepth - 1,
- // false, language::output::LANG_SMTLIB_V2);
+ // false, language::output::LANG_SMTLIB_V2_5);
out << ')';
if(++i != iend) {
out << ' ';
tryToStream<CheckSatCommand>(out, c) ||
tryToStream<QueryCommand>(out, c) ||
tryToStream<ResetCommand>(out, c) ||
+ tryToStream<ResetAssertionsCommand>(out, c) ||
tryToStream<QuitCommand>(out, c) ||
tryToStream<DeclarationSequence>(out, c) ||
tryToStream<CommandSequence>(out, c) ||
tryToStream<GetAssertionsCommand>(out, c) ||
tryToStream<GetProofCommand>(out, c) ||
tryToStream<GetUnsatCoreCommand>(out, c) ||
- tryToStream<SetBenchmarkStatusCommand>(out, c) ||
+ tryToStream<SetBenchmarkStatusCommand>(out, c, d_variant) ||
tryToStream<SetBenchmarkLogicCommand>(out, c, d_variant) ||
- tryToStream<SetInfoCommand>(out, c) ||
+ tryToStream<SetInfoCommand>(out, c, d_variant) ||
tryToStream<GetInfoCommand>(out, c) ||
tryToStream<SetOptionCommand>(out, c) ||
tryToStream<GetOptionCommand>(out, c) ||
tryToStream<DatatypeDeclarationCommand>(out, c) ||
- tryToStream<CommentCommand>(out, c) ||
+ tryToStream<CommentCommand>(out, c, d_variant) ||
tryToStream<EmptyCommand>(out, c) ||
- tryToStream<EchoCommand>(out, c)) {
+ tryToStream<EchoCommand>(out, c, d_variant)) {
return;
}
}/* Smt2Printer::toStream(Command*) */
static inline void toStream(std::ostream& out, const SExpr& sexpr) throw() {
- Printer::getPrinter(language::output::LANG_SMTLIB_V2)->toStream(out, sexpr);
+ Printer::getPrinter(language::output::LANG_SMTLIB_V2_5)->toStream(out, sexpr);
}
// SMT-LIB quoting for symbols
static std::string quoteSymbol(TNode n) {
std::stringstream ss;
- ss << Expr::setlanguage(language::output::LANG_SMTLIB_V2);
+ ss << Expr::setlanguage(language::output::LANG_SMTLIB_V2_5);
return quoteSymbol(ss.str());
}
}
template <class T>
-static bool tryToStream(std::ostream& out, const CommandStatus* s) throw();
+static bool tryToStream(std::ostream& out, const CommandStatus* s, Variant v) throw();
void Smt2Printer::toStream(std::ostream& out, const CommandStatus* s) const throw() {
- if(tryToStream<CommandSuccess>(out, s) ||
- tryToStream<CommandFailure>(out, s) ||
- tryToStream<CommandUnsupported>(out, s)) {
+ if(tryToStream<CommandSuccess>(out, s, d_variant) ||
+ tryToStream<CommandFailure>(out, s, d_variant) ||
+ tryToStream<CommandUnsupported>(out, s, d_variant)) {
return;
}
out << "(reset)";
}
+static void toStream(std::ostream& out, const ResetAssertionsCommand* c) throw() {
+ out << "(reset-assertions)";
+}
+
static void toStream(std::ostream& out, const QuitCommand* c) throw() {
out << "(exit)";
}
out << "(get-unsat-core)";
}
-static void toStream(std::ostream& out, const SetBenchmarkStatusCommand* c) throw() {
- out << "(set-info :status " << c->getStatus() << ")";
+static void toStream(std::ostream& out, const SetBenchmarkStatusCommand* c, Variant v) throw() {
+ if(v == z3str_variant || v == smt2_0_variant) {
+ out << "(set-info :status " << c->getStatus() << ")";
+ } else {
+ out << "(meta-info :status " << c->getStatus() << ")";
+ }
}
static void toStream(std::ostream& out, const SetBenchmarkLogicCommand* c, Variant v) throw() {
}
}
-static void toStream(std::ostream& out, const SetInfoCommand* c) throw() {
- out << "(set-info :" << c->getFlag() << " ";
+static void toStream(std::ostream& out, const SetInfoCommand* c, Variant v) throw() {
+ if(v == z3str_variant || v == smt2_0_variant) {
+ out << "(set-info :" << c->getFlag() << " ";
+ } else {
+ out << "(meta-info :" << c->getFlag() << " ";
+ }
toStream(out, c->getSExpr());
out << ")";
}
out << "))";
}
-static void toStream(std::ostream& out, const CommentCommand* c) throw() {
+static void toStream(std::ostream& out, const CommentCommand* c, Variant v) throw() {
string s = c->getComment();
size_t pos = 0;
while((pos = s.find_first_of('"', pos)) != string::npos) {
- s.replace(pos, 1, "\\\"");
+ s.replace(pos, 1, (v == z3str_variant || v == smt2_0_variant) ? "\\\"" : "\"\"");
pos += 2;
}
out << "(set-info :notes \"" << s << "\")";
static void toStream(std::ostream& out, const EmptyCommand* c) throw() {
}
-static void toStream(std::ostream& out, const EchoCommand* c) throw() {
- out << "(echo \"" << c->getOutput() << "\")";
+static void toStream(std::ostream& out, const EchoCommand* c, Variant v) throw() {
+ std::string s = c->getOutput();
+ // escape all double-quotes
+ size_t pos = 0;
+ while((pos = s.find('"', pos)) != string::npos) {
+ s.replace(pos, 1, (v == z3str_variant || v == smt2_0_variant) ? "\\\"" : "\"\"");
+ pos += 2;
+ }
+ out << "(echo \"" << s << "\")";
}
template <class T>
return false;
}
-static void toStream(std::ostream& out, const CommandSuccess* s) throw() {
+static void toStream(std::ostream& out, const CommandSuccess* s, Variant v) throw() {
if(Command::printsuccess::getPrintSuccess(out)) {
out << "success" << endl;
}
}
-static void toStream(std::ostream& out, const CommandUnsupported* s) throw() {
+static void toStream(std::ostream& out, const CommandUnsupported* s, Variant v) throw() {
#ifdef CVC4_COMPETITION_MODE
// if in competition mode, lie and say we're ok
// (we have nothing to lose by saying success, and everything to lose
#endif /* CVC4_COMPETITION_MODE */
}
-static void toStream(std::ostream& out, const CommandFailure* s) throw() {
+static void toStream(std::ostream& out, const CommandFailure* s, Variant v) throw() {
string message = s->getMessage();
// escape all double-quotes
size_t pos = 0;
while((pos = message.find('"', pos)) != string::npos) {
- message = message.replace(pos, 1, "\\\"");
+ message.replace(pos, 1, (v == z3str_variant || v == smt2_0_variant) ? "\\\"" : "\"\"");
pos += 2;
}
out << "(error \"" << message << "\")" << endl;
}
template <class T>
-static bool tryToStream(std::ostream& out, const CommandStatus* s) throw() {
+static bool tryToStream(std::ostream& out, const CommandStatus* s, Variant v) throw() {
if(typeid(*s) == typeid(T)) {
- toStream(out, dynamic_cast<const T*>(s));
+ toStream(out, dynamic_cast<const T*>(s), v);
return true;
}
return false;
enum Variant {
no_variant,
- z3str_variant
+ smt2_0_variant, // old-style 2.0 syntax, when it makes a difference
+ z3str_variant // old-style 2.0 and also z3str syntax
};/* enum Variant */
class Smt2Printer : public CVC4::Printer {
void TptpPrinter::toStream(std::ostream& out, TNode n,
int toDepth, bool types, size_t dag) const throw() {
- n.toStream(out, toDepth, types, dag, language::output::LANG_SMTLIB_V2);
+ n.toStream(out, toDepth, types, dag, language::output::LANG_SMTLIB_V2_5);
}/* TptpPrinter::toStream() */
void TptpPrinter::toStream(std::ostream& out, const Command* c,
int toDepth, bool types, size_t dag) const throw() {
- c->toStream(out, toDepth, types, dag, language::output::LANG_SMTLIB_V2);
+ c->toStream(out, toDepth, types, dag, language::output::LANG_SMTLIB_V2_5);
}/* TptpPrinter::toStream() */
void TptpPrinter::toStream(std::ostream& out, const CommandStatus* s) const throw() {
- s->toStream(out, language::output::LANG_SMTLIB_V2);
+ s->toStream(out, language::output::LANG_SMTLIB_V2_5);
}/* TptpPrinter::toStream() */
void TptpPrinter::toStream(std::ostream& out, const SExpr& sexpr) const throw() {
- Printer::getPrinter(language::output::LANG_SMTLIB_V2)->toStream(out, sexpr);
+ Printer::getPrinter(language::output::LANG_SMTLIB_V2_5)->toStream(out, sexpr);
}/* TptpPrinter::toStream() */
void TptpPrinter::toStream(std::ostream& out, const Model& m) const throw() {
out << "% SZS output start FiniteModel for " << m.getInputName() << endl;
for(size_t i = 0; i < m.getNumCommands(); ++i) {
- this->Printer::toStreamUsing(language::output::LANG_SMTLIB_V2, out, m, m.getCommand(i));
+ this->Printer::toStreamUsing(language::output::LANG_SMTLIB_V2_5, out, m, m.getCommand(i));
}
out << "% SZS output end FiniteModel for " << m.getInputName() << endl;
}
always expand symbol definitions in output
common-option produceModels produce-models -m --produce-models bool :default false :predicate CVC4::smt::beforeSearch :predicate-include "smt/smt_engine.h"
support the get-value and get-model commands
-option checkModels check-models --check-models bool :link --produce-models --interactive :link-smt produce-models :link-smt interactive-mode :predicate CVC4::smt::beforeSearch :predicate-include "smt/options_handlers.h"
+option checkModels check-models --check-models bool :link --produce-models --produce-assertions :link-smt produce-models :link-smt produce-assertions :predicate CVC4::smt::beforeSearch :predicate-include "smt/options_handlers.h"
after SAT/INVALID/UNKNOWN, check that the generated model satisfies user assertions
option dumpModels --dump-models bool :default false :link --produce-models
output models after every SAT/INVALID/UNKNOWN response
option produceAssignments produce-assignments --produce-assignments bool :default false :predicate CVC4::smt::beforeSearch :predicate-include "smt/options_handlers.h"
support the get-assignment command
-# This could go in src/main/options, but by SMT-LIBv2 spec, "interactive"
-# is a mode in which the assertion list must be kept. So it belongs here.
-common-option interactive interactive-mode --interactive bool :predicate CVC4::smt::beforeSearch :predicate-include "smt/options_handlers.h" :read-write
- force interactive mode
+undocumented-option interactiveMode interactive-mode bool :predicate CVC4::smt::beforeSearch CVC4::smt::setProduceAssertions :predicate-include "smt/options_handlers.h" :read-write
+ deprecated name for produce-assertions
+common-option produceAssertions produce-assertions --produce-assertions bool :predicate CVC4::smt::beforeSearch CVC4::smt::setProduceAssertions :predicate-include "smt/options_handlers.h" :read-write
+ keep an assertions list (enables get-assertions command)
option doITESimp --ite-simp bool :read-write
turn on ite simplification (Kim (and Somenzi) et al., SAT 2009)
enable time limiting per query (give milliseconds)
common-option cumulativeResourceLimit rlimit --rlimit=N "unsigned long"
enable resource limiting (currently, roughly the number of SAT conflicts)
-common-option perCallResourceLimit rlimit-per --rlimit-per=N "unsigned long"
+common-option perCallResourceLimit reproducible-resource-limit --rlimit-per=N "unsigned long"
enable resource limiting per query
expert-option rewriteApplyToConst rewrite-apply-to-const --rewrite-apply-to-const bool :default false
}
}
+inline void setProduceAssertions(std::string option, bool value, SmtEngine* smt) throw() {
+ options::produceAssertions.set(value);
+ options::interactiveMode.set(value);
+}
+
// ensure we are a proof-enabled build of CVC4
inline void proofEnabledBuild(std::string option, bool value, SmtEngine* smt) throw(OptionException) {
#ifndef CVC4_PROOF
val = d_smt.d_nodeManager->mkAbstractValue(n.getType());
d_abstractValueMap.addSubstitution(val, n);
}
- return val;
+ // We are supposed to ascribe types to all abstract values that go out.
+ Node retval = d_smt.d_nodeManager->mkNode(kind::APPLY_TYPE_ASCRIPTION, d_smt.d_nodeManager->mkConst(AscriptionType(n.getType().toType())), val);
+ return retval;
}
std::hash_map<Node, Node, NodeHashFunction> rewriteApplyToConstCache;
d_modelCommands(NULL),
d_dumpCommands(),
d_logic(),
+ d_originalOptions(em->getOptions()),
d_pendingPops(0),
d_fullyInited(false),
d_problemExtended(false),
// cleanup ordering issue and Nodes/TNodes. If SAT is popped
// first, some user-context-dependent TNodes might still exist
// with rc == 0.
- if(options::interactive() ||
+ if(options::produceAssertions() ||
options::incrementalSolving()) {
// In the case of incremental solving, we appear to need these to
// ensure the relevant Nodes remain live.
}
if(options::checkModels()) {
- if(! options::interactive()) {
- Notice() << "SmtEngine: turning on interactive-mode to support check-models" << endl;
- setOption("interactive-mode", SExpr("true"));
+ if(! options::produceAssertions()) {
+ Notice() << "SmtEngine: turning on produce-assertions to support check-models" << endl;
+ setOption("produce-assertions", SExpr("true"));
}
}
} else if(key == "smt-lib-version") {
if( (value.isInteger() && value.getIntegerValue() == Integer(2)) ||
(value.isRational() && value.getRationalValue() == Rational(2)) ||
- (value.getValue() == "2") ) {
+ value.getValue() == "2" ||
+ value.getValue() == "2.0" ) {
// supported SMT-LIB version
+ if(!options::outputLanguage.wasSetByUser() &&
+ options::outputLanguage() == language::output::LANG_SMTLIB_V2_5) {
+ options::outputLanguage.set(language::output::LANG_SMTLIB_V2_0);
+ *options::out() << Expr::setlanguage(language::output::LANG_SMTLIB_V2_0);
+ }
+ return;
+ } else if( (value.isRational() && value.getRationalValue() == Rational(5, 2)) ||
+ value.getValue() == "2.5" ) {
+ // supported SMT-LIB version
+ if(!options::outputLanguage.wasSetByUser() &&
+ options::outputLanguage() == language::output::LANG_SMTLIB_V2_0) {
+ options::outputLanguage.set(language::output::LANG_SMTLIB_V2_5);
+ *options::out() << Expr::setlanguage(language::output::LANG_SMTLIB_V2_5);
+ }
return;
}
Warning() << "Warning: unsupported smt-lib-version: " << value << endl;
throw ModalException("Can't get-info :reason-unknown when the "
"last result wasn't unknown!");
}
+ } else if(key == "assertion-stack-levels") {
+ return SExpr(d_userLevels.size());
} else if(key == "all-options") {
// get the options, like all-statistics
return Options::current().getOptions();
if(options::abstractValues() && resultNode.getType().isArray()) {
resultNode = d_private->mkAbstractValue(resultNode);
+ Trace("smt") << "--- abstract value >> " << resultNode << endl;
}
return resultNode.toExpr();
}
void SmtEngine::checkModel(bool hardFailure) {
- // --check-model implies --interactive, which enables the assertion list,
- // so we should be ok.
+ // --check-model implies --produce-assertions, which enables the
+ // assertion list, so we should be ok.
Assert(d_assertionList != NULL, "don't have an assertion list to check in SmtEngine::checkModel()");
TimerStat::CodeTimer checkModelTimer(d_stats->d_checkModelTime);
Dump("benchmark") << GetAssertionsCommand();
}
Trace("smt") << "SMT getAssertions()" << endl;
- if(!options::interactive()) {
+ if(!options::produceAssertions()) {
const char* msg =
- "Cannot query the current assertion list when not in interactive mode.";
+ "Cannot query the current assertion list when not in produce-assertions mode.";
throw ModalException(msg);
}
Assert(d_assertionList != NULL);
if(Dump.isOn("benchmark")) {
Dump("benchmark") << ResetCommand();
}
+ Options opts = d_originalOptions;
this->~SmtEngine();
+ NodeManager::fromExprManager(em)->getOptions() = opts;
new(this) SmtEngine(em);
}
void SmtEngine::resetAssertions() throw() {
SmtScope smts(this);
+ Trace("smt") << "SMT resetAssertions()" << endl;
+ if(Dump.isOn("benchmark")) {
+ Dump("benchmark") << ResetAssertionsCommand();
+ }
+
while(!d_userLevels.empty()) {
pop();
}
*/
LogicInfo d_logic;
+ /**
+ * Keep a copy of the original option settings (for reset()).
+ */
+ Options d_originalOptions;
+
/**
* Number of internal pops that have been deferred.
*/
InputLanguage toInputLanguage(OutputLanguage language) {
switch(language) {
case output::LANG_SMTLIB_V1:
- case output::LANG_SMTLIB_V2:
+ case output::LANG_SMTLIB_V2_0:
+ case output::LANG_SMTLIB_V2_5:
case output::LANG_TPTP:
case output::LANG_CVC4:
case output::LANG_Z3STR:
OutputLanguage toOutputLanguage(InputLanguage language) {
switch(language) {
case input::LANG_SMTLIB_V1:
- case input::LANG_SMTLIB_V2:
+ case input::LANG_SMTLIB_V2_0:
+ case input::LANG_SMTLIB_V2_5:
case input::LANG_TPTP:
case input::LANG_CVC4:
case input::LANG_Z3STR:
return output::LANG_SMTLIB_V1;
} else if(language == "smtlib" || language == "smt" ||
language == "smtlib2" || language == "smt2" ||
- language == "LANG_SMTLIB_V2") {
- return output::LANG_SMTLIB_V2;
+ language == "smtlib2.0" || language == "smt2.0" ||
+ language == "LANG_SMTLIB_V2_0" || language == "LANG_SMTLIB_V2") {
+ return output::LANG_SMTLIB_V2_0;
+ } else if(language == "smtlib2.5" || language == "smt2.5" ||
+ language == "LANG_SMTLIB_V2_5") {
+ return output::LANG_SMTLIB_V2_5;
} else if(language == "tptp" || language == "LANG_TPTP") {
return output::LANG_TPTP;
} else if(language == "z3str" || language == "z3-str" ||
return input::LANG_SMTLIB_V1;
} else if(language == "smtlib" || language == "smt" ||
language == "smtlib2" || language == "smt2" ||
- language == "LANG_SMTLIB_V2") {
- return input::LANG_SMTLIB_V2;
+ language == "smtlib2.0" || language == "smt2.0" ||
+ language == "LANG_SMTLIB_V2_0" || language == "LANG_SMTLIB_V2") {
+ return input::LANG_SMTLIB_V2_0;
+ } else if(language == "smtlib2.5" || language == "smt2.5" ||
+ language == "LANG_SMTLIB_V2_5") {
+ return input::LANG_SMTLIB_V2_5;
} else if(language == "tptp" || language == "LANG_TPTP") {
return input::LANG_TPTP;
} else if(language == "z3str" || language == "z3-str" ||
/** The SMTLIB v1 input language */
LANG_SMTLIB_V1 = 0,
- /** The SMTLIB v2 input language */
- LANG_SMTLIB_V2,
+ /** The SMTLIB v2.0 input language */
+ LANG_SMTLIB_V2_0,
+ /** The SMTLIB v2.5 input language */
+ LANG_SMTLIB_V2_5,
+ /** Backward-compatibility for enumeration naming */
+ LANG_SMTLIB_V2 = LANG_SMTLIB_V2_5,
/** The TPTP input language */
LANG_TPTP,
/** The CVC4 input language */
case LANG_SMTLIB_V1:
out << "LANG_SMTLIB_V1";
break;
- case LANG_SMTLIB_V2:
- out << "LANG_SMTLIB_V2";
+ case LANG_SMTLIB_V2_0:
+ out << "LANG_SMTLIB_V2_0";
+ break;
+ case LANG_SMTLIB_V2_5:
+ out << "LANG_SMTLIB_V2_5";
break;
case LANG_TPTP:
out << "LANG_TPTP";
/** The SMTLIB v1 output language */
LANG_SMTLIB_V1 = input::LANG_SMTLIB_V1,
- /** The SMTLIB v2 output language */
+ /** The SMTLIB v2.0 output language */
+ LANG_SMTLIB_V2_0 = input::LANG_SMTLIB_V2_0,
+ /** The SMTLIB v2.5 output language */
+ LANG_SMTLIB_V2_5 = input::LANG_SMTLIB_V2_5,
+ /** Backward-compatibility for enumeration naming */
LANG_SMTLIB_V2 = input::LANG_SMTLIB_V2,
/** The TPTP output language */
LANG_TPTP = input::LANG_TPTP,
case LANG_SMTLIB_V1:
out << "LANG_SMTLIB_V1";
break;
- case LANG_SMTLIB_V2:
- out << "LANG_SMTLIB_V2";
+ case LANG_SMTLIB_V2_0:
+ out << "LANG_SMTLIB_V2_0";
+ break;
+ case LANG_SMTLIB_V2_5:
+ out << "LANG_SMTLIB_V2_5";
break;
case LANG_TPTP:
out << "LANG_TPTP";
%rename(INPUT_LANG_AUTO) CVC4::language::input::LANG_AUTO;
%rename(INPUT_LANG_SMTLIB_V1) CVC4::language::input::LANG_SMTLIB_V1;
%rename(INPUT_LANG_SMTLIB_V2) CVC4::language::input::LANG_SMTLIB_V2;
+%rename(INPUT_LANG_SMTLIB_V2_0) CVC4::language::input::LANG_SMTLIB_V2_0;
+%rename(INPUT_LANG_SMTLIB_V2_5) CVC4::language::input::LANG_SMTLIB_V2_5;
%rename(INPUT_LANG_TPTP) CVC4::language::input::LANG_TPTP;
%rename(INPUT_LANG_CVC4) CVC4::language::input::LANG_CVC4;
%rename(INPUT_LANG_MAX) CVC4::language::input::LANG_MAX;
%rename(OUTPUT_LANG_AUTO) CVC4::language::output::LANG_AUTO;
%rename(OUTPUT_LANG_SMTLIB_V1) CVC4::language::output::LANG_SMTLIB_V1;
%rename(OUTPUT_LANG_SMTLIB_V2) CVC4::language::output::LANG_SMTLIB_V2;
+%rename(OUTPUT_LANG_SMTLIB_V2_0) CVC4::language::output::LANG_SMTLIB_V2_0;
+%rename(OUTPUT_LANG_SMTLIB_V2_5) CVC4::language::output::LANG_SMTLIB_V2_5;
%rename(OUTPUT_LANG_TPTP) CVC4::language::output::LANG_TPTP;
%rename(OUTPUT_LANG_CVC4) CVC4::language::output::LANG_CVC4;
%rename(OUTPUT_LANG_AST) CVC4::language::output::LANG_AST;
; COMMAND-LINE: --incremental --abstract-values
; EXPECT: sat
-; EXPECT: ((a @1) (b @2))
+; EXPECT: ((a (as @1 (Array Int Int))) (b (as @2 (Array Int Int))))
(set-logic QF_AUFLIA)
(set-option :produce-models true)
(declare-fun a () (Array Int Int))
;
; COMMAND-LINE: --incremental --abstract-values --check-models
; EXPECT: sat
-; EXPECT: ((a @1) (b @2))
+; EXPECT: ((a (as @1 (Array Int Int))) (b (as @2 (Array Int Int))))
(set-logic QF_AUFLIA)
(set-option :produce-models true)
(declare-fun a () (Array Int Int))
(set-logic QF_ALL_SUPPORTED)
(set-option :strings-exp true)
(set-option :produce-models true)
+(set-info :smt-lib-version 2.0)
(set-info :status sat)
(declare-fun text () String)
--- /dev/null
+;; This is a nasty parsing test for define-fun-rec
+
+(set-logic UFLIRA)
+(set-info :smt-lib-version 2.5)
+(define-fun-rec (
+ (f ((x Int)) Int 5) ;; ok, f : Int -> Int
+ (g ((x Int)) Int (h 4)) ;; um, ok, so g : Int -> Int and h : Int -> Int?
+ (h ((x Real)) Int 4) ;; oops no we were wrong, **CRASH**
+))
+
+(reset)
+
+(set-logic UFLIRA)
+(set-info :smt-lib-version 2.5)
+(define-fun-rec (
+ (f ((x Int)) Int (g (h 4) 5)) ;; ok, f : Int -> Int and g : Int -> X -> Int and h : Int -> X ??! What the F?! (pun intended)
+ (g ((x Int)) Int 5) ;; wait, now g has wrong arity?!! **BURN**
+ (h ((x Int)) Int 2)
+))
+
+(reset)
+
+(set-logic UFLIRA)
+(set-info :smt-lib-version 2.5)
+(declare-const g Int 2)
+(define-fun-rec (
+ (f () Int g) ;; wait, which g does this refer to?! **LOCUSTS**
+ (g () Int 5)
+))
# If a test shouldn't be run in e.g. competition mode,
# put it below in "TESTS +="
TESTS = \
- declarefun-emptyset-uf.smt2
+ declarefun-emptyset-uf.smt2 \
+ strings20.smt2 \
+ strings25.smt2
EXTRA_DIST = $(TESTS)
--- /dev/null
+; EXPECT: sat
+; EXPECT: (model
+; EXPECT: (define-fun s () String "\"")
+; EXPECT: )
+
+(set-logic QF_S)
+(set-info :smt-lib-version 2.0)
+(set-option :produce-models true)
+
+(declare-fun s () String)
+
+(assert (= s "\""))
+
+(check-sat)
+(get-model)
--- /dev/null
+; EXPECT: sat
+; EXPECT: (model
+; EXPECT: (define-fun s () String """")
+; EXPECT: )
+
+(set-logic QF_S)
+(set-info :smt-lib-version 2.5)
+(set-option :produce-models true)
+
+(declare-fun s () String)
+
+(assert (= s """"))
+
+(check-sat)
+(get-model)
bug001.smt2 \
cardinality.smt2 \
escchar.smt2 \
+ escchar_25.smt2 \
str001.smt2 \
str002.smt2 \
str003.smt2 \
(set-logic QF_S)\r
(set-info :status sat)\r
+(set-info :smt-lib-version 2.0)\r
\r
(declare-fun x () String)\r
(declare-const I Int)\r
--- /dev/null
+(set-logic QF_S)\r
+(set-info :status sat)\r
+(set-info :smt-lib-version 2.5)\r
+\r
+(declare-fun x () String)\r
+(declare-const I Int)\r
+\r
+(assert (= x "\0\1\2\3\04\005\x06\7\8\9ABC\\""\t\a\b"))\r
+(assert (= I (str.len x)))\r
+\r
+\r
+(check-sat)\r