1 /********************* */
2 /*! \file options_handler.cpp
4 ** Top contributors (to current version):
5 ** Tim King, Aina Niemetz, Mathias Preiner
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2020 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.\endverbatim
12 ** \brief Interface for custom handlers and predicates options.
14 ** Interface for custom handlers and predicates options.
17 #include "options/options_handler.h"
23 #include "cvc4autoconfig.h"
25 #include "base/check.h"
26 #include "base/configuration.h"
27 #include "base/configuration_private.h"
28 #include "base/exception.h"
29 #include "base/modal_exception.h"
30 #include "base/output.h"
31 #include "lib/strtok_r.h"
32 #include "options/base_options.h"
33 #include "options/bv_options.h"
34 #include "options/decision_options.h"
35 #include "options/didyoumean.h"
36 #include "options/language.h"
37 #include "options/option_exception.h"
38 #include "options/smt_options.h"
39 #include "options/theory_options.h"
47 void throwLazyBBUnsupported(options::SatSolverMode m
)
49 std::string sat_solver
;
50 if (m
== options::SatSolverMode::CADICAL
)
52 sat_solver
= "CaDiCaL";
54 else if (m
== options::SatSolverMode::KISSAT
)
56 sat_solver
= "Kissat";
60 Assert(m
== options::SatSolverMode::CRYPTOMINISAT
);
61 sat_solver
= "CryptoMiniSat";
63 std::string
indent(25, ' ');
64 throw OptionException(sat_solver
+ " does not support lazy bit-blasting.\n"
65 + indent
+ "Try --bv-sat-solver=minisat");
70 OptionsHandler::OptionsHandler(Options
* options
) : d_options(options
) { }
72 void OptionsHandler::notifyBeforeSearch(const std::string
& option
)
75 d_options
->d_beforeSearchListeners
.notify();
76 } catch (ModalException
&){
78 ss
<< "cannot change option `" << option
<< "' after final initialization";
79 throw ModalException(ss
.str());
83 unsigned long OptionsHandler::limitHandler(std::string option
,
87 std::istringstream
convert(optarg
);
90 throw OptionException("option `" + option
91 + "` requires a number as an argument");
96 /* options/base_options_handlers.h */
97 void OptionsHandler::notifyPrintSuccess(std::string option
) {
98 d_options
->d_setPrintSuccessListeners
.notify();
101 // theory/quantifiers/options_handlers.h
103 void OptionsHandler::checkInstWhenMode(std::string option
, InstWhenMode mode
)
105 if (mode
== InstWhenMode::PRE_FULL
)
107 throw OptionException(std::string("Mode pre-full for ") + option
108 + " is not supported in this release.");
112 // theory/bv/options_handlers.h
113 void OptionsHandler::abcEnabledBuild(std::string option
, bool value
)
117 std::stringstream ss
;
118 ss
<< "option `" << option
<< "' requires an abc-enabled build of CVC4; this binary was not built with abc support";
119 throw OptionException(ss
.str());
121 #endif /* CVC4_USE_ABC */
124 void OptionsHandler::abcEnabledBuild(std::string option
, std::string value
)
128 std::stringstream ss
;
129 ss
<< "option `" << option
<< "' requires an abc-enabled build of CVC4; this binary was not built with abc support";
130 throw OptionException(ss
.str());
132 #endif /* CVC4_USE_ABC */
135 void OptionsHandler::checkBvSatSolver(std::string option
, SatSolverMode m
)
137 if (m
== SatSolverMode::CRYPTOMINISAT
138 && !Configuration::isBuiltWithCryptominisat())
140 std::stringstream ss
;
141 ss
<< "option `" << option
142 << "' requires a CryptoMiniSat build of CVC4; this binary was not built "
143 "with CryptoMiniSat support";
144 throw OptionException(ss
.str());
147 if (m
== SatSolverMode::CADICAL
&& !Configuration::isBuiltWithCadical())
149 std::stringstream ss
;
150 ss
<< "option `" << option
151 << "' requires a CaDiCaL build of CVC4; this binary was not built with "
153 throw OptionException(ss
.str());
156 if (m
== SatSolverMode::KISSAT
&& !Configuration::isBuiltWithKissat())
158 std::stringstream ss
;
159 ss
<< "option `" << option
160 << "' requires a Kissat build of CVC4; this binary was not built with "
162 throw OptionException(ss
.str());
165 if (m
== SatSolverMode::CRYPTOMINISAT
|| m
== SatSolverMode::CADICAL
166 || m
== SatSolverMode::KISSAT
)
168 if (options::bitblastMode() == options::BitblastMode::LAZY
169 && options::bitblastMode
.wasSetByUser())
171 throwLazyBBUnsupported(m
);
173 if (!options::bitvectorToBool
.wasSetByUser())
175 options::bitvectorToBool
.set(true);
180 void OptionsHandler::checkBitblastMode(std::string option
, BitblastMode m
)
182 if (m
== options::BitblastMode::LAZY
)
184 if (!options::bitvectorPropagate
.wasSetByUser())
186 options::bitvectorPropagate
.set(true);
188 if (!options::bitvectorEqualitySolver
.wasSetByUser())
190 options::bitvectorEqualitySolver
.set(true);
192 if (!options::bitvectorEqualitySlicer
.wasSetByUser())
194 if (options::incrementalSolving() || options::produceModels())
196 options::bitvectorEqualitySlicer
.set(options::BvSlicerMode::OFF
);
200 options::bitvectorEqualitySlicer
.set(options::BvSlicerMode::AUTO
);
204 if (!options::bitvectorInequalitySolver
.wasSetByUser())
206 options::bitvectorInequalitySolver
.set(true);
208 if (!options::bitvectorAlgebraicSolver
.wasSetByUser())
210 options::bitvectorAlgebraicSolver
.set(true);
212 if (options::bvSatSolver() != options::SatSolverMode::MINISAT
)
214 throwLazyBBUnsupported(options::bvSatSolver());
217 else if (m
== BitblastMode::EAGER
)
219 if (!options::bitvectorToBool
.wasSetByUser())
221 options::bitvectorToBool
.set(true);
226 void OptionsHandler::setBitblastAig(std::string option
, bool arg
)
229 if(options::bitblastMode
.wasSetByUser()) {
230 if (options::bitblastMode() != options::BitblastMode::EAGER
)
232 throw OptionException("bitblast-aig must be used with eager bitblaster");
235 options::BitblastMode mode
= stringToBitblastMode("", "eager");
236 options::bitblastMode
.set(mode
);
238 if(!options::bitvectorAigSimplifications
.wasSetByUser()) {
239 options::bitvectorAigSimplifications
.set("balance;drw");
244 // printer/options_handlers.h
245 const std::string
OptionsHandler::s_instFormatHelp
= "\
246 Inst format modes currently supported by the --inst-format option:\n\
249 + Print instantiations as a list in the output language format.\n\
252 + Print instantiations as SZS compliant proof.\n\
255 InstFormatMode
OptionsHandler::stringToInstFormatMode(std::string option
,
258 if(optarg
== "default") {
259 return InstFormatMode::DEFAULT
;
260 } else if(optarg
== "szs") {
261 return InstFormatMode::SZS
;
262 } else if(optarg
== "help") {
263 puts(s_instFormatHelp
.c_str());
266 throw OptionException(std::string("unknown option for --inst-format: `") +
267 optarg
+ "'. Try --inst-format help.");
271 // decision/options_handlers.h
272 void OptionsHandler::setDecisionModeStopOnly(std::string option
, DecisionMode m
)
274 options::decisionStopOnly
.set(m
== DecisionMode::RELEVANCY
);
277 void OptionsHandler::setProduceAssertions(std::string option
, bool value
)
279 options::produceAssertions
.set(value
);
280 options::interactiveMode
.set(value
);
283 void OptionsHandler::proofEnabledBuild(std::string option
, bool value
)
286 if (value
&& options::bitblastMode() == options::BitblastMode::EAGER
287 && options::bvSatSolver() != options::SatSolverMode::MINISAT
288 && options::bvSatSolver() != options::SatSolverMode::CRYPTOMINISAT
)
290 throw OptionException(
291 "Eager BV proofs only supported when MiniSat or CryptoMiniSat is used");
295 std::stringstream ss
;
296 ss
<< "option `" << option
<< "' requires a proofs-enabled build of CVC4; this binary was not built with proof support";
297 throw OptionException(ss
.str());
299 #endif /* CVC4_PROOF */
302 void OptionsHandler::LFSCEnabledBuild(std::string option
, bool value
) {
303 #ifndef CVC4_USE_LFSC
305 std::stringstream ss
;
306 ss
<< "option `" << option
<< "' requires a build of CVC4 with integrated "
307 "LFSC; this binary was not built with LFSC";
308 throw OptionException(ss
.str());
310 #endif /* CVC4_USE_LFSC */
313 void OptionsHandler::notifyDumpToFile(std::string option
) {
314 d_options
->d_dumpToFileListeners
.notify();
318 void OptionsHandler::notifySetRegularOutputChannel(std::string option
) {
319 d_options
->d_setRegularChannelListeners
.notify();
322 void OptionsHandler::notifySetDiagnosticOutputChannel(std::string option
) {
323 d_options
->d_setDiagnosticChannelListeners
.notify();
326 void OptionsHandler::statsEnabledBuild(std::string option
, bool value
)
328 #ifndef CVC4_STATISTICS_ON
330 std::stringstream ss
;
331 ss
<< "option `" << option
<< "' requires a statistics-enabled build of CVC4; this binary was not built with statistics support";
332 throw OptionException(ss
.str());
334 #endif /* CVC4_STATISTICS_ON */
337 void OptionsHandler::threadN(std::string option
) {
338 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\"");
341 void OptionsHandler::notifyDumpMode(std::string option
)
343 d_options
->d_setDumpModeListeners
.notify();
347 // expr/options_handlers.h
348 void OptionsHandler::setDefaultExprDepthPredicate(std::string option
, int depth
) {
350 throw OptionException("--expr-depth requires a positive argument, or -1.");
354 void OptionsHandler::setDefaultDagThreshPredicate(std::string option
, int dag
) {
356 throw OptionException("--dag-thresh requires a nonnegative argument.");
360 void OptionsHandler::notifySetDefaultExprDepth(std::string option
) {
361 d_options
->d_setDefaultExprDepthListeners
.notify();
364 void OptionsHandler::notifySetDefaultDagThresh(std::string option
) {
365 d_options
->d_setDefaultDagThreshListeners
.notify();
368 void OptionsHandler::notifySetPrintExprTypes(std::string option
) {
369 d_options
->d_setPrintExprTypesListeners
.notify();
373 // main/options_handlers.h
375 static void print_config (const char * str
, std::string config
) {
378 if (s
.size() < sz
) s
.resize(sz
, ' ');
379 std::cout
<< s
<< ": " << config
<< std::endl
;
382 static void print_config_cond (const char * str
, bool cond
= false) {
383 print_config(str
, cond
? "yes" : "no");
386 void OptionsHandler::copyright(std::string option
) {
387 std::cout
<< Configuration::copyright() << std::endl
;
391 void OptionsHandler::showConfiguration(std::string option
) {
392 std::cout
<< Configuration::about() << std::endl
;
394 print_config ("version", Configuration::getVersionString());
396 if(Configuration::isGitBuild()) {
397 const char* branchName
= Configuration::getGitBranchName();
398 if(*branchName
== '\0') { branchName
= "-"; }
399 std::stringstream ss
;
402 << std::string(Configuration::getGitCommit()).substr(0, 8)
403 << (Configuration::hasGitModifications() ? " (with modifications)" : "")
405 print_config("scm", ss
.str());
407 print_config_cond("scm", false);
410 std::cout
<< std::endl
;
412 std::stringstream ss
;
413 ss
<< Configuration::getVersionMajor() << "."
414 << Configuration::getVersionMinor() << "."
415 << Configuration::getVersionRelease();
416 print_config("library", ss
.str());
418 std::cout
<< std::endl
;
420 print_config_cond("debug code", Configuration::isDebugBuild());
421 print_config_cond("statistics", Configuration::isStatisticsBuild());
422 print_config_cond("tracing", Configuration::isTracingBuild());
423 print_config_cond("dumping", Configuration::isDumpingBuild());
424 print_config_cond("muzzled", Configuration::isMuzzledBuild());
425 print_config_cond("assertions", Configuration::isAssertionBuild());
426 print_config_cond("proof", Configuration::isProofBuild());
427 print_config_cond("coverage", Configuration::isCoverageBuild());
428 print_config_cond("profiling", Configuration::isProfilingBuild());
429 print_config_cond("asan", Configuration::isAsanBuild());
430 print_config_cond("ubsan", Configuration::isUbsanBuild());
431 print_config_cond("tsan", Configuration::isTsanBuild());
432 print_config_cond("competition", Configuration::isCompetitionBuild());
434 std::cout
<< std::endl
;
436 print_config_cond("abc", Configuration::isBuiltWithAbc());
437 print_config_cond("cln", Configuration::isBuiltWithCln());
438 print_config_cond("glpk", Configuration::isBuiltWithGlpk());
439 print_config_cond("cadical", Configuration::isBuiltWithCadical());
440 print_config_cond("cryptominisat", Configuration::isBuiltWithCryptominisat());
441 print_config_cond("drat2er", Configuration::isBuiltWithDrat2Er());
442 print_config_cond("gmp", Configuration::isBuiltWithGmp());
443 print_config_cond("kissat", Configuration::isBuiltWithKissat());
444 print_config_cond("lfsc", Configuration::isBuiltWithLfsc());
445 print_config_cond("poly", Configuration::isBuiltWithPoly());
446 print_config_cond("editline", Configuration::isBuiltWithEditline());
447 print_config_cond("symfpu", Configuration::isBuiltWithSymFPU());
452 static void printTags(unsigned ntags
, char const* const* tags
)
454 std::cout
<< "available tags:";
455 for (unsigned i
= 0; i
< ntags
; ++ i
)
457 std::cout
<< " " << tags
[i
] << std::endl
;
459 std::cout
<< std::endl
;
462 void OptionsHandler::showDebugTags(std::string option
)
464 if (!Configuration::isDebugBuild())
466 throw OptionException("debug tags not available in non-debug builds");
468 else if (!Configuration::isTracingBuild())
470 throw OptionException("debug tags not available in non-tracing builds");
472 printTags(Configuration::getNumDebugTags(),Configuration::getDebugTags());
476 void OptionsHandler::showTraceTags(std::string option
)
478 if (!Configuration::isTracingBuild())
480 throw OptionException("trace tags not available in non-tracing build");
482 printTags(Configuration::getNumTraceTags(), Configuration::getTraceTags());
486 static std::string
suggestTags(char const* const* validTags
,
487 std::string inputTag
,
488 char const* const* additionalTags
)
490 DidYouMean didYouMean
;
493 for (size_t i
= 0; (opt
= validTags
[i
]) != nullptr; ++i
)
495 didYouMean
.addWord(validTags
[i
]);
497 if (additionalTags
!= nullptr)
499 for (size_t i
= 0; (opt
= additionalTags
[i
]) != nullptr; ++i
)
501 didYouMean
.addWord(additionalTags
[i
]);
505 return didYouMean
.getMatchAsString(inputTag
);
508 void OptionsHandler::enableTraceTag(std::string option
, std::string optarg
)
510 if(!Configuration::isTracingBuild())
512 throw OptionException("trace tags not available in non-tracing builds");
514 else if(!Configuration::isTraceTag(optarg
.c_str()))
516 if (optarg
== "help")
519 Configuration::getNumTraceTags(), Configuration::getTraceTags());
523 throw OptionException(
524 std::string("trace tag ") + optarg
+ std::string(" not available.")
525 + suggestTags(Configuration::getTraceTags(), optarg
, nullptr));
530 void OptionsHandler::enableDebugTag(std::string option
, std::string optarg
)
532 if (!Configuration::isDebugBuild())
534 throw OptionException("debug tags not available in non-debug builds");
536 else if (!Configuration::isTracingBuild())
538 throw OptionException("debug tags not available in non-tracing builds");
541 if (!Configuration::isDebugTag(optarg
.c_str())
542 && !Configuration::isTraceTag(optarg
.c_str()))
544 if (optarg
== "help")
547 Configuration::getNumDebugTags(), Configuration::getDebugTags());
551 throw OptionException(std::string("debug tag ") + optarg
552 + std::string(" not available.")
553 + suggestTags(Configuration::getDebugTags(),
555 Configuration::getTraceTags()));
561 OutputLanguage
OptionsHandler::stringToOutputLanguage(std::string option
,
564 if(optarg
== "help") {
565 options::languageHelp
.set(true);
566 return language::output::LANG_AUTO
;
570 return language::toOutputLanguage(optarg
);
571 } catch(OptionException
& oe
) {
572 throw OptionException("Error in " + option
+ ": " + oe
.getMessage() +
573 "\nTry --output-language help");
579 InputLanguage
OptionsHandler::stringToInputLanguage(std::string option
,
582 if(optarg
== "help") {
583 options::languageHelp
.set(true);
584 return language::input::LANG_AUTO
;
588 return language::toInputLanguage(optarg
);
589 } catch(OptionException
& oe
) {
590 throw OptionException("Error in " + option
+ ": " + oe
.getMessage() + "\nTry --language help");
596 /* options/base_options_handlers.h */
597 void OptionsHandler::setVerbosity(std::string option
, int value
)
599 if(Configuration::isMuzzledBuild()) {
600 DebugChannel
.setStream(&CVC4::null_os
);
601 TraceChannel
.setStream(&CVC4::null_os
);
602 NoticeChannel
.setStream(&CVC4::null_os
);
603 ChatChannel
.setStream(&CVC4::null_os
);
604 MessageChannel
.setStream(&CVC4::null_os
);
605 WarningChannel
.setStream(&CVC4::null_os
);
608 ChatChannel
.setStream(&CVC4::null_os
);
610 ChatChannel
.setStream(&std::cout
);
613 NoticeChannel
.setStream(&CVC4::null_os
);
615 NoticeChannel
.setStream(&std::cout
);
618 MessageChannel
.setStream(&CVC4::null_os
);
619 WarningChannel
.setStream(&CVC4::null_os
);
621 MessageChannel
.setStream(&std::cout
);
622 WarningChannel
.setStream(&std::cerr
);
627 void OptionsHandler::increaseVerbosity(std::string option
) {
628 options::verbosity
.set(options::verbosity() + 1);
629 setVerbosity(option
, options::verbosity());
632 void OptionsHandler::decreaseVerbosity(std::string option
) {
633 options::verbosity
.set(options::verbosity() - 1);
634 setVerbosity(option
, options::verbosity());
638 }/* CVC4::options namespace */
639 }/* CVC4 namespace */