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/smt_options.h"
37 #include "options/theory_options.h"
45 void throwLazyBBUnsupported(options::SatSolverMode m
)
47 std::string sat_solver
;
48 if (m
== options::SatSolverMode::CADICAL
)
50 sat_solver
= "CaDiCaL";
52 else if (m
== options::SatSolverMode::KISSAT
)
54 sat_solver
= "Kissat";
58 Assert(m
== options::SatSolverMode::CRYPTOMINISAT
);
59 sat_solver
= "CryptoMiniSat";
61 std::string
indent(25, ' ');
62 throw OptionException(sat_solver
+ " does not support lazy bit-blasting.\n"
63 + indent
+ "Try --bv-sat-solver=minisat");
68 OptionsHandler::OptionsHandler(Options
* options
) : d_options(options
) { }
70 uint64_t OptionsHandler::limitHandler(const std::string
& option
,
71 const std::string
& flag
,
72 const std::string
& optarg
)
75 std::istringstream
convert(optarg
);
78 throw OptionException("option `" + option
79 + "` requires a number as an argument");
84 void OptionsHandler::setResourceWeight(const std::string
& option
,
85 const std::string
& flag
,
86 const std::string
& optarg
)
88 d_options
->base
.resourceWeightHolder
.emplace_back(optarg
);
91 // theory/quantifiers/options_handlers.h
93 void OptionsHandler::checkInstWhenMode(const std::string
& option
,
94 const std::string
& flag
,
97 if (mode
== InstWhenMode::PRE_FULL
)
99 throw OptionException(std::string("Mode pre-full for ") + option
100 + " is not supported in this release.");
104 // theory/bv/options_handlers.h
105 void OptionsHandler::abcEnabledBuild(const std::string
& option
,
106 const std::string
& flag
,
111 std::stringstream ss
;
112 ss
<< "option `" << option
113 << "' requires an abc-enabled build of cvc5; this binary was not built "
115 throw OptionException(ss
.str());
117 #endif /* CVC5_USE_ABC */
120 void OptionsHandler::abcEnabledBuild(const std::string
& option
,
121 const std::string
& flag
,
122 const std::string
& value
)
126 std::stringstream ss
;
127 ss
<< "option `" << option
128 << "' requires an abc-enabled build of cvc5; this binary was not built "
130 throw OptionException(ss
.str());
132 #endif /* CVC5_USE_ABC */
135 void OptionsHandler::checkBvSatSolver(const std::string
& option
,
136 const std::string
& flag
,
139 if (m
== SatSolverMode::CRYPTOMINISAT
140 && !Configuration::isBuiltWithCryptominisat())
142 std::stringstream ss
;
143 ss
<< "option `" << option
144 << "' requires a CryptoMiniSat build of cvc5; this binary was not built "
145 "with CryptoMiniSat support";
146 throw OptionException(ss
.str());
149 if (m
== SatSolverMode::KISSAT
&& !Configuration::isBuiltWithKissat())
151 std::stringstream ss
;
152 ss
<< "option `" << option
153 << "' requires a Kissat build of cvc5; this binary was not built with "
155 throw OptionException(ss
.str());
158 if (options::bvSolver() != options::BVSolver::BITBLAST
159 && (m
== SatSolverMode::CRYPTOMINISAT
|| m
== SatSolverMode::CADICAL
160 || m
== SatSolverMode::KISSAT
))
162 if (options::bitblastMode() == options::BitblastMode::LAZY
163 && d_options
->bv
.bitblastModeWasSetByUser
)
165 throwLazyBBUnsupported(m
);
167 options::bv::setDefaultBitvectorToBool(*d_options
, true);
171 void OptionsHandler::checkBitblastMode(const std::string
& option
,
172 const std::string
& flag
,
175 if (m
== options::BitblastMode::LAZY
)
177 options::bv::setDefaultBitvectorPropagate(*d_options
, true);
178 options::bv::setDefaultBitvectorEqualitySolver(*d_options
, true);
179 options::bv::setDefaultBitvectorInequalitySolver(*d_options
, true);
180 options::bv::setDefaultBitvectorAlgebraicSolver(*d_options
, true);
181 if (options::bvSatSolver() != options::SatSolverMode::MINISAT
)
183 throwLazyBBUnsupported(options::bvSatSolver());
186 else if (m
== BitblastMode::EAGER
)
188 options::bv::setDefaultBitvectorToBool(*d_options
, true);
192 void OptionsHandler::setBitblastAig(const std::string
& option
,
193 const std::string
& flag
,
197 if (d_options
->bv
.bitblastModeWasSetByUser
) {
198 if (options::bitblastMode() != options::BitblastMode::EAGER
)
200 throw OptionException("bitblast-aig must be used with eager bitblaster");
203 options::BitblastMode mode
= stringToBitblastMode("eager");
204 d_options
->bv
.bitblastMode
= mode
;
209 // printer/options_handlers.h
210 const std::string
OptionsHandler::s_instFormatHelp
= "\
211 Inst format modes currently supported by the --inst-format option:\n\
214 + Print instantiations as a list in the output language format.\n\
217 + Print instantiations as SZS compliant proof.\n\
220 InstFormatMode
OptionsHandler::stringToInstFormatMode(const std::string
& option
,
221 const std::string
& flag
,
222 const std::string
& optarg
)
224 if(optarg
== "default") {
225 return InstFormatMode::DEFAULT
;
226 } else if(optarg
== "szs") {
227 return InstFormatMode::SZS
;
228 } else if(optarg
== "help") {
229 puts(s_instFormatHelp
.c_str());
232 throw OptionException(std::string("unknown option for --inst-format: `") +
233 optarg
+ "'. Try --inst-format help.");
237 // decision/options_handlers.h
238 void OptionsHandler::setDecisionModeStopOnly(const std::string
& option
,
239 const std::string
& flag
,
242 d_options
->decision
.decisionStopOnly
= (m
== DecisionMode::RELEVANCY
);
245 void OptionsHandler::setProduceAssertions(const std::string
& option
,
246 const std::string
& flag
,
249 d_options
->smt
.produceAssertions
= value
;
250 d_options
->smt
.interactiveMode
= value
;
253 void OptionsHandler::setStats(const std::string
& option
,
254 const std::string
& flag
,
257 #ifndef CVC5_STATISTICS_ON
260 std::stringstream ss
;
261 ss
<< "option `" << flag
262 << "' requires a statistics-enabled build of cvc5; this binary was not "
263 "built with statistics support";
264 throw OptionException(ss
.str());
266 #endif /* CVC5_STATISTICS_ON */
267 std::string opt
= option
;
268 if (option
.substr(0, 2) == "--")
274 if (opt
== options::base::statisticsAll__name
)
276 d_options
->base
.statistics
= true;
278 else if (opt
== options::base::statisticsEveryQuery__name
)
280 d_options
->base
.statistics
= true;
282 else if (opt
== options::base::statisticsExpert__name
)
284 d_options
->base
.statistics
= true;
289 if (opt
== options::base::statistics__name
)
291 d_options
->base
.statisticsAll
= false;
292 d_options
->base
.statisticsEveryQuery
= false;
293 d_options
->base
.statisticsExpert
= false;
298 void OptionsHandler::threadN(const std::string
& option
, const std::string
& flag
)
300 throw OptionException(flag
+ " 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\"");
303 // expr/options_handlers.h
304 void OptionsHandler::setDefaultExprDepthPredicate(const std::string
& option
,
305 const std::string
& flag
,
309 throw OptionException("--expr-depth requires a positive argument, or -1.");
313 void OptionsHandler::setDefaultDagThreshPredicate(const std::string
& option
,
314 const std::string
& flag
,
318 throw OptionException("--dag-thresh requires a nonnegative argument.");
322 // main/options_handlers.h
324 static void print_config (const char * str
, std::string config
) {
327 if (s
.size() < sz
) s
.resize(sz
, ' ');
328 std::cout
<< s
<< ": " << config
<< std::endl
;
331 static void print_config_cond (const char * str
, bool cond
= false) {
332 print_config(str
, cond
? "yes" : "no");
335 void OptionsHandler::copyright(const std::string
& option
,
336 const std::string
& flag
)
338 std::cout
<< Configuration::copyright() << std::endl
;
342 void OptionsHandler::showConfiguration(const std::string
& option
,
343 const std::string
& flag
)
345 std::cout
<< Configuration::about() << std::endl
;
347 print_config ("version", Configuration::getVersionString());
349 if(Configuration::isGitBuild()) {
350 const char* branchName
= Configuration::getGitBranchName();
351 if(*branchName
== '\0') { branchName
= "-"; }
352 std::stringstream ss
;
355 << std::string(Configuration::getGitCommit()).substr(0, 8)
356 << (Configuration::hasGitModifications() ? " (with modifications)" : "")
358 print_config("scm", ss
.str());
360 print_config_cond("scm", false);
363 std::cout
<< std::endl
;
365 std::stringstream ss
;
366 ss
<< Configuration::getVersionMajor() << "."
367 << Configuration::getVersionMinor() << "."
368 << Configuration::getVersionRelease();
369 print_config("library", ss
.str());
371 std::cout
<< std::endl
;
373 print_config_cond("debug code", Configuration::isDebugBuild());
374 print_config_cond("statistics", Configuration::isStatisticsBuild());
375 print_config_cond("tracing", Configuration::isTracingBuild());
376 print_config_cond("dumping", Configuration::isDumpingBuild());
377 print_config_cond("muzzled", Configuration::isMuzzledBuild());
378 print_config_cond("assertions", Configuration::isAssertionBuild());
379 print_config_cond("coverage", Configuration::isCoverageBuild());
380 print_config_cond("profiling", Configuration::isProfilingBuild());
381 print_config_cond("asan", Configuration::isAsanBuild());
382 print_config_cond("ubsan", Configuration::isUbsanBuild());
383 print_config_cond("tsan", Configuration::isTsanBuild());
384 print_config_cond("competition", Configuration::isCompetitionBuild());
386 std::cout
<< std::endl
;
388 print_config_cond("abc", Configuration::isBuiltWithAbc());
389 print_config_cond("cln", Configuration::isBuiltWithCln());
390 print_config_cond("glpk", Configuration::isBuiltWithGlpk());
391 print_config_cond("cryptominisat", Configuration::isBuiltWithCryptominisat());
392 print_config_cond("gmp", Configuration::isBuiltWithGmp());
393 print_config_cond("kissat", Configuration::isBuiltWithKissat());
394 print_config_cond("poly", Configuration::isBuiltWithPoly());
395 print_config_cond("editline", Configuration::isBuiltWithEditline());
400 static void printTags(unsigned ntags
, char const* const* tags
)
402 std::cout
<< "available tags:";
403 for (unsigned i
= 0; i
< ntags
; ++ i
)
405 std::cout
<< " " << tags
[i
] << std::endl
;
407 std::cout
<< std::endl
;
410 void OptionsHandler::showDebugTags(const std::string
& option
,
411 const std::string
& flag
)
413 if (!Configuration::isDebugBuild())
415 throw OptionException("debug tags not available in non-debug builds");
417 else if (!Configuration::isTracingBuild())
419 throw OptionException("debug tags not available in non-tracing builds");
421 printTags(Configuration::getNumDebugTags(),Configuration::getDebugTags());
425 void OptionsHandler::showTraceTags(const std::string
& option
,
426 const std::string
& flag
)
428 if (!Configuration::isTracingBuild())
430 throw OptionException("trace tags not available in non-tracing build");
432 printTags(Configuration::getNumTraceTags(), Configuration::getTraceTags());
436 static std::string
suggestTags(char const* const* validTags
,
437 std::string inputTag
,
438 char const* const* additionalTags
)
440 DidYouMean didYouMean
;
443 for (size_t i
= 0; (opt
= validTags
[i
]) != nullptr; ++i
)
445 didYouMean
.addWord(validTags
[i
]);
447 if (additionalTags
!= nullptr)
449 for (size_t i
= 0; (opt
= additionalTags
[i
]) != nullptr; ++i
)
451 didYouMean
.addWord(additionalTags
[i
]);
455 return didYouMean
.getMatchAsString(inputTag
);
458 void OptionsHandler::enableTraceTag(const std::string
& option
,
459 const std::string
& flag
,
460 const std::string
& optarg
)
462 if(!Configuration::isTracingBuild())
464 throw OptionException("trace tags not available in non-tracing builds");
466 else if(!Configuration::isTraceTag(optarg
.c_str()))
468 if (optarg
== "help")
471 Configuration::getNumTraceTags(), Configuration::getTraceTags());
475 throw OptionException(
476 std::string("trace tag ") + optarg
+ std::string(" not available.")
477 + suggestTags(Configuration::getTraceTags(), optarg
, nullptr));
482 void OptionsHandler::enableDebugTag(const std::string
& option
,
483 const std::string
& flag
,
484 const std::string
& optarg
)
486 if (!Configuration::isDebugBuild())
488 throw OptionException("debug tags not available in non-debug builds");
490 else if (!Configuration::isTracingBuild())
492 throw OptionException("debug tags not available in non-tracing builds");
495 if (!Configuration::isDebugTag(optarg
.c_str())
496 && !Configuration::isTraceTag(optarg
.c_str()))
498 if (optarg
== "help")
501 Configuration::getNumDebugTags(), Configuration::getDebugTags());
505 throw OptionException(std::string("debug tag ") + optarg
506 + std::string(" not available.")
507 + suggestTags(Configuration::getDebugTags(),
509 Configuration::getTraceTags()));
515 OutputLanguage
OptionsHandler::stringToOutputLanguage(const std::string
& option
,
516 const std::string
& flag
,
517 const std::string
& optarg
)
519 if(optarg
== "help") {
520 d_options
->base
.languageHelp
= true;
521 return language::output::LANG_AUTO
;
525 return language::toOutputLanguage(optarg
);
526 } catch(OptionException
& oe
) {
527 throw OptionException("Error in " + option
+ ": " + oe
.getMessage() +
528 "\nTry --output-language help");
534 InputLanguage
OptionsHandler::stringToInputLanguage(const std::string
& option
,
535 const std::string
& flag
,
536 const std::string
& optarg
)
538 if(optarg
== "help") {
539 d_options
->base
.languageHelp
= true;
540 return language::input::LANG_AUTO
;
544 return language::toInputLanguage(optarg
);
545 } catch(OptionException
& oe
) {
546 throw OptionException("Error in " + option
+ ": " + oe
.getMessage() + "\nTry --lang help");
552 /* options/base_options_handlers.h */
553 void OptionsHandler::setVerbosity(const std::string
& option
,
554 const std::string
& flag
,
557 if(Configuration::isMuzzledBuild()) {
558 DebugChannel
.setStream(&cvc5::null_os
);
559 TraceChannel
.setStream(&cvc5::null_os
);
560 NoticeChannel
.setStream(&cvc5::null_os
);
561 ChatChannel
.setStream(&cvc5::null_os
);
562 MessageChannel
.setStream(&cvc5::null_os
);
563 WarningChannel
.setStream(&cvc5::null_os
);
566 ChatChannel
.setStream(&cvc5::null_os
);
568 ChatChannel
.setStream(&std::cout
);
571 NoticeChannel
.setStream(&cvc5::null_os
);
573 NoticeChannel
.setStream(&std::cout
);
576 MessageChannel
.setStream(&cvc5::null_os
);
577 WarningChannel
.setStream(&cvc5::null_os
);
579 MessageChannel
.setStream(&std::cout
);
580 WarningChannel
.setStream(&std::cerr
);
585 void OptionsHandler::increaseVerbosity(const std::string
& option
,
586 const std::string
& flag
)
588 d_options
->base
.verbosity
+= 1;
589 setVerbosity(option
, flag
, d_options
->base
.verbosity
);
592 void OptionsHandler::decreaseVerbosity(const std::string
& option
,
593 const std::string
& flag
)
595 d_options
->base
.verbosity
-= 1;
596 setVerbosity(option
, flag
, d_options
->base
.verbosity
);
599 } // namespace options