This PR adds a new API function Solver::getDriverOptions() which is used to communicate special options that (a) can not be properly communicated via getOption() and (b) need to be available in the driver (in a type-safe manner).
As of now, this concerns the input stream and output streams.
Furthermore, this PR refactors the driver to obtain them via the driver options instead of using the (deprecated) Solver::getOptions() method.
ROUND_NEAREST_TIES_TO_AWAY},
};
+/* -------------------------------------------------------------------------- */
+/* Options */
+/* -------------------------------------------------------------------------- */
+
+DriverOptions::DriverOptions(const Solver& solver) : d_solver(solver) {}
+
+std::istream& DriverOptions::in() const
+{
+ return *d_solver.d_smtEngine->getOptions().base.in;
+}
+std::ostream& DriverOptions::err() const
+{
+ return *d_solver.d_smtEngine->getOptions().base.err;
+}
+std::ostream& DriverOptions::out() const
+{
+ return *d_solver.d_smtEngine->getOptions().base.out;
+}
+
/* -------------------------------------------------------------------------- */
/* Statistics */
/* -------------------------------------------------------------------------- */
CVC5_API_TRY_CATCH_END;
}
+DriverOptions Solver::getDriverOptions() const { return DriverOptions(*this); }
+
std::vector<Term> Solver::getUnsatAssumptions(void) const
{
CVC5_API_TRY_CATCH_BEGIN;
} // namespace std
namespace cvc5::api {
+/* -------------------------------------------------------------------------- */
+/* Options */
+/* -------------------------------------------------------------------------- */
+
+/**
+ * Provides access to options that can not be communicated via the regular
+ * getOption() or getOptionInfo() methods. This class does not store the options
+ * itself, but only acts as a wrapper to the solver object. It can thus no
+ * longer be used after the solver object has been destroyed.
+ */
+class CVC5_EXPORT DriverOptions
+{
+ friend class Solver;
+
+ public:
+ /** Access the solvers input stream */
+ std::istream& in() const;
+ /** Access the solvers error output stream */
+ std::ostream& err() const;
+ /** Access the solvers output stream */
+ std::ostream& out() const;
+
+ private:
+ DriverOptions(const Solver& solver);
+ const Solver& d_solver;
+};
+
/* -------------------------------------------------------------------------- */
/* Statistics */
/* -------------------------------------------------------------------------- */
friend class DatatypeConstructor;
friend class DatatypeConstructorDecl;
friend class DatatypeSelector;
+ friend class DriverOptions;
friend class Grammar;
friend class Op;
friend class cvc5::Command;
*/
std::vector<std::string> getOptionNames() const;
+ /**
+ * Get the driver options, which provide access to options that can not be
+ * communicated properly via getOption() and getOptionInfo().
+ * @return a DriverOptions object.
+ */
+ DriverOptions getDriverOptions() const;
+
/**
* Get the set of unsat ("failed") assumptions.
* SMT-LIB:
} else {
if (d_solver->getOptions().base.verbosity > 2)
{
- *d_solver->getOptions().base.out << "Invoking: " << *cmd << std::endl;
+ d_solver->getDriverOptions().out() << "Invoking: " << *cmd << std::endl;
}
return doCommandSingleton(cmd);
void CommandExecutor::reset()
{
- printStatistics(*d_solver->getOptions().base.err);
-
+ printStatistics(d_solver->getDriverOptions().err());
Command::resetSolver(d_solver.get());
}
bool CommandExecutor::doCommandSingleton(Command* cmd)
{
- bool status = true;
- if (d_solver->getOptions().base.verbosity >= -1)
- {
- status = solverInvoke(
- d_solver.get(), d_symman.get(), cmd, d_solver->getOptions().base.out);
- }
- else
- {
- status = solverInvoke(d_solver.get(), d_symman.get(), cmd, nullptr);
- }
+ bool status = solverInvoke(
+ d_solver.get(), d_symman.get(), cmd, d_solver->getDriverOptions().out());
api::Result res;
const CheckSatCommand* cs = dynamic_cast<const CheckSatCommand*>(cmd);
bool solverInvoke(api::Solver* solver,
SymbolManager* sm,
Command* cmd,
- std::ostream* out)
+ std::ostream& out)
{
- if (out == NULL)
- {
- cmd->invoke(solver, sm);
- }
- else
- {
- cmd->invoke(solver, sm, *out);
- }
+ cmd->invoke(solver, sm, out);
// ignore the error if the command-verbosity is 0 for this command
std::string commandName =
std::string("command-verbosity:") + cmd->getCommandName();
}
void CommandExecutor::flushOutputStreams() {
- printStatistics(*d_solver->getOptions().base.err);
+ printStatistics(d_solver->getDriverOptions().err());
// make sure out and err streams are flushed too
-
- if (d_solver->getOptions().base.out != nullptr)
- {
- *d_solver->getOptions().base.out << std::flush;
- }
- if (d_solver->getOptions().base.err != nullptr)
- {
- *d_solver->getOptions().base.err << std::flush;
- }
+ d_solver->getDriverOptions().out() << std::flush;
+ d_solver->getDriverOptions().err() << std::flush;
}
} // namespace main
bool solverInvoke(api::Solver* solver,
SymbolManager* sm,
Command* cmd,
- std::ostream* out);
+ std::ostream& out);
} // namespace main
} // namespace cvc5
} // namespace main
} // namespace cvc5
-void printUsage(const Options& opts, bool full) {
- stringstream ss;
- ss << "usage: " << progName << " [options] [input-file]"
- << endl
- << endl
- << "Without an input file, or with `-', cvc5 reads from standard input."
- << endl
- << endl
- << "cvc5 options:" << endl;
- if(full) {
- main::printUsage(ss.str(), *opts.base.out);
- } else {
- main::printShortUsage(ss.str(), *opts.base.out);
- }
-}
+ void printUsage(const api::DriverOptions& dopts, bool full)
+ {
+ std::stringstream ss;
+ ss << "usage: " << progName << " [options] [input-file]" << std::endl
+ << std::endl
+ << "Without an input file, or with `-', cvc5 reads from standard "
+ "input."
+ << std::endl
+ << std::endl
+ << "cvc5 options:" << std::endl;
+ if (full)
+ {
+ main::printUsage(ss.str(), dopts.out());
+ }
+ else
+ {
+ main::printShortUsage(ss.str(), dopts.out());
+ }
+ }
int runCvc5(int argc, char* argv[], std::unique_ptr<api::Solver>& solver)
{
// Create the command executor to execute the parsed commands
pExecutor = std::make_unique<CommandExecutor>(solver);
+ api::DriverOptions dopts = solver->getDriverOptions();
Options* opts = &pExecutor->getOptions();
// Parse the options
if (opts->driver.help)
{
- printUsage(*opts, true);
+ printUsage(dopts, true);
exit(1);
}
else if (opts->base.languageHelp)
{
- main::printLanguageHelp(*opts->base.out);
+ main::printLanguageHelp(dopts.out());
exit(1);
}
else if (opts->driver.version)
{
- *opts->base.out << Configuration::about().c_str() << flush;
+ dopts.out() << Configuration::about().c_str() << flush;
exit(0);
}
// If in competition mode, set output stream option to flush immediately
#ifdef CVC5_COMPETITION_MODE
- *opts->base.out << unitbuf;
+ dopts.out() << unitbuf;
#endif /* CVC5_COMPETITION_MODE */
// We only accept one input file
try {
cmd.reset(shell.readCommand());
} catch(UnsafeInterruptException& e) {
- *opts->base.out << CommandInterrupted();
+ dopts.out() << CommandInterrupted();
break;
}
if (cmd == nullptr)
while (status)
{
if (interrupted) {
- *opts->base.out << CommandInterrupted();
+ dopts.out() << CommandInterrupted();
pExecutor->reset();
opts = &pExecutor->getOptions();
break;
}
#ifdef CVC5_COMPETITION_MODE
- if (opts->base.out != nullptr)
- {
- *opts->base.out << std::flush;
- }
+ dopts.out() << std::flush;
// exit, don't return (don't want destructors to run)
// _exit() from unistd.h doesn't run global destructors
// or other on_exit/atexit stuff.
InteractiveShell::InteractiveShell(api::Solver* solver, SymbolManager* sm)
: d_solver(solver),
- d_in(*solver->getOptions().base.in),
- d_out(*solver->getOptions().base.out),
+ d_in(solver->getDriverOptions().in()),
+ d_out(solver->getDriverOptions().out()),
d_quit(false)
{
ParserBuilder parserBuilder(solver, sm, true);
catch (cvc5::api::CVC5ApiOptionException& e)
{
#ifdef CVC5_COMPETITION_MODE
- *solver->getOptions().base.out << "unknown" << endl;
+ solver->getDriverOptions().out() << "unknown" << std::endl;
#endif
cerr << "(error \"" << e.getMessage() << "\")" << endl
<< endl
catch (OptionException& e)
{
#ifdef CVC5_COMPETITION_MODE
- *solver->getOptions().base.out << "unknown" << endl;
+ solver->getDriverOptions().out() << "unknown" << std::endl;
#endif
cerr << "(error \"" << e.getMessage() << "\")" << endl
<< endl
catch (Exception& e)
{
#ifdef CVC5_COMPETITION_MODE
- *solver->getOptions().base.out << "unknown" << endl;
+ solver->getDriverOptions().out() << "unknown" << std::endl;
#endif
if (language::isLangSmt2(solver->getOptions().base.outputLanguage))
{
- *solver->getOptions().base.out << "(error \"" << e << "\")" << endl;
+ solver->getDriverOptions().out()
+ << "(error \"" << e << "\")" << std::endl;
}
else
{
- *solver->getOptions().base.err << "(error \"" << e << "\")" << endl;
+ solver->getDriverOptions().err()
+ << "(error \"" << e << "\")" << std::endl;
}
if (solver->getOptions().base.statistics && pExecutor != nullptr)
{
totalTime.reset();
- pExecutor->printStatistics(*solver->getOptions().base.err);
+ pExecutor->printStatistics(solver->getDriverOptions().err());
}
}
exit(1);