1 /******************************************************************************
2 * Top contributors (to current version):
3 * Aina Niemetz, Tim King, Mathias Preiner
5 * This file is part of the cvc5 project.
7 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8 * in the top-level source directory and their institutional affiliations.
9 * All rights reserved. See the file COPYING in the top-level source
10 * directory for licensing information.
11 * ****************************************************************************
13 * Interface for custom handlers and predicates options.
16 #include "options/options_handler.h"
22 #include "base/check.h"
23 #include "base/configuration.h"
24 #include "base/configuration_private.h"
25 #include "base/cvc5config.h"
26 #include "base/exception.h"
27 #include "base/modal_exception.h"
28 #include "base/output.h"
29 #include "lib/strtok_r.h"
30 #include "options/base_options.h"
31 #include "options/bv_options.h"
32 #include "options/decision_options.h"
33 #include "options/didyoumean.h"
34 #include "options/language.h"
35 #include "options/option_exception.h"
36 #include "options/resource_manager_options.h"
37 #include "options/smt_options.h"
38 #include "options/theory_options.h"
46 void throwLazyBBUnsupported(options::SatSolverMode m
)
48 std::string sat_solver
;
49 if (m
== options::SatSolverMode::CADICAL
)
51 sat_solver
= "CaDiCaL";
53 else if (m
== options::SatSolverMode::KISSAT
)
55 sat_solver
= "Kissat";
59 Assert(m
== options::SatSolverMode::CRYPTOMINISAT
);
60 sat_solver
= "CryptoMiniSat";
62 std::string
indent(25, ' ');
63 throw OptionException(sat_solver
+ " does not support lazy bit-blasting.\n"
64 + indent
+ "Try --bv-sat-solver=minisat");
69 OptionsHandler::OptionsHandler(Options
* options
) : d_options(options
) { }
71 unsigned long OptionsHandler::limitHandler(std::string option
,
75 std::istringstream
convert(optarg
);
78 throw OptionException("option `" + option
79 + "` requires a number as an argument");
84 void OptionsHandler::setResourceWeight(std::string option
, std::string optarg
)
86 d_options
->resman
.resourceWeightHolder
.emplace_back(optarg
);
89 // theory/quantifiers/options_handlers.h
91 void OptionsHandler::checkInstWhenMode(std::string option
, InstWhenMode mode
)
93 if (mode
== InstWhenMode::PRE_FULL
)
95 throw OptionException(std::string("Mode pre-full for ") + option
96 + " is not supported in this release.");
100 // theory/bv/options_handlers.h
101 void OptionsHandler::abcEnabledBuild(std::string option
, bool value
)
105 std::stringstream ss
;
106 ss
<< "option `" << option
107 << "' requires an abc-enabled build of cvc5; this binary was not built "
109 throw OptionException(ss
.str());
111 #endif /* CVC5_USE_ABC */
114 void OptionsHandler::abcEnabledBuild(std::string option
, std::string value
)
118 std::stringstream ss
;
119 ss
<< "option `" << option
120 << "' requires an abc-enabled build of cvc5; this binary was not built "
122 throw OptionException(ss
.str());
124 #endif /* CVC5_USE_ABC */
127 void OptionsHandler::checkBvSatSolver(std::string option
, SatSolverMode m
)
129 if (m
== SatSolverMode::CRYPTOMINISAT
130 && !Configuration::isBuiltWithCryptominisat())
132 std::stringstream ss
;
133 ss
<< "option `" << option
134 << "' requires a CryptoMiniSat build of cvc5; this binary was not built "
135 "with CryptoMiniSat support";
136 throw OptionException(ss
.str());
139 if (m
== SatSolverMode::CADICAL
&& !Configuration::isBuiltWithCadical())
141 std::stringstream ss
;
142 ss
<< "option `" << option
143 << "' requires a CaDiCaL build of cvc5; this binary was not built with "
145 throw OptionException(ss
.str());
148 if (m
== SatSolverMode::KISSAT
&& !Configuration::isBuiltWithKissat())
150 std::stringstream ss
;
151 ss
<< "option `" << option
152 << "' requires a Kissat build of cvc5; this binary was not built with "
154 throw OptionException(ss
.str());
157 if (options::bvSolver() != options::BVSolver::BITBLAST
158 && (m
== SatSolverMode::CRYPTOMINISAT
|| m
== SatSolverMode::CADICAL
159 || m
== SatSolverMode::KISSAT
))
161 if (options::bitblastMode() == options::BitblastMode::LAZY
162 && d_options
->bv
.bitblastModeWasSetByUser
)
164 throwLazyBBUnsupported(m
);
166 options::bv::setDefaultBitvectorToBool(*d_options
, true);
170 void OptionsHandler::checkBitblastMode(std::string option
, BitblastMode m
)
172 if (m
== options::BitblastMode::LAZY
)
174 options::bv::setDefaultBitvectorPropagate(*d_options
, true);
175 options::bv::setDefaultBitvectorEqualitySolver(*d_options
, true);
176 options::bv::setDefaultBitvectorInequalitySolver(*d_options
, true);
177 options::bv::setDefaultBitvectorAlgebraicSolver(*d_options
, true);
178 if (options::bvSatSolver() != options::SatSolverMode::MINISAT
)
180 throwLazyBBUnsupported(options::bvSatSolver());
183 else if (m
== BitblastMode::EAGER
)
185 options::bv::setDefaultBitvectorToBool(*d_options
, true);
189 void OptionsHandler::setBitblastAig(std::string option
, bool arg
)
192 if (d_options
->bv
.bitblastModeWasSetByUser
) {
193 if (options::bitblastMode() != options::BitblastMode::EAGER
)
195 throw OptionException("bitblast-aig must be used with eager bitblaster");
198 options::BitblastMode mode
= stringToBitblastMode("eager");
199 d_options
->bv
.bitblastMode
= mode
;
204 // printer/options_handlers.h
205 const std::string
OptionsHandler::s_instFormatHelp
= "\
206 Inst format modes currently supported by the --inst-format option:\n\
209 + Print instantiations as a list in the output language format.\n\
212 + Print instantiations as SZS compliant proof.\n\
215 InstFormatMode
OptionsHandler::stringToInstFormatMode(std::string option
,
218 if(optarg
== "default") {
219 return InstFormatMode::DEFAULT
;
220 } else if(optarg
== "szs") {
221 return InstFormatMode::SZS
;
222 } else if(optarg
== "help") {
223 puts(s_instFormatHelp
.c_str());
226 throw OptionException(std::string("unknown option for --inst-format: `") +
227 optarg
+ "'. Try --inst-format help.");
231 // decision/options_handlers.h
232 void OptionsHandler::setDecisionModeStopOnly(std::string option
, DecisionMode m
)
234 d_options
->decision
.decisionStopOnly
= (m
== DecisionMode::RELEVANCY
);
237 void OptionsHandler::setProduceAssertions(std::string option
, bool value
)
239 d_options
->smt
.produceAssertions
= value
;
240 d_options
->smt
.interactiveMode
= value
;
243 void OptionsHandler::setStats(const std::string
& option
, bool value
)
245 #ifndef CVC5_STATISTICS_ON
248 std::stringstream ss
;
249 ss
<< "option `" << option
250 << "' requires a statistics-enabled build of cvc5; this binary was not "
251 "built with statistics support";
252 throw OptionException(ss
.str());
254 #endif /* CVC5_STATISTICS_ON */
255 std::string opt
= option
;
256 if (option
.substr(0, 2) == "--")
262 if (opt
== options::base::statisticsAll__name
)
264 d_options
->base
.statistics
= true;
266 else if (opt
== options::base::statisticsEveryQuery__name
)
268 d_options
->base
.statistics
= true;
270 else if (opt
== options::base::statisticsExpert__name
)
272 d_options
->base
.statistics
= true;
277 if (opt
== options::base::statistics__name
)
279 d_options
->base
.statisticsAll
= false;
280 d_options
->base
.statisticsEveryQuery
= false;
281 d_options
->base
.statisticsExpert
= false;
286 void OptionsHandler::threadN(std::string option
) {
287 throw OptionException(option
+ " is not a real option by itself. Use e.g. --thread0=\"--random-seed=10 --random-freq=0.02\" --thread1=\"--random-seed=20 --random-freq=0.05\"");
290 // expr/options_handlers.h
291 void OptionsHandler::setDefaultExprDepthPredicate(std::string option
, int depth
) {
293 throw OptionException("--expr-depth requires a positive argument, or -1.");
297 void OptionsHandler::setDefaultDagThreshPredicate(std::string option
, int dag
) {
299 throw OptionException("--dag-thresh requires a nonnegative argument.");
303 // main/options_handlers.h
305 static void print_config (const char * str
, std::string config
) {
308 if (s
.size() < sz
) s
.resize(sz
, ' ');
309 std::cout
<< s
<< ": " << config
<< std::endl
;
312 static void print_config_cond (const char * str
, bool cond
= false) {
313 print_config(str
, cond
? "yes" : "no");
316 void OptionsHandler::copyright(std::string option
) {
317 std::cout
<< Configuration::copyright() << std::endl
;
321 void OptionsHandler::showConfiguration(std::string option
) {
322 std::cout
<< Configuration::about() << std::endl
;
324 print_config ("version", Configuration::getVersionString());
326 if(Configuration::isGitBuild()) {
327 const char* branchName
= Configuration::getGitBranchName();
328 if(*branchName
== '\0') { branchName
= "-"; }
329 std::stringstream ss
;
332 << std::string(Configuration::getGitCommit()).substr(0, 8)
333 << (Configuration::hasGitModifications() ? " (with modifications)" : "")
335 print_config("scm", ss
.str());
337 print_config_cond("scm", false);
340 std::cout
<< std::endl
;
342 std::stringstream ss
;
343 ss
<< Configuration::getVersionMajor() << "."
344 << Configuration::getVersionMinor() << "."
345 << Configuration::getVersionRelease();
346 print_config("library", ss
.str());
348 std::cout
<< std::endl
;
350 print_config_cond("debug code", Configuration::isDebugBuild());
351 print_config_cond("statistics", Configuration::isStatisticsBuild());
352 print_config_cond("tracing", Configuration::isTracingBuild());
353 print_config_cond("dumping", Configuration::isDumpingBuild());
354 print_config_cond("muzzled", Configuration::isMuzzledBuild());
355 print_config_cond("assertions", Configuration::isAssertionBuild());
356 print_config_cond("coverage", Configuration::isCoverageBuild());
357 print_config_cond("profiling", Configuration::isProfilingBuild());
358 print_config_cond("asan", Configuration::isAsanBuild());
359 print_config_cond("ubsan", Configuration::isUbsanBuild());
360 print_config_cond("tsan", Configuration::isTsanBuild());
361 print_config_cond("competition", Configuration::isCompetitionBuild());
363 std::cout
<< std::endl
;
365 print_config_cond("abc", Configuration::isBuiltWithAbc());
366 print_config_cond("cln", Configuration::isBuiltWithCln());
367 print_config_cond("glpk", Configuration::isBuiltWithGlpk());
368 print_config_cond("cadical", Configuration::isBuiltWithCadical());
369 print_config_cond("cryptominisat", Configuration::isBuiltWithCryptominisat());
370 print_config_cond("gmp", Configuration::isBuiltWithGmp());
371 print_config_cond("kissat", Configuration::isBuiltWithKissat());
372 print_config_cond("poly", Configuration::isBuiltWithPoly());
373 print_config_cond("editline", Configuration::isBuiltWithEditline());
374 print_config_cond("symfpu", Configuration::isBuiltWithSymFPU());
379 static void printTags(unsigned ntags
, char const* const* tags
)
381 std::cout
<< "available tags:";
382 for (unsigned i
= 0; i
< ntags
; ++ i
)
384 std::cout
<< " " << tags
[i
] << std::endl
;
386 std::cout
<< std::endl
;
389 void OptionsHandler::showDebugTags(std::string option
)
391 if (!Configuration::isDebugBuild())
393 throw OptionException("debug tags not available in non-debug builds");
395 else if (!Configuration::isTracingBuild())
397 throw OptionException("debug tags not available in non-tracing builds");
399 printTags(Configuration::getNumDebugTags(),Configuration::getDebugTags());
403 void OptionsHandler::showTraceTags(std::string option
)
405 if (!Configuration::isTracingBuild())
407 throw OptionException("trace tags not available in non-tracing build");
409 printTags(Configuration::getNumTraceTags(), Configuration::getTraceTags());
413 static std::string
suggestTags(char const* const* validTags
,
414 std::string inputTag
,
415 char const* const* additionalTags
)
417 DidYouMean didYouMean
;
420 for (size_t i
= 0; (opt
= validTags
[i
]) != nullptr; ++i
)
422 didYouMean
.addWord(validTags
[i
]);
424 if (additionalTags
!= nullptr)
426 for (size_t i
= 0; (opt
= additionalTags
[i
]) != nullptr; ++i
)
428 didYouMean
.addWord(additionalTags
[i
]);
432 return didYouMean
.getMatchAsString(inputTag
);
435 void OptionsHandler::enableTraceTag(std::string option
, std::string optarg
)
437 if(!Configuration::isTracingBuild())
439 throw OptionException("trace tags not available in non-tracing builds");
441 else if(!Configuration::isTraceTag(optarg
.c_str()))
443 if (optarg
== "help")
446 Configuration::getNumTraceTags(), Configuration::getTraceTags());
450 throw OptionException(
451 std::string("trace tag ") + optarg
+ std::string(" not available.")
452 + suggestTags(Configuration::getTraceTags(), optarg
, nullptr));
457 void OptionsHandler::enableDebugTag(std::string option
, std::string optarg
)
459 if (!Configuration::isDebugBuild())
461 throw OptionException("debug tags not available in non-debug builds");
463 else if (!Configuration::isTracingBuild())
465 throw OptionException("debug tags not available in non-tracing builds");
468 if (!Configuration::isDebugTag(optarg
.c_str())
469 && !Configuration::isTraceTag(optarg
.c_str()))
471 if (optarg
== "help")
474 Configuration::getNumDebugTags(), Configuration::getDebugTags());
478 throw OptionException(std::string("debug tag ") + optarg
479 + std::string(" not available.")
480 + suggestTags(Configuration::getDebugTags(),
482 Configuration::getTraceTags()));
488 OutputLanguage
OptionsHandler::stringToOutputLanguage(std::string option
,
491 if(optarg
== "help") {
492 d_options
->base
.languageHelp
= true;
493 return language::output::LANG_AUTO
;
497 return language::toOutputLanguage(optarg
);
498 } catch(OptionException
& oe
) {
499 throw OptionException("Error in " + option
+ ": " + oe
.getMessage() +
500 "\nTry --output-language help");
506 InputLanguage
OptionsHandler::stringToInputLanguage(std::string option
,
509 if(optarg
== "help") {
510 d_options
->base
.languageHelp
= true;
511 return language::input::LANG_AUTO
;
515 return language::toInputLanguage(optarg
);
516 } catch(OptionException
& oe
) {
517 throw OptionException("Error in " + option
+ ": " + oe
.getMessage() + "\nTry --lang help");
523 /* options/base_options_handlers.h */
524 void OptionsHandler::setVerbosity(std::string option
, int value
)
526 if(Configuration::isMuzzledBuild()) {
527 DebugChannel
.setStream(&cvc5::null_os
);
528 TraceChannel
.setStream(&cvc5::null_os
);
529 NoticeChannel
.setStream(&cvc5::null_os
);
530 ChatChannel
.setStream(&cvc5::null_os
);
531 MessageChannel
.setStream(&cvc5::null_os
);
532 WarningChannel
.setStream(&cvc5::null_os
);
535 ChatChannel
.setStream(&cvc5::null_os
);
537 ChatChannel
.setStream(&std::cout
);
540 NoticeChannel
.setStream(&cvc5::null_os
);
542 NoticeChannel
.setStream(&std::cout
);
545 MessageChannel
.setStream(&cvc5::null_os
);
546 WarningChannel
.setStream(&cvc5::null_os
);
548 MessageChannel
.setStream(&std::cout
);
549 WarningChannel
.setStream(&std::cerr
);
554 void OptionsHandler::increaseVerbosity(std::string option
) {
555 d_options
->base
.verbosity
+= 1;
556 setVerbosity(option
, options::verbosity());
559 void OptionsHandler::decreaseVerbosity(std::string option
) {
560 d_options
->base
.verbosity
-= 1;
561 setVerbosity(option
, options::verbosity());
564 } // namespace options