summaryrefslogtreecommitdiff
path: root/src/parser
diff options
context:
space:
mode:
authorAndres Noetzli <andres.noetzli@gmail.com>2019-06-21 11:58:25 -0700
committerGitHub <noreply@github.com>2019-06-21 11:58:25 -0700
commitbe33ac9656bf7feafa3715d6623749f6afd962b5 (patch)
tree63fe6f537e6b2df5791c02f0183706a8e7f5ead2 /src/parser
parentcf9dfb9be23b4f802989fecd18756ed62aecc8e4 (diff)
Fix and simplify handling of --force-logic (#3062)
The `--force-logic` command line argument can be used to override a logic specified in an input file or to set a logic when none is given. Before this commit, both the `SmtEngine` and the parser were aware of that argument. However, there were two issues if an input file didn't specify a logic but `--force-logic` was used: - Upon parsing `--force-logic`, the `SmtEngine` was informed about it and set the logic to the forced logic. Then, the parser detected that there was no `set-logic` command, so it set the logic to `ALL` and emitted a corresponding warning. Finally, `SmtEngine::setDefaults()` detected that `forceLogic` was set by the user and changed the logic back to the forced logic. The warning was confusing and setting the logic multiple times was not elegant. - For eager bit-blasting, the logic was checked before resetting the logic to the forced logic, so it would emit an error that eager bit-blasting couldn't be used with the logic (which was `ALL` at that point of the execution). This was a problem in the competition because our runscript parses the `set-logic` command to decide on the appropriate arguments to use and passes the logic to CVC4 via `--force-logic`. This commit moves the handling of `--force-logic` entirely into the parser. The rationale for that is that this is not an API-level issue (if you use the API you simply set the logic you want, forcing a different logic in addition doesn't make sense) and simplifies the handling of the option (no listeners need to be installed and the logic is set only once). This commit also removes the option to set the logic via `(set-option :cvc4-logic ...)` because it complicates matters (e.g. which method of setting the logic takes precedence?). For the CVC and the TPTP languages the commit creates a command to set the logic in `SmtEngine` when the logic is forced in the parser instead of relying on `SmtEngine` to figure it out itself.
Diffstat (limited to 'src/parser')
-rw-r--r--src/parser/CMakeLists.txt2
-rw-r--r--src/parser/cvc/cvc.cpp29
-rw-r--r--src/parser/cvc/cvc.h50
-rw-r--r--src/parser/parser.h7
-rw-r--r--src/parser/parser_builder.cpp3
-rw-r--r--src/parser/smt2/Smt2.g15
-rw-r--r--src/parser/smt2/smt2.cpp80
-rw-r--r--src/parser/smt2/smt2.h10
-rw-r--r--src/parser/tptp/tptp.cpp6
-rw-r--r--src/parser/tptp/tptp.h2
10 files changed, 164 insertions, 40 deletions
diff --git a/src/parser/CMakeLists.txt b/src/parser/CMakeLists.txt
index d79d7b22c..03e194b90 100644
--- a/src/parser/CMakeLists.txt
+++ b/src/parser/CMakeLists.txt
@@ -22,6 +22,8 @@ set(libcvc4parser_src_files
bounded_token_buffer.h
bounded_token_factory.cpp
bounded_token_factory.h
+ cvc/cvc.cpp
+ cvc/cvc.h
cvc/cvc_input.cpp
cvc/cvc_input.h
input.cpp
diff --git a/src/parser/cvc/cvc.cpp b/src/parser/cvc/cvc.cpp
new file mode 100644
index 000000000..9b7e1f403
--- /dev/null
+++ b/src/parser/cvc/cvc.cpp
@@ -0,0 +1,29 @@
+/********************* */
+/*! \file cvc.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andres Noetzli
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief The parser class for the CVC language.
+ **
+ ** The parser class for the CVC language.
+ **/
+
+#include "parser/cvc/cvc.h"
+
+namespace CVC4 {
+namespace parser {
+
+void Cvc::forceLogic(const std::string& logic)
+{
+ Parser::forceLogic(logic);
+ preemptCommand(new SetBenchmarkLogicCommand(logic));
+}
+
+} // namespace parser
+} // namespace CVC4
diff --git a/src/parser/cvc/cvc.h b/src/parser/cvc/cvc.h
new file mode 100644
index 000000000..feb962a09
--- /dev/null
+++ b/src/parser/cvc/cvc.h
@@ -0,0 +1,50 @@
+/********************* */
+/*! \file cvc.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Andres Noetzli
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2019 by the authors listed in the file AUTHORS
+ ** in the top-level source directory) and their institutional affiliations.
+ ** All rights reserved. See the file COPYING in the top-level source
+ ** directory for licensing information.\endverbatim
+ **
+ ** \brief The parser class for the CVC language.
+ **
+ ** The parser class for the CVC language.
+ **/
+
+#include "cvc4parser_private.h"
+
+#ifndef CVC4__PARSER__CVC_H
+#define CVC4__PARSER__CVC_H
+
+#include "api/cvc4cpp.h"
+#include "parser/parser.h"
+#include "smt/command.h"
+
+namespace CVC4 {
+
+namespace parser {
+
+class Cvc : public Parser
+{
+ friend class ParserBuilder;
+
+ public:
+ void forceLogic(const std::string& logic) override;
+
+ protected:
+ Cvc(api::Solver* solver,
+ Input* input,
+ bool strictMode = false,
+ bool parseOnly = false)
+ : Parser(solver, input, strictMode, parseOnly)
+ {
+ }
+};
+
+} // namespace parser
+} // namespace CVC4
+
+#endif /* CVC4__PARSER__CVC_H */
diff --git a/src/parser/parser.h b/src/parser/parser.h
index fcc37d5d3..8f9cc425a 100644
--- a/src/parser/parser.h
+++ b/src/parser/parser.h
@@ -322,7 +322,12 @@ public:
implementation optional by returning false by default. */
virtual bool logicIsSet() { return false; }
- void forceLogic(const std::string& logic) { assert(!d_logicIsForced); d_logicIsForced = true; d_forcedLogic = logic; }
+ virtual void forceLogic(const std::string& logic)
+ {
+ assert(!d_logicIsForced);
+ d_logicIsForced = true;
+ d_forcedLogic = logic;
+ }
const std::string& getForcedLogic() const { return d_forcedLogic; }
bool logicIsForced() const { return d_logicIsForced; }
diff --git a/src/parser/parser_builder.cpp b/src/parser/parser_builder.cpp
index 57b63cc0f..f0e6ad284 100644
--- a/src/parser/parser_builder.cpp
+++ b/src/parser/parser_builder.cpp
@@ -22,6 +22,7 @@
#include <string>
#include "api/cvc4cpp.h"
+#include "cvc/cvc.h"
#include "expr/expr_manager.h"
#include "options/options.h"
#include "parser/input.h"
@@ -105,7 +106,7 @@ Parser* ParserBuilder::build()
}
else
{
- parser = new Parser(d_solver, input, d_strictMode, d_parseOnly);
+ parser = new Cvc(d_solver, input, d_strictMode, d_parseOnly);
}
break;
}
diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g
index 4a30841e6..b49b62604 100644
--- a/src/parser/smt2/Smt2.g
+++ b/src/parser/smt2/Smt2.g
@@ -269,16 +269,8 @@ command [std::unique_ptr<CVC4::Command>* cmd]
}
: /* set the logic */
SET_LOGIC_TOK symbol[name,CHECK_NONE,SYM_SORT]
- { Debug("parser") << "set logic: '" << name << "'" << std::endl;
- if( PARSER_STATE->logicIsSet() ) {
- PARSER_STATE->parseError("Only one set-logic is allowed.");
- }
- PARSER_STATE->setLogic(name);
- if( PARSER_STATE->sygus() ){
- cmd->reset(new SetBenchmarkLogicCommand(PARSER_STATE->getLogic().getLogicString()));
- }else{
- cmd->reset(new SetBenchmarkLogicCommand(name));
- }
+ {
+ cmd->reset(PARSER_STATE->setLogic(name));
}
| /* set-info */
SET_INFO_TOK metaInfoInternal[cmd]
@@ -1029,9 +1021,6 @@ metaInfoInternal[std::unique_ptr<CVC4::Command>* cmd]
}
: 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->reset(new SetInfoCommand(name.c_str() + 1, sexpr));
}
diff --git a/src/parser/smt2/smt2.cpp b/src/parser/smt2/smt2.cpp
index 12b43f346..c072c535f 100644
--- a/src/parser/smt2/smt2.cpp
+++ b/src/parser/smt2/smt2.cpp
@@ -22,7 +22,6 @@
#include "parser/smt1/smt1.h"
#include "parser/smt2/smt2_input.h"
#include "printer/sygus_print_callback.h"
-#include "smt/command.h"
#include "util/bitvector.h"
#include <algorithm>
@@ -35,7 +34,9 @@ namespace CVC4 {
namespace parser {
Smt2::Smt2(api::Solver* solver, Input* input, bool strictMode, bool parseOnly)
- : Parser(solver, input, strictMode, parseOnly), d_logicSet(false)
+ : Parser(solver, input, strictMode, parseOnly),
+ d_logicSet(false),
+ d_seenSetLogic(false)
{
if (!strictModeEnabled())
{
@@ -626,7 +627,22 @@ void Smt2::resetAssertions() {
}
}
-void Smt2::setLogic(std::string name) {
+Command* Smt2::setLogic(std::string name, bool fromCommand)
+{
+ if (fromCommand)
+ {
+ if (d_seenSetLogic)
+ {
+ parseError("Only one set-logic is allowed.");
+ }
+ d_seenSetLogic = true;
+
+ if (logicIsForced())
+ {
+ // If the logic is forced, we ignore all set-logic requests from commands.
+ return new EmptyCommand();
+ }
+ }
if(sygus()) {
// non-smt2-standard sygus logic names go here (http://sygus.seas.upenn.edu/files/sygus.pdf Section 3.2)
@@ -638,11 +654,7 @@ void Smt2::setLogic(std::string name) {
}
d_logicSet = true;
- if(logicIsForced()) {
- d_logic = getForcedLogic();
- } else {
- d_logic = name;
- }
+ d_logic = name;
// if sygus is enabled, we must enable UF, datatypes, integer arithmetic and
// higher-order
@@ -718,8 +730,16 @@ void Smt2::setLogic(std::string name) {
if (d_logic.isTheoryEnabled(theory::THEORY_SEP)) {
addTheory(THEORY_SEP);
}
-
-}/* Smt2::setLogic() */
+
+ if (sygus())
+ {
+ return new SetBenchmarkLogicCommand(d_logic.getLogicString());
+ }
+ else
+ {
+ return new SetBenchmarkLogicCommand(name);
+ }
+} /* Smt2::setLogic() */
void Smt2::setInfo(const std::string& flag, const SExpr& sexpr) {
// TODO: ???
@@ -729,21 +749,33 @@ void Smt2::setOption(const std::string& flag, const SExpr& sexpr) {
// TODO: ???
}
-void Smt2::checkThatLogicIsSet() {
- if( ! logicIsSet() ) {
- if(strictModeEnabled()) {
+void Smt2::checkThatLogicIsSet()
+{
+ if (!logicIsSet())
+ {
+ if (strictModeEnabled())
+ {
parseError("set-logic must appear before this point.");
- } else {
- warning("No set-logic command was given before this point.");
- warning("CVC4 will make all theories available.");
- warning("Consider setting a stricter logic for (likely) better performance.");
- warning("To suppress this warning in the future use (set-logic ALL).");
-
- setLogic("ALL");
-
- Command* c = new SetBenchmarkLogicCommand("ALL");
- c->setMuted(true);
- preemptCommand(c);
+ }
+ else
+ {
+ Command* cmd = nullptr;
+ if (logicIsForced())
+ {
+ cmd = setLogic(getForcedLogic(), false);
+ }
+ else
+ {
+ warning("No set-logic command was given before this point.");
+ warning("CVC4 will make all theories available.");
+ warning(
+ "Consider setting a stricter logic for (likely) better "
+ "performance.");
+ warning("To suppress this warning in the future use (set-logic ALL).");
+
+ cmd = setLogic("ALL", false);
+ }
+ preemptCommand(cmd);
}
}
}
diff --git a/src/parser/smt2/smt2.h b/src/parser/smt2/smt2.h
index d4d310b89..2ac796166 100644
--- a/src/parser/smt2/smt2.h
+++ b/src/parser/smt2/smt2.h
@@ -28,6 +28,7 @@
#include "api/cvc4cpp.h"
#include "parser/parser.h"
#include "parser/smt1/smt1.h"
+#include "smt/command.h"
#include "theory/logic_info.h"
#include "util/abstract_value.h"
@@ -65,7 +66,11 @@ class Smt2 : public Parser
};
private:
+ /** Has the logic been set (either by forcing it or a set-logic command)? */
bool d_logicSet;
+ /** Have we seen a set-logic command yet? */
+ bool d_seenSetLogic;
+
LogicInfo d_logic;
std::unordered_map<std::string, Kind> operatorKindMap;
/**
@@ -197,8 +202,11 @@ class Smt2 : public Parser
* theory symbols.
*
* @param name the name of the logic (e.g., QF_UF, AUFLIA)
+ * @param fromCommand should be set to true if the request originates from a
+ * set-logic command and false otherwise
+ * @return the command corresponding to setting the logic
*/
- void setLogic(std::string name);
+ Command* setLogic(std::string name, bool fromCommand = true);
/**
* Get the logic.
diff --git a/src/parser/tptp/tptp.cpp b/src/parser/tptp/tptp.cpp
index fd593c68b..c4efe5e09 100644
--- a/src/parser/tptp/tptp.cpp
+++ b/src/parser/tptp/tptp.cpp
@@ -214,6 +214,12 @@ void Tptp::checkLetBinding(const std::vector<Expr>& bvlist, Expr lhs, Expr rhs,
}
}
+void Tptp::forceLogic(const std::string& logic)
+{
+ Parser::forceLogic(logic);
+ preemptCommand(new SetBenchmarkLogicCommand(logic));
+}
+
void Tptp::addFreeVar(Expr var) {
assert(cnf());
d_freeVar.push_back(var);
diff --git a/src/parser/tptp/tptp.h b/src/parser/tptp/tptp.h
index 082b905df..605748d88 100644
--- a/src/parser/tptp/tptp.h
+++ b/src/parser/tptp/tptp.h
@@ -47,6 +47,8 @@ class Tptp : public Parser {
bool fof() const { return d_fof; }
void setFof(bool fof) { d_fof = fof; }
+ void forceLogic(const std::string& logic) override;
+
void addFreeVar(Expr var);
std::vector< Expr > getFreeVar();
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback