diff options
author | Andres Noetzli <andres.noetzli@gmail.com> | 2019-06-21 11:58:25 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-21 11:58:25 -0700 |
commit | be33ac9656bf7feafa3715d6623749f6afd962b5 (patch) | |
tree | 63fe6f537e6b2df5791c02f0183706a8e7f5ead2 /src/parser | |
parent | cf9dfb9be23b4f802989fecd18756ed62aecc8e4 (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.txt | 2 | ||||
-rw-r--r-- | src/parser/cvc/cvc.cpp | 29 | ||||
-rw-r--r-- | src/parser/cvc/cvc.h | 50 | ||||
-rw-r--r-- | src/parser/parser.h | 7 | ||||
-rw-r--r-- | src/parser/parser_builder.cpp | 3 | ||||
-rw-r--r-- | src/parser/smt2/Smt2.g | 15 | ||||
-rw-r--r-- | src/parser/smt2/smt2.cpp | 80 | ||||
-rw-r--r-- | src/parser/smt2/smt2.h | 10 | ||||
-rw-r--r-- | src/parser/tptp/tptp.cpp | 6 | ||||
-rw-r--r-- | src/parser/tptp/tptp.h | 2 |
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(); |