diff options
175 files changed, 5991 insertions, 3335 deletions
diff --git a/Makefile.am b/Makefile.am index b3cd37e9a..6253f653b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -104,7 +104,7 @@ EXTRA_DIST = \ config/build-type \ config/mkbuilddir \ config/doxygen.cfg \ - doc/cvc4.1.in \ + doc/cvc4.1_template.in \ doc/cvc4.5.in \ doc/libcvc4.3.in \ doc/libcvc4parser.3.in \ diff --git a/configure.ac b/configure.ac index e7cb9a3d3..6820b2bb4 100644 --- a/configure.ac +++ b/configure.ac @@ -203,7 +203,7 @@ if test -n "${enable_replay+set}"; then fi AC_MSG_RESULT([$with_build]) -AM_INIT_AUTOMAKE([1.11 no-define tar-pax parallel-tests color-tests]) +AM_INIT_AUTOMAKE([1.11 no-define tar-pax parallel-tests color-tests subdir-objects]) AC_CONFIG_HEADERS([cvc4autoconfig.h]) # Initialize libtool's configuration options. @@ -849,7 +849,7 @@ AC_LIB_ANTLR # supported by the build host). CVC4_CHECK_BINDINGS([c java])dnl csharp perl php python ruby tcl ocaml]) -# Checks for header files. +# Checks for header files and their contents. AC_CHECK_HEADERS([getopt.h unistd.h]) # Checks for typedefs, structures, and compiler characteristics. @@ -1062,6 +1062,7 @@ fi AC_SUBST(CVC4_USE_CLN_IMP) AC_SUBST(CVC4_USE_GMP_IMP) +# month/year for man pages MAN_DATE=`date '+%B %Y'` AC_SUBST(MAN_DATE) @@ -1085,7 +1086,7 @@ CVC4_CONFIG_FILE_ONLY_IF_CHANGED([src/util/rational.h]) CVC4_CONFIG_FILE_ONLY_IF_CHANGED([src/util/integer.h]) CVC4_CONFIG_FILE_ONLY_IF_CHANGED([src/util/tls.h]) -CVC4_CONFIG_FILE_ONLY_IF_CHANGED([doc/cvc4.1]) +CVC4_CONFIG_FILE_ONLY_IF_CHANGED([doc/cvc4.1_template]) CVC4_CONFIG_FILE_ONLY_IF_CHANGED([doc/cvc4.5]) CVC4_CONFIG_FILE_ONLY_IF_CHANGED([doc/libcvc4.3]) CVC4_CONFIG_FILE_ONLY_IF_CHANGED([doc/libcvc4parser.3]) diff --git a/contrib/addsourcedir b/contrib/addsourcedir index 00357cadf..431ec1d90 100755 --- a/contrib/addsourcedir +++ b/contrib/addsourcedir @@ -44,7 +44,7 @@ while [ $# -gt 0 ]; do # enough dotdots to get us back to the top-level directory # (e.g. "src/foo" yields "../.." here), used for $(topdir) in Makefile - topdir=`echo "$srcdir" | sed 's,[^/]\+,..,g'` + topdir=`echo "$srcdir" | sed 's,[^/][^/]*,..,g'` # one less, used for the include path in Makefile.am topsrcdir=`echo "$topdir" | sed 's,\.\./,,'` @@ -64,7 +64,7 @@ EOF echo "$progname: warning: not replacing extant \`$srcdir/Makefile.am'." >&2 else echo "generating \`$srcdir/Makefile.am'..." - clibbase=`expr "$srcdir" : '.*/\([^/]\+\)$'` + clibbase=`expr "$srcdir" : '.*/\([^/][^/]*\)$'` if expr "$srcdir" : src/parser >/dev/null; then definitions=" -D__BUILDING_CVC4PARSERLIB \\ " diff --git a/doc/cvc4.1.in b/doc/cvc4.1_template.in index 6c6a9768c..23eff6110 100644 --- a/doc/cvc4.1.in +++ b/doc/cvc4.1_template.in @@ -44,91 +44,10 @@ is unspecified and .B CVC4 is connected to a terminal, interactive mode is assumed. -.SH OPTIONS -.IP "\-\-lang=LANG | \-L LANG" -force input language (default is \(lqauto\(rq; see \-\-lang help) -.IP \-\-output\-lang=LANG -force output language (default is \(lqauto\(rq; see \-\-output\-lang help) -.IP "\-\-version | \-V" -identify this CVC4 binary -.IP "\-\-help | \-h" -this command line reference -.IP \-\-parse\-only -exit after parsing input -.IP \-\-preprocess\-only -exit after preprocessing (useful with \-\-stats or \-\-dump) -.IP \-\-dump=MODE -dump preprocessed assertions, T\-propagations, etc., see \-\-dump=help -.IP \-\-dump\-to=FILE -all dumping goes to FILE (instead of stdout) -.IP \-\-mmap -memory map file input -.IP \-\-show\-config -show CVC4 static configuration -.IP \-\-segv\-nospin -don't spin on segfault waiting for gdb -.IP \-\-lazy\-type\-checking -type check expressions only when necessary (default) -.IP \-\-eager\-type\-checking -type check expressions immediately on creation (debug builds only) -.IP \-\-no\-type\-checking -never type check expressions -.IP \-\-no\-checking -disable ALL semantic checks, including type checks -.IP \-\-no\-theory\-registration -disable theory reg (not safe for some theories) -.IP \-\-strict\-parsing -fail on non\-conformant inputs (SMT2 only) -.IP "\-\-verbose | \-v" -increase verbosity (may be repeated) -.IP "\-\-quiet | \-q" -decrease verbosity (may be repeated) -.IP "\-\-trace=FLAG | \-t FLAG" -trace something (e.g. \-t pushpop), can repeat -.IP "\-\-debug=FLAG | \-d FLAG" -debug something (e.g. \-d arith), can repeat -.IP \-\-stats -give statistics on exit -.IP \-\-default\-expr\-depth=N -print exprs to depth N (0 == default, \-1 == no limit) -.IP \-\-print\-expr\-types -print types with variables when printing exprs -.IP \-\-interactive -run interactively -.IP \-\-no\-interactive -do not run interactively -.IP \-\-produce\-models -support the get\-value command -.IP \-\-produce\-assignments -support the get\-assignment command -.IP \-\-lazy\-definition\-expansion -expand define\-fun lazily -.IP \-\-simplification=MODE -choose simplification mode, see \-\-simplification=help -.IP \-\-no\-static\-learning -turn off static learning (e.g. diamond\-breaking) -.IP \-\-replay=file -replay decisions from file -.IP \-\-replay\-log=file -log decisions and propagations to file -.IP \-\-pivot\-rule=RULE -change the pivot rule (see \-\-pivot\-rule help) -.IP \-\-pivot\-threshold=N -sets the number of heuristic pivots per variable per simplex instance -.IP \-\-prop\-row\-length=N -sets the maximum row length to be used in propagation -.IP \-\-random\-freq=P -sets the frequency of random decisions in the sat solver(P=0.0 by default) -.IP \-\-random\-seed=S -sets the random seed for the sat solver -.IP \-\-disable\-variable\-removal -enable permanent removal of variables in arithmetic (UNSAFE! experts only) -.IP \-\-disable\-arithmetic\-propagation -turns on arithmetic propagation -.IP \-\-disable\-symmetry\-breaker -turns off UF symmetry breaker (Deharbe et al., CADE 2011) -.IP \-\-incremental -enable incremental solving +.SH COMMON OPTIONS +${common_manpage_documentation} + +${remaining_manpage_documentation} .\".SH FILES .\".SH ENVIRONMENT diff --git a/examples/hashsmt/word.cpp b/examples/hashsmt/word.cpp index 46687db14..d1b8e2fef 100644 --- a/examples/hashsmt/word.cpp +++ b/examples/hashsmt/word.cpp @@ -10,6 +10,7 @@ using namespace std; using namespace hashsmt; using namespace CVC4; +using namespace CVC4::options; Expr Word::extendToSize(unsigned newSize) const { if (newSize <= size()) { @@ -26,8 +27,8 @@ ExprManager* Word::s_manager = 0; ExprManager* Word::em() { if (s_manager == 0) { CVC4::Options options; - options.inputLanguage = language::input::LANG_SMTLIB_V2; - options.outputLanguage = language::output::LANG_SMTLIB_V2; + options.set(inputLanguage, language::input::LANG_SMTLIB_V2); + options.set(outputLanguage, language::output::LANG_SMTLIB_V2); s_manager = new CVC4::ExprManager(options); } return s_manager; diff --git a/examples/hashsmt/word.h b/examples/hashsmt/word.h index 6195d0699..50fdee0c0 100644 --- a/examples/hashsmt/word.h +++ b/examples/hashsmt/word.h @@ -13,7 +13,7 @@ #include "expr/expr.h" #include "expr/expr_manager.h" -#include "util/options.h" +#include "options/options.h" namespace hashsmt { diff --git a/examples/nra-translate/normalize.cpp b/examples/nra-translate/normalize.cpp index 598055ea3..ac5780439 100644 --- a/examples/nra-translate/normalize.cpp +++ b/examples/nra-translate/normalize.cpp @@ -6,7 +6,7 @@ #include <map> -#include "util/options.h" +#include "options/options.h" #include "expr/expr.h" #include "expr/command.h" #include "parser/parser.h" @@ -16,6 +16,7 @@ using namespace std; using namespace CVC4; using namespace CVC4::parser; +using namespace CVC4::options; using namespace CVC4::theory; int main(int argc, char* argv[]) @@ -26,7 +27,7 @@ int main(int argc, char* argv[]) // Create the expression manager Options options; - options.inputLanguage = language::input::LANG_SMTLIB_V2; + options.set(inputLanguage, language::input::LANG_SMTLIB_V2); ExprManager exprManager(options); cout << Expr::setlanguage(language::output::LANG_SMTLIB_V2) << Expr::setdepth(-1); diff --git a/examples/nra-translate/smt2info.cpp b/examples/nra-translate/smt2info.cpp index a789bb8d9..b14f8fa8f 100644 --- a/examples/nra-translate/smt2info.cpp +++ b/examples/nra-translate/smt2info.cpp @@ -5,7 +5,7 @@ #include <vector> -#include "util/options.h" +#include "options/options.h" #include "expr/expr.h" #include "expr/command.h" #include "parser/parser.h" @@ -14,6 +14,7 @@ using namespace std; using namespace CVC4; using namespace CVC4::parser; +using namespace CVC4::options; unsigned compute_degree(ExprManager& exprManager, const Expr& term) { unsigned n = term.getNumChildren(); @@ -60,7 +61,7 @@ int main(int argc, char* argv[]) // Create the expression manager Options options; - options.inputLanguage = language::input::LANG_SMTLIB_V2; + options.set(inputLanguage, language::input::LANG_SMTLIB_V2); ExprManager exprManager(options); // Create the parser diff --git a/examples/nra-translate/smt2todreal.cpp b/examples/nra-translate/smt2todreal.cpp index 34e28bb75..8bdb27181 100644 --- a/examples/nra-translate/smt2todreal.cpp +++ b/examples/nra-translate/smt2todreal.cpp @@ -5,7 +5,7 @@ #include <vector> #include <map> -#include "util/options.h" +#include "options/options.h" #include "expr/expr.h" #include "expr/command.h" #include "parser/parser.h" @@ -15,6 +15,7 @@ using namespace std; using namespace CVC4; using namespace CVC4::parser; +using namespace CVC4::options; int main(int argc, char* argv[]) { @@ -24,8 +25,8 @@ int main(int argc, char* argv[]) // Create the expression manager Options options; - options.inputLanguage = language::input::LANG_SMTLIB_V2; - options.outputLanguage = language::output::LANG_SMTLIB_V2; + options.set(inputLanguage, language::input::LANG_SMTLIB_V2); + options.set(outputLanguage, language::output::LANG_SMTLIB_V2); ExprManager exprManager(options); cout << Expr::dag(0) << Expr::setdepth(-1); diff --git a/examples/nra-translate/smt2toisat.cpp b/examples/nra-translate/smt2toisat.cpp index 1ad56805b..e2b55b4b9 100644 --- a/examples/nra-translate/smt2toisat.cpp +++ b/examples/nra-translate/smt2toisat.cpp @@ -6,7 +6,7 @@ #include <map> -#include "util/options.h" +#include "options/options.h" #include "expr/expr.h" #include "expr/command.h" #include "parser/parser.h" @@ -16,6 +16,7 @@ using namespace std; using namespace CVC4; using namespace CVC4::parser; +using namespace CVC4::options; void translate_to_isat( string input, @@ -32,7 +33,7 @@ int main(int argc, char* argv[]) // Create the expression manager Options options; - options.inputLanguage = language::input::LANG_SMTLIB_V2; + options.set(inputLanguage, language::input::LANG_SMTLIB_V2); ExprManager exprManager(options); // Create the parser diff --git a/examples/nra-translate/smt2tomathematica.cpp b/examples/nra-translate/smt2tomathematica.cpp index 25bc850ae..9da21b69b 100644 --- a/examples/nra-translate/smt2tomathematica.cpp +++ b/examples/nra-translate/smt2tomathematica.cpp @@ -6,7 +6,7 @@ #include <map> -#include "util/options.h" +#include "options/options.h" #include "expr/expr.h" #include "expr/command.h" #include "parser/parser.h" @@ -15,6 +15,7 @@ using namespace std; using namespace CVC4; using namespace CVC4::parser; +using namespace CVC4::options; void translate_to_mathematica( string input, @@ -31,7 +32,7 @@ int main(int argc, char* argv[]) // Create the expression manager Options options; - options.inputLanguage = language::input::LANG_SMTLIB_V2; + options.set(inputLanguage, language::input::LANG_SMTLIB_V2); ExprManager exprManager(options); // Create the parser diff --git a/examples/nra-translate/smt2toqepcad.cpp b/examples/nra-translate/smt2toqepcad.cpp index fe3730382..bed9b42ea 100644 --- a/examples/nra-translate/smt2toqepcad.cpp +++ b/examples/nra-translate/smt2toqepcad.cpp @@ -5,7 +5,7 @@ #include <vector> #include <map> -#include "util/options.h" +#include "options/options.h" #include "expr/expr.h" #include "expr/command.h" #include "parser/parser.h" @@ -14,6 +14,7 @@ using namespace std; using namespace CVC4; using namespace CVC4::parser; +using namespace CVC4::options; void translate_to_qepcad( @@ -32,7 +33,7 @@ int main(int argc, char* argv[]) // Create the expression manager Options options; - options.inputLanguage = language::input::LANG_SMTLIB_V2; + options.set(inputLanguage, language::input::LANG_SMTLIB_V2); ExprManager exprManager(options); // Create the parser diff --git a/examples/nra-translate/smt2toredlog.cpp b/examples/nra-translate/smt2toredlog.cpp index a7111e595..da34ca4da 100644 --- a/examples/nra-translate/smt2toredlog.cpp +++ b/examples/nra-translate/smt2toredlog.cpp @@ -6,7 +6,7 @@ #include <map> -#include "util/options.h" +#include "options/options.h" #include "expr/expr.h" #include "expr/command.h" #include "parser/parser.h" @@ -16,6 +16,7 @@ using namespace std; using namespace CVC4; using namespace CVC4::parser; +using namespace CVC4::options; void translate_to_redlog( string input, @@ -35,7 +36,7 @@ int main(int argc, char* argv[]) // Create the expression manager Options options; - options.inputLanguage = language::input::LANG_SMTLIB_V2; + options.set(inputLanguage, language::input::LANG_SMTLIB_V2); ExprManager exprManager(options); // Create the parser diff --git a/src/Makefile.am b/src/Makefile.am index e04910804..232d8dd94 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -17,7 +17,7 @@ AM_CPPFLAGS = \ -I@srcdir@/include -I@srcdir@ -I@builddir@ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) -SUBDIRS = lib expr util context theory prop decision smt printer proof . parser compat bindings main +SUBDIRS = lib options expr util context theory prop decision smt printer proof . parser compat bindings main lib_LTLIBRARIES = libcvc4.la if HAVE_CXXTESTGEN @@ -33,6 +33,7 @@ nodist_EXTRA_libcvc4_la_SOURCES = dummy.cpp libcvc4_noinst_la_SOURCES = subversion_versioninfo.cpp libcvc4_la_SOURCES = subversion_versioninfo.cpp libcvc4_la_LIBADD = \ + @builddir@/options/liboptions.la \ @builddir@/util/libutil.la \ @builddir@/expr/libexpr.la \ @builddir@/context/libcontext.la \ @@ -46,6 +47,7 @@ libcvc4_la_LIBADD = \ @builddir@/decision/libdecision.la \ @builddir@/lib/libreplacements.la libcvc4_noinst_la_LIBADD = \ + @builddir@/options/liboptions.la \ @builddir@/util/libutil.la \ @builddir@/expr/libexpr.la \ @builddir@/context/libcontext.la \ diff --git a/src/compat/cvc3_compat.cpp b/src/compat/cvc3_compat.cpp index 15e0d8001..afac925e2 100644 --- a/src/compat/cvc3_compat.cpp +++ b/src/compat/cvc3_compat.cpp @@ -31,6 +31,10 @@ #include "parser/parser.h" #include "parser/parser_builder.h" +#include "parser/options.h" +#include "smt/options.h" +#include "expr/options.h" + #include <iostream> #include <string> #include <sstream> @@ -707,21 +711,20 @@ void CLFlags::setFlag(const std::string& name, void ValidityChecker::setUpOptions(CVC4::Options& options, const CLFlags& clflags) { // always incremental and model-producing in CVC3 compatibility mode - options.incrementalSolving = true; - options.produceModels = true; - - options.statistics = clflags["stats"].getBool(); - options.satRandomSeed = double(clflags["seed"].getInt()); - options.interactive = clflags["interactive"].getBool(); - if(options.interactive) { - options.interactiveSetByUser = true; - } - options.parseOnly = clflags["parse-only"].getBool(); - options.setInputLanguage(clflags["lang"].getString().c_str()); + d_smt->setOption("incremental", string("true")); + d_smt->setOption("produce-models", string("true")); + + d_smt->setOption("statistics", string(clflags["stats"].getBool() ? "true" : "false")); + d_smt->setOption("random-seed", int2string(clflags["seed"].getInt())); + d_smt->setOption("interactive-mode", string(clflags["interactive"].getBool() ? "true" : "false")); + d_smt->setOption("parse-only", string(clflags["parse-only"].getBool() ? "true" : "false")); + d_smt->setOption("input-language", clflags["lang"].getString()); if(clflags["output-lang"].getString() == "") { - options.outputLanguage = CVC4::language::toOutputLanguage(options.inputLanguage); + stringstream langss; + langss << CVC4::language::toOutputLanguage(options[CVC4::options::inputLanguage]); + d_smt->setOption("output-language", langss.str()); } else { - options.setOutputLanguage(clflags["output-lang"].getString().c_str()); + d_smt->setOption("output-language", clflags["output-lang"].getString()); } } @@ -1290,7 +1293,7 @@ void ValidityChecker::printExpr(const Expr& e) { void ValidityChecker::printExpr(const Expr& e, std::ostream& os) { Expr::setdepth::Scope sd(os, -1); Expr::printtypes::Scope pt(os, false); - Expr::setlanguage::Scope sl(os, d_em->getOptions()->outputLanguage); + Expr::setlanguage::Scope sl(os, d_em->getOptions()[CVC4::options::outputLanguage]); os << e; } @@ -2133,8 +2136,8 @@ void ValidityChecker::logAnnotation(const Expr& annot) { static void doCommands(CVC4::parser::Parser* parser, CVC4::SmtEngine* smt, CVC4::Options& opts) { while(CVC4::Command* cmd = parser->nextCommand()) { - if(opts.verbosity >= 0) { - cmd->invoke(smt, *opts.out); + if(opts[CVC4::options::verbosity] >= 0) { + cmd->invoke(smt, *opts[CVC4::options::out]); } else { cmd->invoke(smt); } @@ -2146,10 +2149,11 @@ void ValidityChecker::loadFile(const std::string& fileName, InputLanguage lang, bool interactive, bool calledFromParser) { - CVC4::Options opts = *d_em->getOptions(); - opts.inputLanguage = lang; - opts.interactive = interactive; - opts.interactiveSetByUser = true; + CVC4::Options opts = d_em->getOptions(); + stringstream langss; + langss << lang; + d_smt->setOption("input-language", langss.str()); + d_smt->setOption("interactive-mode", string(interactive ? "true" : "false")); CVC4::parser::ParserBuilder parserBuilder(d_em, fileName, opts); CVC4::parser::Parser* p = parserBuilder.build(); p->useDeclarationsFrom(d_parserContext); @@ -2160,10 +2164,11 @@ void ValidityChecker::loadFile(const std::string& fileName, void ValidityChecker::loadFile(std::istream& is, InputLanguage lang, bool interactive) { - CVC4::Options opts = *d_em->getOptions(); - opts.inputLanguage = lang; - opts.interactive = interactive; - opts.interactiveSetByUser = true; + CVC4::Options opts = d_em->getOptions(); + stringstream langss; + langss << lang; + d_smt->setOption("input-language", langss.str()); + d_smt->setOption("interactive-mode", string(interactive ? "true" : "false")); CVC4::parser::ParserBuilder parserBuilder(d_em, "[stream]", opts); CVC4::parser::Parser* p = parserBuilder.withStreamInput(is).build(); d_parserContext = p; diff --git a/src/cvc4.i b/src/cvc4.i index ce4639137..cddd3891c 100644 --- a/src/cvc4.i +++ b/src/cvc4.i @@ -92,7 +92,7 @@ using namespace CVC4; %include "util/stats.i" %include "util/exception.i" %include "util/language.i" -%include "util/options.i" +%include "options/options.i" %include "util/cardinality.i" %include "util/bool.i" %include "util/sexpr.i" diff --git a/src/decision/Makefile.am b/src/decision/Makefile.am index 4f454e9bf..5f62568ee 100644 --- a/src/decision/Makefile.am +++ b/src/decision/Makefile.am @@ -6,6 +6,8 @@ AM_CXXFLAGS = -Wall -Wno-unknown-pragmas $(FLAG_VISIBILITY_HIDDEN) noinst_LTLIBRARIES = libdecision.la libdecision_la_SOURCES = \ + decision_mode.h \ + decision_mode.cpp \ decision_engine.h \ decision_engine.cpp \ decision_strategy.h \ @@ -13,3 +15,6 @@ libdecision_la_SOURCES = \ justification_heuristic.cpp \ relevancy.h \ relevancy.cpp + +EXTRA_DIST = \ + options_handlers.h diff --git a/src/decision/decision_engine.cpp b/src/decision/decision_engine.cpp index b42f69b7f..2832a9577 100644 --- a/src/decision/decision_engine.cpp +++ b/src/decision/decision_engine.cpp @@ -21,7 +21,10 @@ #include "decision/relevancy.h" #include "expr/node.h" -#include "util/options.h" +#include "decision/options.h" +#include "decision/decision_mode.h" + +#include "smt/options.h" using namespace std; @@ -49,24 +52,23 @@ void DecisionEngine::init() d_engineState = 1; Trace("decision-init") << "DecisionEngine::init()" << std::endl; - const Options* options = Options::current(); - if(options->incrementalSolving) return; + if(options::incrementalSolving()) return; Trace("decision-init") << " * options->decisionMode: " - << options->decisionMode << std:: endl; - Trace("decision-init") << " * options->decisionOptions.stopOnly: " - << ((options->decisionOptions).stopOnly) << std::endl; + << options::decisionMode() << std:: endl; + Trace("decision-init") << " * options->decisionStopOnly: " + << options::decisionStopOnly() << std::endl; - if(options->decisionMode == Options::DECISION_STRATEGY_INTERNAL) { } - if(options->decisionMode == Options::DECISION_STRATEGY_JUSTIFICATION) { + if(options::decisionMode() == decision::DECISION_STRATEGY_INTERNAL) { } + if(options::decisionMode() == decision::DECISION_STRATEGY_JUSTIFICATION) { ITEDecisionStrategy* ds = new decision::JustificationHeuristic(this, d_satContext); enableStrategy(ds); d_needIteSkolemMap.push_back(ds); } - if(options->decisionMode == Options::DECISION_STRATEGY_RELEVANCY) { + if(options::decisionMode() == decision::DECISION_STRATEGY_RELEVANCY) { RelevancyStrategy* ds = - new decision::Relevancy(this, d_satContext, options->decisionOptions); + new decision::Relevancy(this, d_satContext); enableStrategy(ds); d_needIteSkolemMap.push_back(ds); d_relevancyStrategy = ds; diff --git a/src/decision/decision_mode.cpp b/src/decision/decision_mode.cpp new file mode 100644 index 000000000..c4bb58b93 --- /dev/null +++ b/src/decision/decision_mode.cpp @@ -0,0 +1,40 @@ +/********************* */ +/*! \file decision_mode.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "decision/decision_mode.h" + +namespace CVC4 { + +std::ostream& operator<<(std::ostream& out, decision::DecisionMode mode) { + switch(mode) { + case decision::DECISION_STRATEGY_INTERNAL: + out << "DECISION_STRATEGY_INTERNAL"; + break; + case decision::DECISION_STRATEGY_JUSTIFICATION: + out << "DECISION_STRATEGY_JUSTIFICATION"; + break; + default: + out << "DecisionMode:UNKNOWN![" << unsigned(mode) << "]"; + } + + return out; +} + +}/* CVC4 namespace */ + diff --git a/src/decision/decision_mode.h b/src/decision/decision_mode.h new file mode 100644 index 000000000..f6dba32ea --- /dev/null +++ b/src/decision/decision_mode.h @@ -0,0 +1,57 @@ +/********************* */ +/*! \file decision_mode.h + ** \verbatim + ** Original author: kshitij + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__SMT__DECISION_MODE_H +#define __CVC4__SMT__DECISION_MODE_H + +#include <iostream> + +namespace CVC4 { +namespace decision { + +/** Enumeration of decision strategies */ +enum DecisionMode { + + /** + * Decision engine doesn't do anything. Use sat solver's internal + * heuristics + */ + DECISION_STRATEGY_INTERNAL, + + /** + * Use the justification heuristic + */ + DECISION_STRATEGY_JUSTIFICATION, + + /** + * Use may-relevancy. + */ + DECISION_STRATEGY_RELEVANCY + +};/* enum DecisionMode */ + +}/* CVC4::decision namespace */ + +std::ostream& operator<<(std::ostream& out, decision::DecisionMode mode) CVC4_PUBLIC; + +}/* CVC4 namespace */ + +#endif /* __CVC4__SMT__DECISION_MODE_H */ diff --git a/src/decision/decision_strategy.h b/src/decision/decision_strategy.h index ee7d340c4..dd6c7f548 100644 --- a/src/decision/decision_strategy.h +++ b/src/decision/decision_strategy.h @@ -27,8 +27,8 @@ namespace CVC4 { class DecisionEngine; namespace context { -class Context; -} + class Context; +}/* CVC4::context namespace */ namespace decision { @@ -47,7 +47,7 @@ public: virtual bool needIteSkolemMap() { return false; } virtual void notifyAssertionsAvailable() { return; } -}; +};/* class DecisionStrategy */ class ITEDecisionStrategy : public DecisionStrategy { public: @@ -61,7 +61,7 @@ public: virtual void addAssertions(const std::vector<Node> &assertions, unsigned assertionsEnd, IteSkolemMap iteSkolemMap) = 0; -}; +};/* class ITEDecisionStrategy */ class RelevancyStrategy : public ITEDecisionStrategy { public: @@ -71,10 +71,9 @@ public: virtual bool isRelevant(TNode n) = 0; virtual prop::SatValue getPolarity(TNode n) = 0; -}; +};/* class RelevancyStrategy */ - -}/* decision namespace */ +}/* CVC4::decision namespace */ }/* CVC4 namespace */ #endif /* __CVC4__DECISION__DECISION_STRATEGY_H */ diff --git a/src/decision/options b/src/decision/options new file mode 100644 index 000000000..7e457f125 --- /dev/null +++ b/src/decision/options @@ -0,0 +1,23 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module DECISION "decision/options.h" Decision heuristics + +# When/whether to use any decision strategies +option decisionMode --decision=MODE decision::DecisionMode :handler CVC4::decision::stringToDecisionMode :default decision::DECISION_STRATEGY_INTERNAL :read-write :include "decision/decision_mode.h" :handler-include "decision/options_handlers.h" + choose decision mode, see --decision=help + +option decisionRelevancyLeaves bool +# permille = part per thousand +option decisionMaxRelTimeAsPermille --decision-budget=N "unsigned short" :read-write :predicate less_equal(1000L) :predicate CVC4::decision::checkDecisionBudget :predicate-include "decision/options_handlers.h" + impose a budget for relevancy heuristic which increases linearly with each decision. N between 0 and 1000. (default: 1000, no budget) +# if false, do justification stuff using relevancy.h +option decisionComputeRelevancy bool +# use the must be relevant +option decisionMustRelevancy bool +# only use DE to determine when to stop, not to make decisions +option decisionStopOnly bool + +endmodule diff --git a/src/decision/options_handlers.h b/src/decision/options_handlers.h new file mode 100644 index 000000000..e9f227043 --- /dev/null +++ b/src/decision/options_handlers.h @@ -0,0 +1,112 @@ +/********************* */ +/*! \file options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Custom handlers and predicates for DecisionEngine options + ** + ** Custom handlers and predicates for DecisionEngine options. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__DECISION__OPTIONS_HANDLERS_H +#define __CVC4__DECISION__OPTIONS_HANDLERS_H + +#include "decision/decision_mode.h" +#include "main/options.h" + +namespace CVC4 { +namespace decision { + +static const std::string decisionModeHelp = "\ +Decision modes currently supported by the --decision option:\n\ +\n\ +internal (default)\n\ ++ Use the internal decision hueristics of the SAT solver\n\ +\n\ +justification\n\ ++ An ATGP-inspired justification heuristic\n\ +\n\ +justification-stoponly\n\ ++ Use the justification heuristic only to stop early, not for decisions\n\ +\n\ +relevancy\n\ ++ Under development may-relevancy\n\ +\n\ +relevancy-leaves\n\ ++ May-relevancy, but decide only on leaves\n\ +\n\ +Developer modes:\n\ +\n\ +justification-rel\n\ ++ Use the relevancy code to do the justification stuff\n\ ++ (This should do exact same thing as justification)\n\ +\n\ +justification-must\n\ ++ Start deciding on literals close to root instead of those\n\ ++ near leaves (don't expect it to work well) [Unimplemented]\n\ +"; + +inline DecisionMode stringToDecisionMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { + options::decisionRelevancyLeaves.set(false); + options::decisionMaxRelTimeAsPermille.set(1000); + options::decisionComputeRelevancy.set(true); + options::decisionMustRelevancy.set(false); + options::decisionStopOnly.set(false); + + if(optarg == "internal") { + return DECISION_STRATEGY_INTERNAL; + } else if(optarg == "justification") { + return DECISION_STRATEGY_JUSTIFICATION; + } else if(optarg == "justification-stoponly") { + options::decisionStopOnly.set(true); + return DECISION_STRATEGY_JUSTIFICATION; + } else if(optarg == "relevancy") { + options::decisionRelevancyLeaves.set(false); + return DECISION_STRATEGY_RELEVANCY; + } else if(optarg == "relevancy-leaves") { + options::decisionRelevancyLeaves.set(true); + Trace("options") << "version is " << options::version() << std::endl; + return DECISION_STRATEGY_RELEVANCY; + } else if(optarg == "justification-rel") { + // relevancyLeaves : irrelevant + // maxRelTimeAsPermille : irrelevant + options::decisionComputeRelevancy.set(false); + options::decisionMustRelevancy.set(false); + return DECISION_STRATEGY_RELEVANCY; + } else if(optarg == "justification-must") { + // relevancyLeaves : irrelevant + // maxRelTimeAsPermille : irrelevant + options::decisionComputeRelevancy.set(false); + options::decisionMustRelevancy.set(true); + return DECISION_STRATEGY_RELEVANCY; + } else if(optarg == "help") { + puts(decisionModeHelp.c_str()); + exit(1); + } else { + throw OptionException(std::string("unknown option for --decision: `") + + optarg + "'. Try --decision help."); + } +} + +inline void checkDecisionBudget(std::string option, unsigned short budget, SmtEngine* smt) throw(OptionException) { + if(budget == 0) { + Warning() << "Decision budget is 0. Consider using internal decision heuristic and " + << std::endl << " removing this option." << std::endl; + + } +} + +}/* CVC4::decision namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__DECISION__OPTIONS_HANDLERS_H */ diff --git a/src/decision/relevancy.cpp b/src/decision/relevancy.cpp index d0d44f606..fe5bdcc20 100644 --- a/src/decision/relevancy.cpp +++ b/src/decision/relevancy.cpp @@ -34,7 +34,7 @@ void Relevancy::setJustified(TNode n) { Debug("decision") << " marking [" << n.getId() << "]"<< n << "as justified" << std::endl; d_justified.insert(n); - if(d_opt.computeRelevancy) { + if(options::decisionComputeRelevancy()) { d_relevancy[n] = d_maxRelevancy[n]; updateRelevancy(n); } @@ -117,7 +117,7 @@ bool Relevancy::findSplitterRec(TNode node, if(d_polarityCache.find(node) == d_polarityCache.end()) { d_polarityCache[node] = desiredVal; } else { - Assert(d_multipleBacktrace || d_opt.computeRelevancy); + Assert(d_multipleBacktrace || options::decisionComputeRelevancy()); return true; } @@ -289,7 +289,7 @@ bool Relevancy::handleOrFalse(TNode node, SatValue desiredVal) { bool ret = false; for(int i = 0; i < n; ++i) { if (findSplitterRec(node[i], desiredVal)) { - if(!d_opt.computeRelevancy) + if(!options::decisionComputeRelevancy()) return true; else ret = true; diff --git a/src/decision/relevancy.h b/src/decision/relevancy.h index f45ce2e8f..a529b974e 100644 --- a/src/decision/relevancy.h +++ b/src/decision/relevancy.h @@ -35,12 +35,12 @@ #include "decision_engine.h" #include "decision_strategy.h" +#include "decision/options.h" #include "context/cdhashset.h" #include "context/cdhashmap.h" #include "expr/node.h" #include "prop/sat_solver_types.h" -#include "util/options.h" namespace CVC4 { @@ -109,9 +109,6 @@ class Relevancy : public RelevancyStrategy { bool d_multipleBacktrace; //bool d_computeRelevancy; // are we in a mode where we compute relevancy? - /** Only leaves can be relevant */ - Options::DecisionOptions d_opt; // may be we shouldn't be caching them? - static const double secondsPerDecision = 0.001; static const double secondsPerExpense = 1e-7; static const double EPS = 1e-9; @@ -121,7 +118,7 @@ class Relevancy : public RelevancyStrategy { /** current decision for the recursive call */ SatLiteral* d_curDecision; public: - Relevancy(CVC4::DecisionEngine* de, context::Context *c, const Options::DecisionOptions &decOpt): + Relevancy(CVC4::DecisionEngine* de, context::Context *c): RelevancyStrategy(de, c), d_justified(c), d_prvsIndex(c, 0), @@ -132,10 +129,9 @@ public: d_expense("decision::rel::expense", 0), d_timestat("decision::rel::time"), d_relevancy(c), - d_multipleBacktrace(decOpt.computeRelevancy), + d_multipleBacktrace(options::decisionComputeRelevancy()), // d_computeRelevancy(decOpt.computeRelevancy), - d_opt(decOpt), - d_maxTimeAsPercentageOfTotalTime(decOpt.maxRelTimeAsPermille*1.0/10.0), + d_maxTimeAsPercentageOfTotalTime(options::decisionMaxRelTimeAsPermille()*1.0/10.0), d_curDecision(NULL) { Warning() << "There are known bugs in this Relevancy code which we know" @@ -149,11 +145,11 @@ public: StatisticsRegistry::registerStat(&d_expense); StatisticsRegistry::registerStat(&d_timestat); Trace("decision") << "relevancy enabled with" << std::endl; - Trace("decision") << " * computeRelevancy: " << (d_opt.computeRelevancy ? "on" : "off") + Trace("decision") << " * computeRelevancy: " << (options::decisionComputeRelevancy() ? "on" : "off") << std::endl; - Trace("decision") << " * relevancyLeaves: " << (d_opt.relevancyLeaves ? "on" : "off") + Trace("decision") << " * relevancyLeaves: " << (options::decisionRelevancyLeaves() ? "on" : "off") << std::endl; - Trace("decision") << " * mustRelevancy [unimplemented]: " << (d_opt.mustRelevancy ? "on" : "off") + Trace("decision") << " * mustRelevancy [unimplemented]: " << (options::decisionMustRelevancy() ? "on" : "off") << std::endl; } ~Relevancy() { @@ -189,13 +185,13 @@ public: SatValue desiredVal = SAT_VALUE_TRUE; SatLiteral litDecision = findSplitter(d_assertions[i], desiredVal); - if(!d_opt.computeRelevancy && litDecision != undefSatLiteral) { + if(!options::decisionComputeRelevancy() && litDecision != undefSatLiteral) { d_prvsIndex = i; return litDecision; } } - if(d_opt.computeRelevancy) return undefSatLiteral; + if(options::decisionComputeRelevancy()) return undefSatLiteral; Trace("decision") << "jh: Nothing to split on " << std::endl; @@ -244,7 +240,7 @@ public: for(unsigned i = 0; i < assertionsEnd; ++i) { d_assertions.push_back(assertions[i]); d_visited.clear(); - if(d_opt.computeRelevancy) increaseMaxRelevancy(assertions[i]); + if(options::decisionComputeRelevancy()) increaseMaxRelevancy(assertions[i]); d_visited.clear(); } @@ -267,7 +263,7 @@ public: return true; } - if(d_opt.relevancyLeaves && !isAtomicFormula(n)) { + if(options::decisionRelevancyLeaves() && !isAtomicFormula(n)) { Trace("decision") << "no [not a leaf]" << std::endl; return false; } diff --git a/src/expr/Makefile.am b/src/expr/Makefile.am index 6baa4613f..38cb8250c 100644 --- a/src/expr/Makefile.am +++ b/src/expr/Makefile.am @@ -56,6 +56,7 @@ EXTRA_DIST = \ expr_template.h \ expr_template.cpp \ type_checker_template.cpp \ + options_handlers.h \ mkkind \ mkmetakind \ mkexpr \ @@ -154,3 +155,6 @@ type_checker.cpp: type_checker_template.cpp mkexpr @top_builddir@/src/theory/.su $< \ `cat @top_builddir@/src/theory/.subdirs` \ > $@) || (rm -f $@ && exit 1) + +.PHONY: builts +builts: $(BUILT_SOURCES) diff --git a/src/expr/command.cpp b/src/expr/command.cpp index 12830a618..c127aca75 100644 --- a/src/expr/command.cpp +++ b/src/expr/command.cpp @@ -902,7 +902,7 @@ void SetBenchmarkStatusCommand::invoke(SmtEngine* smtEngine) throw() { stringstream ss; ss << d_status; SExpr status = ss.str(); - smtEngine->setInfo(":status", status); + smtEngine->setInfo("status", status); d_commandStatus = CommandSuccess::instance(); } catch(exception& e) { d_commandStatus = new CommandFailure(e.what()); @@ -1074,7 +1074,13 @@ std::string GetOptionCommand::getFlag() const throw() { void GetOptionCommand::invoke(SmtEngine* smtEngine) throw() { try { - d_result = smtEngine->getOption(d_flag).getValue(); + vector<SExpr> v; + v.push_back(SExpr(SExpr::Keyword(string(":") + d_flag))); + v.push_back(smtEngine->getOption(d_flag)); + stringstream ss; + + ss << SExpr(v); + d_result = ss.str(); d_commandStatus = CommandSuccess::instance(); } catch(BadOptionException&) { d_commandStatus = new CommandUnsupported(); diff --git a/src/expr/expr_manager_template.cpp b/src/expr/expr_manager_template.cpp index 25578399f..a8491c937 100644 --- a/src/expr/expr_manager_template.cpp +++ b/src/expr/expr_manager_template.cpp @@ -20,7 +20,7 @@ #include "expr/expr_manager.h" #include "expr/variable_type_map.h" #include "context/context.h" -#include "util/options.h" +#include "options/options.h" #include "util/stats.h" #include <map> @@ -126,7 +126,7 @@ ExprManager::~ExprManager() throw() { } } -const Options* ExprManager::getOptions() const { +const Options& ExprManager::getOptions() const { return d_nodeManager->getOptions(); } diff --git a/src/expr/expr_manager_template.h b/src/expr/expr_manager_template.h index fdc1e1159..b762da3ea 100644 --- a/src/expr/expr_manager_template.h +++ b/src/expr/expr_manager_template.h @@ -42,7 +42,7 @@ namespace CVC4 { class Expr; class SmtEngine; class NodeManager; -struct Options; +class Options; class IntStat; class ExprManagerMapCollection; @@ -124,7 +124,7 @@ public: ~ExprManager() throw(); /** Get this node manager's options */ - const Options* getOptions() const; + const Options& getOptions() const; /** Get the type for booleans */ BooleanType booleanType() const; diff --git a/src/expr/expr_template.h b/src/expr/expr_template.h index dc82daec4..a2e861118 100644 --- a/src/expr/expr_template.h +++ b/src/expr/expr_template.h @@ -36,7 +36,7 @@ ${includes} #include "util/exception.h" #include "util/language.h" #include "util/hash.h" -#include "util/options.h" +#include "expr/options.h" // This is a hack, but an important one: if there's an error, the // compiler directs the user to the template file instead of the @@ -683,8 +683,8 @@ public: long& l = out.iword(s_iosIndex); if(l == 0) { // set the default print depth on this ostream - if(Options::current() != NULL) { - l = Options::current()->defaultExprDepth; + if(&Options::current() != NULL) { + l = options::defaultExprDepth(); } if(l == 0) { l = s_defaultPrintDepth; @@ -909,8 +909,8 @@ public: if(l == 0) { // set the default language on this ostream // (offset by one to detect whether default has been set yet) - if(Options::current() != NULL) { - l = Options::current()->outputLanguage + 1; + if(&Options::current() != NULL) { + l = options::outputLanguage() + 1; } if(l <= 0 || l > language::output::LANG_MAX) { // if called from outside the library, we may not have options diff --git a/src/expr/node_builder.h b/src/expr/node_builder.h index fcb503d37..fa9b1c011 100644 --- a/src/expr/node_builder.h +++ b/src/expr/node_builder.h @@ -742,7 +742,7 @@ public: #include "expr/node.h" #include "expr/node_manager.h" -#include "util/options.h" +#include "expr/options.h" namespace CVC4 { @@ -1301,7 +1301,7 @@ inline void NodeBuilder<nchild_thresh>::maybeCheckType(const TNode n) const throw(TypeCheckingExceptionPrivate, AssertionException) { /* force an immediate type check, if early type checking is enabled and the current node isn't a variable or constant */ - if( d_nm->getOptions()->earlyTypeChecking ) { + if( d_nm->getOptions()[options::earlyTypeChecking] ) { kind::MetaKind mk = n.getMetaKind(); if( mk != kind::metakind::VARIABLE && mk != kind::metakind::CONSTANT ) { diff --git a/src/expr/node_manager.cpp b/src/expr/node_manager.cpp index 1abcf398b..fc2eec774 100644 --- a/src/expr/node_manager.cpp +++ b/src/expr/node_manager.cpp @@ -21,7 +21,7 @@ #include "expr/node_manager.h" #include "util/Assert.h" -#include "util/options.h" +#include "options/options.h" #include "util/stats.h" #include "util/tls.h" @@ -82,7 +82,7 @@ struct NVReclaim { NodeManager::NodeManager(context::Context* ctxt, ExprManager* exprManager) : - d_options(), + d_options(new Options()), d_statisticsRegistry(new StatisticsRegistry()), next_id(0), d_attrManager(ctxt), @@ -92,11 +92,10 @@ NodeManager::NodeManager(context::Context* ctxt, init(); } - NodeManager::NodeManager(context::Context* ctxt, ExprManager* exprManager, const Options& options) : - d_options(options), + d_options(new Options(options)), d_statisticsRegistry(new StatisticsRegistry()), next_id(0), d_attrManager(ctxt), @@ -154,6 +153,7 @@ NodeManager::~NodeManager() { } delete d_statisticsRegistry; + delete d_options; } void NodeManager::reclaimZombies() { @@ -253,7 +253,7 @@ TypeNode NodeManager::getType(TNode n, bool check) Debug("getType") << "getting type for " << n << std::endl; - if(needsCheck && !d_options.earlyTypeChecking) { + if(needsCheck && !(*d_options)[options::earlyTypeChecking]) { /* Iterate and compute the children bottom up. This avoids stack overflows in computeType() when the Node graph is really deep, which should only affect us when we're type checking lazily. */ diff --git a/src/expr/node_manager.h b/src/expr/node_manager.h index 6c34eb4a3..501a0f4fd 100644 --- a/src/expr/node_manager.h +++ b/src/expr/node_manager.h @@ -41,7 +41,7 @@ #include "util/subrange_bound.h" #include "util/configuration_private.h" #include "util/tls.h" -#include "util/options.h" +#include "options/options.h" namespace CVC4 { @@ -83,7 +83,7 @@ class NodeManager { static CVC4_THREADLOCAL(NodeManager*) s_current; - Options d_options; + Options* d_options; StatisticsRegistry* d_statisticsRegistry; NodeValuePool d_nodeValuePool; @@ -267,13 +267,13 @@ public: static NodeManager* currentNM() { return s_current; } /** Get this node manager's options (const version) */ - const Options* getOptions() const { - return &d_options; + const Options& getOptions() const { + return *d_options; } /** Get this node manager's options (non-const version) */ - Options* getOptions() { - return &d_options; + Options& getOptions() { + return *d_options; } /** Get this node manager's statistics registry */ @@ -791,14 +791,14 @@ public: // Expr is destructed, there's no active node manager. //Assert(nm != NULL); NodeManager::s_current = nm; - Options::s_current = nm ? &nm->d_options : NULL; + Options::s_current = nm ? nm->d_options : NULL; Debug("current") << "node manager scope: " << NodeManager::s_current << "\n"; } ~NodeManagerScope() { NodeManager::s_current = d_oldNodeManager; - Options::s_current = d_oldNodeManager ? &d_oldNodeManager->d_options : NULL; + Options::s_current = d_oldNodeManager ? d_oldNodeManager->d_options : NULL; Debug("current") << "node manager scope: " << "returning to " << NodeManager::s_current << "\n"; } diff --git a/src/expr/node_value.cpp b/src/expr/node_value.cpp index dbf706c45..587f3873b 100644 --- a/src/expr/node_value.cpp +++ b/src/expr/node_value.cpp @@ -25,6 +25,7 @@ #include "expr/kind.h" #include "expr/metakind.h" #include "util/language.h" +#include "options/options.h" #include "printer/printer.h" #include <sstream> @@ -37,11 +38,12 @@ NodeValue NodeValue::s_null(0); string NodeValue::toString() const { stringstream ss; - OutputLanguage outputLanguage = (this == &s_null) ? language::output::LANG_AST : Options::current()->outputLanguage; + + OutputLanguage outlang = (this == &s_null) ? language::output::LANG_AST : options::outputLanguage(); toStream(ss, -1, false, - outputLanguage == language::output::LANG_AUTO ? + outlang == language::output::LANG_AUTO ? language::output::LANG_AST : - outputLanguage); + outlang); return ss.str(); } diff --git a/src/expr/options b/src/expr/options new file mode 100644 index 000000000..24810962e --- /dev/null +++ b/src/expr/options @@ -0,0 +1,25 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module EXPR "expr/options.h" Expression package + +option defaultExprDepth --default-expr-depth=N int :predicate CVC4::expr::setDefaultExprDepth :predicate-include "expr/options_handlers.h" + print exprs to depth N (0 == default, -1 == no limit) +option - --default-dag-thresh=N argument :handler CVC4::expr::setDefaultDagThresh :handler-include "expr/options_handlers.h" + dagify common subexprs appearing > N times (1 == default, 0 == don't dagify) +option - --print-expr-types void :handler CVC4::expr::setPrintExprTypes :handler-include "expr/options_handlers.h" + print types with variables when printing exprs + +option earlyTypeChecking --eager-type-checking/--lazy-type-checking bool :default USE_EARLY_TYPE_CHECKING_BY_DEFAULT + type check expressions immediately on creation (debug builds only) +/type check expressions only when necessary (default) + +# --no-type-checking will override any --early-type-checking or --lazy-type-checking option +# --lazy-type-checking is linked because earlyTypeChecking should be set false too +option typeChecking /--no-type-checking bool :default DO_SEMANTIC_CHECKS_BY_DEFAULT :link /--lazy-type-checking + never type check expressions + +endmodule + diff --git a/src/expr/options_handlers.h b/src/expr/options_handlers.h new file mode 100644 index 000000000..a17445188 --- /dev/null +++ b/src/expr/options_handlers.h @@ -0,0 +1,72 @@ +/********************* */ +/*! \file options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Custom handlers and predicates for expression package options + ** + ** Custom handlers and predicates for expression package options. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__EXPR__OPTIONS_HANDLERS_H +#define __CVC4__EXPR__OPTIONS_HANDLERS_H + +#include "util/output.h" +#include "util/dump.h" + +namespace CVC4 { +namespace expr { + +inline void setDefaultExprDepth(std::string option, int depth, SmtEngine* smt) { + if(depth < -1) { + throw OptionException("--default-expr-depth requires a positive argument, or -1."); + } + + Debug.getStream() << Expr::setdepth(depth); + Trace.getStream() << Expr::setdepth(depth); + Notice.getStream() << Expr::setdepth(depth); + Chat.getStream() << Expr::setdepth(depth); + Message.getStream() << Expr::setdepth(depth); + Warning.getStream() << Expr::setdepth(depth); + // intentionally exclude Dump stream from this list +} + +inline void setDefaultDagThresh(std::string option, std::string optarg, SmtEngine* smt) { + int dag = atoi(optarg.c_str()); + if(dag < 0) { + throw OptionException("--default-dag-thresh requires a nonnegative argument."); + } + + Debug.getStream() << Expr::dag(dag); + Trace.getStream() << Expr::dag(dag); + Notice.getStream() << Expr::dag(dag); + Chat.getStream() << Expr::dag(dag); + Message.getStream() << Expr::dag(dag); + Warning.getStream() << Expr::dag(dag); + Dump.getStream() << Expr::dag(dag); +} + +inline void setPrintExprTypes(std::string option, SmtEngine* smt) { + Debug.getStream() << Expr::printtypes(true); + Trace.getStream() << Expr::printtypes(true); + Notice.getStream() << Expr::printtypes(true); + Chat.getStream() << Expr::printtypes(true); + Message.getStream() << Expr::printtypes(true); + Warning.getStream() << Expr::printtypes(true); + // intentionally exclude Dump stream from this list +} + +}/* CVC4::expr namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__EXPR__OPTIONS_HANDLERS_H */ diff --git a/src/include/cvc4.h b/src/include/cvc4.h index cfe11fb82..6523f6b32 100644 --- a/src/include/cvc4.h +++ b/src/include/cvc4.h @@ -30,7 +30,7 @@ #include <cvc4/util/integer.h> #include <cvc4/util/rational.h> #include <cvc4/util/exception.h> -#include <cvc4/util/options.h> +#include <cvc4/options/options.h> #include <cvc4/util/configuration.h> #include <cvc4/parser/parser.h> diff --git a/src/main/Makefile.am b/src/main/Makefile.am index 594751358..730afa32d 100644 --- a/src/main/Makefile.am +++ b/src/main/Makefile.am @@ -65,6 +65,9 @@ smt2_tokens.h: @srcdir@/../parser/smt2/Smt2.g tptp_tokens.h: @srcdir@/../parser/tptp/Tptp.g $(AM_V_GEN)grep "'[a-zA-Z][a-zA-Z0-9][a-zA-Z0-9]*'" $^ | sed 's/.*'\''\([a-zA-Z0-9]*\)'\''.*/"\1",/' | sort -u >$@ +EXTRA_DIST = \ + options_handlers.h + clean-local: rm -f $(BUILT_SOURCES) diff --git a/src/main/driver.cpp b/src/main/driver.cpp index f24526e6c..ca5dfad93 100644 --- a/src/main/driver.cpp +++ b/src/main/driver.cpp @@ -36,7 +36,10 @@ #include "expr/command.h" #include "util/Assert.h" #include "util/configuration.h" -#include "util/options.h" +#include "options/options.h" +#include "main/options.h" +#include "smt/options.h" +#include "theory/uf/options.h" #include "util/output.h" #include "util/dump.h" #include "util/result.h" @@ -66,28 +69,28 @@ namespace CVC4 { } -void printUsage(Options& options, bool full) { +void printUsage(Options& opts, bool full) { stringstream ss; - ss << "usage: " << options.binary_name << " [options] [input-file]" << endl + ss << "usage: " << opts[options::binary_name] << " [options] [input-file]" << endl << endl << "Without an input file, or with `-', CVC4 reads from standard input." << endl << endl << "CVC4 options:" << endl; if(full) { - Options::printUsage( ss.str(), *options.out ); + Options::printUsage( ss.str(), *opts[options::out] ); } else { - Options::printShortUsage( ss.str(), *options.out ); + Options::printShortUsage( ss.str(), *opts[options::out] ); } } -int runCvc4(int argc, char* argv[], Options& options) { +int runCvc4(int argc, char* argv[], Options& opts) { // Timer statistic TimerStat s_totalTime("totalTime"); s_totalTime.start(); // For the signal handlers' benefit - pOptions = &options; + pOptions = &opts; // Initialize the signal handlers cvc4_init(); @@ -95,26 +98,26 @@ int runCvc4(int argc, char* argv[], Options& options) { progPath = argv[0]; // Parse the options - int firstArgIndex = options.parseOptions(argc, argv); + int firstArgIndex = opts.parseOptions(argc, argv); - progName = options.binary_name.c_str(); + progName = opts[options::binary_name].c_str(); - if( options.help ) { - printUsage(options, true); + if( opts[options::help] ) { + printUsage(opts, true); exit(1); - } else if( options.languageHelp ) { - Options::printLanguageHelp(*options.out); + } else if( opts[options::languageHelp] ) { + Options::printLanguageHelp(*opts[options::out]); exit(1); - } else if( options.version ) { - *options.out << Configuration::about().c_str() << flush; + } else if( opts[options::version] ) { + *opts[options::out] << Configuration::about().c_str() << flush; exit(0); } - segvNoSpin = options.segvNoSpin; + segvNoSpin = opts[options::segvNoSpin]; // If in competition mode, set output stream option to flush immediately #ifdef CVC4_COMPETITION_MODE - *options.out << unitbuf; + *opts[options::out] << unitbuf; #endif /* CVC4_COMPETITION_MODE */ // We only accept one input file @@ -127,8 +130,8 @@ int runCvc4(int argc, char* argv[], Options& options) { firstArgIndex >= argc || !strcmp("-", argv[firstArgIndex]); // if we're reading from stdin on a TTY, default to interactive mode - if(!options.interactiveSetByUser) { - options.interactive = inputFromStdin && isatty(fileno(stdin)); + if(!opts.wasSetByUser(options::interactive)) { + opts.set(options::interactive, inputFromStdin && isatty(fileno(stdin))); } // Determine which messages to show based on smtcomp_mode and verbosity @@ -141,13 +144,13 @@ int runCvc4(int argc, char* argv[], Options& options) { Warning.setStream(CVC4::null_os); Dump.setStream(CVC4::null_os); } else { - if(options.verbosity < 2) { + if(opts[options::verbosity] < 2) { Chat.setStream(CVC4::null_os); } - if(options.verbosity < 1) { + if(opts[options::verbosity] < 1) { Notice.setStream(CVC4::null_os); } - if(options.verbosity < 0) { + if(opts[options::verbosity] < 0) { Message.setStream(CVC4::null_os); Warning.setStream(CVC4::null_os); } @@ -156,28 +159,28 @@ int runCvc4(int argc, char* argv[], Options& options) { // Auto-detect input language by filename extension const char* filename = inputFromStdin ? "<stdin>" : argv[firstArgIndex]; - if(options.inputLanguage == language::input::LANG_AUTO) { + if(opts[options::inputLanguage] == language::input::LANG_AUTO) { if( inputFromStdin ) { // We can't do any fancy detection on stdin - options.inputLanguage = language::input::LANG_CVC4; + opts.set(options::inputLanguage, language::input::LANG_CVC4); } else { unsigned len = strlen(filename); if(len >= 5 && !strcmp(".smt2", filename + len - 5)) { - options.inputLanguage = language::input::LANG_SMTLIB_V2; + opts.set(options::inputLanguage, language::input::LANG_SMTLIB_V2); } else if(len >= 4 && !strcmp(".smt", filename + len - 4)) { - options.inputLanguage = language::input::LANG_SMTLIB; + opts.set(options::inputLanguage, language::input::LANG_SMTLIB); } else if((len >= 2 && !strcmp(".p", filename + len - 2)) || (len >= 5 && !strcmp(".tptp", filename + len - 5))) { - options.inputLanguage = language::input::LANG_TPTP; + opts.set(options::inputLanguage, language::input::LANG_TPTP); } else if(( len >= 4 && !strcmp(".cvc", filename + len - 4) ) || ( len >= 5 && !strcmp(".cvc4", filename + len - 5) )) { - options.inputLanguage = language::input::LANG_CVC4; + opts.set(options::inputLanguage, language::input::LANG_CVC4); } } } - if(options.outputLanguage == language::output::LANG_AUTO) { - options.outputLanguage = language::toOutputLanguage(options.inputLanguage); + if(opts[options::outputLanguage] == language::output::LANG_AUTO) { + opts.set(options::outputLanguage, language::toOutputLanguage(opts[options::inputLanguage])); } // Determine which messages to show based on smtcomp_mode and verbosity @@ -190,70 +193,73 @@ int runCvc4(int argc, char* argv[], Options& options) { Warning.setStream(CVC4::null_os); Dump.setStream(CVC4::null_os); } else { - if(options.verbosity < 2) { + if(opts[options::verbosity] < 2) { Chat.setStream(CVC4::null_os); } - if(options.verbosity < 1) { + if(opts[options::verbosity] < 1) { Notice.setStream(CVC4::null_os); } - if(options.verbosity < 0) { + if(opts[options::verbosity] < 0) { Message.setStream(CVC4::null_os); Warning.setStream(CVC4::null_os); } - Debug.getStream() << Expr::setlanguage(options.outputLanguage); - Trace.getStream() << Expr::setlanguage(options.outputLanguage); - Notice.getStream() << Expr::setlanguage(options.outputLanguage); - Chat.getStream() << Expr::setlanguage(options.outputLanguage); - Message.getStream() << Expr::setlanguage(options.outputLanguage); - Warning.getStream() << Expr::setlanguage(options.outputLanguage); - Dump.getStream() << Expr::setlanguage(options.outputLanguage) + Debug.getStream() << Expr::setlanguage(opts[options::outputLanguage]); + Trace.getStream() << Expr::setlanguage(opts[options::outputLanguage]); + Notice.getStream() << Expr::setlanguage(opts[options::outputLanguage]); + Chat.getStream() << Expr::setlanguage(opts[options::outputLanguage]); + Message.getStream() << Expr::setlanguage(opts[options::outputLanguage]); + Warning.getStream() << Expr::setlanguage(opts[options::outputLanguage]); + Dump.getStream() << Expr::setlanguage(opts[options::outputLanguage]) << Expr::setdepth(-1) << Expr::printtypes(false); } // important even for muzzled builds (to get result output right) - *options.out << Expr::setlanguage(options.outputLanguage); + *opts[options::out] << Expr::setlanguage(opts[options::outputLanguage]); // Create the expression manager - ExprManager exprMgr(options); + ExprManager exprMgr(opts); // Create the SmtEngine + StatisticsRegistry driverStats("driver"); SmtEngine smt(&exprMgr); Parser* replayParser = NULL; - if( options.replayFilename != "" ) { - ParserBuilder replayParserBuilder(&exprMgr, options.replayFilename, options); + if( opts[options::replayFilename] != "" ) { + ParserBuilder replayParserBuilder(&exprMgr, opts[options::replayFilename], opts); - if( options.replayFilename == "-") { + if( opts[options::replayFilename] == "-") { if( inputFromStdin ) { throw OptionException("Replay file and input file can't both be stdin."); } replayParserBuilder.withStreamInput(cin); } replayParser = replayParserBuilder.build(); - options.replayStream = new Parser::ExprStream(replayParser); + opts.set(options::replayStream, new Parser::ExprStream(replayParser)); } - if( options.replayLog != NULL ) { - *options.replayLog << Expr::setlanguage(options.outputLanguage) << Expr::setdepth(-1); + if( opts[options::replayLog] != NULL ) { + *opts[options::replayLog] << Expr::setlanguage(opts[options::outputLanguage]) << Expr::setdepth(-1); } // signal handlers need access pStatistics = smt.getStatisticsRegistry(); + exprMgr.getStatisticsRegistry()->setName("ExprManager"); pStatistics->registerStat_(exprMgr.getStatisticsRegistry()); + pStatistics->registerStat_(&driverStats); // Timer statistic - RegisterStatistic statTotalTime(exprMgr, &s_totalTime); + RegisterStatistic statTotalTime(&driverStats, &s_totalTime); // Filename statistics ReferenceStat< const char* > s_statFilename("filename", filename); - RegisterStatistic statFilenameReg(exprMgr, &s_statFilename); + RegisterStatistic statFilenameReg(&driverStats, &s_statFilename); // Parse and execute commands until we are done Command* cmd; bool status = true; - if( options.interactive ) { - InteractiveShell shell(exprMgr, options); + if( opts[options::interactive] ) { + InteractiveShell shell(exprMgr, opts); Message() << Configuration::getPackageName() << " " << Configuration::getVersionString(); if(Configuration::isSubversionBuild()) { @@ -268,11 +274,11 @@ int runCvc4(int argc, char* argv[], Options& options) { replayParser->useDeclarationsFrom(shell.getParser()); } while((cmd = shell.readCommand())) { - status = doCommand(smt,cmd, options) && status; + status = doCommand(smt,cmd, opts) && status; delete cmd; } } else { - ParserBuilder parserBuilder(&exprMgr, filename, options); + ParserBuilder parserBuilder(&exprMgr, filename, opts); if( inputFromStdin ) { #if defined(CVC4_COMPETITION_MODE) && !defined(CVC4_SMTCOMP_APPLICATION_TRACK) @@ -292,23 +298,23 @@ int runCvc4(int argc, char* argv[], Options& options) { delete cmd; break; } - status = doCommand(smt, cmd, options) && status; + status = doCommand(smt, cmd, opts) && status; delete cmd; } // Remove the parser delete parser; } - if( options.replayStream != NULL ) { + if( opts[options::replayStream] != NULL ) { // this deletes the expression parser too - delete options.replayStream; - options.replayStream = NULL; + delete opts[options::replayStream]; + opts.set(options::replayStream, NULL); } int returnValue; string result = "unknown"; if(status) { - result = smt.getInfo(":status").getValue(); + result = smt.getInfo("status").getValue(); if(result == "sat") { returnValue = 10; @@ -329,20 +335,20 @@ int runCvc4(int argc, char* argv[], Options& options) { #endif /* CVC4_COMPETITION_MODE */ ReferenceStat< Result > s_statSatResult("sat/unsat", result); - RegisterStatistic statSatResultReg(exprMgr, &s_statSatResult); + RegisterStatistic statSatResultReg(&driverStats, &s_statSatResult); s_totalTime.stop(); - if(options.statistics) { - pStatistics->flushInformation(*options.err); + if(opts[options::statistics]) { + pStatistics->flushInformation(*opts[options::err]); } return returnValue; } /** Executes a command. Deletes the command after execution. */ -static bool doCommand(SmtEngine& smt, Command* cmd, Options& options) { - if( options.parseOnly ) { +static bool doCommand(SmtEngine& smt, Command* cmd, Options& opts) { + if( opts[options::parseOnly] ) { return true; } @@ -354,15 +360,15 @@ static bool doCommand(SmtEngine& smt, Command* cmd, Options& options) { for(CommandSequence::iterator subcmd = seq->begin(); subcmd != seq->end(); ++subcmd) { - status = doCommand(smt, *subcmd, options) && status; + status = doCommand(smt, *subcmd, opts) && status; } } else { - if(options.verbosity > 0) { - *options.out << "Invoking: " << *cmd << endl; + if(opts[options::verbosity] > 0) { + *opts[options::out] << "Invoking: " << *cmd << endl; } - if(options.verbosity >= 0) { - cmd->invoke(&smt, *options.out); + if(opts[options::verbosity] >= 0) { + cmd->invoke(&smt, *opts[options::out]); } else { cmd->invoke(&smt); } diff --git a/src/main/driver_portfolio.cpp b/src/main/driver_portfolio.cpp index d93e9f872..648c6c9f9 100644 --- a/src/main/driver_portfolio.cpp +++ b/src/main/driver_portfolio.cpp @@ -40,7 +40,11 @@ #include "expr/command.h" #include "util/Assert.h" #include "util/configuration.h" -#include "util/options.h" +#include "options/options.h" +#include "main/options.h" +#include "smt/options.h" +#include "prop/options.h" +#include "theory/uf/options.h" #include "util/output.h" #include "util/dump.h" #include "util/result.h" @@ -78,7 +82,7 @@ static bool doCommand(SmtEngine&, Command*, Options&); Result doSmt(SmtEngine &smt, Command *cmd, Options &options); template<typename T> -void sharingManager(int numThreads, +void sharingManager(unsigned numThreads, SharedChannel<T>* channelsOut[], SharedChannel<T>* channelsIn[], SmtEngine* smts[]); @@ -122,23 +126,25 @@ public: {} void notifyNewLemma(Expr lemma) { - if(Debug.isOn("disable-lemma-sharing")) return; - const Options *options = Options::current(); - if(options->sharingFilterByLength >= 0) { // 0 would mean no-sharing effectively - if( int(lemma.getNumChildren()) > options->sharingFilterByLength) + if(Debug.isOn("disable-lemma-sharing")) { + return; + } + if(options::sharingFilterByLength() >= 0) { // 0 would mean no-sharing effectively + if(int(lemma.getNumChildren()) > options::sharingFilterByLength()) { return; + } } ++cnt; - Trace("sharing") << d_tag << ": " << lemma << std::endl; + Trace("sharing") << d_tag << ": " << lemma << endl; expr::pickle::Pickle pkl; - try{ + try { d_pickler.toPickle(lemma, pkl); d_sharedChannel->push(pkl); - if(Trace.isOn("showSharing") and options->thread_id == 0) { - *(Options::current()->out) << "thread #0: notifyNewLemma: " << lemma << endl; + if(Trace.isOn("showSharing") && options::thread_id() == 0) { + *options::out() << "thread #0: notifyNewLemma: " << lemma << endl; } - }catch(expr::pickle::PicklingException& p){ - Trace("sharing::blocked") << lemma << std::endl; + } catch(expr::pickle::PicklingException& p){ + Trace("sharing::blocked") << lemma << endl; } } @@ -172,8 +178,8 @@ public: expr::pickle::Pickle pkl = d_sharedChannel->pop(); Expr e = d_pickler.fromPickle(pkl); - if(Trace.isOn("showSharing") and Options::current()->thread_id == 0) { - *(Options::current()->out) << "thread #0: getNewLemma: " << e << endl; + if(Trace.isOn("showSharing") && options::thread_id() == 0) { + *options::out() << "thread #0: getNewLemma: " << e << endl; } return e; } @@ -182,7 +188,7 @@ public: -int runCvc4(int argc, char *argv[], Options& options) { +int runCvc4(int argc, char *argv[], Options& opts) { #ifdef CVC4_CLN_IMP Warning() << "WARNING:" << endl @@ -211,7 +217,7 @@ int runCvc4(int argc, char *argv[], Options& options) { s_beforePortfolioTime.start(); // For the signal handlers' benefit - pOptions = &options; + pOptions = &opts; // Initialize the signal handlers cvc4_init(); @@ -222,36 +228,36 @@ int runCvc4(int argc, char *argv[], Options& options) { /****************************** Options Processing ************************/ // Parse the options - int firstArgIndex = options.parseOptions(argc, argv); + int firstArgIndex = opts.parseOptions(argc, argv); - progName = options.binary_name.c_str(); + progName = opts[options::binary_name].c_str(); - if( options.help ) { - printUsage(options, true); + if( opts[options::help] ) { + printUsage(opts, true); exit(1); - } else if( options.languageHelp ) { - Options::printLanguageHelp(*options.out); + } else if( opts[options::languageHelp] ) { + Options::printLanguageHelp(*opts[options::out]); exit(1); - } else if( options.version ) { - *options.out << Configuration::about().c_str() << flush; + } else if( opts[options::version] ) { + *opts[options::out] << Configuration::about().c_str() << flush; exit(0); } - int numThreads = options.threads; + unsigned numThreads = opts[options::threads]; - if(options.threadArgv.size() > size_t(numThreads)) { + if(opts[options::threadArgv].size() > size_t(numThreads)) { stringstream ss; - ss << "--thread" << (options.threadArgv.size() - 1) + ss << "--thread" << (opts[options::threadArgv].size() - 1) << " configuration string seen but this portfolio will only contain " << numThreads << " thread(s)!"; throw OptionException(ss.str()); } - segvNoSpin = options.segvNoSpin; + segvNoSpin = opts[options::segvNoSpin]; // If in competition mode, set output stream option to flush immediately #ifdef CVC4_COMPETITION_MODE - *options.out << unitbuf; + *opts[options::out] << unitbuf; #endif /* CVC4_COMPETITION_MODE */ // We only accept one input file @@ -264,29 +270,29 @@ int runCvc4(int argc, char *argv[], Options& options) { firstArgIndex >= argc || !strcmp("-", argv[firstArgIndex]); // if we're reading from stdin on a TTY, default to interactive mode - if(!options.interactiveSetByUser) { - options.interactive = inputFromStdin && isatty(fileno(stdin)); + if(!opts.wasSetByUser(options::interactive)) { + opts.set(options::interactive, inputFromStdin && isatty(fileno(stdin))); } // Auto-detect input language by filename extension const char* filename = inputFromStdin ? "<stdin>" : argv[firstArgIndex]; - if(options.inputLanguage == language::input::LANG_AUTO) { + if(opts[options::inputLanguage] == language::input::LANG_AUTO) { if( inputFromStdin ) { // We can't do any fancy detection on stdin - options.inputLanguage = language::input::LANG_CVC4; + opts.set(options::inputLanguage, language::input::LANG_CVC4); } else { unsigned len = strlen(filename); if(len >= 5 && !strcmp(".smt2", filename + len - 5)) { - options.inputLanguage = language::input::LANG_SMTLIB_V2; + opts.set(options::inputLanguage, language::input::LANG_SMTLIB_V2); } else if(len >= 4 && !strcmp(".smt", filename + len - 4)) { - options.inputLanguage = language::input::LANG_SMTLIB; + opts.set(options::inputLanguage, language::input::LANG_SMTLIB); } else if((len >= 2 && !strcmp(".p", filename + len - 2)) || (len >= 5 && !strcmp(".tptp", filename + len - 5))) { - options.inputLanguage = language::input::LANG_TPTP; + opts.set(options::inputLanguage, language::input::LANG_TPTP); } else if(( len >= 4 && !strcmp(".cvc", filename + len - 4) ) || ( len >= 5 && !strcmp(".cvc4", filename + len - 5) )) { - options.inputLanguage = language::input::LANG_CVC4; + opts.set(options::inputLanguage, language::input::LANG_CVC4); } } } @@ -301,54 +307,55 @@ int runCvc4(int argc, char *argv[], Options& options) { Warning.setStream(CVC4::null_os); Dump.setStream(CVC4::null_os); } else { - if(options.verbosity < 2) { + if(opts[options::verbosity] < 2) { Chat.setStream(CVC4::null_os); } - if(options.verbosity < 1) { + if(opts[options::verbosity] < 1) { Notice.setStream(CVC4::null_os); } - if(options.verbosity < 0) { + if(opts[options::verbosity] < 0) { Message.setStream(CVC4::null_os); Warning.setStream(CVC4::null_os); } - OutputLanguage language = language::toOutputLanguage(options.inputLanguage); + OutputLanguage language = language::toOutputLanguage(opts[options::inputLanguage]); Debug.getStream() << Expr::setlanguage(language); Trace.getStream() << Expr::setlanguage(language); Notice.getStream() << Expr::setlanguage(language); Chat.getStream() << Expr::setlanguage(language); Message.getStream() << Expr::setlanguage(language); Warning.getStream() << Expr::setlanguage(language); - Dump.getStream() << Expr::setlanguage(options.outputLanguage) + Dump.getStream() << Expr::setlanguage(language) << Expr::setdepth(-1) << Expr::printtypes(false); } // important even for muzzled builds (to get result output right) - *options.out << Expr::setlanguage(options.outputLanguage); + *opts[options::out] << Expr::setlanguage(opts[options::outputLanguage]); vector<Options> threadOptions; - for(int i = 0; i < numThreads; ++i) { - threadOptions.push_back(options); - Options& opts = threadOptions.back(); + for(unsigned i = 0; i < numThreads; ++i) { + threadOptions.push_back(opts); + Options& tOpts = threadOptions.back(); // Set thread identifier - opts.thread_id = i; + tOpts.set(options::thread_id, i); // If the random-seed is negative, pick a random seed randomly - if(options.satRandomSeed < 0) - opts.satRandomSeed = (double)rand(); + if(opts[options::satRandomSeed] < 0) { + tOpts.set(options::satRandomSeed, (double)rand()); + } - if(i < (int)options.threadArgv.size() && !options.threadArgv[i].empty()) { + if(i < opts[options::threadArgv].size() && !opts[options::threadArgv][i].empty()) { // separate out the thread's individual configuration string stringstream optidss; optidss << "--thread" << i; string optid = optidss.str(); int targc = 1; - char* tbuf = strdup(options.threadArgv[i].c_str()); + char* tbuf = strdup(opts[options::threadArgv][i].c_str()); char* p = tbuf; // string length is certainly an upper bound on size needed - char** targv = new char*[options.threadArgv[i].size()]; + char** targv = new char*[opts[options::threadArgv][i].size()]; char** vp = targv; *vp++ = strdup(optid.c_str()); p = strtok(p, " "); @@ -360,7 +367,7 @@ int runCvc4(int argc, char *argv[], Options& options) { *vp++ = NULL; if(targc > 1) { // this is necessary in case you do e.g. --thread0=" " try { - opts.parseOptions(targc, targv); + tOpts.parseOptions(targc, targv); } catch(OptionException& e) { stringstream ss; ss << optid << ": " << e.getMessage(); @@ -372,7 +379,7 @@ int runCvc4(int argc, char *argv[], Options& options) { << "' in thread configuration " << optid << " !"; throw OptionException(ss.str()); } - if(opts.threads != numThreads || opts.threadArgv != options.threadArgv) { + if(tOpts[options::threads] != numThreads || tOpts[options::threadArgv] != opts[options::threadArgv]) { stringstream ss; ss << "not allowed to set thread options in " << optid << " !"; throw OptionException(ss.str()); @@ -387,16 +394,16 @@ int runCvc4(int argc, char *argv[], Options& options) { // Some more options related stuff /* Use satRandomSeed for generating random numbers, in particular satRandomSeed-s */ - srand((unsigned int)(-options.satRandomSeed)); + srand((unsigned int)(-opts[options::satRandomSeed])); assert(numThreads >= 1); //do we need this? /* Output to string stream */ vector<stringstream*> ss_out(numThreads); - if(options.verbosity == 0 or options.separateOutput) { - for(int i = 0;i <numThreads; ++i) { + if(opts[options::verbosity] == 0 || opts[options::separateOutput]) { + for(unsigned i = 0; i < numThreads; ++i) { ss_out[i] = new stringstream; - threadOptions[i].out = ss_out[i]; + threadOptions[i].set(options::out, ss_out[i]); } } @@ -431,8 +438,8 @@ int runCvc4(int argc, char *argv[], Options& options) { Command* cmd; // bool status = true; // Doesn't seem to be use right now: commenting it out CommandSequence* seq = new CommandSequence(); - if( options.interactive ) { - InteractiveShell shell(*exprMgr, options); + if( opts[options::interactive] ) { + InteractiveShell shell(*exprMgr, opts); Message() << Configuration::getPackageName() << " " << Configuration::getVersionString(); if(Configuration::isSubversionBuild()) { @@ -452,7 +459,7 @@ int runCvc4(int argc, char *argv[], Options& options) { } else { ParserBuilder parserBuilder = ParserBuilder(exprMgr, filename). - withOptions(options); + withOptions(opts); if( inputFromStdin ) { #if defined(CVC4_COMPETITION_MODE) && !defined(CVC4_SMTCOMP_APPLICATION_TRACK) @@ -465,15 +472,16 @@ int runCvc4(int argc, char *argv[], Options& options) { Parser *parser = parserBuilder.build(); while((cmd = parser->nextCommand())) { seq->addCommand(cmd); - // doCommand(smt, cmd, options); + // doCommand(smt, cmd, opts); // delete cmd; } // Remove the parser delete parser; } - if(options.parseOnly) + if(opts[options::parseOnly]) { return 0; + } exprMgr = NULL; // don't want to use that variable // after this point @@ -482,7 +490,7 @@ int runCvc4(int argc, char *argv[], Options& options) { ExprManagerMapCollection* vmaps[numThreads]; // vmaps[0] is generally empty Command *seqs[numThreads]; seqs[0] = seq; seq = NULL; - for(int i = 1; i < numThreads; ++i) { + for(unsigned i = 1; i < numThreads; ++i) { vmaps[i] = new ExprManagerMapCollection(); exprMgrs[i] = new ExprManager(threadOptions[i]); seqs[i] = seqs[0]->exportTo(exprMgrs[i], *(vmaps[i]) ); @@ -515,14 +523,16 @@ int runCvc4(int argc, char *argv[], Options& options) { // Create the SmtEngine(s) SmtEngine *smts[numThreads]; - for(int i = 0; i < numThreads; ++i) { + for(unsigned i = 0; i < numThreads; ++i) { smts[i] = new SmtEngine(exprMgrs[i]); // Register the statistics registry of the thread - string tag = "thread #" + boost::lexical_cast<string>(threadOptions[i].thread_id); - smts[i]->getStatisticsRegistry()->setName(tag); - theStatisticsRegistry.registerStat_( smts[i]->getStatisticsRegistry() ); + string emTag = "ExprManager thread #" + boost::lexical_cast<string>(threadOptions[i][options::thread_id]); + string smtTag = "SmtEngine thread #" + boost::lexical_cast<string>(threadOptions[i][options::thread_id]); + exprMgrs[i]->getStatisticsRegistry()->setName(emTag); + smts[i]->getStatisticsRegistry()->setName(smtTag); theStatisticsRegistry.registerStat_( exprMgrs[i]->getStatisticsRegistry() ); + theStatisticsRegistry.registerStat_( smts[i]->getStatisticsRegistry() ); } /************************* Lemma sharing init ************************/ @@ -532,12 +542,12 @@ int runCvc4(int argc, char *argv[], Options& options) { if(numThreads == 1) { // Disable sharing - threadOptions[0].sharingFilterByLength = 0; + threadOptions[0].set(options::sharingFilterByLength, 0); } else { // Setup sharing channels const unsigned int sharingChannelSize = 1000000; - for(int i = 0; i<numThreads; ++i){ + for(unsigned i = 0; i < numThreads; ++i){ if(Debug.isOn("channel-empty")) { channelsOut[i] = new EmptySharedChannel<channelFormat>(sharingChannelSize); channelsIn[i] = new EmptySharedChannel<channelFormat>(sharingChannelSize); @@ -548,14 +558,14 @@ int runCvc4(int argc, char *argv[], Options& options) { } /* Lemma output channel */ - for(int i = 0; i<numThreads; ++i) { - string tag = "thread #" + boost::lexical_cast<string>(threadOptions[i].thread_id); - threadOptions[i].lemmaOutputChannel = + for(unsigned i = 0; i < numThreads; ++i) { + string tag = "thread #" + boost::lexical_cast<string>(threadOptions[i][options::thread_id]); + threadOptions[i].set(options::lemmaOutputChannel, new PortfolioLemmaOutputChannel(tag, channelsOut[i], exprMgrs[i], - vmaps[i]->d_from, vmaps[i]->d_to); - threadOptions[i].lemmaInputChannel = + vmaps[i]->d_from, vmaps[i]->d_to)); + threadOptions[i].set(options::lemmaInputChannel, new PortfolioLemmaInputChannel(tag, channelsIn[i], exprMgrs[i], - vmaps[i]->d_from, vmaps[i]->d_to); + vmaps[i]->d_from, vmaps[i]->d_to)); } } @@ -564,7 +574,7 @@ int runCvc4(int argc, char *argv[], Options& options) { /* Portfolio */ boost::function<Result()> fns[numThreads]; - for(int i = 0; i < numThreads; ++i) { + for(unsigned i = 0; i < numThreads; ++i) { fns[i] = boost::bind(doSmt, boost::ref(*smts[i]), seqs[i], boost::ref(threadOptions[i])); } @@ -580,7 +590,7 @@ int runCvc4(int argc, char *argv[], Options& options) { /************************* Post printing answer ***********************/ - if(options.printWinner){ + if(opts[options::printWinner]){ cout << "The winner is #" << winner << endl; } @@ -606,29 +616,29 @@ int runCvc4(int argc, char *argv[], Options& options) { // Stop timers, enough work done s_totalTime.stop(); - if(options.statistics) { - pStatistics->flushInformation(*options.err); + if(opts[options::statistics]) { + pStatistics->flushInformation(*opts[options::err]); } - if(options.separateOutput) { - for(int i = 0; i < numThreads; ++i) { - *options.out << "--- Output from thread #" << i << " ---" << endl; - *options.out << ss_out[i]->str(); + if(opts[options::separateOutput]) { + for(unsigned i = 0; i < numThreads; ++i) { + *opts[options::out] << "--- Output from thread #" << i << " ---" << endl; + *opts[options::out] << ss_out[i]->str(); } } - /*if(options.statistics) { + /*if(opts[options::statistics]) { double totalTime = double(s_totalTime.getData().tv_sec) + double(s_totalTime.getData().tv_nsec)/1000000000.0; cout.precision(6); - *options.err << "real time: " << totalTime << "s\n"; - int th0_lemcnt = (*static_cast<PortfolioLemmaOutputChannel*>(options.lemmaOutputChannel)).cnt; + *opts[options::err] << "real time: " << totalTime << "s\n"; + int th0_lemcnt = (*static_cast<PortfolioLemmaOutputChannel*>(opts[options::lemmaOutputChannel])).cnt; int th1_lemcnt = (*static_cast<PortfolioLemmaOutputChannel*>(threadOptions[1].lemmaOutputChannel)).cnt; - *options.err << "lemmas shared by thread #0: " << th0_lemcnt << endl; - *options.err << "lemmas shared by thread #1: " << th1_lemcnt << endl; - *options.err << "sharing rate: " << double(th0_lemcnt+th1_lemcnt)/(totalTime) + *opts[options::err] << "lemmas shared by thread #0: " << th0_lemcnt << endl; + *opts[options::err] << "lemmas shared by thread #1: " << th1_lemcnt << endl; + *opts[options::err] << "sharing rate: " << double(th0_lemcnt+th1_lemcnt)/(totalTime) << " lem/sec" << endl; - *options.err << "winner: #" << (winner == 0 ? 0 : 1) << endl; + *opts[options::err] << "winner: #" << (winner == 0 ? 0 : 1) << endl; }*/ // destruction is causing segfaults, let us just exit @@ -663,23 +673,23 @@ namespace CVC4 { } } -void printUsage(Options& options, bool full) { +void printUsage(Options& opts, bool full) { stringstream ss; - ss << "usage: " << options.binary_name << " [options] [input-file]" << endl + ss << "usage: " << opts[options::binary_name] << " [options] [input-file]" << endl << endl << "Without an input file, or with `-', CVC4 reads from standard input." << endl << endl << "CVC4 options:" << endl; if(full) { - Options::printUsage( ss.str(), *options.out ); + Options::printUsage( ss.str(), *opts[options::out] ); } else { - Options::printShortUsage( ss.str(), *options.out ); + Options::printShortUsage( ss.str(), *opts[options::out] ); } } /** Executes a command. Deletes the command after execution. */ -static bool doCommand(SmtEngine& smt, Command* cmd, Options& options) { - if( options.parseOnly ) { +static bool doCommand(SmtEngine& smt, Command* cmd, Options& opts) { + if( opts[options::parseOnly] ) { return true; } @@ -691,15 +701,15 @@ static bool doCommand(SmtEngine& smt, Command* cmd, Options& options) { for(CommandSequence::iterator subcmd = seq->begin(); subcmd != seq->end(); ++subcmd) { - status = doCommand(smt, *subcmd, options) && status; + status = doCommand(smt, *subcmd, opts) && status; } } else { - if(options.verbosity > 0) { - *options.out << "Invoking: " << *cmd << endl; + if(opts[options::verbosity] > 0) { + *opts[options::out] << "Invoking: " << *cmd << endl; } - if(options.verbosity >= 0) { - cmd->invoke(&smt, *options.out); + if(opts[options::verbosity] >= 0) { + cmd->invoke(&smt, *opts[options::out]); } else { cmd->invoke(&smt); } @@ -712,48 +722,48 @@ static bool doCommand(SmtEngine& smt, Command* cmd, Options& options) { /**** End of code shared with driver.cpp ****/ /** Create the SMT engine and execute the commands */ -Result doSmt(SmtEngine &smt, Command *cmd, Options &options) { +Result doSmt(SmtEngine &smt, Command *cmd, Options &opts) { try { // For the signal handlers' benefit - pOptions = &options; + pOptions = &opts; // Execute the commands - bool status = doCommand(smt, cmd, options); + bool status = doCommand(smt, cmd, opts); - // if(options.statistics) { - // smt.getStatisticsRegistry()->flushInformation(*options.err); - // *options.err << "Statistics printing of my thread complete " << endl; + // if(opts[options::statistics]) { + // smt.getStatisticsRegistry()->flushInformation(*opts[options::err]); + // *opts[options::err] << "Statistics printing of my thread complete " << endl; // } return status ? smt.getStatusOfLastCommand() : Result::SAT_UNKNOWN; } catch(OptionException& e) { - *pOptions->out << "unknown" << endl; + *(*pOptions)[options::out] << "unknown" << endl; cerr << "CVC4 Error:" << endl << e << endl; printUsage(*pOptions); } catch(Exception& e) { #ifdef CVC4_COMPETITION_MODE - *pOptions->out << "unknown" << endl; + *(*pOptions)[options::out] << "unknown" << endl; #endif - *pOptions->err << "CVC4 Error:" << endl << e << endl; - if(pOptions->statistics) { - pStatistics->flushInformation(*pOptions->err); + *(*pOptions)[options::err] << "CVC4 Error:" << endl << e << endl; + if((*pOptions)[options::statistics]) { + pStatistics->flushInformation(*(*pOptions)[options::err]); } } return Result::SAT_UNKNOWN; } template<typename T> -void sharingManager(int numThreads, +void sharingManager(unsigned numThreads, SharedChannel<T> *channelsOut[], // out and in with respect SharedChannel<T> *channelsIn[], SmtEngine *smts[]) // to smt engines { - Trace("sharing") << "sharing: thread started " << std::endl; + Trace("sharing") << "sharing: thread started " << endl; vector <int> cnt(numThreads); // Debug("sharing") vector< queue<T> > queues; - for(int i = 0; i < numThreads; ++i){ + for(unsigned i = 0; i < numThreads; ++i){ queues.push_back(queue<T>()); } @@ -768,7 +778,7 @@ void sharingManager(int numThreads, boost::this_thread::sleep(boost::posix_time::milliseconds(sharingBroadcastInterval)); - for(int t = 0; t < numThreads; ++t) { + for(unsigned t = 0; t < numThreads; ++t) { if(channelsOut[t]->empty()) continue; /* No activity on this channel */ @@ -784,22 +794,22 @@ void sharingManager(int numThreads, << ". Chunk " << cnt[t] << std :: endl; } - for(int u = 0; u < numThreads; ++u) { + for(unsigned u = 0; u < numThreads; ++u) { if(u != t){ - Trace("sharing") << "sharing: adding to queue " << u << std::endl; + Trace("sharing") << "sharing: adding to queue " << u << endl; queues[u].push(data); } }/* end of inner for: broadcast activity */ } /* end of outer for: look for activity */ - for(int t = 0; t < numThreads; ++t){ + for(unsigned t = 0; t < numThreads; ++t){ /* Alert if channel full, so that we increase sharingChannelSize or decrease sharingBroadcastInterval */ Assert(not channelsIn[t]->full()); while(!queues[t].empty() && !channelsIn[t]->full()){ - Trace("sharing") << "sharing: pushing on channel " << t << std::endl; + Trace("sharing") << "sharing: pushing on channel " << t << endl; T data = queues[t].front(); channelsIn[t]->push(data); queues[t].pop(); @@ -807,17 +817,17 @@ void sharingManager(int numThreads, } } /* end of infinite while */ - Trace("interrupt") << "sharing thread interrupted, interrupting all smtEngines" << std::endl; + Trace("interrupt") << "sharing thread interrupted, interrupting all smtEngines" << endl; - for(int t = 0; t < numThreads; ++t) { - Trace("interrupt") << "Interrupting thread #" << t << std::endl; + for(unsigned t = 0; t < numThreads; ++t) { + Trace("interrupt") << "Interrupting thread #" << t << endl; try{ smts[t]->interrupt(); }catch(ModalException &e){ // It's fine, the thread is probably not there. - Trace("interrupt") << "Could not interrupt thread #" << t << std::endl; + Trace("interrupt") << "Could not interrupt thread #" << t << endl; } } - Trace("sharing") << "sharing: Interrupted, exiting." << std::endl; + Trace("sharing") << "sharing: Interrupted, exiting." << endl; } diff --git a/src/main/interactive_shell.cpp b/src/main/interactive_shell.cpp index 03a3a0ae3..443404384 100644 --- a/src/main/interactive_shell.cpp +++ b/src/main/interactive_shell.cpp @@ -33,7 +33,7 @@ #include "parser/input.h" #include "parser/parser.h" #include "parser/parser_builder.h" -#include "util/options.h" +#include "options/options.h" #include "util/language.h" #include <string.h> @@ -85,8 +85,8 @@ static set<string> s_declarations; InteractiveShell::InteractiveShell(ExprManager& exprManager, const Options& options) : - d_in(*options.in), - d_out(*options.out), + d_in(*options[options::in]), + d_out(*options[options::out]), d_options(options), d_quit(false) { ParserBuilder parserBuilder(&exprManager, INPUT_FILENAME, options); @@ -99,7 +99,7 @@ InteractiveShell::InteractiveShell(ExprManager& exprManager, ::rl_completion_entry_function = commandGenerator; ::using_history(); - switch(OutputLanguage lang = toOutputLanguage(d_options.inputLanguage)) { + switch(OutputLanguage lang = toOutputLanguage(d_options[options::inputLanguage])) { case output::LANG_CVC4: d_historyFilename = string(getenv("HOME")) + "/.cvc4_history"; commandsBegin = cvc_commands; @@ -174,7 +174,7 @@ Command* InteractiveShell::readCommand() { /* Prompt the user for input. */ if(d_usingReadline) { #if HAVE_LIBREADLINE - lineBuf = ::readline(d_options.verbosity >= 0 ? "CVC4> " : ""); + lineBuf = ::readline(d_options[options::verbosity] >= 0 ? "CVC4> " : ""); if(lineBuf != NULL && lineBuf[0] != '\0') { ::add_history(lineBuf); } @@ -182,7 +182,7 @@ Command* InteractiveShell::readCommand() { free(lineBuf); #endif /* HAVE_LIBREADLINE */ } else { - if(d_options.verbosity >= 0) { + if(d_options[options::verbosity] >= 0) { d_out << "CVC4> " << flush; } @@ -239,7 +239,7 @@ Command* InteractiveShell::readCommand() { input[n] = '\n'; if(d_usingReadline) { #if HAVE_LIBREADLINE - lineBuf = ::readline(d_options.verbosity >= 0 ? "... > " : ""); + lineBuf = ::readline(d_options[options::verbosity] >= 0 ? "... > " : ""); if(lineBuf != NULL && lineBuf[0] != '\0') { ::add_history(lineBuf); } @@ -247,7 +247,7 @@ Command* InteractiveShell::readCommand() { free(lineBuf); #endif /* HAVE_LIBREADLINE */ } else { - if(d_options.verbosity >= 0) { + if(d_options[options::verbosity] >= 0) { d_out << "... > " << flush; } @@ -262,7 +262,7 @@ Command* InteractiveShell::readCommand() { } } - d_parser->setInput(Input::newStringInput(d_options.inputLanguage, input, INPUT_FILENAME)); + d_parser->setInput(Input::newStringInput(d_options[options::inputLanguage], input, INPUT_FILENAME)); /* There may be more than one command in the input. Build up a sequence. */ diff --git a/src/main/interactive_shell.h b/src/main/interactive_shell.h index 7f17b88d7..214ae0d02 100644 --- a/src/main/interactive_shell.h +++ b/src/main/interactive_shell.h @@ -21,6 +21,7 @@ #include <string> #include "util/language.h" +#include "options/options.h" namespace CVC4 { diff --git a/src/main/main.cpp b/src/main/main.cpp index b90ab433a..70f2783a5 100644 --- a/src/main/main.cpp +++ b/src/main/main.cpp @@ -34,7 +34,8 @@ #include "expr/command.h" #include "util/Assert.h" #include "util/configuration.h" -#include "util/options.h" +#include "main/options.h" +#include "theory/uf/options.h" #include "util/output.h" #include "util/result.h" #include "util/stats.h" @@ -51,22 +52,22 @@ using namespace CVC4::main; * Put everything in runCvc4(). */ int main(int argc, char* argv[]) { - Options options; + Options opts; try { - return runCvc4(argc, argv, options); + return runCvc4(argc, argv, opts); } catch(OptionException& e) { #ifdef CVC4_COMPETITION_MODE - *options.out << "unknown" << endl; + *opts[options::out] << "unknown" << endl; #endif cerr << "CVC4 Error:" << endl << e << endl; - printUsage(options); + printUsage(opts); } catch(Exception& e) { #ifdef CVC4_COMPETITION_MODE - *options.out << "unknown" << endl; + *opts[options::out] << "unknown" << endl; #endif - *options.err << "CVC4 Error:" << endl << e << endl; - if(options.statistics && pStatistics != NULL) { - pStatistics->flushInformation(*options.err); + *opts[options::err] << "CVC4 Error:" << endl << e << endl; + if(opts[options::statistics] && pStatistics != NULL) { + pStatistics->flushInformation(*opts[options::err]); } } exit(1); diff --git a/src/main/main.h b/src/main/main.h index 4df5ccc49..09ba60c94 100644 --- a/src/main/main.h +++ b/src/main/main.h @@ -19,7 +19,7 @@ #include <exception> #include <string> -#include "util/options.h" +#include "options/options.h" #include "util/exception.h" #include "util/stats.h" #include "util/tls.h" diff --git a/src/main/options b/src/main/options new file mode 100644 index 000000000..6defc8642 --- /dev/null +++ b/src/main/options @@ -0,0 +1,38 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module DRIVER "main/options.h" Driver + +common-option version -V --version/ bool + identify this CVC4 binary + +common-option help -h --help/ bool + full command line reference + +common-option - --show-config void :handler CVC4::main::showConfiguration :handler-include "main/options_handlers.h" + show CVC4 static configuration + +option - --show-debug-tags void :handler CVC4::main::showDebugTags :handler-include "main/options_handlers.h" + show all available tags for debugging +option - --show-trace-tags void :handler CVC4::main::showTraceTags :handler-include "main/options_handlers.h" + show all available tags for tracing + +# portfolio options +option printWinner bool + enable printing the winning thread (pcvc4 only) +option - --threadN=string void + configures thread N (0..#threads-1) +option threadArgv std::vector<std::string> +#:includes <vector> <string> + Thread configuration (a string to be passed to parseOptions) +option thread_id int :default -1 + Thread ID, for internal use in case of multi-threaded run +option separateOutput bool :default false + In multi-threaded setting print output of each thread at the + end of run, separated by a divider ("----"). +option sharingFilterByLength --filter-lemma-length=N int :default -1 :read-write + don't share lemmas strictly longer than N + +endmodule diff --git a/src/main/options_handlers.h b/src/main/options_handlers.h new file mode 100644 index 000000000..e607e13ce --- /dev/null +++ b/src/main/options_handlers.h @@ -0,0 +1,101 @@ +/********************* */ +/*! \file options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Custom handlers and predicates for main driver options + ** + ** Custom handlers and predicates for main driver options. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__MAIN__OPTIONS_HANDLERS_H +#define __CVC4__MAIN__OPTIONS_HANDLERS_H + +namespace CVC4 { +namespace main { + +inline void showConfiguration(std::string option, SmtEngine* smt) { + fputs(Configuration::about().c_str(), stdout); + printf("\n"); + printf("version : %s\n", Configuration::getVersionString().c_str()); + if(Configuration::isSubversionBuild()) { + printf("subversion : yes [%s r%u%s]\n", + Configuration::getSubversionBranchName(), + Configuration::getSubversionRevision(), + Configuration::hasSubversionModifications() ? + " (with modifications)" : ""); + } else { + printf("subversion : %s\n", Configuration::isSubversionBuild() ? "yes" : "no"); + } + printf("\n"); + printf("library : %u.%u.%u\n", + Configuration::getVersionMajor(), + Configuration::getVersionMinor(), + Configuration::getVersionRelease()); + printf("\n"); + printf("debug code : %s\n", Configuration::isDebugBuild() ? "yes" : "no"); + printf("statistics : %s\n", Configuration::isStatisticsBuild() ? "yes" : "no"); + printf("replay : %s\n", Configuration::isReplayBuild() ? "yes" : "no"); + printf("tracing : %s\n", Configuration::isTracingBuild() ? "yes" : "no"); + printf("dumping : %s\n", Configuration::isDumpingBuild() ? "yes" : "no"); + printf("muzzled : %s\n", Configuration::isMuzzledBuild() ? "yes" : "no"); + printf("assertions : %s\n", Configuration::isAssertionBuild() ? "yes" : "no"); + printf("proof : %s\n", Configuration::isProofBuild() ? "yes" : "no"); + printf("coverage : %s\n", Configuration::isCoverageBuild() ? "yes" : "no"); + printf("profiling : %s\n", Configuration::isProfilingBuild() ? "yes" : "no"); + printf("competition: %s\n", Configuration::isCompetitionBuild() ? "yes" : "no"); + printf("\n"); + printf("cudd : %s\n", Configuration::isBuiltWithCudd() ? "yes" : "no"); + printf("cln : %s\n", Configuration::isBuiltWithCln() ? "yes" : "no"); + printf("gmp : %s\n", Configuration::isBuiltWithGmp() ? "yes" : "no"); + printf("tls : %s\n", Configuration::isBuiltWithTlsSupport() ? "yes" : "no"); + exit(0); +} + +inline void showDebugTags(std::string option, SmtEngine* smt) { + if(Configuration::isDebugBuild() && Configuration::isTracingBuild()) { + printf("available tags:"); + unsigned ntags = Configuration::getNumDebugTags(); + char const* const* tags = Configuration::getDebugTags(); + for(unsigned i = 0; i < ntags; ++ i) { + printf(" %s", tags[i]); + } + printf("\n"); + } else if(! Configuration::isDebugBuild()) { + throw OptionException("debug tags not available in non-debug builds"); + } else { + throw OptionException("debug tags not available in non-tracing builds"); + } + exit(0); +} + +inline void showTraceTags(std::string option, SmtEngine* smt) { + if(Configuration::isTracingBuild()) { + printf("available tags:"); + unsigned ntags = Configuration::getNumTraceTags(); + char const* const* tags = Configuration::getTraceTags(); + for (unsigned i = 0; i < ntags; ++ i) { + printf(" %s", tags[i]); + } + printf("\n"); + } else { + throw OptionException("trace tags not available in non-tracing build"); + } + exit(0); +} + + +}/* CVC4::main namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__MAIN__OPTIONS_HANDLERS_H */ diff --git a/src/main/portfolio.cpp b/src/main/portfolio.cpp index fc22374cf..10c387b14 100644 --- a/src/main/portfolio.cpp +++ b/src/main/portfolio.cpp @@ -25,7 +25,7 @@ #include "smt/smt_engine.h" #include "util/result.h" -#include "util/options.h" +#include "options/options.h" using namespace boost; diff --git a/src/main/portfolio.h b/src/main/portfolio.h index 9bc911be3..1a82d651b 100644 --- a/src/main/portfolio.h +++ b/src/main/portfolio.h @@ -25,7 +25,7 @@ #include "smt/smt_engine.h" #include "expr/command.h" -#include "util/options.h" +#include "options/options.h" namespace CVC4 { diff --git a/src/main/util.cpp b/src/main/util.cpp index 5877704ae..756c7d7a9 100644 --- a/src/main/util.cpp +++ b/src/main/util.cpp @@ -27,7 +27,7 @@ #include "util/Assert.h" #include "util/exception.h" -#include "util/options.h" +#include "options/options.h" #include "util/stats.h" #include "cvc4autoconfig.h" @@ -52,7 +52,7 @@ bool segvNoSpin = false; /** Handler for SIGXCPU, i.e., timeout. */ void timeout_handler(int sig, siginfo_t* info, void*) { fprintf(stderr, "CVC4 interrupted by timeout.\n"); - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } abort(); @@ -61,7 +61,7 @@ void timeout_handler(int sig, siginfo_t* info, void*) { /** Handler for SIGINT, i.e., when the user hits control C. */ void sigint_handler(int sig, siginfo_t* info, void*) { fprintf(stderr, "CVC4 interrupted by user.\n"); - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } abort(); @@ -86,7 +86,7 @@ void segv_handler(int sig, siginfo_t* info, void* c) { if(segvNoSpin) { fprintf(stderr, "No-spin requested, aborting...\n"); - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } abort(); @@ -106,7 +106,7 @@ void segv_handler(int sig, siginfo_t* info, void* c) { } else if(addr < 10*1024) { cerr << "Looks like a NULL pointer was dereferenced." << endl; } - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } abort(); @@ -119,7 +119,7 @@ void ill_handler(int sig, siginfo_t* info, void*) { fprintf(stderr, "CVC4 executed an illegal instruction in DEBUG mode.\n"); if(segvNoSpin) { fprintf(stderr, "No-spin requested, aborting...\n"); - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } abort(); @@ -132,7 +132,7 @@ void ill_handler(int sig, siginfo_t* info, void*) { } #else /* CVC4_DEBUG */ fprintf(stderr, "CVC4 executed an illegal instruction.\n"); - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } abort(); @@ -156,7 +156,7 @@ void cvc4unexpected() { } if(segvNoSpin) { fprintf(stderr, "No-spin requested.\n"); - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } set_terminate(default_terminator); @@ -169,7 +169,7 @@ void cvc4unexpected() { } #else /* CVC4_DEBUG */ fprintf(stderr, "CVC4 threw an \"unexpected\" exception.\n"); - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } set_terminate(default_terminator); @@ -182,7 +182,7 @@ void cvc4terminate() { "CVC4 was terminated by the C++ runtime.\n" "Perhaps an exception was thrown during stack unwinding. " "(Don't do that.)\n"); - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } default_terminator(); @@ -190,7 +190,7 @@ void cvc4terminate() { fprintf(stderr, "CVC4 was terminated by the C++ runtime.\n" "Perhaps an exception was thrown during stack unwinding.\n"); - if(pOptions->statistics && pStatistics != NULL) { + if((*pOptions)[options::statistics] && pStatistics != NULL) { pStatistics->flushInformation(cerr); } default_terminator(); diff --git a/src/options/Makefile b/src/options/Makefile new file mode 100644 index 000000000..54a46191d --- /dev/null +++ b/src/options/Makefile @@ -0,0 +1,4 @@ +topdir = ../.. +srcdir = src/options + +include $(topdir)/Makefile.subdir diff --git a/src/options/Makefile.am b/src/options/Makefile.am new file mode 100644 index 000000000..1f4e991a5 --- /dev/null +++ b/src/options/Makefile.am @@ -0,0 +1,134 @@ +OPTIONS_FILES = \ + options/base_options \ + expr/options \ + theory/booleans/options \ + theory/options \ + theory/bv/options \ + theory/datatypes/options \ + theory/builtin/options \ + theory/arith/options \ + theory/uf/options \ + theory/arrays/options \ + theory/quantifiers/options \ + theory/rewriterules/options \ + prop/options \ + proof/options \ + printer/options \ + smt/options \ + decision/options \ + main/options \ + parser/options + +AM_CPPFLAGS = \ + -D__BUILDING_CVC4LIB \ + -I@srcdir@/../include -I@srcdir@/.. -I@builddir@/.. +AM_CXXFLAGS = -Wall $(FLAG_VISIBILITY_HIDDEN) + +noinst_LTLIBRARIES = liboptions.la + +liboptions_la_SOURCES = \ + options.h \ + base_options_handlers.h + +nodist_liboptions_la_SOURCES = \ + options.cpp \ + options_holder.h \ + $(OPTIONS_FILES:%=../%.cpp) \ + $(OPTIONS_FILES:%=../%.h) +nodist_liboptions_la_OBJECTS = \ + $(patsubst %.cpp,%.lo,$(filter %.cpp,$(nodist_liboptions_la_SOURCES))) + +BUILT_SOURCES = \ + options.cpp \ + options_holder.h \ + base_options.cpp \ + base_options.h \ + ../smt/smt_options.cpp \ + $(OPTIONS_FILES:%=../%.cpp) \ + $(OPTIONS_FILES:%=../%.h) \ + exprs-builts + +DISTCLEANFILES = \ + $(BUILT_SOURCES) \ + options-stamp + +EXTRA_DIST = \ + mkoptions \ + base_options \ + base_options_template.h \ + base_options_template.cpp \ + options_template.cpp \ + options_holder_template.h \ + options.i \ + $(OPTIONS_FILES:%=../%) + +if CVC4_DEBUG +# listing Debug_tags too ensures that make doesn't auto-remove it +# after building (if it does, we don't get the "cached" effect with +# the .tmp files below, and we have to re-compile and re-link each +# time, even when there are no changes). +BUILT_SOURCES += \ + Debug_tags.h \ + Debug_tags +endif +if CVC4_TRACING +# listing Trace_tags too ensures that make doesn't auto-remove it +# after building (if it does, we don't get the "cached" effect with +# the .tmp files below, and we have to re-compile and re-link each +# time, even when there are no changes). +BUILT_SOURCES += \ + Trace_tags.h \ + Trace_tags +endif +%_tags.h: %_tags + $(AM_V_GEN)( \ + echo 'static char const* const $^[] = {'; \ + for tag in `cat $^`; do \ + echo "\"$$tag\","; \ + done; \ + echo 'NULL'; \ + echo '};' \ + ) >"$@" + +# This .tmp business is to keep from having to re-compile options.cpp +# (and then re-link the libraries) if nothing has changed. +%_tags: %_tags.tmp + $(AM_V_GEN)\ + diff -q "$^" "$@" &>/dev/null || mv "$^" "$@" || true +# .PHONY ensures the .tmp version is always rebuilt (to check for any changes) +.PHONY: Debug_tags.tmp Trace_tags.tmp +# The "sed" invocation below is particularly obnoxious, but it works around +# inconsistencies in REs on different platforms, using only a basic regular +# expression (no |, no \<, ...). +Debug_tags.tmp Trace_tags.tmp: + $(AM_V_GEN)\ + grep '\<$(@:_tags.tmp=) *( *\".*\" *)' \ + `find @srcdir@/../ -name "*.cpp" -or -name "*.h" -or -name "*.cc" -or -name "*.g"` | \ + sed 's/^$(@:_tags.tmp=) *( *\"\([^"]*\)\".*/\1/;s/.*[^a-zA-Z0-9_]$(@:_tags.tmp=) *( *\"\([^"]*\)\".*/\1/' | sort | uniq >"$@" + +MOSTLYCLEANFILES = \ + Debug_tags \ + Trace_tags \ + Debug_tags.tmp \ + Trace_tags.tmp \ + Debug_tags.h \ + Trace_tags.h + +options_holder.h options.cpp ../smt/smt_options.cpp base_options.cpp base_options.h $(OPTIONS_FILES:%=../%.cpp) $(OPTIONS_FILES:%=../%.h): options-stamp +options-stamp: options_holder_template.h options_template.cpp ../smt/smt_options_template.cpp base_options_template.h base_options_template.cpp mkoptions $(OPTIONS_FILES:%=../%) + $(AM_V_at)chmod +x @srcdir@/mkoptions + $(AM_V_GEN)(@srcdir@/mkoptions \ + @srcdir@/options_holder_template.h @srcdir@/options_holder.h \ + @srcdir@/options_template.cpp @srcdir@/options.cpp \ + @srcdir@/../smt/smt_options_template.cpp @srcdir@/../smt/smt_options.cpp \ + @top_builddir@/doc/cvc4.1_template @top_builddir@/doc/cvc4.1 \ + -t \ + @srcdir@/base_options_template.h @srcdir@/base_options_template.cpp \ + $(foreach o,$(OPTIONS_FILES),"$(srcdir)/../$(o)" "$(dir $(srcdir)/../$(o))") \ + ) + touch "$@" + +base_options $(OPTIONS_FILES:%=../%):; + +.PHONY: exprs-builts +exprs-builts:; $(AM_V_at)[ "$(FROM_EXPR)" != 1 ] && $(MAKE) -C ../expr builts || true diff --git a/src/options/base_options b/src/options/base_options new file mode 100644 index 000000000..10ad564e6 --- /dev/null +++ b/src/options/base_options @@ -0,0 +1,110 @@ +# +# Option specification file for CVC4 +# +# This is essentially a shell script interpreted with special commands. +# +# Lines starting with whitespace are special. They are passed in their entirety (minus +# the first whitespace char) to the "doc" command. Lines starting with a single slash +# are stripped of this initial character and interpreted by the "doc-alt" command. A period +# "." in the first column of a line, followed optionally by whitespace but without any other +# content on the line, is interpreted as an empty string passed to doc. (This allows +# multi-paragraph documentation for options.) Lines may be continued with a backslash (\) +# at the end of a line. +# +# commands are: +# +# module ID "include-file" name +# +# Identifies the module. Must be the first command in the file. ID is a suitable +# identifier for a preprocessor definition, and should be unique; name is a "pretty" +# name used for the benefit of the end CVC4 user in, e.g., option listings. +# +# common-option SPECIFICATION +# option SPECIFICATION +# expert-option SPECIFICATION +# undocumented-option SPECIFICATION +# +# These commands declare (respectively) common options presented first to the user, +# standard options that the user might want to see with "--help" documentation, +# expert options that should be marked as expert-only, and options that should not +# appear in normal option documentation (even if documentation is included here). +# +# SPECIFICATIONs take this form: +# +# SPECIFICATION ::= (internal-name | -) [-short-option/-alternate-short-option] [--long-option/--alternate-long-option] [smt-option-name] C++-type [ATTRIBUTEs...] +# ATTRIBUTE ::= :include include-files.. +# | :default C++-expression +# | :handler custom-option-handlers.. +# | :handler-include include-files.. +# | :read-only +# | :read-write +# | :link linked-options.. +# +# alias smt-option-name = (smt-option-name[=argument])+ +# alias (-short-option | --long-option) = (-option[=argument] | --long-option[=argument])+ +# +# The alias command creates a new SmtEngine option name, or short option, or long option, +# and binds it to act the same way as if the options to the right of "=" were passed. +# For example, if there are options to --disable-warning-1 and --disable-warning-2, etc., +# a useful alias might be: +# +# alias --disable-all-warnings = --disable-warning-1 --disable-warning-2 +# +# Aliases cannot take arguments, and command-line aliases cannot set SmtEngine properties, +# and SmtEngine aliases cannot set command-line properties. For these things, you need a +# custom handler. +# +# warning message +# +# Warn about something during processing (like a FIXME). +# +# endmodule +# +# This file should end with the "endmodule" command, and nothing should follow it. +# + +module BASE "options/base_options.h" Base + +option binary_name std::string + +option in std::istream* :default &std::cin :include <iostream> +option out std::ostream* :default &std::cout :include <iostream> +option err std::ostream* :default &std::cerr :include <iostream> + +common-option inputLanguage -L --lang=LANG InputLanguage :handler CVC4::options::stringToInputLanguage :include "util/language.h" :default language::input::LANG_AUTO :read-write + force input language (default is "auto"; see --lang help) +common-option outputLanguage --output-lang=LANG OutputLanguage :handler CVC4::options::stringToOutputLanguage :include "util/language.h" :default language::output::LANG_AUTO :read-write + force input language (default is "auto"; see --lang help) +option languageHelp bool + +option verbosity verbosity int :read-write :default 0 + the verbosity level of CVC4 +common-option - -v --verbose void :handler CVC4::options::increaseVerbosity + increase verbosity (may be repeated) +common-option - -q --quiet void :handler CVC4::options::decreaseVerbosity + decrease verbosity (may be repeated) + +common-option statistics stats --stats bool + give statistics on exit + +common-option parseOnly parse-only --parse-only bool :read-write + exit after parsing input + +common-option preprocessOnly preprocess-only --preprocess-only bool + exit after preprocessing input + +option segvNoSpin --segv-nospin bool + don't spin on segfault waiting for gdb + +option - -t --trace=TAG argument :handler CVC4::options::addTraceTag + trace something (e.g. -t pushpop), can repeat +option - -d --debug=TAG argument :handler CVC4::options::addDebugTag + debug something (e.g. -d arith), can repeat + +option printSuccess print-success --print-success bool :predicate CVC4::options::setPrintSuccess :predicate-include "options/base_options_handlers.h" + print the "success" output required of SMT-LIBv2 + +alias --smtlib2 = --lang=smt2 --output-lang=smt2 --strict-parsing --default-expr-depth=-1 --print-success + SMT-LIBv2 compliance mode (implies other options) + +endmodule diff --git a/src/options/base_options_handlers.h b/src/options/base_options_handlers.h new file mode 100644 index 000000000..5f82280da --- /dev/null +++ b/src/options/base_options_handlers.h @@ -0,0 +1,173 @@ +/********************* */ +/*! \file base_options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#ifndef __CVC4__BASE_OPTIONS_HANDLERS_H +#define __CVC4__BASE_OPTIONS_HANDLERS_H + +#include <iostream> +#include <string> +#include <sstream> + +#include "expr/command.h" + +namespace CVC4 { +namespace options { + +inline void increaseVerbosity(std::string option, SmtEngine* smt) { + options::verbosity.set(options::verbosity() + 1); +} + +inline void decreaseVerbosity(std::string option, SmtEngine* smt) { + options::verbosity.set(options::verbosity() - 1); +} + +inline OutputLanguage stringToOutputLanguage(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { + if(optarg == "cvc4" || optarg == "pl") { + return language::output::LANG_CVC4; + } else if(optarg == "smtlib" || optarg == "smt") { + return language::output::LANG_SMTLIB; + } else if(optarg == "smtlib2" || optarg == "smt2") { + return language::output::LANG_SMTLIB_V2; + } else if(optarg == "tptp") { + return language::output::LANG_TPTP; + } else if(optarg == "ast") { + return language::output::LANG_AST; + } else if(optarg == "auto") { + return language::output::LANG_AUTO; + } + + if(optarg != "help") { + throw OptionException(std::string("unknown language for --output-lang: `") + + optarg + "'. Try --output-lang help."); + } + + options::languageHelp.set(true); + return language::output::LANG_AUTO; +} + +inline InputLanguage stringToInputLanguage(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { + if(optarg == "cvc4" || optarg == "pl" || optarg == "presentation") { + return language::input::LANG_CVC4; + } else if(optarg == "smtlib" || optarg == "smt") { + return language::input::LANG_SMTLIB; + } else if(optarg == "smtlib2" || optarg == "smt2") { + return language::input::LANG_SMTLIB_V2; + } else if(optarg == "tptp") { + return language::input::LANG_TPTP; + } else if(optarg == "auto") { + return language::input::LANG_AUTO; + } + + if(optarg != "help") { + throw OptionException(std::string("unknown language for --lang: `") + + optarg + "'. Try --lang help."); + } + + options::languageHelp.set(true); + return language::input::LANG_AUTO; +} + +inline void addTraceTag(std::string option, std::string optarg, SmtEngine* smt) { + if(Configuration::isTracingBuild()) { + if(!Configuration::isTraceTag(optarg.c_str())) + throw OptionException(std::string("trace tag ") + optarg + + std::string(" not available")); + } else { + throw OptionException("trace tags not available in non-tracing builds"); + } + Trace.on(optarg); +} + +inline void addDebugTag(std::string option, std::string optarg, SmtEngine* smt) { + if(Configuration::isDebugBuild() && Configuration::isTracingBuild()) { + if(!Configuration::isDebugTag(optarg.c_str()) && + !Configuration::isTraceTag(optarg.c_str())) { + throw OptionException(std::string("debug tag ") + optarg + + std::string(" not available")); + } + } else if(! Configuration::isDebugBuild()) { + throw OptionException("debug tags not available in non-debug builds"); + } else { + throw OptionException("debug tags not available in non-tracing builds"); + } + Debug.on(optarg); + Trace.on(optarg); +} + +inline void setPrintSuccess(std::string option, bool value, SmtEngine* smt) { + Debug.getStream() << Command::printsuccess(value); + Trace.getStream() << Command::printsuccess(value); + Notice.getStream() << Command::printsuccess(value); + Chat.getStream() << Command::printsuccess(value); + Message.getStream() << Command::printsuccess(value); + Warning.getStream() << Command::printsuccess(value); + *options::out() << Command::printsuccess(value); +} + +template <template <class U> class Cmp> +class comparator { + long d_lbound; + double d_dbound; + bool d_hasLbound; + +public: + comparator(long l) throw() : d_lbound(l), d_dbound(0.0), d_hasLbound(true) {} + comparator(double d) throw() : d_lbound(0), d_dbound(d), d_hasLbound(false) {} + + template <class T> + void operator()(std::string option, const T& value, SmtEngine* smt) { + if((d_hasLbound && !(Cmp<T>()(value, T(d_lbound)))) || + (!d_hasLbound && !(Cmp<T>()(value, T(d_dbound))))) { + std::stringstream ss; + ss << option << ": " << value << " is not a legal setting"; + throw OptionException(ss.str()); + } + } +};/* class comparator */ + +struct greater : public comparator<std::greater> { + greater(long l) throw() : comparator<std::greater>(l) {} + greater(double d) throw() : comparator<std::greater>(d) {} +};/* struct greater */ + +struct greater_equal : public comparator<std::greater_equal> { + greater_equal(long l) throw() : comparator<std::greater_equal>(l) {} + greater_equal(double d) throw() : comparator<std::greater_equal>(d) {} +};/* struct greater_equal */ + +struct less : public comparator<std::less> { + less(long l) throw() : comparator<std::less>(l) {} + less(double d) throw() : comparator<std::less>(d) {} +};/* struct less */ + +struct less_equal : public comparator<std::less_equal> { + less_equal(long l) throw() : comparator<std::less_equal>(l) {} + less_equal(double d) throw() : comparator<std::less_equal>(d) {} +};/* struct less_equal */ + +struct not_equal : public comparator<std::not_equal_to> { + not_equal(long l) throw() : comparator<std::not_equal_to>(l) {} + not_equal(double d) throw() : comparator<std::not_equal_to>(d) {} +};/* struct not_equal_to */ + +}/* CVC4::options namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__BASE_OPTIONS_HANDLERS_H */ + diff --git a/src/options/base_options_template.cpp b/src/options/base_options_template.cpp new file mode 100644 index 000000000..97d747652 --- /dev/null +++ b/src/options/base_options_template.cpp @@ -0,0 +1,35 @@ +/********************* */ +/*! \file base_options_template.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Contains code for handling command-line options. + ** + ** Contains code for handling command-line options + **/ + +#include "options/options_holder.h" + +namespace CVC4 { + +${module_accessors} + +#line 26 "${template}" + +namespace options { + +${module_global_definitions} + +#line 32 "${template}" + +}/* CVC4::options namespace */ + +}/* CVC4 namespace */ diff --git a/src/options/base_options_template.h b/src/options/base_options_template.h new file mode 100644 index 000000000..211cb866a --- /dev/null +++ b/src/options/base_options_template.h @@ -0,0 +1,55 @@ +/********************* */ +/*! \file base_options_template.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Contains code for handling command-line options. + ** + ** Contains code for handling command-line options + **/ + +#ifndef __CVC4__OPTIONS__${module_id}_H +#define __CVC4__OPTIONS__${module_id}_H + +#include "options/options.h" +${module_includes} + +#line 26 "${template}" + +${module_optionholder_spec} + +#line 30 "${template}" + +namespace CVC4 { + +namespace options { + +${module_decls} + +#line 38 "${template}" + +}/* CVC4::options namespace */ + +${module_specializations} + +#line 44 "${template}" + +namespace options { + +${module_inlines} + +#line 50 "${template}" + +}/* CVC4::options namespace */ + +}/* CVC4 namespace */ + +#endif /* __CVC4__OPTIONS__${module_id}_H */ diff --git a/src/options/mkoptions b/src/options/mkoptions new file mode 100755 index 000000000..2bfd6a2d9 --- /dev/null +++ b/src/options/mkoptions @@ -0,0 +1,1260 @@ +#!/bin/bash +# +# mkoptions +# Morgan Deters <mdeters@cs.nyu.edu> for CVC4 +# Copyright (c) 2011 The CVC4 Project +# +# The purpose of this script is to create options.{h,cpp} +# from template files and a list of options. +# +# Invocation: +# +# mkoptions (template-file output-file)+ -t options.h-template options.cpp-template (options-file output-dir)+ +# + +copyright=2011 + +me=$(basename "$0") + +function usage { + echo "usage: $me (template-file output-file)+ -t options.h-template options.cpp-template (options-file output-dir)+" >&2 +} + +declare -a templates +declare -a outputs + +while [ "$1" != -t ]; do + if [ "$#" -lt 2 ]; then + echo "$me: error: expected -t on command line" >&2 + usage + exit 1 + fi + templates[${#templates[@]}]="$1"; shift + if [ "$1" = -t ]; then + echo "$me: error: mismatched number of templates and output files (before -t)" >&2 + usage + exit 1 + fi + outputs[${#outputs[@]}]="$1"; shift +done + +shift +if [ "$#" -lt 3 ]; then + echo "$me: error: not enough arguments" >&2 + usage + exit 1 +fi + +options_h_template="$1"; shift +options_cpp_template="$1"; shift + +all_modules_defaults= +all_modules_short_options= +all_modules_long_options= +all_modules_option_handlers= +smt_getoption_handlers= +smt_setoption_handlers= +include_all_option_headers= +all_modules_contributions= +option_handler_includes= +all_custom_handlers= +common_documentation= +remaining_documentation= +common_manpage_documentation= +remaining_manpage_documentation= + +seen_module=false +seen_endmodule=false +expect_doc=false +expect_doc_alternate=false +n_long=256 + +internal= +smtname= +short_option= +short_option_alternate= +long_option= +long_option_alternate= +long_option_alternate_set= +type= +predicates= + +# just for duplicates-checking +all_declared_internal_options= +all_declared_long_options= +all_declared_short_options= +all_declared_smt_options= + +long_option_value_begin=$n_long + +function module { + # module id name + + module_id= + module_name= + module_includes= + module_optionholder_spec= + module_decls= + module_specializations= + module_inlines= + module_accessors= + module_global_definitions= + + seen_module=true + if [ $# -lt 3 -o -z "$1" -o -z "$2" -o -z "$3" ]; then + echo "$kf:$lineno: error: \"module\" directive requires exactly three arguments" >&2 + exit 1 + fi + + module_id="$1"; shift + include="$1"; shift + module_name="$@" + include_all_option_headers="${include_all_option_headers} +#line $lineno \"$kf\" +#include $(check_include "$include")" + all_modules_contributions="${all_modules_contributions} + CVC4_OPTIONS__${module_id}__FOR_OPTION_HOLDER" + module_optionholder_spec="#define CVC4_OPTIONS__${module_id}__FOR_OPTION_HOLDER" + + remaining_documentation="${remaining_documentation}\\n\\n\" +#line $lineno \"$kf\" +\"$module_name options:" + remaining_manpage_documentation="${remaining_manpage_documentation} +.SH `echo "$module_name" | tr a-z A-Z` OPTIONS +" +} + +function endmodule { + # endmodule + check_module_seen + check_doc + seen_endmodule=true + if [ $# -ne 0 ]; then + echo "$kf:$lineno: error: endmodule takes no arguments" >&2 + exit 1 + fi +} + +function common-option { + # common-option option-args... + handle_option COMMON "$@" +} + +function option { + # option option-args... + handle_option STANDARD "$@" +} + +function expert-option { + # expert-option option-args... + handle_option EXPERT "$@" +} + +function undocumented-option { + # undocumented-option option-args... + handle_option UNDOCUMENTED "$@" +} + +function handle_option { + check_module_seen + check_doc + + args=("$@") + + category="${args[0]}" + internal="${args[1]}" + smtname= + short_option= + short_option_alternate= + long_option= + long_option_alternate= + long_option_alternate_set= + type= + readOnly=true + required_argument=false + default_value= + handlers= + predicates= + links= + links_alternate= + + options_already_documented=false + alternate_options_already_documented=false + + if [ "$category" = UNDOCUMENTED ]; then + expect_doc=false + else + expect_doc=true + fi + expect_doc_alternate=false + + # scan ahead to see where the type is + type_pos=2 + while [ $(($type_pos+1)) -lt ${#args[@]} ] && ! expr "${args[$(($type_pos+1))]}" : ":" &>/dev/null; do + let ++type_pos + done + + type="${args[$type_pos]}" + + if [ "$type" = argument ]; then + type=void + required_argument=true + fi + + if [ $type_pos -eq 2 ]; then + expect_doc=false + readOnly=false + else + i=2 + while [ $i -lt $type_pos ]; do + if expr "${args[$i]}" : '--' &>/dev/null || expr "${args[$i]}" : '/--' &>/dev/null; then + if [ -n "$long_option" -o -n "$long_option_alternate" ]; then + echo "$kf:$lineno: error: malformed option line for \`$internal': unexpected \`${args[$i]}'" >&2 + exit 1 + fi + long_option="$(echo "${args[$i]}" | sed 's,/.*,,')" + if [ -n "$long_option" ]; then + if ! expr "$long_option" : '--.' &>/dev/null; then + echo "$kf:$option: bad long option \`$long_option': expected something like \`--foo'" >&2 + exit 1 + fi + long_option="$(echo "$long_option" | sed 's,^--,,')" + fi + if expr "${args[$i]}" : '.*/' &>/dev/null; then + long_option_alternate="$(echo "${args[$i]}" | sed 's,[^/]*/,,')" + long_option_alternate_set=set + if [ -n "$long_option_alternate" ]; then + if ! expr "$long_option_alternate" : '--.' &>/dev/null; then + echo "$kf:$option: bad alternate long option \`$long_option_alternate': expected something like \`--foo'" >&2 + exit 1 + fi + long_option_alternate="$(echo "$long_option_alternate" | sed 's,^--,,')" + fi + fi + elif expr "${args[$i]}" : '-' &>/dev/null || expr "${args[$i]}" : '/-' &>/dev/null; then + if [ -n "$short_option" -o -n "$short_option_alternate" -o -n "$long_option" -o -n "$long_option_alternate" ]; then + echo "$kf:$lineno: error: malformed option line for \`$internal': unexpected \`${args[$i]}'" >&2 + exit 1 + fi + short_option="$(echo "${args[$i]}" | sed 's,/.*,,')" + if [ -n "$short_option" ]; then + if ! expr "$short_option" : '-.$' &>/dev/null; then + echo "$kf:$option: bad short option \`$short_option': expected something like \`-x'" >&2 + exit 1 + fi + short_option="$(echo "$short_option" | sed 's,^-,,')" + fi + if expr "${args[$i]}" : '.*/' &>/dev/null; then + short_option_alternate="$(echo "${args[$i]}" | sed 's,[^/]*/,,')" + if expr "$short_option_alternate" : - &>/dev/null; then + if ! expr "$short_option_alternate" : '-.$' &>/dev/null; then + echo "$kf:$option: bad alternate short option \`$short_option_alternate': expected something like \`-x'" >&2 + exit 1 + fi + short_option_alternate="$(echo "$short_option_alternate" | sed 's,^-,,')" + fi + fi + else + if [ -n "$smtname" -o -n "$short_option" -o -n "$short_option_alternate" -o -n "$long_option" -o -n "$long_option_alternate" ]; then + echo "$kf:$lineno: error: malformed option line for \`$internal': unexpected \`${args[$i]}'" >&2 + exit 1 + fi + smtname="${args[$i]}" + fi + let ++i + done + fi + + if [ "$type" = void -a "$internal" != - ]; then + echo "$kf:$lineno: error: $internal cannot be void-typed; use \`-' as the name if its to be void" >&2 + exit 1 + elif [ "$type" != void -a "$internal" = - ]; then + echo "$kf:$lineno: error: cannot use an unnamed option if its type is not void" >&2 + exit 1 + fi + + if [ "$type" = bool -a -n "$long_option$short_option" -a "$category" != UNDOCUMENTED ]; then + if [ -n "$short_option_alternate" -o -n "$long_option_alternate" ]; then + expect_doc_alternate=true + fi + fi + if [ "$type" = bool -a -n "$long_option" -a -z "$long_option_alternate" -a -z "$long_option_alternate_set" ]; then + long_option_alternate="no-$(echo "$long_option" | sed 's,^--,,')" + fi + if [ "$type" != bool -a -n "$short_option_alternate" ]; then + echo "$kf:$lineno: error: cannot use alternate short option -$short_option_alternate for \`$internal' because it's not of bool type" >&2 + exit 1 + elif [ "$type" != bool -a -n "$long_option_alternate" ]; then + echo "$kf:$lineno: error: cannot use alternate long option --$long_option_alternate for \`$internal' because it's not of bool type" >&2 + exit 1 + fi + + # check for duplicates + if [ "$internal" != - ]; then + if echo " $all_declared_internal_options " | grep -q " $internal "; then + echo "$kf:$lineno: error: internal option name \`$internal' previously declared" >&2 + exit 1 + fi + all_declared_internal_options="$all_declared_internal_options $internal" + fi + if [ -n "$long_option" ]; then + if echo " $all_declared_long_options " | grep -q " $long_option "; then + echo "$kf:$lineno: error: long option name \`--$long_option' previously declared" >&2 + exit 1 + fi + all_declared_long_options="$all_declared_long_options $long_option" + fi + if [ -n "$long_option_alternate" ]; then + if echo " $all_declared_long_options " | grep -q " $long_option_alternate "; then + echo "$kf:$lineno: error: long option name \`--$long_option_alternate' previously declared" >&2 + exit 1 + fi + all_declared_long_options="$all_declared_long_options $long_option_alternate" + fi + if [ -n "$short_option" ]; then + if echo " $all_declared_short_options " | grep -q " $short_option "; then + echo "$kf:$lineno: error: short option name \`-$short_option' previously declared" >&2 + exit 1 + fi + all_declared_short_options="$all_declared_short_options $short_option" + fi + if [ -n "$short_option_alternate" ]; then + if echo " $all_declared_short_options " | grep -q " $short_option_alternate "; then + echo "$kf:$lineno: error: short option name \`-$short_option_alternate' previously declared" >&2 + exit 1 + fi + all_declared_short_options="$all_declared_short_options $short_option_alternate" + fi + if [ -n "$smtname" ]; then + if echo " $all_declared_smt_options " | grep -q " $smtname "; then + echo "$kf:$lineno: error: SMT option name \`$smtname' previously declared" >&2 + exit 1 + fi + all_declared_smt_options="$all_declared_smt_options $smtname" + fi + + # parse attributes + i=$(($type_pos+1)) + while [ $i -lt ${#args[@]} ]; do + attribute="${args[$i]}" + case "$attribute" in + :default) + let ++i + default_value="${args[$i]}" + ;; + :handler) + let ++i + if [ -n "$handlers" ]; then + echo "$kf:$lineno: error: cannot specify more than one handler; maybe you want a :handler and a :predicate" >&2 + exit 1 + fi + handlers="${args[$i]}" + ;; + :predicate) + while [ $(($i+1)) -lt ${#args[@]} ] && ! expr "${args[$(($i+1))]}" : ":" &>/dev/null; do + let ++i + predicates="${predicates} ${args[$i]}" + done + ;; + :link) + while [ $(($i+1)) -lt ${#args[@]} ] && ! expr "${args[$(($i+1))]}" : ":" &>/dev/null; do + let ++i + link="${args[$i]}" + if expr "${args[$i]}" : '.*/' &>/dev/null; then + links="${links} $(echo "${args[$i]}" | sed 's,/.*,,')" + links_alternate="${links_alternate} $(echo "${args[$i]}" | sed 's,[^/]*/,,')" + else + links="${links} ${args[$i]}" + links_alternate="${links_alternate} ${args[$i]}" + fi + done + ;; + :include) + while [ $(($i+1)) -lt ${#args[@]} ] && ! expr "${args[$(($i+1))]}" : ":" &>/dev/null; do + let ++i + module_includes="${module_includes} +#line $lineno \"$kf\" +#include $(check_include "${args[$i]}")" + done + ;; + :handler-include|:predicate-include) + while [ $(($i+1)) -lt ${#args[@]} ] && ! expr "${args[$(($i+1))]}" : ":" &>/dev/null; do + let ++i + option_handler_includes="${option_handler_includes} +#line $lineno \"$kf\" +#include $(check_include "${args[$i]}")" + done + ;; + :read-write) + readOnly=false + ;; + :read-only) + readOnly=true + ;; + *) + echo "$kf:$lineno: error in option \`$internal': bad attribute \`$attribute'" >&2 + exit 1 + esac + let ++i + done + + # set up structures + if [ "$internal" != - ]; then + # set up a field in the options_holder + module_optionholder_spec="${module_optionholder_spec} \\ + ${internal}__option_t::type $internal; \\ + bool ${internal}__setByUser__;" + all_modules_defaults="${all_modules_defaults:+${all_modules_defaults},} +#line $lineno \"$kf\" + $internal($default_value), +#line $lineno \"$kf\" + ${internal}__setByUser__(false)" + if $readOnly; then + module_decls="${module_decls} +#line $lineno \"$kf\" +extern struct CVC4_PUBLIC ${internal}__option_t { typedef $type type; type operator()() const; bool wasSetByUser() const; } $internal CVC4_PUBLIC;" + module_inlines="${module_inlines} +#line $lineno \"$kf\" +inline ${internal}__option_t::type ${internal}__option_t::operator()() const { return Options::current()[*this]; } +#line $lineno \"$kf\" +inline bool ${internal}__option_t::wasSetByUser() const { return Options::current().wasSetByUser(*this); } +" + else + module_decls="${module_decls} +#line $lineno \"$kf\" +extern struct CVC4_PUBLIC ${internal}__option_t { typedef $type type; type operator()() const; bool wasSetByUser() const; void set(const type& v); } $internal CVC4_PUBLIC;" + module_inlines="${module_inlines} +#line $lineno \"$kf\" +inline ${internal}__option_t::type ${internal}__option_t::operator()() const { return Options::current()[*this]; } +#line $lineno \"$kf\" +inline bool ${internal}__option_t::wasSetByUser() const { return Options::current().wasSetByUser(*this); } +#line $lineno \"$kf\" +inline void ${internal}__option_t::set(const ${internal}__option_t::type& v) { Options::current().set(*this, v); } +" + module_specializations="${module_specializations} +#line $lineno \"$kf\" +template <> void Options::set(options::${internal}__option_t, const options::${internal}__option_t::type& x);" + module_accessors="${module_accessors} +#line $lineno \"$kf\" +template <> void Options::set(options::${internal}__option_t, const options::${internal}__option_t::type& x) { d_holder->$internal = x; }" + fi + module_global_definitions="${module_global_definitions} +#line $lineno \"$kf\" +struct ${internal}__option_t $internal;" + module_specializations="${module_specializations} +#line $lineno \"$kf\" +template <> const options::${internal}__option_t::type& Options::operator[](options::${internal}__option_t) const; +#line $lineno \"$kf\" +template <> bool Options::wasSetByUser(options::${internal}__option_t) const;" + if [ "$type" = bool ]; then + module_specializations="${module_specializations} +#line $lineno \"$kf\" +template <> void Options::assignBool(options::${internal}__option_t, std::string option, bool value, SmtEngine* smt);" + elif [ "$internal" != - ]; then + module_specializations="${module_specializations} +#line $lineno \"$kf\" +template <> void Options::assign(options::${internal}__option_t, std::string option, std::string value, SmtEngine* smt);" + fi + + module_accessors="${module_accessors} +#line $lineno \"$kf\" +template <> const options::${internal}__option_t::type& Options::operator[](options::${internal}__option_t) const { return d_holder->$internal; } +#line $lineno \"$kf\" +template <> bool Options::wasSetByUser(options::${internal}__option_t) const { return d_holder->${internal}__setByUser__; }" + fi + + if $required_argument || [ "$type" != bool -a "$type" != void ]; then + expect_arg=: + expect_arg_long=required_argument + else + expect_arg= + expect_arg_long=no_argument + fi + cases= + cases_alternate= + if [ -n "$short_option" ]; then + all_modules_short_options="${all_modules_short_options}$short_option$expect_arg" + cases="${cases} + case '$short_option':" + fi + if [ -n "$short_option_alternate" ]; then + all_modules_short_options="${all_modules_short_options}$short_option_alternate$expect_arg" + cases_alternate="${cases_alternate} + case '$short_option_alternate':" + fi + if [ -n "$long_option" ]; then + all_modules_long_options="${all_modules_long_options} + { \"$(echo "$long_option" | sed 's,=.*,,')\", $expect_arg_long, NULL, $n_long }," + cases="${cases} + case $n_long:// --$long_option" + let ++n_long + fi + if [ -n "$long_option_alternate" ]; then + all_modules_long_options="${all_modules_long_options} + { \"$(echo "$long_option_alternate" | sed 's,=.*,,')\", $expect_arg_long, NULL, $n_long }," + cases_alternate="${cases_alternate} + case $n_long:// --$long_option_alternate" + let ++n_long + fi + run_links= + run_links_alternate= + if [ -n "$links" ]; then + for link in $links; do + run_links="$run_links +#line $lineno \"$kf\" + preemptGetopt(extra_argc, extra_argv, \"$link\");" + done + fi + if [ -n "$links_alternate" ]; then + for link in $links_alternate; do + run_links_alternate="$run_links_alternate +#line $lineno \"$kf\" + preemptGetopt(extra_argc, extra_argv, \"$link\");" + done + fi + if [ "$type" = bool -a -n "$cases" -o -n "$cases_alternate" ]; then + run_handlers= + if [ -n "$handlers" ]; then + echo "$kf:$lineno: error: bool-valued options cannot have handlers" >&2 + exit 1 + fi + if [ -n "$predicates" ]; then + for predicate in $predicates; do + run_handlers="$run_handlers +#line $lineno \"$kf\" + $predicate(option, b, smt);" + done + fi + if [ -n "$run_handlers" ]; then + all_custom_handlers="${all_custom_handlers} +#line $lineno \"$kf\" +template <> void runBoolPredicates(options::${internal}__option_t, std::string option, bool b, SmtEngine* smt) { + $run_handlers +}" + fi + fi + if [ -n "$cases" ]; then + if [ "$type" = bool ]; then + all_modules_option_handlers="${all_modules_option_handlers}${cases} +#line $lineno \"$kf\" + assignBool(options::$internal, argv[old_optind == 0 ? 1 : old_optind], true, NULL);$run_links + break; +" + elif [ -n "$expect_arg" -a "$internal" != - ]; then + run_handlers= + if [ -n "$handlers" ]; then + for handler in $handlers; do + run_handlers="$run_handlers +#line $lineno \"$kf\" + $handler(option, optarg, smt);" + done + else + run_handlers=" +#line $lineno \"$kf\" + handleOption<$type>(option, optarg);" + fi + if [ -n "$predicates" ]; then + for predicate in $predicates; do + run_handlers="$run_handlers +#line $lineno \"$kf\" + $predicate(option, retval, smt);" + done + fi + all_custom_handlers="${all_custom_handlers} +#line $lineno \"$kf\" +template <> options::${internal}__option_t::type runHandlerAndPredicates(options::${internal}__option_t, std::string option, std::string optarg, SmtEngine* smt) { +#line $lineno \"$kf\" + options::${internal}__option_t::type retval = $run_handlers +#line $lineno \"$kf\" + return retval; +}" + all_modules_option_handlers="${all_modules_option_handlers}${cases} +#line $lineno \"$kf\" + assign(options::$internal, argv[old_optind == 0 ? 1 : old_optind], optarg, NULL);$run_links + break; +" + elif [ -n "$expect_arg" ]; then + run_handlers= + if [ -n "$predicates" ]; then + echo "$kf:$lineno: error: void-valued options cannot have predicates" >&2 + exit 1 + fi + if [ -n "$handlers" ]; then + for handler in $handlers; do + run_handlers="$run_handlers +#line $lineno \"$kf\" + $handler(argv[old_optind == 0 ? 1 : old_optind], optarg, smt);" + done + fi + all_modules_option_handlers="${all_modules_option_handlers}${cases} +#line $lineno \"$kf\" + $run_handlers$run_links + break; +" + else + run_handlers= + if [ -n "$predicates" ]; then + echo "$kf:$lineno: error: void-valued options cannot have predicates" >&2 + exit 1 + fi + if [ -n "$handlers" ]; then + for handler in $handlers; do + run_handlers="$run_handlers +#line $lineno \"$kf\" + $handler(argv[old_optind == 0 ? 1 : old_optind], smt);" + done + fi + all_modules_option_handlers="${all_modules_option_handlers}${cases} +#line $lineno \"$kf\" + $run_handlers$run_links + break; +" + fi + fi + if [ -n "$cases_alternate" ]; then + if [ "$type" = bool ]; then + all_modules_option_handlers="${all_modules_option_handlers}${cases_alternate} +#line $lineno \"$kf\" + assignBool(options::$internal, argv[old_optind == 0 ? 1 : old_optind], false, NULL);$run_links_alternate + break; +" + else + echo "$kf:$lineno: internal error: expected BOOL-typed option in alternate handler" >&2 + exit 1 + fi + fi + + if [ -n "$smtname" ]; then + if [ "$internal" != - ]; then + smt_getoption_handlers="${smt_getoption_handlers} +#line $lineno \"$kf\" + if(key == \"$smtname\") { +#line $lineno \"$kf\" + stringstream ss; ss << options::$internal(); + return SExpr(ss.str()); + }" + fi + + if [ "$type" = bool ]; then + smt_setoption_handlers="${smt_setoption_handlers} +#line $lineno \"$kf\" + if(key == \"$smtname\") { +#line $lineno \"$kf\" + Options::current().assignBool(options::$internal, \"$smtname\", optarg == \"true\", smt);$run_links + return; + }" + elif [ -n "$expect_arg" -a "$internal" != - ]; then + run_handlers= + if [ -n "$handlers" ]; then + for handler in $handlers; do + run_handlers="$run_handlers +#line $lineno \"$kf\" + $handler(\"$smtname\", value, smt); +" + done + fi + smt_setoption_handlers="${smt_setoption_handlers} +#line $lineno \"$kf\" + if(key == \"$smtname\") { +#line $lineno \"$kf\" + Options::current().assign(options::$internal, \"$smtname\", optarg, smt);$run_links + return; + }" + elif [ -n "$expect_arg" ]; then + run_handlers= + for handler in $handlers; do + run_handlers="$run_handlers +#line $lineno \"$kf\" + $handler(\"$smtname\", value, smt); +" + done + smt_setoption_handlers="${smt_setoption_handlers} +#line $lineno \"$kf\" + if(key == \"$smtname\") { +#line $lineno \"$kf\" + $run_handlers$run_links + return; + }" + else + run_handlers= + for handler in $handlers; do + run_handlers="$run_handlers +#line $lineno \"$kf\" + $handler(\"$smtname\", smt); +" + done + smt_setoption_handlers="${smt_setoption_handlers} +#line $lineno \"$kf\" + if(key == \"$smtname\") { +#line $lineno \"$kf\" + $run_handlers$run_links + return; + }" + fi + fi + + if [ "$type" = bool ]; then + # emit assignBool/assign + all_custom_handlers="${all_custom_handlers} +#line $lineno \"$kf\" +template <> void Options::assignBool(options::${internal}__option_t, std::string option, bool value, SmtEngine* smt) { +#line $lineno \"$kf\" + runBoolPredicates(options::$internal, option, value, smt); +#line $lineno \"$kf\" + d_holder->$internal = value; +#line $lineno \"$kf\" + d_holder->${internal}__setByUser__ = true; +#line $lineno \"$kf\" + Trace(\"options\") << \"user assigned option $internal\" << std::endl; +}" + elif [ -n "$expect_arg" -a "$internal" != - ] && [ -n "$cases" -o "$cases_alternate" -o "$smtname" ]; then + all_custom_handlers="${all_custom_handlers} +#line $lineno \"$kf\" +template <> void Options::assign(options::${internal}__option_t, std::string option, std::string value, SmtEngine* smt) { +#line $lineno \"$kf\" + d_holder->$internal = runHandlerAndPredicates(options::$internal, option, value, smt); +#line $lineno \"$kf\" + d_holder->${internal}__setByUser__ = true; +#line $lineno \"$kf\" + Trace(\"options\") << \"user assigned option $internal\" << std::endl; +}" + fi +} + +function alias { + # alias (smtname | -option) = (smtname [arg] | -option [arg])+ + check_module_seen + check_doc + + category=STANDARD + internal=- + smtname= + short_option= + short_option_alternate= + long_option= + long_option_alternate= + long_option_alternate_set= + type=void + readOnly=true + required_argument=false + default_value= + handlers= + predicates= + links= + links_alternate= + + options_already_documented=false + alternate_options_already_documented=false + + if [ $# -lt 3 ]; then + echo "$kf:$lineno: error: malformed \"alias\" command; expected more arguments" >&2 + exit 1 + fi + options= + while [ $# -gt 0 -a "$1" != = ]; do + options="$options $1" + shift + done + if [ $# -eq 0 ]; then + echo "$kf:$lineno: error: malformed \"alias\" command; expected \`='" >&2 + exit 1 + fi + shift + if [ $# -eq 0 ]; then + echo "$kf:$lineno: error: malformed \"alias\" command; expected more arguments" >&2 + exit 1 + fi + cases= + for option in $options; do + if ! expr "$option" : - &>/dev/null; then + echo "$kf:$lineno: error: alias for SMT options not yet supported" >&2 + exit 1 + fi + if expr "$option" : -- &>/dev/null; then + option="$(echo "$option" | sed 's,--,,')" + all_modules_long_options="${all_modules_long_options} + { \"$(echo "$option" | sed 's,=.*,,')\", no_argument, NULL, $n_long }," + cases="${cases} + case $n_long:// --$option" + let ++n_long + long_option="${long_option:+$long_option | --}$option" + else + if ! expr "$option" : '-.$' &>/dev/null; then + echo "$kf:$lineno: error: expected short option specification, got \`$option'" >&2 + exit 1 + fi + option="$(echo "$option" | sed 's,-,,')" + all_modules_short_options="${all_modules_short_options}$option" + cases="${cases} + case '$option':" + short_option="${short_option:+$short_option | -}$option" + fi + done + while [ $# -gt 0 ]; do + links="$links +#line $lineno \"$kf\" + preemptGetopt(extra_argc, extra_argv, \"$1\");" + shift + done + all_modules_option_handlers="$all_modules_option_handlers$cases$links + break; +" + expect_doc=true + expect_doc_alternate=false +} + +function warning { + # warning message + check_module_seen + check_doc + + echo "$kf:$lineno: warning: $@" >&2 +} + +function doc { + # doc text... + check_module_seen + expect_doc=false + + if [ -z "$short_option" -a -z "$long_option" ]; then + if [ -n "$short_option_alternate" -o -n "$long_option_alternate" ]; then + if [ -n "$smtname" ]; then + expect_doc_alternate=true + else + doc-alternate "$@" + return + fi + fi + fi + + if [ "$category" = UNDOCUMENTED ]; then + return + fi + + if ! $options_already_documented; then + options_already_documented=true + the_opt= + if [ "$long_option" ]; then + the_opt="--$long_option" + if [ "$short_option" ]; then + shortoptarg= + if expr "$the_opt" : '.*=' &>/dev/null; then + shortoptarg="$(echo "$the_opt" | sed 's,[^=]*=, ,')" + fi + the_opt="$the_opt | -$short_option$shortoptarg" + fi + elif [ "$short_option" ]; then + the_opt="-$short_option" + fi + if [ -z "$the_opt" ]; then + # nothing to document + return + fi + + the_doc="$@" + if [ "$category" = EXPERT ]; then + the_doc="$the_doc (EXPERTS only)" + fi + + doc_line= + while [ -n "$the_doc" ]; do + remaining_doc="$(expr "$the_doc " : '.\{1,53\} \(.*\)')" + the_doc="$(expr "$the_doc " : '\(.\{1,53\}\) ')" + if [ -z "$doc_line" ]; then + if expr "$the_opt" : '.\{23\}' &>/dev/null; then + # break into two lines + doc_line="$(printf ' %s\\n\\\n%-24s %s' "$the_opt" "" "$the_doc")" + else + doc_line="$(printf ' %-22s %s' "$the_opt" "$the_doc")" + fi + else + doc_line="$doc_line\\n$(printf '%-24s %s' "" "$the_doc")" + fi + the_doc="$(expr "$remaining_doc" : '\(.*\) ')" + done + + if [ "$category" = COMMON ]; then + common_documentation="${common_documentation}\\n\" +#line $lineno \"$kf\" +\"$(echo "$doc_line" | sed 's,'\'',\\'\'',g;s,",\\",g')" + common_manpage_documentation="${common_manpage_documentation} +.IP \"$the_opt\" +$@" + else + remaining_documentation="${remaining_documentation}\\n\" +#line $lineno \"$kf\" +\"$(echo "$doc_line" | sed 's,'\'',\\'\'',g;s,",\\",g')" + remaining_manpage_documentation="${remaining_manpage_documentation} +.IP \"$the_opt\" +$@" + fi + else + if [ "$category" = COMMON ]; then + common_manpage_documentation="${common_manpage_documentation} +$@" + else + remaining_manpage_documentation="${remaining_manpage_documentation} +$@" + fi + fi +} + +function doc-alternate { + # doc-alternate text... + check_module_seen + expect_doc_alternate=false + + if $expect_doc; then + echo "$kf:$lineno: error: must provide documentation before alternate documentation" >&2 + exit 1 + fi + + if [ -z "$short_option_alternate" -a -z "$long_option_alternate" ]; then + echo "$kf:$lineno: cannot document an alternative for option \`$internal'; one does not exist" >&2 + exit 1 + fi + + if [ "$category" = UNDOCUMENTED ]; then + return + fi + + if ! $alternate_options_already_documented; then + alternate_options_already_documented=true + the_opt= + if [ "$long_option_alternate" ]; then + the_opt="--$long_option_alternate" + shortoptarg= + if expr "$the_opt" : '.*=' &>/dev/null; then + shortoptarg="$(echo "$the_opt" | sed 's,[^=]*=, ,')" + fi + if [ "$short_option_alternate" ]; then + the_opt="$the_opt | -$short_option_alternate$shortoptarg" + fi + elif [ "$short_option_alternate" ]; then + the_opt="-$short_option_alternate" + fi + if [ -z "$the_opt" ]; then + # nothing to document + return + fi + + the_doc="$@" + if [ "$category" = EXPERT ]; then + the_doc="$the_doc (EXPERTS only)" + fi + + doc_line= + while [ -n "$the_doc" ]; do + remaining_doc="$(expr "$the_doc " : '.\{1,53\} \(.*\)')" + the_doc="$(expr "$the_doc " : '\(.\{1,53\}\) ')" + if [ -z "$doc_line" ]; then + if expr "$the_opt" : '.\{23\}' &>/dev/null; then + # break into two lines + doc_line="$(printf ' %s\\n\\\n%-24s %s' "$the_opt" "" "$the_doc")" + else + doc_line="$(printf ' %-22s %s' "$the_opt" "$the_doc")" + fi + else + doc_line="$doc_line\\n$(printf '%-24s %s' "" "$the_doc")" + fi + the_doc="$(expr "$remaining_doc" : '\(.*\) ')" + done + + if [ "$category" = COMMON ]; then + common_documentation="${common_documentation}\\n\" +#line $lineno \"$kf\" +\"$(echo "$doc_line" | sed 's,'\'',\\'\'',g;s,",\\",g')" + common_manpage_documentation="${common_manpage_documentation} +.IP \"$the_opt\" +$@" + else + remaining_documentation="${remaining_documentation}\\n\" +#line $lineno \"$kf\" +\"$(echo "$doc_line" | sed 's,'\'',\\'\'',g;s,",\\",g')" + remaining_manpage_documentation="${remaining_manpage_documentation} +.IP \"$the_opt\" +$@" + fi + else + if [ "$category" = COMMON ]; then + common_manpage_documentation="${common_manpage_documentation} +$@" + else + remaining_manpage_documentation="${remaining_manpage_documentation} +$@" + fi + fi +} + +function check_doc { + if $expect_doc; then + if [ "$internal" != - ]; then + echo "$kf:$lineno: warning: $internal is lacking documentation" >&2 + elif [ -n "$long_option" ]; then + echo "$kf:$lineno: warning: option --$long_option is lacking documentation" >&2 + elif [ -n "$short_option" ]; then + echo "$kf:$lineno: warning: option -$short_option is lacking documentation" >&2 + elif [ -n "$smtname" ]; then + echo "$kf:$lineno: warning: SMT option $smtname is lacking documentation" >&2 + fi + expect_doc=false + fi + + if $expect_doc_alternate; then + echo "$kf:$lineno: warning: $internal is lacking documentation for the alternative option(s): $short_option_alternate $long_option_alternate" >&2 + expect_doc_alternate=false + fi +} + +function check_module_seen { + if $seen_endmodule; then + echo "$kf:$lineno: error: command after \"endmodule\" declaration (endmodule has to be last)" >&2 + exit 1 + fi + if ! $seen_module; then + echo "$kf:$lineno: error: no \"module\" declaration found (it has to be first)" >&2 + exit 1 + fi +} + +function check_include { + if ! expr "$1" : '".*"$' &>/dev/null && ! expr "$1" : '<.*>$' &>/dev/null; then + echo "\"$1\"" + else + echo "$1" + fi +} + +function output_module { + template="$1" + output="$2" + + filename="$(basename "$output")" + + #echo "generating module $output from $template" + + # generate warnings about incorrect #line annotations in templates + nl -ba -s' ' "$template" | grep '^ *[0-9][0-9]* # *line' | + awk '{OFS="";if($1+1!=$3) print "'"$template"':",$1,": warning: incorrect annotation \"#line ",$3,"\" (it should be \"#line ",($1+1),"\")"}' >&2 + + text=$(cat "$template") + for var in \ + module_id \ + module_name \ + module_includes \ + module_optionholder_spec \ + module_decls \ + module_specializations \ + module_inlines \ + module_accessors \ + module_global_definitions \ + template \ + ; do + eval text="\${text//\\\$\\{$var\\}/\${$var}}" + done + error="$(echo "$text" | grep '.*\${[^}]*}.*' | head -n 1)" + if [ -n "$error" ]; then + error="$(echo "$error" | sed 's,.*\${\([^}]*\)}.*,\1,')" + echo "$template:0: error: undefined replacement \${$error}" >&2 + exit 1 + fi + + ( + + # Output header (if this is a .cpp or .c or .h file) and then the + # processed text + + if expr "$output" : '.*\.cpp$' &>/dev/null || expr "$output" : '.*\.[ch]$' &>/dev/null; then + + cat <<EOF +/********************* */ +/** $filename + ** + ** Copyright $copyright The AcSys Group, New York University, and as below. + ** + ** This file automatically generated by: + ** + ** $0 $@ + ** + ** for the CVC4 project. + **/ + +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ + +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ + +/* Edit the template file instead: */ +/* $1 */ + +EOF + fi + + echo "$text" + + ) >"$output.tmp" + + diff -q "$output" "$output.tmp" &>/dev/null || (mv -f "$output.tmp" "$output" && echo "regenerated $output") + rm -f "$output.tmp" +} + +while [ $# -gt 0 ]; do + kf="$1"; shift + if [ $# -eq 0 ]; then + echo "$me: error: mismatched number of templates and output files (before -t)" >&2 + usage + exit 1 + fi + outdir="$1"; shift + + #echo "scanning $kf" + + seen_module=false + seen_endmodule=false + b=$(basename $(dirname "$kf")) + lineno=0 + # IFS= forces read to read an entire line + while IFS= read -r line; do + let ++lineno + # read any continuations of the line + while expr "$line" : '.*\\$' &>/dev/null; do + IFS= read -r line2 + line="$(echo "$line" | sed 's,\\$,,')$line2" + let ++lineno + done + if expr "$line" : '[ ].*' &>/dev/null; then + doc "$(echo "$line" | sed 's,^[ ],,')" + elif expr "$line" : '\.[ ]*$' &>/dev/null; then + doc "" + elif expr "$line" : '\.' &>/dev/null; then + echo "$kf:$lineno: error: malformed line during processing of option \`$internal': continuation lines should not have content" >&2 + exit 1 + elif expr "$line" : '/.*' &>/dev/null; then + doc-alternate "$(echo "$line" | sed 's,^/,,')" + else + line="$(echo "$line" | sed 's,\([<>&()!?*]\),\\\1,g')" + if ! eval "$line"; then + echo "$kf:$lineno: error was due to evaluation of this line" >&2 + exit 1 + fi + fi + done < "$kf" + if ! $seen_module; then + echo "$kf: error: no module content found in file!" >&2 + exit 1 + fi + if ! $seen_endmodule; then + echo "$kf:$lineno: error: no \"endmodule\" declaration found (it is required at the end)" >&2 + exit 1 + fi + + output_module "$options_h_template" "$outdir/$(basename "$kf").h" + output_module "$options_cpp_template" "$outdir/$(basename "$kf").cpp" +done + +## final outputs + +i=0; while [ $i -lt ${#templates[@]} ]; do + +template="${templates[$i]}" +output="${outputs[$i]}" + +let ++i + +filename="$(basename "$output")" + +#echo "generating $output from $template" + +# generate warnings about incorrect #line annotations in templates +nl -ba -s' ' "$template" | grep '^ *[0-9][0-9]* # *line' | + awk '{OFS="";if($1+1!=$3) print "'"$template"':",$1,": warning: incorrect annotation \"#line ",$3,"\" (it should be \"#line ",($1+1),"\")"}' >&2 + +long_option_value_end=$n_long + +text=$(cat "$template") +for var in \ + all_modules_defaults \ + all_modules_short_options \ + all_modules_long_options \ + all_modules_option_handlers \ + include_all_option_headers \ + all_modules_contributions \ + option_handler_includes \ + all_custom_handlers \ + common_documentation \ + remaining_documentation \ + common_manpage_documentation \ + remaining_manpage_documentation \ + smt_getoption_handlers \ + smt_setoption_handlers \ + long_option_value_begin \ + long_option_value_end \ + template \ + ; do + eval text="\${text//\\\$\\{$var\\}/\${$var}}" +done +error="$(echo "$text" | grep '.*\${[^}]*}.*' | head -n 1)" +if [ -n "$error" ]; then + error="$(echo "$error" | sed 's,.*\${\([^}]*\)}.*,\1,')" + echo "$template:0: error: undefined replacement \${$error}" >&2 + exit 1 +fi + +( + +# Output header (if this is a .cpp or .c or .h file) and then the +# processed text + +if expr "$output" : '.*\.cpp$' &>/dev/null || expr "$output" : '.*\.[ch]$' &>/dev/null; then + +cat <<EOF +/********************* */ +/** $filename + ** + ** Copyright $copyright The AcSys Group, New York University, and as below. + ** + ** This file automatically generated by: + ** + ** $0 $@ + ** + ** for the CVC4 project. + **/ + +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ + +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ +/* THIS FILE IS AUTOMATICALLY GENERATED, DO NOT EDIT ! */ + +/* Edit the template file instead: */ +/* $1 */ + +EOF +fi + +echo "$text" + +) >"$output.tmp" + +diff -q "$output" "$output.tmp" &>/dev/null || (mv -f "$output.tmp" "$output" && echo "regenerated $output") +rm -f "$output.tmp" + +done + diff --git a/src/options/options.h b/src/options/options.h new file mode 100644 index 000000000..a3abdd54b --- /dev/null +++ b/src/options/options.h @@ -0,0 +1,150 @@ +/********************* */ +/*! \file options.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: taking, cconway + ** Minor contributors (to current version): dejan + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Global (command-line, set-option, ...) parameters for SMT. + ** + ** Global (command-line, set-option, ...) parameters for SMT. + **/ + +#include "cvc4_public.h" + +#ifndef __CVC4__OPTIONS__OPTIONS_H +#define __CVC4__OPTIONS__OPTIONS_H + +#include <iostream> +#include <fstream> +#include <string> + +#include "util/exception.h" +#include "util/language.h" +#include "util/tls.h" + +namespace CVC4 { + +namespace options { + class OptionsHolder; +}/* CVC4::options namespace */ + +class ExprStream; +class NodeManager; +class NodeManagerScope; +class SmtEngine; + +/** Class representing an option-parsing exception. */ +class CVC4_PUBLIC OptionException : public CVC4::Exception { +public: + OptionException(const std::string& s) throw() : + CVC4::Exception("Error in option parsing: " + s) { + } +};/* class OptionException */ + +class CVC4_PUBLIC Options { + /** The struct that holds all option values. */ + options::OptionsHolder* d_holder; + + /** The current Options in effect */ + static CVC4_THREADLOCAL(Options*) s_current; + + /** Low-level assignment function for options */ + template <class T> + void assign(T, std::string option, std::string value, SmtEngine* smt); + /** Low-level assignment function for bool-valued options */ + template <class T> + void assignBool(T, std::string option, bool value, SmtEngine* smt); + + friend class NodeManager; + friend class NodeManagerScope; + friend class SmtEngine; + +public: + + /** Get the current Options in effect */ + static inline Options& current() { + return *s_current; + } + + Options(); + Options(const Options& options); + ~Options(); + + /** + * Set the value of the given option. Use of this default + * implementation causes a compile-time error; write-able + * options specialize this template with a real implementation. + */ + template <class T> + void set(T, const typename T::type&) { + // Flag a compile-time error. Write-able options specialize + // this template to provide an implementation. + T::you_are_trying_to_assign_to_a_read_only_option; + } + + /** Get the value of the given option. Const access only. */ + template <class T> + const typename T::type& operator[](T) const; + + /** + * Returns true iff the value of the given option was set + * by the user via a command-line option or SmtEngine::setOption(). + * (Options::set() is low-level and doesn't count.) Returns false + * otherwise. + */ + template <class T> + bool wasSetByUser(T) const; + + /** + * Get a description of the command-line flags accepted by + * parseOptions. The returned string will be escaped so that it is + * suitable as an argument to printf. */ + std::string getDescription() const; + + /** + * Print overall command-line option usage message, prefixed by + * "msg"---which could be an error message causing the usage + * output in the first place, e.g. "no such option --foo" + */ + static void printUsage(const std::string msg, std::ostream& out); + + /** + * Print command-line option usage message for only the most-commonly + * used options. The message is prefixed by "msg"---which could be + * an error message causing the usage output in the first place, e.g. + * "no such option --foo" + */ + static void printShortUsage(const std::string msg, std::ostream& out); + + /** Print help for the --lang command line option */ + static void printLanguageHelp(std::ostream& out); + + /** + * Initialize the options based on the given command-line arguments. + */ + int parseOptions(int argc, char* argv[]) throw(OptionException); + + /** + * Set the output language based on the given string. + */ + void setOutputLanguage(const char* str) throw(OptionException); + + /** + * Set the input language based on the given string. + */ + void setInputLanguage(const char* str) throw(OptionException); + +};/* class Options */ + +}/* CVC4 namespace */ + +#include "options/base_options.h" + +#endif /* __CVC4__OPTIONS__OPTIONS_H */ diff --git a/src/options/options.i b/src/options/options.i new file mode 100644 index 000000000..25eecaf2d --- /dev/null +++ b/src/options/options.i @@ -0,0 +1,10 @@ +%{ +#include "options/options.h" +%} + +%ignore CVC4::operator<<(std::ostream&, SimplificationMode); +%ignore CVC4::operator<<(std::ostream&, ArithPivotRule); + +%apply char** STRING_ARRAY { char* argv[] } +%include "options/options.h" +%clear char* argv[]; diff --git a/src/options/options_holder_template.h b/src/options/options_holder_template.h new file mode 100644 index 000000000..5b2c9a35d --- /dev/null +++ b/src/options/options_holder_template.h @@ -0,0 +1,42 @@ +/********************* */ +/*! \file options_holder_template.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Global (command-line, set-option, ...) parameters for SMT + ** + ** Global (command-line, set-option, ...) parameters for SMT. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__OPTIONS__OPTIONS_HOLDER_H +#define __CVC4__OPTIONS__OPTIONS_HOLDER_H + +${include_all_option_headers} + +#line 27 "${template}" + +namespace CVC4 { +namespace options { + +struct OptionsHolder { + OptionsHolder(); +${all_modules_contributions} + +#line 36 "${template}" + +};/* struct OptionsHolder */ + +}/* CVC4::options namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__OPTIONS__OPTIONS_HOLDER_H */ diff --git a/src/options/options_template.cpp b/src/options/options_template.cpp new file mode 100644 index 000000000..2df69b5d3 --- /dev/null +++ b/src/options/options_template.cpp @@ -0,0 +1,471 @@ +/********************* */ +/*! \file options_template.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Contains code for handling command-line options. + ** + ** Contains code for handling command-line options + **/ + +#include <cstdio> +#include <cstdlib> +#include <new> +#include <string> +#include <sstream> +#include <limits> +#include <unistd.h> +#include <string.h> +#include <stdint.h> +#include <time.h> + +#include <getopt.h> + +#include "expr/expr.h" +#include "util/configuration.h" +#include "util/exception.h" +#include "util/language.h" + +${include_all_option_headers} + +#line 40 "${template}" + +#include "util/output.h" +#include "options/options_holder.h" +#include "cvc4autoconfig.h" +#include "options/base_options_handlers.h" + +${option_handler_includes} + +#line 49 "${template}" + +using namespace CVC4; +using namespace CVC4::options; + +namespace CVC4 { + +CVC4_THREADLOCAL(Options*) Options::s_current = NULL; + +/** + * This is a default handler for options of built-in C++ type. This + * template is really just a helper for the handleOption() template, + * below. Variants of this template handle numeric and non-numeric, + * integral and non-integral, signed and unsigned C++ types. + * handleOption() makes sure to instantiate the right one. + * + * This implements default behavior when e.g. an option is + * unsigned but the user specifies a negative argument; etc. + */ +template <class T, bool is_numeric, bool is_integer> +struct OptionHandler { + static T handle(std::string option, std::string optarg); +};/* struct OptionHandler<> */ + +/** Variant for integral C++ types */ +template <class T> +struct OptionHandler<T, true, true> { + static T handle(std::string option, std::string optarg) { + try { + Integer i(optarg, 0); + + if(! std::numeric_limits<T>::is_signed && i < 0) { + // unsigned type but user gave negative argument + throw OptionException(option + " requires a nonnegative argument"); + } else if(i < std::numeric_limits<T>::min()) { + // negative overflow for type + std::stringstream ss; + ss << option << " requires an argument >= " << std::numeric_limits<T>::min(); + throw OptionException(ss.str()); + } else if(i > std::numeric_limits<T>::max()) { + // positive overflow for type + std::stringstream ss; + ss << option << " requires an argument <= " << std::numeric_limits<T>::max(); + throw OptionException(ss.str()); + } + + if(std::numeric_limits<T>::is_signed) { + return T(i.getLong()); + } else { + return T(i.getUnsignedLong()); + } + } catch(std::invalid_argument&) { + // user gave something other than an integer + throw OptionException(option + " requires an integer argument"); + } + } +};/* struct OptionHandler<T, true, true> */ + +/** Variant for numeric but non-integral C++ types */ +template <class T> +struct OptionHandler<T, true, false> { + static T handle(std::string option, std::string optarg) { + std::stringstream in(optarg); + long double r; + in >> r; + if(! in.eof()) { + // we didn't consume the whole string (junk at end) + throw OptionException(option + " requires a numeric argument"); + } + + if(! std::numeric_limits<T>::is_signed && r < 0.0) { + // unsigned type but user gave negative value + throw OptionException(option + " requires a nonnegative argument"); + } else if(r < -std::numeric_limits<T>::max()) { + // negative overflow for type + std::stringstream ss; + ss << option << " requires an argument >= " << -std::numeric_limits<T>::max(); + throw OptionException(ss.str()); + } else if(r > std::numeric_limits<T>::max()) { + // positive overflow for type + std::stringstream ss; + ss << option << " requires an argument <= " << std::numeric_limits<T>::max(); + throw OptionException(ss.str()); + } + + return T(r); + } +};/* struct OptionHandler<T, true, false> */ + +/** Variant for non-numeric C++ types */ +template <class T> +struct OptionHandler<T, false, false> { + static T handle(std::string option, std::string optarg) { + T::unsupported_handleOption_call___please_write_me; + // The above line causes a compiler error if this version of the template + // is ever instantiated (meaning that a specialization is missing). So + // don't worry about the segfault in the next line, the "return" is only + // there to keep the compiler from giving additional, distracting errors + // and warnings. + return *(T*)0; + } +};/* struct OptionHandler<T, false, false> */ + +/** Handle an option of type T in the default way. */ +template <class T> +T handleOption(std::string option, std::string optarg) { + return OptionHandler<T, std::numeric_limits<T>::is_specialized, std::numeric_limits<T>::is_integer>::handle(option, optarg); +} + +/** Handle an option of type std::string in the default way. */ +template <> +std::string handleOption<std::string>(std::string option, std::string optarg) { + return optarg; +} + +/** + * Run handler, and any user-given predicates, for option T. + * If a user specifies a :handler or :predicates, it overrides this. + */ +template <class T> +typename T::type runHandlerAndPredicates(T, std::string option, std::string optarg, SmtEngine* smt) { + // By default, parse the option argument in a way appropriate for its type. + // E.g., for "unsigned int" options, ensure that the provided argument is + // a nonnegative integer that fits in the unsigned int type. + + return handleOption<typename T::type>(option, optarg); +} + +template <class T> +void runBoolPredicates(T, std::string option, bool b, SmtEngine* smt) { + // By default, nothing to do for bool. Users add things with + // :predicate in options files to provide custom checking routines + // that can throw exceptions. +} + +${all_custom_handlers} + +#line 186 "${template}" + +#ifdef CVC4_DEBUG +# define USE_EARLY_TYPE_CHECKING_BY_DEFAULT true +#else /* CVC4_DEBUG */ +# define USE_EARLY_TYPE_CHECKING_BY_DEFAULT false +#endif /* CVC4_DEBUG */ + +#if defined(CVC4_MUZZLED) || defined(CVC4_COMPETITION_MODE) +# define DO_SEMANTIC_CHECKS_BY_DEFAULT false +#else /* CVC4_MUZZLED || CVC4_COMPETITION_MODE */ +# define DO_SEMANTIC_CHECKS_BY_DEFAULT true +#endif /* CVC4_MUZZLED || CVC4_COMPETITION_MODE */ + +Options::Options() : + d_holder(new options::OptionsHolder()) { +} + +Options::Options(const Options& options) : + d_holder(new options::OptionsHolder(*options.d_holder)) { +} + +Options::~Options() { + delete d_holder; +} + +options::OptionsHolder::OptionsHolder() : ${all_modules_defaults} +{ +} + +#line 216 "${template}" + +static const std::string mostCommonOptionsDescription = "\ +Most commonly-used CVC4 options:${common_documentation}"; + +#line 221 "${template}" + +static const std::string optionsDescription = mostCommonOptionsDescription + "\n\ +\n\ +Additional CVC4 options:${remaining_documentation}"; + +#line 227 "${template}" + +static const std::string languageDescription = "\ +Languages currently supported as arguments to the -L / --lang option:\n\ + auto attempt to automatically determine the input language\n\ + pl | cvc4 CVC4 presentation language\n\ + smt | smtlib SMT-LIB format 1.2\n\ + smt2 | smtlib2 SMT-LIB format 2.0\n\ + tptp TPTP format (cnf and fof)\n\ +\n\ +Languages currently supported as arguments to the --output-lang option:\n\ + auto match the output language to the input language\n\ + pl | cvc4 CVC4 presentation language\n\ + smt | smtlib SMT-LIB format 1.2\n\ + smt2 | smtlib2 SMT-LIB format 2.0\n\ + tptp TPTP format\n\ + ast internal format (simple syntax-tree language)\n\ +"; + +std::string Options::getDescription() const { + return optionsDescription; +} + +void Options::printUsage(const std::string msg, std::ostream& out) { + out << msg << optionsDescription << std::endl << std::flush; +} + +void Options::printShortUsage(const std::string msg, std::ostream& out) { + out << msg << mostCommonOptionsDescription << std::endl << std::endl + << "For full usage, please use --help." << std::endl << std::flush; +} + +void Options::printLanguageHelp(std::ostream& out) { + out << languageDescription << std::flush; +} + +/** + * This is a table of long options. By policy, each short option + * should have an equivalent long option (but the reverse isn't the + * case), so this table should thus contain all command-line options. + * + * Each option in this array has four elements: + * + * 1. the long option string + * 2. argument behavior for the option: + * no_argument - no argument permitted + * required_argument - an argument is expected + * optional_argument - an argument is permitted but not required + * 3. this is a pointer to an int which is set to the 4th entry of the + * array if the option is present; or NULL, in which case + * getopt_long() returns the 4th entry + * 4. the return value for getopt_long() when this long option (or the + * value to set the 3rd entry to; see #3) + * + * If you add something here, you should add it in src/main/usage.h + * also, to document it. + * + * If you add something that has a short option equivalent, you should + * add it to the getopt_long() call in parseOptions(). + */ +static struct option cmdlineOptions[] = {${all_modules_long_options} + { NULL, no_argument, NULL, '\0' } +};/* cmdlineOptions */ + +#line 291 "${template}" + +static void preemptGetopt(int& argc, char**& argv, const char* opt) { + const size_t maxoptlen = 128; + + Debug("preemptGetopt") << "preempting getopt() with " << opt << std::endl; + + AlwaysAssert(opt != NULL && *opt != '\0'); + AlwaysAssert(strlen(opt) <= maxoptlen); + + ++argc; + unsigned i = 1; + while(argv[i] != NULL && argv[i][0] != '\0') { + ++i; + } + + if(argv[i] == NULL) { + argv = (char**) realloc(argv, (i + 6) * sizeof(char*)); + for(unsigned j = i; j < i + 5; ++j) { + argv[j] = (char*) malloc(sizeof(char) * maxoptlen); + argv[j][0] = '\0'; + } + argv[i + 5] = NULL; + } + + strncpy(argv[i], opt, maxoptlen - 1); + argv[i][maxoptlen - 1] = '\0'; // ensure NUL-termination even on overflow +} + +namespace options { + +/** Set a given Options* as "current" just for a particular scope. */ +class OptionsGuard { + Options** d_field; + Options* d_old; +public: + OptionsGuard(Options** field, Options* opts) : + d_field(field), + d_old(*field) { + *field = opts; + } + ~OptionsGuard() { + *d_field = d_old; + } +};/* class OptionsGuard */ + +}/* CVC4::options namespace */ + +/** Parse argc/argv and put the result into a CVC4::Options. */ +int Options::parseOptions(int argc, char* main_argv[]) throw(OptionException) { + options::OptionsGuard guard(&s_current, this); + + const char *progName = main_argv[0]; + SmtEngine* const smt = NULL; + + // Reset getopt(), in the case of multiple calls to parseOptions(). + // This can be = 1 in newer GNU getopt, but older (< 2007) require = 0. + optind = 0; +#if HAVE_DECL_OPTRESET + optreset = 1; // on BSD getopt() (e.g. Mac OS), might also need this +#endif /* HAVE_DECL_OPTRESET */ + + // find the base name of the program + const char *x = strrchr(progName, '/'); + if(x != NULL) { + progName = x + 1; + } + d_holder->binary_name = std::string(progName); + + int extra_argc = 1; + char **extra_argv = (char**) malloc(2 * sizeof(char*)); + extra_argv[0] = NULL; + extra_argv[1] = NULL; + + int extra_optind = 0, main_optind = 0; + int old_optind; + + char** argv = main_argv; + + for(;;) { + int c = -1; + Debug("preemptGetopt") << "top of loop, extra_optind == " << extra_optind << ", extra_argc == " << extra_argc << std::endl; + if((extra_optind == 0 ? 1 : extra_optind) < extra_argc) { +#if HAVE_DECL_OPTRESET + optreset = 1; // on BSD getopt() (e.g. Mac OS), might also need this +#endif /* HAVE_DECL_OPTRESET */ + old_optind = optind = extra_optind; + argv = extra_argv; + Debug("preemptGetopt") << "in preempt code, next arg is " << extra_argv[optind == 0 ? 1 : optind] << std::endl; + c = getopt_long(extra_argc, extra_argv, + ":${all_modules_short_options}", + cmdlineOptions, NULL); + Debug("preemptGetopt") << "in preempt code, c == " << c << " (`" << char(c) << "') optind == " << optind << std::endl; + if(optind >= extra_argc) { + Debug("preemptGetopt") << "-- no more preempt args" << std::endl; + unsigned i = 0; + while(extra_argv[i] != NULL && extra_argv[i][0] != '\0') { + extra_argv[i][0] = '\0'; + ++i; + } + extra_argc = 1; + extra_optind = 0; + } else { + Debug("preemptGetopt") << "-- more preempt args" << std::endl; + extra_optind = optind; + } + } + if(c == -1) { +#if HAVE_DECL_OPTRESET + optreset = 1; // on BSD getopt() (e.g. Mac OS), might also need this +#endif /* HAVE_DECL_OPTRESET */ + old_optind = optind = main_optind; + argv = main_argv; + c = getopt_long(argc, main_argv, + ":${all_modules_short_options}", + cmdlineOptions, NULL); + main_optind = optind; + if(c == -1) { + break; + } + } + + Debug("preemptGetopt") << "processing option " << c << " (`" << char(c) << "')" << std::endl; + + switch(c) { +${all_modules_option_handlers} + +#line 418 "${template}" + + case ':': + // This can be a long or short option, and the way to get at the + // name of it is different. + if(optopt == 0 || + ( optopt >= ${long_option_value_begin} && optopt <= ${long_option_value_end} )) { + // was a long option + throw OptionException(std::string("option `") + argv[optind - 1] + "' missing its required argument"); + } else { + // was a short option + throw OptionException(std::string("option `-") + char(optopt) + "' missing its required argument"); + } + + case '?': + default: + if(optopt == 0 && + !strncmp(argv[optind - 1], "--thread", 8) && + strlen(argv[optind - 1]) > 8 && + isdigit(argv[optind - 1][8])) { + std::vector<std::string>& threadArgv = d_holder->threadArgv; + int tnum = atoi(argv[optind - 1] + 8); + threadArgv.resize(tnum + 1); + if(threadArgv[tnum] != "") { + threadArgv[tnum] += " "; + } + const char* p = strchr(argv[optind - 1] + 9, '='); + if(p == NULL) { // e.g., we have --thread0 "foo" + threadArgv[tnum] += argv[optind++]; + } else { // e.g., we have --thread0="foo" + threadArgv[tnum] += p + 1; + } + break; + } + + // This can be a long or short option, and the way to get at the name of it is different. + if(optopt == 0) { // was a long option + throw OptionException(std::string("can't understand option `") + argv[optind - 1] + "'"); + } else { // was a short option + throw OptionException(std::string("can't understand option `-") + char(optopt) + "'"); + } + } + } + + if((*this)[options::incrementalSolving] && (*this)[options::proof]) { + throw OptionException(std::string("The use of --incremental with --proof is not yet supported")); + } + + return optind; +} + +#undef USE_EARLY_TYPE_CHECKING_BY_DEFAULT +#undef DO_SEMANTIC_CHECKS_BY_DEFAULT + +}/* CVC4 namespace */ diff --git a/src/parser/cvc/Makefile.am b/src/parser/cvc/Makefile.am index 15a572745..e5666b702 100644 --- a/src/parser/cvc/Makefile.am +++ b/src/parser/cvc/Makefile.am @@ -15,14 +15,14 @@ ANTLR_OPTS = noinst_LTLIBRARIES = libparsercvc.la ANTLR_TOKEN_STUFF = \ - @srcdir@/generated/Cvc.tokens + generated/Cvc.tokens ANTLR_LEXER_STUFF = \ - @srcdir@/generated/CvcLexer.h \ - @srcdir@/generated/CvcLexer.c \ + generated/CvcLexer.h \ + generated/CvcLexer.c \ $(ANTLR_TOKEN_STUFF) ANTLR_PARSER_STUFF = \ - @srcdir@/generated/CvcParser.h \ - @srcdir@/generated/CvcParser.c + generated/CvcParser.h \ + generated/CvcParser.c ANTLR_STUFF = \ $(ANTLR_LEXER_STUFF) \ $(ANTLR_PARSER_STUFF) @@ -33,29 +33,27 @@ libparsercvc_la_SOURCES = \ cvc_input.cpp \ $(ANTLR_STUFF) -BUILT_SOURCES = $(ANTLR_STUFF) @srcdir@/stamp-generated +BUILT_SOURCES = $(ANTLR_STUFF) stamp-generated -EXTRA_DIST = \ - @srcdir@/stamp-generated \ - README +EXTRA_DIST = README MAINTAINERCLEANFILES = $(ANTLR_STUFF) maintainer-clean-local: - -$(AM_V_at)rmdir @srcdir@/generated - -$(AM_V_at)rm -f @srcdir@/stamp-generated + -$(AM_V_at)rmdir generated + -$(AM_V_at)rm -f stamp-generated -@srcdir@/stamp-generated: - $(AM_V_at)mkdir -p @srcdir@/generated - $(AM_V_at)touch @srcdir@/stamp-generated +stamp-generated: + $(AM_V_at)mkdir -p generated + $(AM_V_at)touch stamp-generated # antlr doesn't overwrite output files, it just leaves them. So we have to delete them first. -@srcdir@/generated/CvcLexer.h: Cvc.g @srcdir@/stamp-generated +generated/CvcLexer.h: Cvc.g stamp-generated -$(AM_V_at)rm -f $(ANTLR_STUFF) @if test -z "$(ANTLR)"; then echo "ERROR: antlr parser generator cannot be found, cannot generate the parser" >&2; exit 1; fi - $(AM_V_GEN)$(ANTLR) $(ANTLR_OPTS) -fo "@srcdir@/generated" "@srcdir@/Cvc.g" + $(AM_V_GEN)$(ANTLR) $(ANTLR_OPTS) -fo "generated" "@srcdir@/Cvc.g" # These don't actually depend on CvcLexer.h, but if we're doing parallel # make and the lexer needs to be rebuilt, we have to keep the rules # from running in parallel (since the token files will be deleted & # recreated) -@srcdir@/generated/CvcLexer.c @srcdir@/generated/CvcParser.h @srcdir@/generated/CvcParser.c $(ANTLR_TOKEN_STUFF): @srcdir@/generated/CvcLexer.h +generated/CvcLexer.c generated/CvcParser.h generated/CvcParser.c $(ANTLR_TOKEN_STUFF): generated/CvcLexer.h diff --git a/src/parser/options b/src/parser/options new file mode 100644 index 000000000..beae09823 --- /dev/null +++ b/src/parser/options @@ -0,0 +1,17 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module PARSER "parser/options.h" Parser + +common-option strictParsing --strict-parsing bool + be less tolerant of non-conforming inputs + +option memoryMap --mmap bool + memory map file input + +option semanticChecks /--no-checking bool :default DO_SEMANTIC_CHECKS_BY_DEFAULT :link /--no-type-checking + disable ALL semantic checks, including type checks + +endmodule diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp index 2265355f0..44148a7f1 100644 --- a/src/parser/parser.cpp +++ b/src/parser/parser.cpp @@ -29,7 +29,7 @@ #include "expr/kind.h" #include "expr/type.h" #include "util/output.h" -#include "util/options.h" +#include "options/options.h" #include "util/Assert.h" #include "parser/cvc/cvc_input.h" #include "parser/smt/smt_input.h" diff --git a/src/parser/parser_builder.cpp b/src/parser/parser_builder.cpp index d9b7cf341..bd71f71e7 100644 --- a/src/parser/parser_builder.cpp +++ b/src/parser/parser_builder.cpp @@ -26,7 +26,7 @@ #include "tptp/tptp.h" #include "expr/expr_manager.h" -#include "util/options.h" +#include "parser/options.h" namespace CVC4 { namespace parser { @@ -146,11 +146,11 @@ ParserBuilder& ParserBuilder::withParseOnly(bool flag) { ParserBuilder& ParserBuilder::withOptions(const Options& options) { return - withInputLanguage(options.inputLanguage) - .withMmap(options.memoryMap) - .withChecks(options.semanticChecks) - .withStrictMode(options.strictParsing) - .withParseOnly(options.parseOnly); + withInputLanguage(options[options::inputLanguage]) + .withMmap(options[options::memoryMap]) + .withChecks(options[options::semanticChecks]) + .withStrictMode(options[options::strictParsing]) + .withParseOnly(options[options::parseOnly]); } ParserBuilder& ParserBuilder::withStrictMode(bool flag) { diff --git a/src/parser/smt/Makefile.am b/src/parser/smt/Makefile.am index 975a90b72..a74a6909c 100644 --- a/src/parser/smt/Makefile.am +++ b/src/parser/smt/Makefile.am @@ -15,14 +15,14 @@ ANTLR_OPTS = noinst_LTLIBRARIES = libparsersmt.la ANTLR_TOKEN_STUFF = \ - @srcdir@/generated/Smt.tokens + generated/Smt.tokens ANTLR_LEXER_STUFF = \ - @srcdir@/generated/SmtLexer.h \ - @srcdir@/generated/SmtLexer.c \ + generated/SmtLexer.h \ + generated/SmtLexer.c \ $(ANTLR_TOKEN_STUFF) ANTLR_PARSER_STUFF = \ - @srcdir@/generated/SmtParser.h \ - @srcdir@/generated/SmtParser.c + generated/SmtParser.h \ + generated/SmtParser.c ANTLR_STUFF = \ $(ANTLR_LEXER_STUFF) \ $(ANTLR_PARSER_STUFF) @@ -35,27 +35,25 @@ libparsersmt_la_SOURCES = \ smt_input.cpp \ $(ANTLR_STUFF) -BUILT_SOURCES = $(ANTLR_STUFF) @srcdir@/stamp-generated - -EXTRA_DIST = @srcdir@/stamp-generated +BUILT_SOURCES = $(ANTLR_STUFF) stamp-generated MAINTAINERCLEANFILES = $(ANTLR_STUFF) maintainer-clean-local: - -$(AM_V_at)rmdir @srcdir@/generated - -$(AM_V_at)rm -f @srcdir@/stamp-generated + -$(AM_V_at)rmdir generated + -$(AM_V_at)rm -f stamp-generated -@srcdir@/stamp-generated: - $(AM_V_at)mkdir -p @srcdir@/generated - $(AM_V_at)touch @srcdir@/stamp-generated +stamp-generated: + $(AM_V_at)mkdir -p generated + $(AM_V_at)touch stamp-generated # antlr doesn't overwrite output files, it just leaves them. So we have to delete them first. -@srcdir@/generated/SmtLexer.h: Smt.g @srcdir@/stamp-generated +generated/SmtLexer.h: Smt.g stamp-generated -$(AM_V_at)rm -f $(ANTLR_STUFF) @if test -z "$(ANTLR)"; then echo "ERROR: antlr parser generator cannot be found, cannot generate the parser" >&2; exit 1; fi - $(AM_V_GEN)$(ANTLR) $(ANTLR_OPTS) -fo "@srcdir@/generated" "@srcdir@/Smt.g" + $(AM_V_GEN)$(ANTLR) $(ANTLR_OPTS) -fo "generated" "@srcdir@/Smt.g" # These don't actually depend on SmtLexer.h, but if we're doing parallel # make and the lexer needs to be rebuilt, we have to keep the rules # from running in parallel (since the token files will be deleted & # recreated) -@srcdir@/generated/SmtLexer.c @srcdir@/generated/SmtParser.h @srcdir@/generated/SmtParser.c $(ANTLR_TOKEN_STUFF): @srcdir@/generated/SmtLexer.h +generated/SmtLexer.c generated/SmtParser.h generated/SmtParser.c $(ANTLR_TOKEN_STUFF): generated/SmtLexer.h diff --git a/src/parser/smt/Smt.g b/src/parser/smt/Smt.g index 429adee0a..f9c38385f 100644 --- a/src/parser/smt/Smt.g +++ b/src/parser/smt/Smt.g @@ -565,7 +565,7 @@ annotation[CVC4::Command*& smt_command] value.erase(value.begin(), std::find_if(value.begin(), value.end(), std::not1(std::ptr_fun<int, int>(std::isspace)))); value.erase(value.end() - 1); value.erase(std::find_if(value.rbegin(), value.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), value.end()); - smt_command = new SetInfoCommand(key, value); } + smt_command = new SetInfoCommand(key.c_str() + 1, value); } )? { if(smt_command == NULL) { smt_command = new EmptyCommand(std::string("annotation: ") + key); diff --git a/src/parser/smt2/Makefile.am b/src/parser/smt2/Makefile.am index 75ceec43a..8f7bf433c 100644 --- a/src/parser/smt2/Makefile.am +++ b/src/parser/smt2/Makefile.am @@ -15,14 +15,14 @@ ANTLR_OPTS = noinst_LTLIBRARIES = libparsersmt2.la ANTLR_TOKEN_STUFF = \ - @srcdir@/generated/Smt2.tokens + generated/Smt2.tokens ANTLR_LEXER_STUFF = \ - @srcdir@/generated/Smt2Lexer.h \ - @srcdir@/generated/Smt2Lexer.c \ + generated/Smt2Lexer.h \ + generated/Smt2Lexer.c \ $(ANTLR_TOKEN_STUFF) ANTLR_PARSER_STUFF = \ - @srcdir@/generated/Smt2Parser.h \ - @srcdir@/generated/Smt2Parser.c + generated/Smt2Parser.h \ + generated/Smt2Parser.c ANTLR_STUFF = \ $(ANTLR_LEXER_STUFF) \ $(ANTLR_PARSER_STUFF) @@ -35,27 +35,25 @@ libparsersmt2_la_SOURCES = \ smt2_input.cpp \ $(ANTLR_STUFF) -BUILT_SOURCES = $(ANTLR_STUFF) @srcdir@/stamp-generated - -EXTRA_DIST = @srcdir@/stamp-generated +BUILT_SOURCES = $(ANTLR_STUFF) stamp-generated MAINTAINERCLEANFILES = $(ANTLR_STUFF) maintainer-clean-local: - -$(AM_V_at)rmdir @srcdir@/generated - -$(AM_V_at)rm -f @srcdir@/stamp-generated + -$(AM_V_at)rmdir generated + -$(AM_V_at)rm -f stamp-generated -@srcdir@/stamp-generated: - $(AM_V_at)mkdir -p @srcdir@/generated - $(AM_V_at)touch @srcdir@/stamp-generated +stamp-generated: + $(AM_V_at)mkdir -p generated + $(AM_V_at)touch stamp-generated # antlr doesn't overwrite output files, it just leaves them. So we have to delete them first. -@srcdir@/generated/Smt2Lexer.h: Smt2.g @srcdir@/stamp-generated +generated/Smt2Lexer.h: Smt2.g stamp-generated -$(AM_V_at)rm -f $(ANTLR_STUFF) @if test -z "$(ANTLR)"; then echo "ERROR: antlr parser generator cannot be found, cannot generate the parser" >&2; exit 1; fi - $(AM_V_GEN)$(ANTLR) $(ANTLR_OPTS) -fo "@srcdir@/generated" "@srcdir@/Smt2.g" + $(AM_V_GEN)$(ANTLR) $(ANTLR_OPTS) -fo "generated" "@srcdir@/Smt2.g" # These don't actually depend on SmtLexer.h, but if we're doing parallel # make and the lexer needs to be rebuilt, we have to keep the rules # from running in parallel (since the token files will be deleted & # recreated) -@srcdir@/generated/Smt2Lexer.c @srcdir@/generated/Smt2Parser.h @srcdir@/generated/Smt2Parser.c $(ANTLR_TOKEN_STUFF): @srcdir@/generated/Smt2Lexer.h +generated/Smt2Lexer.c generated/Smt2Parser.h generated/Smt2Parser.c $(ANTLR_TOKEN_STUFF): generated/Smt2Lexer.h diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g index 93d596264..dd0ccb0ad 100644 --- a/src/parser/smt2/Smt2.g +++ b/src/parser/smt2/Smt2.g @@ -183,19 +183,19 @@ command returns [CVC4::Command* cmd = NULL] $cmd = new SetBenchmarkLogicCommand(name); } | SET_INFO_TOK KEYWORD symbolicExpr[sexpr] { name = AntlrInput::tokenText($KEYWORD); - PARSER_STATE->setInfo(name,sexpr); - cmd = new SetInfoCommand(name,sexpr); } + PARSER_STATE->setInfo(name.c_str() + 1, sexpr); + cmd = new SetInfoCommand(name.c_str() + 1, sexpr); } | /* get-info */ GET_INFO_TOK KEYWORD - { cmd = new GetInfoCommand(AntlrInput::tokenText($KEYWORD)); } + { cmd = new GetInfoCommand(AntlrInput::tokenText($KEYWORD).c_str() + 1); } | /* set-option */ SET_OPTION_TOK KEYWORD symbolicExpr[sexpr] { name = AntlrInput::tokenText($KEYWORD); - PARSER_STATE->setOption(name,sexpr); - cmd = new SetOptionCommand(name,sexpr); } + PARSER_STATE->setOption(name.c_str() + 1, sexpr); + cmd = new SetOptionCommand(name.c_str() + 1, sexpr); } | /* get-option */ GET_OPTION_TOK KEYWORD - { cmd = new GetOptionCommand(AntlrInput::tokenText($KEYWORD)); } + { cmd = new GetOptionCommand(AntlrInput::tokenText($KEYWORD).c_str() + 1); } | /* sort declaration */ DECLARE_SORT_TOK { PARSER_STATE->checkThatLogicIsSet(); } symbol[name,CHECK_UNDECLARED,SYM_SORT] diff --git a/src/parser/tptp/Makefile.am b/src/parser/tptp/Makefile.am index 4ec1717e9..3113a523c 100644 --- a/src/parser/tptp/Makefile.am +++ b/src/parser/tptp/Makefile.am @@ -15,14 +15,14 @@ ANTLR_OPTS = noinst_LTLIBRARIES = libparsertptp.la ANTLR_TOKEN_STUFF = \ - @srcdir@/generated/Tptp.tokens + generated/Tptp.tokens ANTLR_LEXER_STUFF = \ - @srcdir@/generated/TptpLexer.h \ - @srcdir@/generated/TptpLexer.c \ + generated/TptpLexer.h \ + generated/TptpLexer.c \ $(ANTLR_TOKEN_STUFF) ANTLR_PARSER_STUFF = \ - @srcdir@/generated/TptpParser.h \ - @srcdir@/generated/TptpParser.c + generated/TptpParser.h \ + generated/TptpParser.c ANTLR_STUFF = \ $(ANTLR_LEXER_STUFF) \ $(ANTLR_PARSER_STUFF) @@ -35,27 +35,25 @@ libparsertptp_la_SOURCES = \ tptp_input.cpp \ $(ANTLR_STUFF) -BUILT_SOURCES = $(ANTLR_STUFF) @srcdir@/stamp-generated - -EXTRA_DIST = @srcdir@/stamp-generated +BUILT_SOURCES = $(ANTLR_STUFF) stamp-generated MAINTAINERCLEANFILES = $(ANTLR_STUFF) maintainer-clean-local: - -$(AM_V_at)rmdir @srcdir@/generated - -$(AM_V_at)rm -f @srcdir@/stamp-generated + -$(AM_V_at)rmdir generated + -$(AM_V_at)rm -f stamp-generated -@srcdir@/stamp-generated: - $(AM_V_at)mkdir -p @srcdir@/generated - $(AM_V_at)touch @srcdir@/stamp-generated +stamp-generated: + $(AM_V_at)mkdir -p generated + $(AM_V_at)touch stamp-generated # antlr doesn't overwrite output files, it just leaves them. So we have to delete them first. -@srcdir@/generated/TptpLexer.h: Tptp.g @srcdir@/stamp-generated +generated/TptpLexer.h: Tptp.g stamp-generated -$(AM_V_at)rm -f $(ANTLR_STUFF) @if test -z "$(ANTLR)"; then echo "ERROR: antlr parser generator cannot be found, cannot generate the parser" >&2; exit 1; fi - $(AM_V_GEN)$(ANTLR) $(ANTLR_OPTS) -fo "@srcdir@/generated" "@srcdir@/Tptp.g" + $(AM_V_GEN)$(ANTLR) $(ANTLR_OPTS) -fo "generated" "@srcdir@/Tptp.g" # These don't actually depend on TptpLexer.h, but if we're doing parallel # make and the lexer needs to be rebuilt, we have to keep the rules # from running in parallel (since the token files will be deleted & # recreated) -@srcdir@/generated/TptpLexer.c @srcdir@/generated/TptpParser.h @srcdir@/generated/TptpParser.c $(ANTLR_TOKEN_STUFF): @srcdir@/generated/TptpLexer.h +generated/TptpLexer.c generated/TptpParser.h generated/TptpParser.c $(ANTLR_TOKEN_STUFF): generated/TptpLexer.h diff --git a/src/printer/Makefile.am b/src/printer/Makefile.am index 21b88d4be..7a6ef1158 100644 --- a/src/printer/Makefile.am +++ b/src/printer/Makefile.am @@ -18,3 +18,5 @@ libprinter_la_SOURCES = \ smt2/smt2_printer.cpp \ cvc/cvc_printer.h \ cvc/cvc_printer.cpp + +EXTRA_DIST = diff --git a/src/printer/options b/src/printer/options new file mode 100644 index 000000000..d95c7457d --- /dev/null +++ b/src/printer/options @@ -0,0 +1,8 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module PRINTER "printer/options.h" Printing + +endmodule diff --git a/src/proof/Makefile.am b/src/proof/Makefile.am index d657dfa80..7588f0dc3 100644 --- a/src/proof/Makefile.am +++ b/src/proof/Makefile.am @@ -16,3 +16,4 @@ libproof_la_SOURCES = \ proof_manager.h \ proof_manager.cpp +EXTRA_DIST = diff --git a/src/proof/options b/src/proof/options new file mode 100644 index 000000000..f00c8fc75 --- /dev/null +++ b/src/proof/options @@ -0,0 +1,11 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module PROOF "proof/options.h" Proof + +option proof produce-proofs --proof bool + turn on proof generation + +endmodule diff --git a/src/proof/proof.h b/src/proof/proof.h index a3270c4c0..39cf2b5bf 100644 --- a/src/proof/proof.h +++ b/src/proof/proof.h @@ -19,12 +19,12 @@ #ifndef __CVC4__PROOF__PROOF_H #define __CVC4__PROOF__PROOF_H -#include "util/options.h" +#include "options/options.h" #ifdef CVC4_PROOF -# define PROOF(x) if(Options::current()->proof) { x; } -# define NULLPROOF(x) (Options::current()->proof)? x : NULL -# define PROOF_ON() Options::current()->proof +# define PROOF(x) if(options::proof()) { x; } +# define NULLPROOF(x) (options::proof())? x : NULL +# define PROOF_ON() options::proof() #else /* CVC4_PROOF */ # define PROOF(x) # define NULLPROOF(x) NULL diff --git a/src/prop/Makefile.am b/src/prop/Makefile.am index 5e6b18c19..f109e0ed2 100644 --- a/src/prop/Makefile.am +++ b/src/prop/Makefile.am @@ -22,5 +22,8 @@ libprop_la_SOURCES = \ sat_solver_registry.h \ sat_solver_registry.cpp +EXTRA_DIST = \ + options_handlers.h + SUBDIRS = minisat bvminisat diff --git a/src/prop/bvminisat/core/Solver.cc b/src/prop/bvminisat/core/Solver.cc index 94f3a6b74..293ddd657 100644 --- a/src/prop/bvminisat/core/Solver.cc +++ b/src/prop/bvminisat/core/Solver.cc @@ -27,7 +27,8 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "util/output.h" #include "util/utility.h" -#include "util/options.h" + +#include "theory/bv/options.h" using namespace BVMinisat; @@ -423,7 +424,7 @@ void Solver::analyze(CRef confl, vec<Lit>& out_learnt, int& out_btlevel, UIP uip out_btlevel = level(var(p)); } - if (out_learnt.size() > 0 && clause_all_marker && CVC4::Options::current()->bitvectorShareLemmas) { + if (out_learnt.size() > 0 && clause_all_marker && CVC4::options::bitvectorShareLemmas()) { notify->notify(out_learnt); } diff --git a/src/prop/cnf_stream.cpp b/src/prop/cnf_stream.cpp index 485ddbb55..b498f1e40 100644 --- a/src/prop/cnf_stream.cpp +++ b/src/prop/cnf_stream.cpp @@ -202,7 +202,7 @@ SatLiteral CnfStream::newLiteral(TNode node, bool theoryLiteral) { // If it's a theory literal, need to store it for back queries if ( theoryLiteral || d_fullLitToNodeMap || - ( CVC4_USE_REPLAY && Options::current()->replayLog != NULL ) || + ( CVC4_USE_REPLAY && options::replayLog() != NULL ) || (Dump.isOn("clauses")) ) { d_nodeCache[lit] = node; d_nodeCache[~lit] = node.notNode(); diff --git a/src/prop/minisat/core/Solver.cc b/src/prop/minisat/core/Solver.cc index 4c5743c7c..675bc8f4e 100644 --- a/src/prop/minisat/core/Solver.cc +++ b/src/prop/minisat/core/Solver.cc @@ -27,6 +27,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "prop/theory_proxy.h" #include "prop/minisat/minisat.h" +#include "prop/options.h" #include "util/output.h" #include "expr/command.h" #include "proof/proof_manager.h" @@ -1079,7 +1080,7 @@ lbool Solver::search(int nof_conflicts) (int)max_learnts, nLearnts(), (double)learnts_literals/nLearnts(), progressEstimate()*100); } - if (theoryConflict && Options::current()->sat_refine_conflicts) { + if (theoryConflict && options::sat_refine_conflicts()) { check_type = CHECK_FINAL_FAKE; } else { check_type = CHECK_WITH_THEORY; diff --git a/src/prop/minisat/minisat.cpp b/src/prop/minisat/minisat.cpp index 6fa698bd0..464a41d74 100644 --- a/src/prop/minisat/minisat.cpp +++ b/src/prop/minisat/minisat.cpp @@ -18,6 +18,9 @@ #include "prop/minisat/minisat.h" #include "prop/minisat/simp/SimpSolver.h" +#include "prop/options.h" +#include "smt/options.h" +#include "decision/options.h" using namespace CVC4; using namespace CVC4::prop; @@ -106,26 +109,26 @@ void MinisatSatSolver::initialize(context::Context* context, TheoryProxy* theory d_context = context; - if( Options::current()->decisionMode != Options::DECISION_STRATEGY_INTERNAL ) { + if( options::decisionMode() != decision::DECISION_STRATEGY_INTERNAL ) { Notice() << "minisat: Incremental solving is disabled" << " unless using internal decision strategy." << std::endl; } // Create the solver d_minisat = new Minisat::SimpSolver(theoryProxy, d_context, - Options::current()->incrementalSolving || - Options::current()->decisionMode != Options::DECISION_STRATEGY_INTERNAL ); + options::incrementalSolving() || + options::decisionMode() != decision::DECISION_STRATEGY_INTERNAL ); // Setup the verbosity - d_minisat->verbosity = (Options::current()->verbosity > 0) ? 1 : -1; + d_minisat->verbosity = (options::verbosity() > 0) ? 1 : -1; // Setup the random decision parameters - d_minisat->random_var_freq = Options::current()->satRandomFreq; - d_minisat->random_seed = Options::current()->satRandomSeed; + d_minisat->random_var_freq = options::satRandomFreq(); + d_minisat->random_seed = options::satRandomSeed(); // Give access to all possible options in the sat solver - d_minisat->var_decay = Options::current()->satVarDecay; - d_minisat->clause_decay = Options::current()->satClauseDecay; - d_minisat->restart_first = Options::current()->satRestartFirst; - d_minisat->restart_inc = Options::current()->satRestartInc; + d_minisat->var_decay = options::satVarDecay(); + d_minisat->clause_decay = options::satClauseDecay(); + d_minisat->restart_first = options::satRestartFirst(); + d_minisat->restart_inc = options::satRestartInc(); d_statistics.init(d_minisat); } diff --git a/src/prop/minisat/simp/SimpSolver.cc b/src/prop/minisat/simp/SimpSolver.cc index 8da3856ff..bf04cec8d 100644 --- a/src/prop/minisat/simp/SimpSolver.cc +++ b/src/prop/minisat/simp/SimpSolver.cc @@ -21,6 +21,7 @@ OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWA #include "prop/minisat/mtl/Sort.h" #include "prop/minisat/simp/SimpSolver.h" #include "prop/minisat/utils/System.h" +#include "prop/options.h" #include "proof/proof.h" using namespace Minisat; using namespace CVC4; @@ -52,7 +53,7 @@ SimpSolver::SimpSolver(CVC4::prop::TheoryProxy* proxy, CVC4::context::Context* c , simp_garbage_frac (opt_simp_garbage_frac) , use_asymm (opt_use_asymm) , use_rcheck (opt_use_rcheck) - , use_elim (!enableIncremental) + , use_elim (options::minisatUseElim() && !enableIncremental) , merges (0) , asymm_lits (0) , eliminated_vars (0) @@ -63,6 +64,12 @@ SimpSolver::SimpSolver(CVC4::prop::TheoryProxy* proxy, CVC4::context::Context* c , bwdsub_assigns (0) , n_touched (0) { + if(options::minisatUseElim() && + options::minisatUseElim.wasSetByUser() && + enableIncremental) { + WarningOnce() << "Incremental mode incompatible with --minisat-elimination" << std::endl; + } + vec<Lit> dummy(1,lit_Undef); ca.extra_clause_field = true; // NOTE: must happen before allocating the dummy clause below. bwdsub_tmpunit = ca.alloc(0, dummy); diff --git a/src/prop/options b/src/prop/options new file mode 100644 index 000000000..c3c2674c4 --- /dev/null +++ b/src/prop/options @@ -0,0 +1,31 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module PROP "prop/options.h" SAT layer + +option - --show-sat-solvers void :handler CVC4::prop::showSatSolvers :handler-include "prop/options_handlers.h" + show all available SAT solvers + +option satRandomFreq random-frequency --random-freq=P double :default 0.0 :predicate greater_equal(0.0) less_equal(1.0) + sets the frequency of random decisions in the sat solver (P=0.0 by default) +option satRandomSeed random-seed --random-seed=S double :default 91648253 :read-write + sets the random seed for the sat solver + +option satVarDecay double :default 0.95 :predicate less_equal(1.0) greater_equal(0.0) + variable activity decay factor for Minisat +option satClauseDecay double :default 0.999 :predicate less_equal(1.0) greater_equal(0.0) + clause activity decay factor for Minisat +option satRestartFirst --restart-int-base=N unsigned :default 25 + sets the base restart interval for the sat solver (N=25 by default) +option satRestartInc --restart-int-inc=F double :default 3.0 :predicate greater_equal(0.0) + sets the restart interval increase factor for the sat solver (F=3.0 by default) + +option sat_refine_conflicts --refine-conflicts bool + refine theory conflict clauses + +option minisatUseElim --minisat-elimination bool :default true + use Minisat elimination + +endmodule diff --git a/src/prop/options_handlers.h b/src/prop/options_handlers.h new file mode 100644 index 000000000..efcb8d911 --- /dev/null +++ b/src/prop/options_handlers.h @@ -0,0 +1,49 @@ +/********************* */ +/*! \file options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__PROP__OPTIONS_HANDLERS_H +#define __CVC4__PROP__OPTIONS_HANDLERS_H + +#include "prop/sat_solver_factory.h" +#include <string> +#include <vector> + +namespace CVC4 { +namespace prop { + +inline void showSatSolvers(std::string option, SmtEngine* smt) { + std::vector<std::string> solvers; + SatSolverFactory::getSolverIds(solvers); + printf("Available SAT solvers: "); + for (unsigned i = 0; i < solvers.size(); ++ i) { + if (i > 0) { + printf(", "); + } + printf("%s", solvers[i].c_str()); + } + printf("\n"); + exit(0); +} + +}/* CVC4::prop namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__PROP__OPTIONS_HANDLERS_H */ diff --git a/src/prop/prop_engine.cpp b/src/prop/prop_engine.cpp index 0f138eb65..54309cd01 100644 --- a/src/prop/prop_engine.cpp +++ b/src/prop/prop_engine.cpp @@ -23,10 +23,12 @@ #include "prop/sat_solver_factory.h" #include "decision/decision_engine.h" +#include "decision/options.h" #include "theory/theory_engine.h" #include "theory/theory_registrar.h" #include "util/Assert.h" -#include "util/options.h" +#include "options/options.h" +#include "smt/options.h" #include "util/output.h" #include "util/result.h" #include "expr/expr.h" @@ -80,8 +82,8 @@ PropEngine::PropEngine(TheoryEngine* te, DecisionEngine *de, Context* context) : d_cnfStream = new CVC4::prop::TseitinCnfStream (d_satSolver, registrar, // fullLitToNode Map = - Options::current()->threads > 1 || - Options::current()->decisionMode == Options::DECISION_STRATEGY_RELEVANCY); + options::threads() > 1 || + options::decisionMode() == decision::DECISION_STRATEGY_RELEVANCY); d_satSolver->initialize(d_context, new TheoryProxy(this, d_theoryEngine, d_decisionEngine, d_context, d_cnfStream)); @@ -165,7 +167,7 @@ Result PropEngine::checkSat(unsigned long& millis, unsigned long& resource) { // TODO This currently ignores conflicts (a dangerous practice). d_theoryEngine->presolve(); - if(Options::current()->preprocessOnly) { + if(options::preprocessOnly()) { millis = resource = 0; return Result(Result::SAT_UNKNOWN, Result::REQUIRES_FULL_CHECK); } diff --git a/src/prop/prop_engine.h b/src/prop/prop_engine.h index dcfc5a9df..2d4e08db7 100644 --- a/src/prop/prop_engine.h +++ b/src/prop/prop_engine.h @@ -24,7 +24,7 @@ #define __CVC4__PROP_ENGINE_H #include "expr/node.h" -#include "util/options.h" +#include "options/options.h" #include "util/result.h" #include "smt/modal_exception.h" #include <sys/time.h> diff --git a/src/prop/sat_module.cpp b/src/prop/sat_module.cpp new file mode 100644 index 000000000..ca41eac2f --- /dev/null +++ b/src/prop/sat_module.cpp @@ -0,0 +1,478 @@ +/********************* */ +/*! \file sat.cpp + ** \verbatim + ** Original author: cconway + ** Major contributors: dejan, taking, mdeters, lianah + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "prop/prop_engine.h" +#include "prop/sat_module.h" +#include "context/context.h" +#include "theory/theory_engine.h" +#include "expr/expr_stream.h" +#include "prop/sat.h" + +// DPLLT Minisat +#include "prop/minisat/simp/SimpSolver.h" + +// BV Minisat +#include "prop/bvminisat/simp/SimpSolver.h" + + +using namespace std; + +namespace CVC4 { +namespace prop { + +string SatLiteral::toString() { + ostringstream os; + os << (isNegated()? "~" : "") << getSatVariable() << " "; + return os.str(); +} + +MinisatSatSolver::MinisatSatSolver() : + d_minisat(new BVMinisat::SimpSolver()) +{ + d_statistics.init(d_minisat); +} + +MinisatSatSolver::~MinisatSatSolver() { + delete d_minisat; +} + +void MinisatSatSolver::addClause(SatClause& clause, bool removable) { + Debug("sat::minisat") << "Add clause " << clause <<"\n"; + BVMinisat::vec<BVMinisat::Lit> minisat_clause; + toMinisatClause(clause, minisat_clause); + // for(unsigned i = 0; i < minisat_clause.size(); ++i) { + // d_minisat->setFrozen(BVMinisat::var(minisat_clause[i]), true); + // } + d_minisat->addClause(minisat_clause); +} + +SatVariable MinisatSatSolver::newVar(bool freeze){ + return d_minisat->newVar(true, true, freeze); +} + +void MinisatSatSolver::markUnremovable(SatLiteral lit){ + d_minisat->setFrozen(BVMinisat::var(toMinisatLit(lit)), true); +} + +void MinisatSatSolver::interrupt(){ + d_minisat->interrupt(); +} + +SatLiteralValue MinisatSatSolver::solve(){ + return toSatLiteralValue(d_minisat->solve()); +} + +SatLiteralValue MinisatSatSolver::solve(long unsigned int& resource){ + Trace("limit") << "MinisatSatSolver::solve(): have limit of " << resource << " conflicts" << std::endl; + if(resource == 0) { + d_minisat->budgetOff(); + } else { + d_minisat->setConfBudget(resource); + } + BVMinisat::vec<BVMinisat::Lit> empty; + unsigned long conflictsBefore = d_minisat->conflicts; + SatLiteralValue result = toSatLiteralValue(d_minisat->solveLimited(empty)); + d_minisat->clearInterrupt(); + resource = d_minisat->conflicts - conflictsBefore; + Trace("limit") << "<MinisatSatSolver::solve(): it took " << resource << " conflicts" << std::endl; + return result; +} + +SatLiteralValue MinisatSatSolver::solve(const context::CDList<SatLiteral> & assumptions){ + Debug("sat::minisat") << "Solve with assumptions "; + context::CDList<SatLiteral>::const_iterator it = assumptions.begin(); + BVMinisat::vec<BVMinisat::Lit> assump; + for(; it!= assumptions.end(); ++it) { + SatLiteral lit = *it; + Debug("sat::minisat") << lit <<" "; + assump.push(toMinisatLit(lit)); + } + Debug("sat::minisat") <<"\n"; + + SatLiteralValue result = toSatLiteralValue(d_minisat->solve(assump)); + return result; +} + + +void MinisatSatSolver::getUnsatCore(SatClause& unsatCore) { + // TODO add assertion to check the call was after an unsat call + for (int i = 0; i < d_minisat->conflict.size(); ++i) { + unsatCore.push_back(toSatLiteral(d_minisat->conflict[i])); + } +} + +SatLiteralValue MinisatSatSolver::value(SatLiteral l){ + Unimplemented(); + return SatValUnknown; +} + +SatLiteralValue MinisatSatSolver::modelValue(SatLiteral l){ + Unimplemented(); + return SatValUnknown; +} + +void MinisatSatSolver::unregisterVar(SatLiteral lit) { + // this should only be called when user context is implemented + // in the BVSatSolver + Unreachable(); +} + +void MinisatSatSolver::renewVar(SatLiteral lit, int level) { + // this should only be called when user context is implemented + // in the BVSatSolver + + Unreachable(); +} + +int MinisatSatSolver::getAssertionLevel() const { + // we have no user context implemented so far + return 0; +} + +// converting from internal Minisat representation + +SatVariable MinisatSatSolver::toSatVariable(BVMinisat::Var var) { + if (var == var_Undef) { + return undefSatVariable; + } + return SatVariable(var); +} + +BVMinisat::Lit MinisatSatSolver::toMinisatLit(SatLiteral lit) { + if (lit == undefSatLiteral) { + return BVMinisat::lit_Undef; + } + return BVMinisat::mkLit(lit.getSatVariable(), lit.isNegated()); +} + +SatLiteral MinisatSatSolver::toSatLiteral(BVMinisat::Lit lit) { + if (lit == BVMinisat::lit_Undef) { + return undefSatLiteral; + } + + return SatLiteral(SatVariable(BVMinisat::var(lit)), + BVMinisat::sign(lit)); +} + +SatLiteralValue MinisatSatSolver::toSatLiteralValue(bool res) { + if(res) return SatValTrue; + else return SatValFalse; +} + +SatLiteralValue MinisatSatSolver::toSatLiteralValue(BVMinisat::lbool res) { + if(res == (BVMinisat::lbool((uint8_t)0))) return SatValTrue; + if(res == (BVMinisat::lbool((uint8_t)2))) return SatValUnknown; + Assert(res == (BVMinisat::lbool((uint8_t)1))); + return SatValFalse; +} + +void MinisatSatSolver::toMinisatClause(SatClause& clause, + BVMinisat::vec<BVMinisat::Lit>& minisat_clause) { + for (unsigned i = 0; i < clause.size(); ++i) { + minisat_clause.push(toMinisatLit(clause[i])); + } + Assert(clause.size() == (unsigned)minisat_clause.size()); +} + +void MinisatSatSolver::toSatClause(BVMinisat::vec<BVMinisat::Lit>& clause, + SatClause& sat_clause) { + for (int i = 0; i < clause.size(); ++i) { + sat_clause.push_back(toSatLiteral(clause[i])); + } + Assert((unsigned)clause.size() == sat_clause.size()); +} + + +// Satistics for MinisatSatSolver + +MinisatSatSolver::Statistics::Statistics() : + d_statStarts("theory::bv::bvminisat::starts"), + d_statDecisions("theory::bv::bvminisat::decisions"), + d_statRndDecisions("theory::bv::bvminisat::rnd_decisions"), + d_statPropagations("theory::bv::bvminisat::propagations"), + d_statConflicts("theory::bv::bvminisat::conflicts"), + d_statClausesLiterals("theory::bv::bvminisat::clauses_literals"), + d_statLearntsLiterals("theory::bv::bvminisat::learnts_literals"), + d_statMaxLiterals("theory::bv::bvminisat::max_literals"), + d_statTotLiterals("theory::bv::bvminisat::tot_literals"), + d_statEliminatedVars("theory::bv::bvminisat::eliminated_vars") +{ + StatisticsRegistry::registerStat(&d_statStarts); + StatisticsRegistry::registerStat(&d_statDecisions); + StatisticsRegistry::registerStat(&d_statRndDecisions); + StatisticsRegistry::registerStat(&d_statPropagations); + StatisticsRegistry::registerStat(&d_statConflicts); + StatisticsRegistry::registerStat(&d_statClausesLiterals); + StatisticsRegistry::registerStat(&d_statLearntsLiterals); + StatisticsRegistry::registerStat(&d_statMaxLiterals); + StatisticsRegistry::registerStat(&d_statTotLiterals); + StatisticsRegistry::registerStat(&d_statEliminatedVars); +} + +MinisatSatSolver::Statistics::~Statistics() { + StatisticsRegistry::unregisterStat(&d_statStarts); + StatisticsRegistry::unregisterStat(&d_statDecisions); + StatisticsRegistry::unregisterStat(&d_statRndDecisions); + StatisticsRegistry::unregisterStat(&d_statPropagations); + StatisticsRegistry::unregisterStat(&d_statConflicts); + StatisticsRegistry::unregisterStat(&d_statClausesLiterals); + StatisticsRegistry::unregisterStat(&d_statLearntsLiterals); + StatisticsRegistry::unregisterStat(&d_statMaxLiterals); + StatisticsRegistry::unregisterStat(&d_statTotLiterals); + StatisticsRegistry::unregisterStat(&d_statEliminatedVars); +} + +void MinisatSatSolver::Statistics::init(BVMinisat::SimpSolver* minisat){ + d_statStarts.setData(minisat->starts); + d_statDecisions.setData(minisat->decisions); + d_statRndDecisions.setData(minisat->rnd_decisions); + d_statPropagations.setData(minisat->propagations); + d_statConflicts.setData(minisat->conflicts); + d_statClausesLiterals.setData(minisat->clauses_literals); + d_statLearntsLiterals.setData(minisat->learnts_literals); + d_statMaxLiterals.setData(minisat->max_literals); + d_statTotLiterals.setData(minisat->tot_literals); + d_statEliminatedVars.setData(minisat->eliminated_vars); +} + + + +//// DPllMinisatSatSolver + +DPLLMinisatSatSolver::DPLLMinisatSatSolver() : + d_minisat(NULL), + d_theoryProxy(NULL), + d_context(NULL) +{} + +DPLLMinisatSatSolver::~DPLLMinisatSatSolver() { + delete d_minisat; +} + +SatVariable DPLLMinisatSatSolver::toSatVariable(Minisat::Var var) { + if (var == var_Undef) { + return undefSatVariable; + } + return SatVariable(var); +} + +Minisat::Lit DPLLMinisatSatSolver::toMinisatLit(SatLiteral lit) { + if (lit == undefSatLiteral) { + return Minisat::lit_Undef; + } + return Minisat::mkLit(lit.getSatVariable(), lit.isNegated()); +} + +SatLiteral DPLLMinisatSatSolver::toSatLiteral(Minisat::Lit lit) { + if (lit == Minisat::lit_Undef) { + return undefSatLiteral; + } + + return SatLiteral(SatVariable(Minisat::var(lit)), + Minisat::sign(lit)); +} + +SatLiteralValue DPLLMinisatSatSolver::toSatLiteralValue(bool res) { + if(res) return SatValTrue; + else return SatValFalse; +} + +SatLiteralValue DPLLMinisatSatSolver::toSatLiteralValue(Minisat::lbool res) { + if(res == (Minisat::lbool((uint8_t)0))) return SatValTrue; + if(res == (Minisat::lbool((uint8_t)2))) return SatValUnknown; + Assert(res == (Minisat::lbool((uint8_t)1))); + return SatValFalse; +} + + +void DPLLMinisatSatSolver::toMinisatClause(SatClause& clause, + Minisat::vec<Minisat::Lit>& minisat_clause) { + for (unsigned i = 0; i < clause.size(); ++i) { + minisat_clause.push(toMinisatLit(clause[i])); + } + Assert(clause.size() == (unsigned)minisat_clause.size()); +} + +void DPLLMinisatSatSolver::toSatClause(Minisat::vec<Minisat::Lit>& clause, + SatClause& sat_clause) { + for (int i = 0; i < clause.size(); ++i) { + sat_clause.push_back(toSatLiteral(clause[i])); + } + Assert((unsigned)clause.size() == sat_clause.size()); +} + + +void DPLLMinisatSatSolver::initialize(context::Context* context, TheoryProxy* theoryProxy) +{ + + d_context = context; + + // Create the solver + d_minisat = new Minisat::SimpSolver(theoryProxy, d_context, + options::incrementalSolving()); + // Setup the verbosity + d_minisat->verbosity = (options::verbosity() > 0) ? 1 : -1; + + // Setup the random decision parameters + d_minisat->random_var_freq = options::satRandomFreq(); + d_minisat->random_seed = options::satRandomSeed(); + // Give access to all possible options in the sat solver + d_minisat->var_decay = options::satVarDecay(); + d_minisat->clause_decay = options::satClauseDecay(); + d_minisat->restart_first = options::satRestartFirst(); + d_minisat->restart_inc = options::satRestartInc(); + + d_statistics.init(d_minisat); +} + +void DPLLMinisatSatSolver::addClause(SatClause& clause, bool removable) { + Minisat::vec<Minisat::Lit> minisat_clause; + toMinisatClause(clause, minisat_clause); + d_minisat->addClause(minisat_clause, removable); +} + +SatVariable DPLLMinisatSatSolver::newVar(bool theoryAtom) { + return d_minisat->newVar(true, true, theoryAtom); +} + + +SatLiteralValue DPLLMinisatSatSolver::solve(unsigned long& resource) { + Trace("limit") << "SatSolver::solve(): have limit of " << resource << " conflicts" << std::endl; + if(resource == 0) { + d_minisat->budgetOff(); + } else { + d_minisat->setConfBudget(resource); + } + Minisat::vec<Minisat::Lit> empty; + unsigned long conflictsBefore = d_minisat->conflicts; + SatLiteralValue result = toSatLiteralValue(d_minisat->solveLimited(empty)); + d_minisat->clearInterrupt(); + resource = d_minisat->conflicts - conflictsBefore; + Trace("limit") << "SatSolver::solve(): it took " << resource << " conflicts" << std::endl; + return result; +} + +SatLiteralValue DPLLMinisatSatSolver::solve() { + d_minisat->budgetOff(); + return toSatLiteralValue(d_minisat->solve()); +} + + +void DPLLMinisatSatSolver::interrupt() { + d_minisat->interrupt(); +} + +SatLiteralValue DPLLMinisatSatSolver::value(SatLiteral l) { + return toSatLiteralValue(d_minisat->value(toMinisatLit(l))); +} + +SatLiteralValue DPLLMinisatSatSolver::modelValue(SatLiteral l){ + return toSatLiteralValue(d_minisat->modelValue(toMinisatLit(l))); +} + +bool DPLLMinisatSatSolver::properExplanation(SatLiteral lit, SatLiteral expl) const { + return true; +} + +/** Incremental interface */ + +int DPLLMinisatSatSolver::getAssertionLevel() const { + return d_minisat->getAssertionLevel(); +} + +void DPLLMinisatSatSolver::push() { + d_minisat->push(); +} + +void DPLLMinisatSatSolver::pop(){ + d_minisat->pop(); +} + +void DPLLMinisatSatSolver::unregisterVar(SatLiteral lit) { + d_minisat->unregisterVar(toMinisatLit(lit)); +} + +void DPLLMinisatSatSolver::renewVar(SatLiteral lit, int level) { + d_minisat->renewVar(toMinisatLit(lit), level); +} + +/// Statistics for DPLLMinisatSatSolver + +DPLLMinisatSatSolver::Statistics::Statistics() : + d_statStarts("sat::starts"), + d_statDecisions("sat::decisions"), + d_statRndDecisions("sat::rnd_decisions"), + d_statPropagations("sat::propagations"), + d_statConflicts("sat::conflicts"), + d_statClausesLiterals("sat::clauses_literals"), + d_statLearntsLiterals("sat::learnts_literals"), + d_statMaxLiterals("sat::max_literals"), + d_statTotLiterals("sat::tot_literals") +{ + StatisticsRegistry::registerStat(&d_statStarts); + StatisticsRegistry::registerStat(&d_statDecisions); + StatisticsRegistry::registerStat(&d_statRndDecisions); + StatisticsRegistry::registerStat(&d_statPropagations); + StatisticsRegistry::registerStat(&d_statConflicts); + StatisticsRegistry::registerStat(&d_statClausesLiterals); + StatisticsRegistry::registerStat(&d_statLearntsLiterals); + StatisticsRegistry::registerStat(&d_statMaxLiterals); + StatisticsRegistry::registerStat(&d_statTotLiterals); +} +DPLLMinisatSatSolver::Statistics::~Statistics() { + StatisticsRegistry::unregisterStat(&d_statStarts); + StatisticsRegistry::unregisterStat(&d_statDecisions); + StatisticsRegistry::unregisterStat(&d_statRndDecisions); + StatisticsRegistry::unregisterStat(&d_statPropagations); + StatisticsRegistry::unregisterStat(&d_statConflicts); + StatisticsRegistry::unregisterStat(&d_statClausesLiterals); + StatisticsRegistry::unregisterStat(&d_statLearntsLiterals); + StatisticsRegistry::unregisterStat(&d_statMaxLiterals); + StatisticsRegistry::unregisterStat(&d_statTotLiterals); +} +void DPLLMinisatSatSolver::Statistics::init(Minisat::SimpSolver* d_minisat){ + d_statStarts.setData(d_minisat->starts); + d_statDecisions.setData(d_minisat->decisions); + d_statRndDecisions.setData(d_minisat->rnd_decisions); + d_statPropagations.setData(d_minisat->propagations); + d_statConflicts.setData(d_minisat->conflicts); + d_statClausesLiterals.setData(d_minisat->clauses_literals); + d_statLearntsLiterals.setData(d_minisat->learnts_literals); + d_statMaxLiterals.setData(d_minisat->max_literals); + d_statTotLiterals.setData(d_minisat->tot_literals); +} + + +/* + + SatSolverFactory + + */ + +MinisatSatSolver* SatSolverFactory::createMinisat() { + return new MinisatSatSolver(); +} + +DPLLMinisatSatSolver* SatSolverFactory::createDPLLMinisat(){ + return new DPLLMinisatSatSolver(); +} + + +}/* CVC4::prop namespace */ +}/* CVC4 namespace */ diff --git a/src/prop/sat_solver.h b/src/prop/sat_solver.h index c30f18d29..ac80e4422 100644 --- a/src/prop/sat_solver.h +++ b/src/prop/sat_solver.h @@ -23,7 +23,6 @@ #include <string> #include <stdint.h> -#include "util/options.h" #include "util/stats.h" #include "context/cdlist.h" #include "prop/sat_solver_types.h" diff --git a/src/prop/theory_proxy.cpp b/src/prop/theory_proxy.cpp index 10d2aee8c..9ed2202fe 100644 --- a/src/prop/theory_proxy.cpp +++ b/src/prop/theory_proxy.cpp @@ -25,6 +25,7 @@ #include "theory/rewriter.h" #include "expr/expr_stream.h" #include "decision/decision_engine.h" +#include "decision/options.h" #include "util/lemma_input_channel.h" #include "util/lemma_output_channel.h" @@ -94,7 +95,7 @@ SatLiteral TheoryProxy::getNextDecisionRequest(bool &stopSearch) { if(stopSearch) { Trace("decision") << " *** Decision Engine stopped search *** " << std::endl; } - return Options::current()->decisionOptions.stopOnly ? undefSatLiteral : ret; + return options::decisionStopOnly() ? undefSatLiteral : ret; } bool TheoryProxy::theoryNeedCheck() const { @@ -115,10 +116,10 @@ void TheoryProxy::notifyRestart() { static uint32_t lemmaCount = 0; - if(Options::current()->lemmaInputChannel != NULL) { - while(Options::current()->lemmaInputChannel->hasNewLemma()) { + if(options::lemmaInputChannel() != NULL) { + while(options::lemmaInputChannel()->hasNewLemma()) { Debug("shared") << "shared" << std::endl; - Expr lemma = Options::current()->lemmaInputChannel->getNewLemma(); + Expr lemma = options::lemmaInputChannel()->getNewLemma(); Node asNode = lemma.getNode(); asNode = theory::Rewriter::rewrite(asNode); @@ -142,10 +143,10 @@ void TheoryProxy::notifyRestart() { void TheoryProxy::notifyNewLemma(SatClause& lemma) { Assert(lemma.size() > 0); - if(Options::current()->lemmaOutputChannel != NULL) { + if(options::lemmaOutputChannel() != NULL) { if(lemma.size() == 1) { // cannot share units yet - //Options::current()->lemmaOutputChannel->notifyNewLemma(d_cnfStream->getNode(lemma[0]).toExpr()); + //options::lemmaOutputChannel()->notifyNewLemma(d_cnfStream->getNode(lemma[0]).toExpr()); } else { NodeBuilder<> b(kind::OR); for(unsigned i = 0, i_end = lemma.size(); i < i_end; ++i) { @@ -155,7 +156,7 @@ void TheoryProxy::notifyNewLemma(SatClause& lemma) { if(d_shared.find(n) == d_shared.end()) { d_shared.insert(n); - Options::current()->lemmaOutputChannel->notifyNewLemma(n.toExpr()); + options::lemmaOutputChannel()->notifyNewLemma(n.toExpr()); } else { Debug("shared") <<"drop new " << n << std::endl; } @@ -165,8 +166,8 @@ void TheoryProxy::notifyNewLemma(SatClause& lemma) { SatLiteral TheoryProxy::getNextReplayDecision() { #ifdef CVC4_REPLAY - if(Options::current()->replayStream != NULL) { - Expr e = Options::current()->replayStream->nextExpr(); + if(options::replayStream() != NULL) { + Expr e = options::replayStream()->nextExpr(); if(!e.isNull()) { // we get null node when out of decisions to replay // convert & return return d_cnfStream->getLiteral(e); @@ -179,9 +180,9 @@ SatLiteral TheoryProxy::getNextReplayDecision() { void TheoryProxy::logDecision(SatLiteral lit) { #ifdef CVC4_REPLAY - if(Options::current()->replayLog != NULL) { + if(options::replayLog() != NULL) { Assert(lit != undefSatLiteral, "logging an `undef' decision ?!"); - *Options::current()->replayLog << d_cnfStream->getNode(lit) << std::endl; + *options::replayLog() << d_cnfStream->getNode(lit) << std::endl; } #endif /* CVC4_REPLAY */ } diff --git a/src/prop/theory_proxy.h b/src/prop/theory_proxy.h index 26357886c..e8da202bd 100644 --- a/src/prop/theory_proxy.h +++ b/src/prop/theory_proxy.h @@ -26,7 +26,6 @@ #define __CVC4_USE_MINISAT #include "theory/theory.h" -#include "util/options.h" #include "util/stats.h" #include "context/cdqueue.h" diff --git a/src/smt/Makefile.am b/src/smt/Makefile.am index 5cc0cedd1..9cc236a13 100644 --- a/src/smt/Makefile.am +++ b/src/smt/Makefile.am @@ -12,9 +12,16 @@ libsmt_la_SOURCES = \ smt_engine_scope.h \ modal_exception.h \ bad_option_exception.h \ - no_such_function_exception.h + no_such_function_exception.h \ + simplification_mode.h \ + simplification_mode.cpp + +nodist_libsmt_la_SOURCES = \ + smt_options.cpp EXTRA_DIST = \ + options_handlers.h \ + smt_options_template.cpp \ bad_option_exception.i \ no_such_function_exception.i \ modal_exception.i \ diff --git a/src/smt/options b/src/smt/options new file mode 100644 index 000000000..5ee65e50a --- /dev/null +++ b/src/smt/options @@ -0,0 +1,81 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +# FIXME: need to add support for SMT-LIBv2-required options: +# +# expand-definitions +# regular-output-channel +# diagnostic-output-channel +# produce-unsat-cores +# + +module SMT "smt/options.h" SMT layer + +common-option - --dump=MODE argument :handler CVC4::smt::dumpMode :handler-include "smt/options_handlers.h" + dump preprocessed assertions, etc., see --dump=help +common-option - --dump-to=FILE argument :handler CVC4::smt::dumpToFile :handler-include "smt/options_handlers.h" + all dumping goes to FILE (instead of stdout) + +expert-option lazyDefinitionExpansion --lazy-definition-expansion bool + expand define-funs/LAMBDAs lazily + +option simplificationMode --simplification=MODE SimplificationMode :handler CVC4::smt::stringToSimplificationMode :default SIMPLIFICATION_MODE_BATCH :read-write :include "smt/simplification_mode.h" :handler-include "smt/options_handlers.h" + choose simplification mode, see --simplification=help +alias --no-simplification = --simplification=none + turn off all simplification (same as --simplification=none) + +option doStaticLearning static-learning /--no-static-learning bool :default true + use static learning (on by default) +/turn off static learning (e.g. diamond-breaking) + +common-option produceModels produce-models -m --produce-models bool :predicate CVC4::SmtEngine::beforeSearch :predicate-include "smt/smt_engine.h" + support the get-value and get-model commands +common-option produceAssignments produce-assignments --produce-assignments bool + support the get-assignment command + +# This could go in src/main/options, but by SMT-LIBv2 spec, "interactive" +# is a mode in which the assertion list must be kept. So it belongs here. +common-option interactive interactive-mode --interactive bool :read-write + force interactive mode + +option doITESimp --ite-simp bool :read-write + turn on ite simplification (Kim (and Somenzi) et al., SAT 2009) +/turn off ite simplification (Kim (and Somenzi) et al., SAT 2009) + +option unconstrainedSimp --unconstrained-simp bool :default false :read-write + turn on unconstrained simplification (see Bruttomesso/Brummayer PhD thesis) +/turn off unconstrained simplification (see Bruttomesso/Brummayer PhD thesis) + +option repeatSimp --repeat-simp bool :read-write + make multiple passes with nonclausal simplifier +/do not make multiple passes with nonclausal simplifier + +common-option incrementalSolving incremental -i --incremental bool + enable incremental solving + +common-option cumulativeMillisecondLimit --tlimit=MS "unsigned long" + enable time limiting (give milliseconds) +common-option perCallMillisecondLimit --tlimit-per=MS "unsigned long" + enable time limiting per query (give milliseconds) +common-option cumulativeResourceLimit --rlimit=N "unsigned long" + enable resource limiting +common-option perCallResourceLimit --rlimit-per=N "unsigned long" + enable resource limiting per query + +option replayFilename --replay=FILE std::string :handler CVC4::smt::checkReplayFilename :handler-include "smt/options_handlers.h" + replay decisions from file +option replayLog --replay-log=FILE std::ostream* :handler CVC4::smt::checkReplayLogFilename :handler-include "smt/options_handlers.h" + log decisions and propagations to file +option replayStream ExprStream* + +# portfolio options +option threads --threads=N unsigned :default 2 + Total number of threads +option lemmaInputChannel LemmaInputChannel* :default NULL :include "util/lemma_input_channel.h" + The input channel to receive notfication events for new lemmas +option lemmaOutputChannel LemmaOutputChannel* :default NULL :include "util/lemma_output_channel.h" + The output channel to receive notfication events for new lemmas + +endmodule diff --git a/src/smt/options_handlers.h b/src/smt/options_handlers.h new file mode 100644 index 000000000..f111f512b --- /dev/null +++ b/src/smt/options_handlers.h @@ -0,0 +1,251 @@ +/********************* */ +/*! \file options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Custom handlers and predicates for SmtEngine options + ** + ** Custom handlers and predicates for SmtEngine options. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__SMT__OPTIONS_HANDLERS_H +#define __CVC4__SMT__OPTIONS_HANDLERS_H + +#include "util/dump.h" + +namespace CVC4 { +namespace smt { + +static const std::string dumpHelp = "\ +Dump modes currently supported by the --dump option:\n\ +\n\ +benchmark\n\ ++ Dump the benchmark structure (set-logic, push/pop, queries, etc.), but\n\ + does not include any declarations or assertions. Implied by all following\n\ + modes.\n\ +\n\ +declarations\n\ ++ Dump declarations. Implied by all following modes.\n\ +\n\ +assertions\n\ ++ Output the assertions after non-clausal simplification and static\n\ + learning phases, but before presolve-time T-lemmas arrive. If\n\ + non-clausal simplification and static learning are off\n\ + (--simplification=none --no-static-learning), the output\n\ + will closely resemble the input (with term-level ITEs removed).\n\ +\n\ +learned\n\ ++ Output the assertions after non-clausal simplification, static\n\ + learning, and presolve-time T-lemmas. This should include all eager\n\ + T-lemmas (in the form provided by the theory, which my or may not be\n\ + clausal). Also includes level-0 BCP done by Minisat.\n\ +\n\ +clauses\n\ ++ Do all the preprocessing outlined above, and dump the CNF-converted\n\ + output\n\ +\n\ +state\n\ ++ Dump all contextual assertions (e.g., SAT decisions, propagations..).\n\ + Implied by all \"stateful\" modes below and conflicts with all\n\ + non-stateful modes below.\n\ +\n\ +t-conflicts [non-stateful]\n\ ++ Output correctness queries for all theory conflicts\n\ +\n\ +missed-t-conflicts [stateful]\n\ ++ Output completeness queries for theory conflicts\n\ +\n\ +t-propagations [stateful]\n\ ++ Output correctness queries for all theory propagations\n\ +\n\ +missed-t-propagations [stateful]\n\ ++ Output completeness queries for theory propagations (LARGE and EXPENSIVE)\n\ +\n\ +t-lemmas [non-stateful]\n\ ++ Output correctness queries for all theory lemmas\n\ +\n\ +t-explanations [non-stateful]\n\ ++ Output correctness queries for all theory explanations\n\ +\n\ +bv-rewrites [non-stateful]\n\ ++ Output correctness queries for all bitvector rewrites\n\ +\n\ +theory::fullcheck [non-stateful]\n\ ++ Output completeness queries for all full-check effort-level theory checks\n\ +\n\ +Dump modes can be combined with multiple uses of --dump. Generally you want\n\ +one from the assertions category (either assertions, learned, or clauses), and\n\ +perhaps one or more stateful or non-stateful modes for checking correctness\n\ +and completeness of decision procedure implementations. Stateful modes dump\n\ +the contextual assertions made by the core solver (all decisions and\n\ +propagations as assertions; that affects the validity of the resulting\n\ +correctness and completeness queries, so of course stateful and non-stateful\n\ +modes cannot be mixed in the same run.\n\ +\n\ +The --output-language option controls the language used for dumping, and\n\ +this allows you to connect CVC4 to another solver implementation via a UNIX\n\ +pipe to perform on-line checking. The --dump-to option can be used to dump\n\ +to a file.\n\ +"; + +static const std::string simplificationHelp = "\ +Simplification modes currently supported by the --simplification option:\n\ +\n\ +batch (default) \n\ ++ save up all ASSERTions; run nonclausal simplification and clausal\n\ + (MiniSat) propagation for all of them only after reaching a querying command\n\ + (CHECKSAT or QUERY or predicate SUBTYPE declaration)\n\ +\n\ +incremental\n\ ++ run nonclausal simplification and clausal propagation at each ASSERT\n\ + (and at CHECKSAT/QUERY/SUBTYPE)\n\ +\n\ +none\n\ ++ do not perform nonclausal simplification\n\ +"; + +inline void dumpMode(std::string option, std::string optarg, SmtEngine* smt) { +#ifdef CVC4_DUMPING + char* optargPtr = strdup(optarg.c_str()); + char* tokstr = optargPtr; + char* toksave; + while((optargPtr = strtok_r(tokstr, ",", &toksave)) != NULL) { + tokstr = NULL; + if(!strcmp(optargPtr, "benchmark")) { + } else if(!strcmp(optargPtr, "declarations")) { + } else if(!strcmp(optargPtr, "assertions")) { + } else if(!strcmp(optargPtr, "learned")) { + } else if(!strcmp(optargPtr, "clauses")) { + } else if(!strcmp(optargPtr, "t-conflicts") || + !strcmp(optargPtr, "t-lemmas") || + !strcmp(optargPtr, "t-explanations") || + !strcmp(optargPtr, "bv-rewrites") || + !strcmp(optargPtr, "theory::fullcheck")) { + // These are "non-state-dumping" modes. If state (SAT decisions, + // propagations, etc.) is dumped, it will interfere with the validity + // of these generated queries. + if(Dump.isOn("state")) { + throw OptionException(std::string("dump option `") + optargPtr + + "' conflicts with a previous, " + "state-dumping dump option. You cannot " + "mix stateful and non-stateful dumping modes; " + "see --dump help."); + } else { + Dump.on("no-permit-state"); + } + } else if(!strcmp(optargPtr, "state") || + !strcmp(optargPtr, "missed-t-conflicts") || + !strcmp(optargPtr, "t-propagations") || + !strcmp(optargPtr, "missed-t-propagations")) { + // These are "state-dumping" modes. If state (SAT decisions, + // propagations, etc.) is not dumped, it will interfere with the + // validity of these generated queries. + if(Dump.isOn("no-permit-state")) { + throw OptionException(std::string("dump option `") + optargPtr + + "' conflicts with a previous, " + "non-state-dumping dump option. You cannot " + "mix stateful and non-stateful dumping modes; " + "see --dump help."); + } else { + Dump.on("state"); + } + } else if(!strcmp(optargPtr, "help")) { + puts(dumpHelp.c_str()); + exit(1); + } else { + throw OptionException(std::string("unknown option for --dump: `") + + optargPtr + "'. Try --dump help."); + } + + Dump.on(optargPtr); + Dump.on("benchmark"); + if(strcmp(optargPtr, "benchmark")) { + Dump.on("declarations"); + } + } + free(optargPtr); +#else /* CVC4_DUMPING */ + throw OptionException("The dumping feature was disabled in this build of CVC4."); +#endif /* CVC4_DUMPING */ +} + +inline void dumpToFile(std::string option, std::string optarg, SmtEngine* smt) { +#ifdef CVC4_DUMPING + size_t dagSetting = expr::ExprDag::getDag(Dump.getStream()); + if(optarg == "") { + throw OptionException(std::string("Bad file name for --dump-to")); + } else if(optarg == "-") { + Dump.setStream(DumpOutC::dump_cout); + } else { + std::ostream* dumpTo = new std::ofstream(optarg.c_str(), std::ofstream::out | std::ofstream::trunc); + if(!*dumpTo) { + throw OptionException(std::string("Cannot open dump-to file (maybe it exists): `") + optarg + "'"); + } + Dump.setStream(*dumpTo); + } + expr::ExprDag::setDag(Dump.getStream(), dagSetting); +#else /* CVC4_DUMPING */ + throw OptionException("The dumping feature was disabled in this build of CVC4."); +#endif /* CVC4_DUMPING */ +} + +inline SimplificationMode stringToSimplificationMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { + if(optarg == "batch") { + return SIMPLIFICATION_MODE_BATCH; + } else if(optarg == "incremental") { + return SIMPLIFICATION_MODE_INCREMENTAL; + } else if(optarg == "none") { + return SIMPLIFICATION_MODE_NONE; + } else if(optarg == "help") { + puts(simplificationHelp.c_str()); + exit(1); + } else { + throw OptionException(std::string("unknown option for --simplification: `") + + optarg + "'. Try --simplification help."); + } +} + +inline std::string checkReplayFilename(std::string option, std::string optarg, SmtEngine* smt) { +#ifdef CVC4_REPLAY + if(optarg == "") { + throw OptionException(std::string("Bad file name for --replay")); + } else { + return optarg; + } +#else /* CVC4_REPLAY */ + throw OptionException("The replay feature was disabled in this build of CVC4."); +#endif /* CVC4_REPLAY */ +} + +inline std::ostream* checkReplayLogFilename(std::string option, std::string optarg, SmtEngine* smt) { +#ifdef CVC4_REPLAY + if(optarg == "") { + throw OptionException(std::string("Bad file name for --replay-log")); + } else if(optarg == "-") { + return &std::cout; + } else { + std::ostream* replayLog = new std::ofstream(optarg.c_str(), std::ofstream::out | std::ofstream::trunc); + if(!*replayLog) { + throw OptionException(std::string("Cannot open replay-log file: `") + optarg + "'"); + } + return replayLog; + } +#else /* CVC4_REPLAY */ + throw OptionException("The replay feature was disabled in this build of CVC4."); +#endif /* CVC4_REPLAY */ +} + +}/* CVC4::smt namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__SMT__OPTIONS_HANDLERS_H */ diff --git a/src/smt/simplification_mode.cpp b/src/smt/simplification_mode.cpp new file mode 100644 index 000000000..7bae74417 --- /dev/null +++ b/src/smt/simplification_mode.cpp @@ -0,0 +1,42 @@ +/********************* */ +/*! \file simplification_mode.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "smt/simplification_mode.h" + +namespace CVC4 { + +std::ostream& operator<<(std::ostream& out, SimplificationMode mode) { + switch(mode) { + case SIMPLIFICATION_MODE_INCREMENTAL: + out << "SIMPLIFICATION_MODE_INCREMENTAL"; + break; + case SIMPLIFICATION_MODE_BATCH: + out << "SIMPLIFICATION_MODE_BATCH"; + break; + case SIMPLIFICATION_MODE_NONE: + out << "SIMPLIFICATION_MODE_NONE"; + break; + default: + out << "SimplificationMode:UNKNOWN![" << unsigned(mode) << "]"; + } + + return out; +} + +}/* CVC4 namespace */ diff --git a/src/smt/simplification_mode.h b/src/smt/simplification_mode.h new file mode 100644 index 000000000..6e0faafc0 --- /dev/null +++ b/src/smt/simplification_mode.h @@ -0,0 +1,43 @@ +/********************* */ +/*! \file simplification_mode.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_public.h" + +#ifndef __CVC4__SMT__SIMPLIFICATION_MODE_H +#define __CVC4__SMT__SIMPLIFICATION_MODE_H + +#include <iostream> + +namespace CVC4 { + +/** Enumeration of simplification modes (when to simplify). */ +typedef enum { + /** Simplify the assertions as they come in */ + SIMPLIFICATION_MODE_INCREMENTAL, + /** Simplify the assertions all together once a check is requested */ + SIMPLIFICATION_MODE_BATCH, + /** Don't do simplification */ + SIMPLIFICATION_MODE_NONE +} SimplificationMode; + +std::ostream& operator<<(std::ostream& out, SimplificationMode mode) CVC4_PUBLIC; + +}/* CVC4 namespace */ + +#endif /* __CVC4__SMT__SIMPLIFICATION_MODE_H */ diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp index 81a212edd..0acc53693 100644 --- a/src/smt/smt_engine.cpp +++ b/src/smt/smt_engine.cpp @@ -22,12 +22,16 @@ #include <utility> #include <sstream> #include <stack> +#include <cctype> +#include <algorithm> #include <ext/hash_map> #include "context/cdlist.h" #include "context/cdhashset.h" #include "context/context.h" #include "decision/decision_engine.h" +#include "decision/decision_mode.h" +#include "decision/options.h" #include "expr/command.h" #include "expr/expr.h" #include "expr/kind.h" @@ -45,12 +49,15 @@ #include "util/boolean_simplification.h" #include "util/configuration.h" #include "util/exception.h" -#include "util/options.h" +#include "smt/options.h" #include "util/output.h" #include "util/hash.h" #include "theory/substitutions.h" +#include "theory/uf/options.h" +#include "theory/arith/options.h" #include "theory/theory_traits.h" #include "theory/logic_info.h" +#include "theory/options.h" #include "theory/booleans/circuit_propagator.h" #include "util/ite_removal.h" #include "theory/model.h" @@ -309,24 +316,24 @@ SmtEngine::SmtEngine(ExprManager* em) throw(AssertionException) : // cleanup ordering issue and Nodes/TNodes. If SAT is popped // first, some user-context-dependent TNodes might still exist // with rc == 0. - if(Options::current()->interactive || - Options::current()->incrementalSolving) { + if(options::interactive() || + options::incrementalSolving()) { // In the case of incremental solving, we appear to need these to // ensure the relevant Nodes remain live. d_assertionList = new(true) AssertionList(d_userContext); } - if(Options::current()->perCallResourceLimit != 0) { - setResourceLimit(Options::current()->perCallResourceLimit, false); + if(options::perCallResourceLimit() != 0) { + setResourceLimit(options::perCallResourceLimit(), false); } - if(Options::current()->cumulativeResourceLimit != 0) { - setResourceLimit(Options::current()->cumulativeResourceLimit, true); + if(options::cumulativeResourceLimit() != 0) { + setResourceLimit(options::cumulativeResourceLimit(), true); } - if(Options::current()->perCallMillisecondLimit != 0) { - setTimeLimit(Options::current()->perCallMillisecondLimit, false); + if(options::perCallMillisecondLimit() != 0) { + setTimeLimit(options::perCallMillisecondLimit(), false); } - if(Options::current()->cumulativeMillisecondLimit != 0) { - setTimeLimit(Options::current()->cumulativeMillisecondLimit, true); + if(options::cumulativeMillisecondLimit() != 0) { + setTimeLimit(options::cumulativeMillisecondLimit(), true); } } @@ -380,7 +387,7 @@ SmtEngine::~SmtEngine() throw() { SmtScope smts(this); try { - while(Options::current()->incrementalSolving && d_userContext->getLevel() > 1) { + while(options::incrementalSolving() && d_userContext->getLevel() > 1) { internalPop(); } @@ -456,28 +463,28 @@ void SmtEngine::setLogicInternal() throw(AssertionException) { d_logic.lock(); // Set the options for the theoryOf - if(!Options::current()->theoryOfModeSetByUser) { + if(!options::theoryOfMode.wasSetByUser()) { if(d_logic.isSharingEnabled() && !d_logic.isTheoryEnabled(THEORY_BV)) { Theory::setTheoryOfMode(theory::THEORY_OF_TERM_BASED); } else { Theory::setTheoryOfMode(theory::THEORY_OF_TYPE_BASED); } } else { - Theory::setTheoryOfMode(Options::current()->theoryOfMode); + Theory::setTheoryOfMode(options::theoryOfMode()); } // by default, symmetry breaker is on only for QF_UF - if(! Options::current()->ufSymmetryBreakerSetByUser) { + if(! options::ufSymmetryBreaker.wasSetByUser()) { bool qf_uf = d_logic.isPure(THEORY_UF) && !d_logic.isQuantified(); Trace("smt") << "setting uf symmetry breaker to " << qf_uf << std::endl; - NodeManager::currentNM()->getOptions()->ufSymmetryBreaker = qf_uf; + options::ufSymmetryBreaker.set(qf_uf); } // by default, nonclausal simplification is off for QF_SAT and for quantifiers - if(! Options::current()->simplificationModeSetByUser) { + if(! options::simplificationMode.wasSetByUser()) { bool qf_sat = d_logic.isPure(THEORY_BOOL) && !d_logic.isQuantified(); bool quantifiers = d_logic.isQuantified(); Trace("smt") << "setting simplification mode to <" << d_logic.getLogicString() << "> " << (!qf_sat && !quantifiers) << std::endl; - NodeManager::currentNM()->getOptions()->simplificationMode = (qf_sat || quantifiers ? Options::SIMPLIFICATION_MODE_NONE : Options::SIMPLIFICATION_MODE_BATCH); + options::simplificationMode.set(qf_sat || quantifiers ? SIMPLIFICATION_MODE_NONE : SIMPLIFICATION_MODE_BATCH); } // If in arrays, set the UF handler to arrays @@ -487,48 +494,48 @@ void SmtEngine::setLogicInternal() throw(AssertionException) { Theory::setUninterpretedSortOwner(THEORY_UF); } // Turn on ite simplification for QF_LIA and QF_AUFBV - if(! Options::current()->doITESimpSetByUser) { + if(! options::doITESimp.wasSetByUser()) { bool iteSimp = !d_logic.isQuantified() && ((d_logic.isPure(THEORY_ARITH) && d_logic.isLinear() && !d_logic.isDifferenceLogic() && !d_logic.areRealsUsed()) || (d_logic.isTheoryEnabled(THEORY_ARRAY) && d_logic.isTheoryEnabled(THEORY_UF) && d_logic.isTheoryEnabled(THEORY_BV))); Trace("smt") << "setting ite simplification to " << iteSimp << std::endl; - NodeManager::currentNM()->getOptions()->doITESimp = iteSimp; + options::doITESimp.set(iteSimp); } // Turn on multiple-pass non-clausal simplification for QF_AUFBV - if(! Options::current()->repeatSimpSetByUser) { + if(! options::repeatSimp.wasSetByUser()) { bool repeatSimp = !d_logic.isQuantified() && (d_logic.isTheoryEnabled(THEORY_ARRAY) && d_logic.isTheoryEnabled(THEORY_UF) && d_logic.isTheoryEnabled(THEORY_BV)); Trace("smt") << "setting repeat simplification to " << repeatSimp << std::endl; - NodeManager::currentNM()->getOptions()->repeatSimp = repeatSimp; + options::repeatSimp.set(repeatSimp); } // Turn on unconstrained simplification for QF_AUFBV - if(! Options::current()->unconstrainedSimpSetByUser || Options::current()->incrementalSolving) { + if(! options::unconstrainedSimp.wasSetByUser() || options::incrementalSolving()) { // bool qf_sat = d_logic.isPure(THEORY_BOOL) && !d_logic.isQuantified(); - // bool uncSimp = false && !qf_sat && !Options::current()->incrementalSolving; - bool uncSimp = !Options::current()->incrementalSolving && !d_logic.isQuantified() && + // bool uncSimp = false && !qf_sat && !options::incrementalSolving(); + bool uncSimp = !options::incrementalSolving() && !d_logic.isQuantified() && (d_logic.isTheoryEnabled(THEORY_ARRAY) && d_logic.isTheoryEnabled(THEORY_BV)); Trace("smt") << "setting unconstrained simplification to " << uncSimp << std::endl; - NodeManager::currentNM()->getOptions()->unconstrainedSimp = uncSimp; + options::unconstrainedSimp.set(uncSimp); } // Turn on arith rewrite equalities only for pure arithmetic - if(! Options::current()->arithRewriteEqSetByUser) { + if(! options::arithRewriteEq.wasSetByUser()) { bool arithRewriteEq = d_logic.isPure(THEORY_ARITH) && !d_logic.isQuantified(); Trace("smt") << "setting arith rewrite equalities " << arithRewriteEq << std::endl; - NodeManager::currentNM()->getOptions()->arithRewriteEq = arithRewriteEq; + options::arithRewriteEq.set(arithRewriteEq); } - if(! Options::current()->arithHeuristicPivotsSetByUser){ + if(! options::arithHeuristicPivots.wasSetByUser()) { int16_t heuristicPivots = 5; - if(d_logic.isPure(THEORY_ARITH) && !d_logic.isQuantified()){ - if(d_logic.isDifferenceLogic()){ + if(d_logic.isPure(THEORY_ARITH) && !d_logic.isQuantified()) { + if(d_logic.isDifferenceLogic()) { heuristicPivots = -1; - }else if(!d_logic.areIntegersUsed()){ + } else if(!d_logic.areIntegersUsed()) { heuristicPivots = 0; } } Trace("smt") << "setting arithHeuristicPivots " << heuristicPivots << std::endl; - NodeManager::currentNM()->getOptions()->arithHeuristicPivots = heuristicPivots; + options::arithHeuristicPivots.set(heuristicPivots); } - if(! Options::current()->arithPivotThresholdSetByUser){ + if(! options::arithPivotThreshold.wasSetByUser()){ uint16_t pivotThreshold = 2; if(d_logic.isPure(THEORY_ARITH) && !d_logic.isQuantified()){ if(d_logic.isDifferenceLogic()){ @@ -536,24 +543,24 @@ void SmtEngine::setLogicInternal() throw(AssertionException) { } } Trace("smt") << "setting arith arithPivotThreshold " << pivotThreshold << std::endl; - NodeManager::currentNM()->getOptions()->arithPivotThreshold = pivotThreshold; + options::arithPivotThreshold.set(pivotThreshold); } - if(! Options::current()->arithStandardCheckVarOrderPivotsSetByUser){ + if(! options::arithStandardCheckVarOrderPivots.wasSetByUser()){ int16_t varOrderPivots = -1; if(d_logic.isPure(THEORY_ARITH) && !d_logic.isQuantified()){ varOrderPivots = 200; } Trace("smt") << "setting arithStandardCheckVarOrderPivots " << varOrderPivots << std::endl; - NodeManager::currentNM()->getOptions()->arithStandardCheckVarOrderPivots = varOrderPivots; + options::arithStandardCheckVarOrderPivots.set(varOrderPivots); } // Turn off early theory preprocessing if arithRewriteEq is on - if (NodeManager::currentNM()->getOptions()->arithRewriteEq) { + if (options::arithRewriteEq()) { d_earlyTheoryPP = false; } // Turn on justification heuristic of the decision engine for QF_BV and QF_AUFBV // and also use it in stop-only mode for QF_AUFLIA, QF_LRA and Quantifiers - if(!Options::current()->decisionModeSetByUser) { - Options::DecisionMode decMode = + if(!options::decisionMode.wasSetByUser()) { + decision::DecisionMode decMode = //QF_BV (not d_logic.isQuantified() && d_logic.isPure(THEORY_BV) @@ -576,8 +583,8 @@ void SmtEngine::setLogicInternal() throw(AssertionException) { ) || // Quantifiers d_logic.isQuantified() - ? Options::DECISION_STRATEGY_JUSTIFICATION - : Options::DECISION_STRATEGY_INTERNAL; + ? decision::DECISION_STRATEGY_JUSTIFICATION + : decision::DECISION_STRATEGY_INTERNAL; bool stoponly = // QF_AUFLIA @@ -595,12 +602,12 @@ void SmtEngine::setLogicInternal() throw(AssertionException) { ? true : false; Trace("smt") << "setting decision mode to " << decMode << std::endl; - NodeManager::currentNM()->getOptions()->decisionMode = decMode; - NodeManager::currentNM()->getOptions()->decisionOptions.stopOnly = stoponly; + options::decisionMode.set(decMode); + options::decisionStopOnly.set(stoponly); } } -void SmtEngine::setInfo(const std::string& key, const SExpr& value) +void SmtEngine::setInfo(const std::string& key, const CVC4::SExpr& value) throw(BadOptionException, ModalException) { SmtScope smts(this); @@ -636,15 +643,15 @@ void SmtEngine::setInfo(const std::string& key, const SExpr& value) } // Check for standard info keys (SMT-LIB v1, SMT-LIB v2, ...) - if(key == ":name" || - key == ":source" || - key == ":category" || - key == ":difficulty" || - key == ":smt-lib-version" || - key == ":notes") { + if(key == "name" || + key == "source" || + key == "category" || + key == "difficulty" || + key == "smt-lib-version" || + key == "notes") { // ignore these return; - } else if(key == ":status") { + } else if(key == "status") { string s; if(value.isAtom()) { s = value.getValue(); @@ -659,16 +666,24 @@ void SmtEngine::setInfo(const std::string& key, const SExpr& value) throw BadOptionException(); } -SExpr SmtEngine::getInfo(const std::string& key) const +CVC4::SExpr SmtEngine::getInfo(const std::string& key) const throw(BadOptionException, ModalException) { SmtScope smts(this); Trace("smt") << "SMT getInfo(" << key << ")" << endl; - if(key == ":all-statistics") { + if(key == "all-statistics") { vector<SExpr> stats; - for(StatisticsRegistry::const_iterator i = StatisticsRegistry::begin(); - i != StatisticsRegistry::end(); + for(StatisticsRegistry::const_iterator i = d_exprManager->getStatisticsRegistry()->begin_(); + i != d_exprManager->getStatisticsRegistry()->end_(); + ++i) { + vector<SExpr> v; + v.push_back((*i)->getName()); + v.push_back((*i)->getValue()); + stats.push_back(v); + } + for(StatisticsRegistry::const_iterator i = d_statisticsRegistry->begin_(); + i != d_statisticsRegistry->end_(); ++i) { vector<SExpr> v; v.push_back((*i)->getName()); @@ -676,21 +691,32 @@ SExpr SmtEngine::getInfo(const std::string& key) const stats.push_back(v); } return stats; - } else if(key == ":error-behavior") { + } else if(key == "error-behavior") { + // immediate-exit | continued-execution return SExpr::Keyword("immediate-exit"); - } else if(key == ":name") { + } else if(key == "name") { return Configuration::getName(); - } else if(key == ":version") { + } else if(key == "version") { return Configuration::getVersionString(); - } else if(key == ":authors") { + } else if(key == "authors") { return Configuration::about(); - } else if(key == ":status") { - return d_status.asSatisfiabilityResult().toString(); - } else if(key == ":reason-unknown") { + } else if(key == "status") { + // sat | unsat | unknown + switch(d_status.asSatisfiabilityResult().isSat()) { + case Result::SAT: + return SExpr::Keyword("sat"); + case Result::UNSAT: + return SExpr::Keyword("unsat"); + default: + return SExpr::Keyword("unknown"); + } + } else if(key == "reason-unknown") { if(!d_status.isNull() && d_status.isUnknown()) { stringstream ss; ss << d_status.whyUnknown(); - return SExpr::Keyword(ss.str()); + string s = ss.str(); + transform(s.begin(), s.end(), s.begin(), ::tolower); + return SExpr::Keyword(s); } else { throw ModalException("Can't get-info :reason-unknown when the " "last result wasn't unknown!"); @@ -700,98 +726,6 @@ SExpr SmtEngine::getInfo(const std::string& key) const } } -void SmtEngine::setOption(const std::string& key, const SExpr& value) - throw(BadOptionException, ModalException) { - - SmtScope smts(this); - - Trace("smt") << "SMT setOption(" << key << ", " << value << ")" << endl; - if(Dump.isOn("benchmark")) { - Dump("benchmark") << SetOptionCommand(key, value); - } - - if(key == ":print-success") { - if(value.isAtom() && value.getValue() == "false") { - *Options::current()->out << Command::printsuccess(false); - } else if(value.isAtom() && value.getValue() == "true") { - *Options::current()->out << Command::printsuccess(true); - } else { - throw BadOptionException(); - } - } else if(key == ":expand-definitions") { - throw BadOptionException(); - } else if(key == ":interactive-mode") { - throw BadOptionException(); - } else if(key == ":regular-output-channel") { - throw BadOptionException(); - } else if(key == ":diagnostic-output-channel") { - throw BadOptionException(); - } else if(key == ":random-seed") { - throw BadOptionException(); - } else if(key == ":verbosity") { - throw BadOptionException(); - } else { - // The following options can only be set at the beginning; we throw - // a ModalException if someone tries. - if(d_logic.isLocked()) { - throw ModalException("logic already set; cannot set options"); - } - - if(key == ":produce-proofs") { - throw BadOptionException(); - } else if(key == ":produce-unsat-cores") { - throw BadOptionException(); - } else if(key == ":produce-models") { - //throw BadOptionException(); - const_cast<Options*>( Options::s_current )->produceModels = true; - } else if(key == ":produce-assignments") { - throw BadOptionException(); - } else { - throw BadOptionException(); - } - } -} - -SExpr SmtEngine::getOption(const std::string& key) const - throw(BadOptionException) { - - SmtScope smts(this); - - Trace("smt") << "SMT getOption(" << key << ")" << endl; - if(Dump.isOn("benchmark")) { - Dump("benchmark") << GetOptionCommand(key); - } - if(key == ":print-success") { - if(Command::printsuccess::getPrintSuccess(*Options::current()->out)) { - return SExpr("true"); - } else { - return SExpr("false"); - } - } else if(key == ":expand-definitions") { - throw BadOptionException(); - } else if(key == ":interactive-mode") { - throw BadOptionException(); - } else if(key == ":produce-proofs") { - throw BadOptionException(); - } else if(key == ":produce-unsat-cores") { - throw BadOptionException(); - } else if(key == ":produce-models") { - throw BadOptionException(); - } else if(key == ":produce-assignments") { - throw BadOptionException(); - } else if(key == ":regular-output-channel") { - return SExpr("stdout"); - } else if(key == ":diagnostic-output-channel") { - return SExpr("stderr"); - } else if(key == ":random-seed") { - throw BadOptionException(); - } else if(key == ":verbosity") { - throw BadOptionException(); - } else { - throw BadOptionException(); - } -} - void SmtEngine::defineFunction(Expr func, const std::vector<Expr>& formals, Expr formula) { @@ -805,7 +739,7 @@ void SmtEngine::defineFunction(Expr func, SmtScope smts(this); // type check body - Type formulaType = formula.getType(Options::current()->typeChecking); + Type formulaType = formula.getType(options::typeChecking()); Type funcType = func.getType(); // We distinguish here between definitions of constants and functions, @@ -1151,8 +1085,8 @@ bool SmtEnginePrivate::nonClausalSimplify() { Assert(d_realAssertionsEnd <= d_assertionsToCheck.size()); learnedBuilder << d_assertionsToCheck[d_realAssertionsEnd-1]; - if( Options::current()->incrementalSolving || - Options::current()->simplificationMode == Options::SIMPLIFICATION_MODE_INCREMENTAL ) { + if( options::incrementalSolving() || + options::simplificationMode() == SIMPLIFICATION_MODE_INCREMENTAL ) { // Keep substitutions SubstitutionMap::iterator pos = d_lastSubstitutionPos; if(pos == d_topLevelSubstitutions.end()) { @@ -1306,7 +1240,7 @@ bool SmtEnginePrivate::simplifyAssertions() Trace("simplify") << "SmtEnginePrivate::simplify()" << endl; - if(Options::current()->simplificationMode != Options::SIMPLIFICATION_MODE_NONE) { + if(options::simplificationMode() != SIMPLIFICATION_MODE_NONE) { // Perform non-clausal simplification Trace("simplify") << "SmtEnginePrivate::simplify(): " << "performing non-clausal simplification" << endl; @@ -1338,7 +1272,7 @@ bool SmtEnginePrivate::simplifyAssertions() Debug("smt") << " d_assertionsToCheck : " << d_assertionsToCheck.size() << endl; // ITE simplification - if(Options::current()->doITESimp) { + if(options::doITESimp()) { simpITE(); } @@ -1347,7 +1281,7 @@ bool SmtEnginePrivate::simplifyAssertions() Debug("smt") << " d_assertionsToCheck : " << d_assertionsToCheck.size() << endl; // Unconstrained simplification - if(Options::current()->unconstrainedSimp) { + if(options::unconstrainedSimp()) { unconstrainedSimp(); } @@ -1355,7 +1289,7 @@ bool SmtEnginePrivate::simplifyAssertions() Debug("smt") << " d_assertionsToPreprocess: " << d_assertionsToPreprocess.size() << endl; Debug("smt") << " d_assertionsToCheck : " << d_assertionsToCheck.size() << endl; - if(Options::current()->repeatSimp && Options::current()->simplificationMode != Options::SIMPLIFICATION_MODE_NONE) { + if(options::repeatSimp() && options::simplificationMode() != SIMPLIFICATION_MODE_NONE) { Trace("simplify") << "SmtEnginePrivate::simplify(): " << " doing repeated simplification" << std::endl; d_assertionsToCheck.swap(d_assertionsToPreprocess); @@ -1458,7 +1392,7 @@ void SmtEnginePrivate::processAssertions() { Debug("smt") << " d_assertionsToPreprocess: " << d_assertionsToPreprocess.size() << endl; Debug("smt") << " d_assertionsToCheck : " << d_assertionsToCheck.size() << endl; - if(!Options::current()->lazyDefinitionExpansion) { + if(!options::lazyDefinitionExpansion()) { Trace("simplify") << "SmtEnginePrivate::simplify(): expanding definitions" << endl; TimerStat::CodeTimer codeTimer(d_smt.d_definitionExpansionTime); hash_map<TNode, Node, TNodeHashFunction> cache; @@ -1480,7 +1414,7 @@ void SmtEnginePrivate::processAssertions() { bool noConflict = simplifyAssertions(); - if(Options::current()->doStaticLearning) { + if(options::doStaticLearning()) { // Perform static learning Trace("simplify") << "SmtEnginePrivate::simplify(): " << "performing static learning" << endl; @@ -1495,7 +1429,7 @@ void SmtEnginePrivate::processAssertions() { d_smt.d_numAssertionsPost += d_assertionsToCheck.size(); } - if(Options::current()->repeatSimp) { + if(options::repeatSimp()) { d_assertionsToCheck.swap(d_assertionsToPreprocess); noConflict &= simplifyAssertions(); if (noConflict) { @@ -1583,13 +1517,13 @@ void SmtEnginePrivate::addFormula(TNode n) d_assertionsToPreprocess.push_back(Rewriter::rewrite(n)); // If the mode of processing is incremental prepreocess and assert immediately - if (Options::current()->simplificationMode == Options::SIMPLIFICATION_MODE_INCREMENTAL) { + if (options::simplificationMode() == SIMPLIFICATION_MODE_INCREMENTAL) { processAssertions(); } } void SmtEngine::ensureBoolean(const BoolExpr& e) { - Type type = e.getType(Options::current()->typeChecking); + Type type = e.getType(options::typeChecking()); Type boolType = d_exprManager->booleanType(); if(type != boolType) { stringstream ss; @@ -1610,7 +1544,7 @@ Result SmtEngine::checkSat(const BoolExpr& e) { Trace("smt") << "SmtEngine::checkSat(" << e << ")" << endl; - if(d_queryMade && !Options::current()->incrementalSolving) { + if(d_queryMade && !options::incrementalSolving()) { throw ModalException("Cannot make multiple queries unless " "incremental solving is enabled " "(try --incremental)"); @@ -1673,7 +1607,7 @@ Result SmtEngine::query(const BoolExpr& e) { Trace("smt") << "SMT query(" << e << ")" << endl; - if(d_queryMade && !Options::current()->incrementalSolving) { + if(d_queryMade && !options::incrementalSolving()) { throw ModalException("Cannot make multiple queries unless " "incremental solving is enabled " "(try --incremental)"); @@ -1738,7 +1672,7 @@ Expr SmtEngine::simplify(const Expr& e) { Assert(e.getExprManager() == d_exprManager); SmtScope smts(this); finalOptionsAreSet(); - if( Options::current()->typeChecking ) { + if( options::typeChecking() ) { e.getType(true);// ensure expr is type-checked at this point } Trace("smt") << "SMT simplify(" << e << ")" << endl; @@ -1754,13 +1688,13 @@ Expr SmtEngine::getValue(const Expr& e) SmtScope smts(this); // ensure expr is type-checked at this point - Type type = e.getType(Options::current()->typeChecking); + Type type = e.getType(options::typeChecking()); Trace("smt") << "SMT getValue(" << e << ")" << endl; if(Dump.isOn("benchmark")) { Dump("benchmark") << GetValueCommand(e); } - if(!Options::current()->produceModels) { + if(!options::produceModels()) { const char* msg = "Cannot get value when produce-models options is off."; throw ModalException(msg); @@ -1799,7 +1733,7 @@ Expr SmtEngine::getValue(const Expr& e) bool SmtEngine::addToAssignment(const Expr& e) throw(AssertionException) { SmtScope smts(this); finalOptionsAreSet(); - Type type = e.getType(Options::current()->typeChecking); + Type type = e.getType(options::typeChecking()); // must be Boolean CheckArgument( type.isBoolean(), e, "expected Boolean-typed variable or function application " @@ -1813,7 +1747,7 @@ bool SmtEngine::addToAssignment(const Expr& e) throw(AssertionException) { n.getMetaKind() == kind::metakind::VARIABLE ), e, "expected variable or defined-function application " "in addToAssignment(),\ngot %s", e.toString().c_str() ); - if(!Options::current()->produceAssignments) { + if(!options::produceAssignments()) { return false; } if(d_assignments == NULL) { @@ -1824,14 +1758,14 @@ bool SmtEngine::addToAssignment(const Expr& e) throw(AssertionException) { return true; } -SExpr SmtEngine::getAssignment() throw(ModalException, AssertionException) { +CVC4::SExpr SmtEngine::getAssignment() throw(ModalException, AssertionException) { Trace("smt") << "SMT getAssignment()" << endl; SmtScope smts(this); finalOptionsAreSet(); if(Dump.isOn("benchmark")) { Dump("benchmark") << GetAssignmentCommand(); } - if(!Options::current()->produceAssignments) { + if(!options::produceAssignments()) { const char* msg = "Cannot get the current assignment when " "produce-assignments option is off."; @@ -1890,7 +1824,7 @@ void SmtEngine::addToModelType( Type& t ){ Trace("smt") << "SMT addToModelType(" << t << ")" << endl; SmtScope smts(this); finalOptionsAreSet(); - if( Options::current()->produceModels ) { + if( options::produceModels() ) { d_theoryEngine->getModel()->addDefineType( TypeNode::fromType( t ) ); } } @@ -1899,7 +1833,7 @@ void SmtEngine::addToModelFunction( Expr& e ){ Trace("smt") << "SMT addToModelFunction(" << e << ")" << endl; SmtScope smts(this); finalOptionsAreSet(); - if( Options::current()->produceModels ) { + if( options::produceModels() ) { d_theoryEngine->getModel()->addDefineFunction( e.getNode() ); } } @@ -1909,9 +1843,9 @@ Model* SmtEngine::getModel() throw(ModalException, AssertionException){ Trace("smt") << "SMT getModel()" << endl; SmtScope smts(this); - if(!Options::current()->produceModels) { + if(!options::produceModels()) { const char* msg = - "Cannot get value when produce-models options is off."; + "Cannot get model when produce-models options is off."; throw ModalException(msg); } if(d_status.isNull() || @@ -1934,7 +1868,7 @@ Proof* SmtEngine::getProof() throw(ModalException, AssertionException) { Dump("benchmark") << GetProofCommand(); } #ifdef CVC4_PROOF - if(!Options::current()->proof) { + if(!options::proof()) { const char* msg = "Cannot get a proof when produce-proofs option is off."; throw ModalException(msg); @@ -1960,7 +1894,7 @@ vector<Expr> SmtEngine::getAssertions() } SmtScope smts(this); Trace("smt") << "SMT getAssertions()" << endl; - if(!Options::current()->interactive) { + if(!options::interactive()) { const char* msg = "Cannot query the current assertion list when not in interactive mode."; throw ModalException(msg); @@ -1983,7 +1917,7 @@ void SmtEngine::push() { if(Dump.isOn("benchmark")) { Dump("benchmark") << PushCommand(); } - if(!Options::current()->incrementalSolving) { + if(!options::incrementalSolving()) { throw ModalException("Cannot push when not solving incrementally (use --incremental)"); } @@ -2006,7 +1940,7 @@ void SmtEngine::pop() { if(Dump.isOn("benchmark")) { Dump("benchmark") << PopCommand(); } - if(!Options::current()->incrementalSolving) { + if(!options::incrementalSolving()) { throw ModalException("Cannot pop when not solving incrementally (use --incremental)"); } if(d_userContext->getLevel() == 0) { @@ -2039,7 +1973,7 @@ void SmtEngine::pop() { void SmtEngine::internalPush() { Assert(d_fullyInited); Trace("smt") << "SmtEngine::internalPush()" << endl; - if(Options::current()->incrementalSolving) { + if(options::incrementalSolving()) { d_private->processAssertions(); d_userContext->push(); d_context->push(); @@ -2050,7 +1984,7 @@ void SmtEngine::internalPush() { void SmtEngine::internalPop() { Assert(d_fullyInited); Trace("smt") << "SmtEngine::internalPop()" << endl; - if(Options::current()->incrementalSolving) { + if(options::incrementalSolving()) { d_propEngine->pop(); d_context->pop(); d_userContext->pop(); diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h index efb2425a1..5f0511894 100644 --- a/src/smt/smt_engine.h +++ b/src/smt/smt_engine.h @@ -34,7 +34,7 @@ #include "smt/modal_exception.h" #include "smt/no_such_function_exception.h" #include "util/hash.h" -#include "util/options.h" +#include "options/options.h" #include "util/result.h" #include "util/sexpr.h" #include "util/stats.h" @@ -302,25 +302,25 @@ public: /** * Set information about the script executing. */ - void setInfo(const std::string& key, const SExpr& value) + void setInfo(const std::string& key, const CVC4::SExpr& value) throw(BadOptionException, ModalException); /** * Query information about the SMT environment. */ - SExpr getInfo(const std::string& key) const + CVC4::SExpr getInfo(const std::string& key) const throw(BadOptionException, ModalException); /** * Set an aspect of the current SMT execution environment. */ - void setOption(const std::string& key, const SExpr& value) + void setOption(const std::string& key, const CVC4::SExpr& value) throw(BadOptionException, ModalException); /** * Get an aspect of the current SMT execution environment. */ - SExpr getOption(const std::string& key) const + CVC4::SExpr getOption(const std::string& key) const throw(BadOptionException); /** @@ -388,7 +388,7 @@ public: * INVALID query). Only permitted if the SmtEngine is set to * operate interactively and produce-assignments is on. */ - SExpr getAssignment() throw(ModalException, AssertionException); + CVC4::SExpr getAssignment() throw(ModalException, AssertionException); /** * Add to Model Type. This is used for recording which types should be reported @@ -552,6 +552,17 @@ public: } /** + * Used as a predicate for options preprocessor. + */ + static void beforeSearch(std::string option, bool value, SmtEngine* smt) { + if(smt->d_queryMade || smt->d_problemExtended) { + std::stringstream ss; + ss << "cannot change option `" << option << "' after assertions have been made"; + throw OptionException(ss.str()); + } + } + + /** * print model function (need this?) */ void printModel( std::ostream& out, Model* m ); diff --git a/src/smt/smt_options_template.cpp b/src/smt/smt_options_template.cpp new file mode 100644 index 000000000..8c7fa1abf --- /dev/null +++ b/src/smt/smt_options_template.cpp @@ -0,0 +1,78 @@ +/********************* */ +/*! \file smt_options_template.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Option handling for SmtEngine + ** + ** Option handling for SmtEngine. + **/ + +#include "smt/smt_engine.h" +#include "smt/bad_option_exception.h" +#include "smt/modal_exception.h" +#include "util/sexpr.h" +#include "util/dump.h" +#include "expr/command.h" +#include "expr/node_manager.h" + +#include <string> +#include <sstream> + +${include_all_option_headers} +${option_handler_includes} + +#line 34 "${template}" + +using namespace std; + +namespace CVC4 { + +void SmtEngine::setOption(const std::string& key, const CVC4::SExpr& value) + throw(BadOptionException, ModalException) { + + NodeManagerScope nms(d_nodeManager); + SmtEngine* const smt = this; + + Trace("smt") << "SMT setOption(" << key << ", " << value << ")" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << SetOptionCommand(key, value); + } + + stringstream ss; + ss << value; + string optarg = ss.str(); + + ${smt_setoption_handlers} + +#line 57 "${template}" + + throw BadOptionException(); +} + +CVC4::SExpr SmtEngine::getOption(const std::string& key) const + throw(BadOptionException) { + + NodeManagerScope nms(d_nodeManager); + + Trace("smt") << "SMT getOption(" << key << ")" << endl; + if(Dump.isOn("benchmark")) { + Dump("benchmark") << GetOptionCommand(key); + } + + ${smt_getoption_handlers} + +#line 74 "${template}" + + throw BadOptionException(); +} + +}/* CVC4 namespace */ diff --git a/src/theory/Makefile.am b/src/theory/Makefile.am index 9d6939ac9..7a4cde04d 100644 --- a/src/theory/Makefile.am +++ b/src/theory/Makefile.am @@ -74,6 +74,7 @@ libtheory_la_LIBADD = \ @builddir@/rewriterules/librewriterules.la EXTRA_DIST = \ + options_handlers.h \ rewriter_tables_template.h \ instantiator_tables_template.cpp \ theory_traits_template.h \ diff --git a/src/theory/arith/Makefile.am b/src/theory/arith/Makefile.am index 68b580c54..b71f07852 100644 --- a/src/theory/arith/Makefile.am +++ b/src/theory/arith/Makefile.am @@ -38,8 +38,15 @@ libarith_la_SOURCES = \ theory_arith.cpp \ dio_solver.h \ dio_solver.cpp \ + arith_heuristic_pivot_rule.h \ + arith_heuristic_pivot_rule.cpp \ + arith_unate_lemma_mode.h \ + arith_unate_lemma_mode.cpp \ + arith_propagation_mode.h \ + arith_propagation_mode.cpp \ theory_arith_instantiator.h \ theory_arith_instantiator.cpp EXTRA_DIST = \ - kinds + kinds \ + options_handlers.h diff --git a/src/theory/arith/arith_heuristic_pivot_rule.cpp b/src/theory/arith/arith_heuristic_pivot_rule.cpp new file mode 100644 index 000000000..1a2958556 --- /dev/null +++ b/src/theory/arith/arith_heuristic_pivot_rule.cpp @@ -0,0 +1,43 @@ +/********************* */ +/*! \file arith_heuristic_pivot_rule.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "theory/arith/arith_heuristic_pivot_rule.h" + +namespace CVC4 { + +std::ostream& operator<<(std::ostream& out, ArithHeuristicPivotRule rule) { + switch(rule) { + case MINIMUM: + out << "MINIMUM"; + break; + case BREAK_TIES: + out << "BREAK_TIES"; + break; + case MAXIMUM: + out << "MAXIMUM"; + break; + default: + out << "ArithHeuristicPivotRule!UNKNOWN"; + } + + return out; +} + +}/* CVC4 namespace */ + diff --git a/src/theory/arith/arith_heuristic_pivot_rule.h b/src/theory/arith/arith_heuristic_pivot_rule.h new file mode 100644 index 000000000..ef0f8cfe5 --- /dev/null +++ b/src/theory/arith/arith_heuristic_pivot_rule.h @@ -0,0 +1,39 @@ +/********************* */ +/*! \file arith_heuristic_pivot_rule.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_public.h" + +#ifndef __CVC4__THEORY__ARITH__ARITH_HEURISTIC_PIVOT_RULE_H +#define __CVC4__THEORY__ARITH__ARITH_HEURISTIC_PIVOT_RULE_H + +#include <iostream> + +namespace CVC4 { + +typedef enum { + MINIMUM, + BREAK_TIES, + MAXIMUM +} ArithHeuristicPivotRule; + +std::ostream& operator<<(std::ostream& out, ArithHeuristicPivotRule rule) CVC4_PUBLIC; + +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__ARITH__ARITH_HEURISTIC_PIVOT_RULE_H */ diff --git a/src/theory/arith/arith_propagation_mode.cpp b/src/theory/arith/arith_propagation_mode.cpp new file mode 100644 index 000000000..08c56ad3b --- /dev/null +++ b/src/theory/arith/arith_propagation_mode.cpp @@ -0,0 +1,46 @@ +/********************* */ +/*! \file arith_propagation_mode.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "theory/arith/arith_propagation_mode.h" + +namespace CVC4 { + +std::ostream& operator<<(std::ostream& out, ArithPropagationMode mode) { + switch(mode) { + case NO_PROP: + out << "NO_PROP"; + break; + case UNATE_PROP: + out << "UNATE_PROP"; + break; + case BOUND_INFERENCE_PROP: + out << "BOUND_INFERENCE_PROP"; + break; + case BOTH_PROP: + out << "BOTH_PROP"; + break; + default: + out << "ArithPropagationMode!UNKNOWN"; + } + + return out; +} + +}/* CVC4 namespace */ + diff --git a/src/theory/arith/arith_propagation_mode.h b/src/theory/arith/arith_propagation_mode.h new file mode 100644 index 000000000..507862415 --- /dev/null +++ b/src/theory/arith/arith_propagation_mode.h @@ -0,0 +1,40 @@ +/********************* */ +/*! \file arith_propagation_mode.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_public.h" + +#ifndef __CVC4__THEORY__ARITH__ARITH_PROPAGATION_MODE_H +#define __CVC4__THEORY__ARITH__ARITH_PROPAGATION_MODE_H + +#include <iostream> + +namespace CVC4 { + +typedef enum { + NO_PROP, + UNATE_PROP, + BOUND_INFERENCE_PROP, + BOTH_PROP +} ArithPropagationMode; + +std::ostream& operator<<(std::ostream& out, ArithPropagationMode rule) CVC4_PUBLIC; + +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__ARITH__ARITH_PROPAGATION_MODE_H */ diff --git a/src/theory/arith/arith_unate_lemma_mode.cpp b/src/theory/arith/arith_unate_lemma_mode.cpp new file mode 100644 index 000000000..58f5d7850 --- /dev/null +++ b/src/theory/arith/arith_unate_lemma_mode.cpp @@ -0,0 +1,46 @@ +/********************* */ +/*! \file arith_unate_lemma_mode.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "theory/arith/arith_unate_lemma_mode.h" + +namespace CVC4 { + +std::ostream& operator<<(std::ostream& out, ArithUnateLemmaMode mode) { + switch(mode) { + case NO_PRESOLVE_LEMMAS: + out << "NO_PRESOLVE_LEMMAS"; + break; + case INEQUALITY_PRESOLVE_LEMMAS: + out << "INEQUALITY_PRESOLVE_LEMMAS"; + break; + case EQUALITY_PRESOLVE_LEMMAS: + out << "EQUALITY_PRESOLVE_LEMMAS"; + break; + case ALL_PRESOLVE_LEMMAS: + out << "ALL_PRESOLVE_LEMMAS"; + break; + default: + out << "ArithUnateLemmaMode!UNKNOWN"; + } + + return out; +} + +}/* CVC4 namespace */ + diff --git a/src/theory/arith/arith_unate_lemma_mode.h b/src/theory/arith/arith_unate_lemma_mode.h new file mode 100644 index 000000000..71ee26ded --- /dev/null +++ b/src/theory/arith/arith_unate_lemma_mode.h @@ -0,0 +1,40 @@ +/********************* */ +/*! \file arith_unate_lemma_mode.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_public.h" + +#ifndef __CVC4__THEORY__ARITH__ARITH_UNATE_LEMMA_MODE_H +#define __CVC4__THEORY__ARITH__ARITH_UNATE_LEMMA_MODE_H + +#include <iostream> + +namespace CVC4 { + +typedef enum { + NO_PRESOLVE_LEMMAS, + INEQUALITY_PRESOLVE_LEMMAS, + EQUALITY_PRESOLVE_LEMMAS, + ALL_PRESOLVE_LEMMAS +} ArithUnateLemmaMode; + +std::ostream& operator<<(std::ostream& out, ArithUnateLemmaMode rule) CVC4_PUBLIC; + +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__ARITH__ARITH_UNATE_LEMMA_MODE_H */ diff --git a/src/theory/arith/options b/src/theory/arith/options new file mode 100644 index 000000000..8b45a6da2 --- /dev/null +++ b/src/theory/arith/options @@ -0,0 +1,55 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module ARITH "theory/arith/options.h" Arithmetic theory + +option arithUnateLemmaMode --unate-lemmas=MODE ArithUnateLemmaMode :handler CVC4::theory::arith::stringToArithUnateLemmaMode :default ALL_PRESOLVE_LEMMAS :handler-include "theory/arith/options_handlers.h" :include "theory/arith/arith_unate_lemma_mode.h" + determines which lemmas to add before solving (default is 'all', see --unate-lemmas=help) + +option arithPropagationMode --arith-prop=MODE ArithPropagationMode :handler CVC4::theory::arith::stringToArithPropagationMode :default BOTH_PROP :handler-include "theory/arith/options_handlers.h" :include "theory/arith/arith_propagation_mode.h" + turns on arithmetic propagation (default is 'old', see --arith-prop=help) + +# The maximum number of difference pivots to do per invocation of simplex. +# If this is negative, the number of pivots done is the number of variables. +# If this is not set by the user, different logics are free to chose different +# defaults. +option arithHeuristicPivots --heuristic-pivots=N int16_t :default 0 :read-write + the number of times to apply the heuristic pivot rule; if N < 0, this defaults to the number of variables; if this is unset, this is tuned by the logic selection + +# The maximum number of variable order pivots to do per invocation of simplex. +# If this is negative, the number of pivots done is unlimited. +# If this is not set by the user, different logics are free to chose different +# defaults. +expert-option arithStandardCheckVarOrderPivots --standard-effort-variable-order-pivots=N int16_t :default -1 :read-write + limits the number of pivots in a single invocation of check() at a non-full effort level using Bland's pivot rule + +option arithHeuristicPivotRule --heuristic-pivot-rule=RULE ArithHeuristicPivotRule :handler CVC4::theory::arith::stringToArithHeuristicPivotRule :default MINIMUM :handler-include "theory/arith/options_handlers.h" :include "theory/arith/arith_heuristic_pivot_rule.h" + change the pivot rule for the basic variable (default is 'min', see --pivot-rule help) + +# The number of pivots before simplex rechecks every basic variable for a conflict +option arithSimplexCheckPeriod --simplex-check-period=N uint16_t :default 200 + the number of pivots to do in simplex before rechecking for a conflict on all variables + +# This is the pivots per basic variable that can be done using heuristic choices +# before variable order must be used. +# If this is not set by the user, different logics are free to chose different +# defaults. +option arithPivotThreshold --pivot-threshold=N uint16_t :default 2 :read-write + sets the number of pivots using --pivot-rule per basic variable per simplex instance before using variable order + +option arithPropagateMaxLength --prop-row-length=N uint16_t :default 16 + sets the maximum row length to be used in propagation + +option arithDioSolver /--disable-dio-solver bool :default true + use Linear Diophantine Equation solver (Griggio, JSAT 2012) +/turns off Linear Diophantine Equation solver (Griggio, JSAT 2012) + +# Whether to split (= x y) into (and (<= x y) (>= x y)) in +# arithmetic preprocessing. +option arithRewriteEq --enable-arith-rewrite-equalities/--disable-arith-rewrite-equalities bool :default false :read-write + turns on the preprocessing rewrite turning equalities into a conjunction of inequalities +/turns off the preprocessing rewrite turning equalities into a conjunction of inequalities + +endmodule diff --git a/src/theory/arith/options_handlers.h b/src/theory/arith/options_handlers.h new file mode 100644 index 000000000..3eafe2ef0 --- /dev/null +++ b/src/theory/arith/options_handlers.h @@ -0,0 +1,124 @@ +/********************* */ +/*! \file options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Custom handlers and predicates for arithmetic options + ** + ** Custom handlers and predicates for arithmetic options. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__ARITH__OPTIONS_HANDLERS_H +#define __CVC4__THEORY__ARITH__OPTIONS_HANDLERS_H + +#include <string> + +namespace CVC4 { +namespace theory { +namespace arith { + +static const std::string arithPresolveLemmasHelp = "\ +Presolve lemmas are generated before SAT search begins using the relationship\n\ +of constant terms and polynomials.\n\ +Modes currently supported by the --arith-presolve-lemmas option:\n\ ++ none \n\ ++ ineqs \n\ + Outputs lemmas of the general form (<= p c) implies (<= p d) for c < d.\n\ ++ eqs \n\ + Outputs lemmas of the general forms\n\ + (= p c) implies (<= p d) for c < d, or\n\ + (= p c) implies (not (= p d)) for c != d.\n\ ++ all \n\ + A combination of inequalities and equalities.\n\ +"; + +static const std::string propagationModeHelp = "\ +This decides on kind of propagation arithmetic attempts to do during the search.\n\ ++ none\n\ ++ unate\n\ + use constraints to do unate propagation\n\ ++ bi (Bounds Inference)\n\ + infers bounds on basic variables using the upper and lower bounds of the\n\ + non-basic variables in the tableau.\n\ ++both\n\ +"; + +static const std::string heuristicPivotRulesHelp = "\ +This decides on the rule used by simplex during hueristic rounds\n\ +for deciding the next basic variable to select.\n\ +Heuristic pivot rules available:\n\ ++min\n\ + The minimum abs() value of the variable's violation of its bound. (default)\n\ ++min-break-ties\n\ + The minimum violation with ties broken by variable order (total)\n\ ++max\n\ + The maximum violation the bound\n\ +"; + +inline ArithUnateLemmaMode stringToArithUnateLemmaMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { + if(optarg == "all") { + return ALL_PRESOLVE_LEMMAS; + } else if(optarg == "none") { + return NO_PRESOLVE_LEMMAS; + } else if(optarg == "ineqs") { + return INEQUALITY_PRESOLVE_LEMMAS; + } else if(optarg == "eqs") { + return EQUALITY_PRESOLVE_LEMMAS; + } else if(optarg == "help") { + puts(arithPresolveLemmasHelp.c_str()); + exit(1); + } else { + throw OptionException(std::string("unknown option for --unate-lemmas: `") + + optarg + "'. Try --unate-lemmas help."); + } +} + +inline ArithPropagationMode stringToArithPropagationMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { + if(optarg == "none") { + return NO_PROP; + } else if(optarg == "unate") { + return UNATE_PROP; + } else if(optarg == "bi") { + return BOUND_INFERENCE_PROP; + } else if(optarg == "both") { + return BOTH_PROP; + } else if(optarg == "help") { + puts(propagationModeHelp.c_str()); + exit(1); + } else { + throw OptionException(std::string("unknown option for --arith-prop: `") + + optarg + "'. Try --arith-prop help."); + } +} + +inline ArithHeuristicPivotRule stringToArithHeuristicPivotRule(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { + if(optarg == "min") { + return MINIMUM; + } else if(optarg == "min-break-ties") { + return BREAK_TIES; + } else if(optarg == "max") { + return MAXIMUM; + } else if(optarg == "help") { + puts(heuristicPivotRulesHelp.c_str()); + exit(1); + } else { + throw OptionException(std::string("unknown option for --heuristic-pivot-rule: `") + + optarg + "'. Try --heuristic-pivot-rule help."); + } +} + +}/* CVC4::theory::arith namespace */ +}/* CVC4::theory namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__ARITH__OPTIONS_HANDLERS_H */ diff --git a/src/theory/arith/simplex.cpp b/src/theory/arith/simplex.cpp index 63bb42e7a..e77067d61 100644 --- a/src/theory/arith/simplex.cpp +++ b/src/theory/arith/simplex.cpp @@ -19,6 +19,7 @@ #include "theory/arith/simplex.h" +#include "theory/arith/options.h" using namespace std; @@ -41,14 +42,14 @@ SimplexDecisionProcedure::SimplexDecisionProcedure(LinearEqualityModule& linEq, d_pivotsInRound(), d_DELTA_ZERO(0,0) { - switch(Options::ArithHeuristicPivotRule rule = Options::current()->arithHeuristicPivotRule) { - case Options::MINIMUM: + switch(ArithHeuristicPivotRule rule = options::arithHeuristicPivotRule()) { + case MINIMUM: d_queue.setPivotRule(ArithPriorityQueue::MINIMUM); break; - case Options::BREAK_TIES: + case BREAK_TIES: d_queue.setPivotRule(ArithPriorityQueue::BREAK_TIES); break; - case Options::MAXIMUM: + case MAXIMUM: d_queue.setPivotRule(ArithPriorityQueue::MAXIMUM); break; default: @@ -262,13 +263,13 @@ Result::Sat SimplexDecisionProcedure::findModel(bool exactResult){ } } static const bool verbose = false; - exactResult |= Options::current()->arithStandardCheckVarOrderPivots < 0; - const uint32_t inexactResultsVarOrderPivots = exactResult ? 0 : Options::current()->arithStandardCheckVarOrderPivots; + exactResult |= options::arithStandardCheckVarOrderPivots() < 0; + const uint32_t inexactResultsVarOrderPivots = exactResult ? 0 : options::arithStandardCheckVarOrderPivots(); - uint32_t checkPeriod = Options::current()->arithSimplexCheckPeriod; + uint32_t checkPeriod = options::arithSimplexCheckPeriod(); if(result == Result::SAT_UNKNOWN){ - uint32_t numDifferencePivots = Options::current()->arithHeuristicPivots < 0 ? - d_numVariables + 1 : Options::current()->arithHeuristicPivots; + uint32_t numDifferencePivots = options::arithHeuristicPivots() < 0 ? + d_numVariables + 1 : options::arithHeuristicPivots(); // The signed to unsigned conversion is safe. uint32_t pivotsRemaining = numDifferencePivots; while(!d_queue.empty() && @@ -421,7 +422,7 @@ bool SimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingItera --remainingIterations; - bool useVarOrderPivot = d_pivotsInRound.count(x_i) >= Options::current()->arithPivotThreshold; + bool useVarOrderPivot = d_pivotsInRound.count(x_i) >= options::arithPivotThreshold(); if(!useVarOrderPivot){ d_pivotsInRound.add(x_i); } @@ -429,7 +430,7 @@ bool SimplexDecisionProcedure::searchForFeasibleSolution(uint32_t remainingItera Debug("playground") << "pivots in rounds: " << d_pivotsInRound.count(x_i) << " use " << useVarOrderPivot - << " threshold " << Options::current()->arithPivotThreshold + << " threshold " << options::arithPivotThreshold() << endl; PreferenceFunction pf = useVarOrderPivot ? minVarOrder : minBoundAndRowCount; diff --git a/src/theory/arith/simplex.h b/src/theory/arith/simplex.h index 33c6537de..324f3b21b 100644 --- a/src/theory/arith/simplex.h +++ b/src/theory/arith/simplex.h @@ -60,7 +60,7 @@ #include "context/cdlist.h" #include "util/dense_map.h" -#include "util/options.h" +#include "options/options.h" #include "util/stats.h" #include "util/result.h" diff --git a/src/theory/arith/theory_arith.cpp b/src/theory/arith/theory_arith.cpp index c68e9cf54..d55860c41 100644 --- a/src/theory/arith/theory_arith.cpp +++ b/src/theory/arith/theory_arith.cpp @@ -42,6 +42,8 @@ #include "theory/arith/normal_form.h" #include "theory/model.h" +#include "theory/arith/options.h" + #include <stdint.h> using namespace std; @@ -651,7 +653,7 @@ Node TheoryArith::ppRewrite(TNode atom) { << a << endl; } - if (a.getKind() == kind::EQUAL && Options::current()->arithRewriteEq) { + if (a.getKind() == kind::EQUAL && options::arithRewriteEq()) { Node leq = NodeBuilder<2>(kind::LEQ) << a[0] << a[1]; Node geq = NodeBuilder<2>(kind::GEQ) << a[0] << a[1]; Node rewritten = Rewriter::rewrite(leq.andNode(geq)); @@ -1536,8 +1538,8 @@ void TheoryArith::check(Effort effortLevel){ // This should be fine if sat or unknown if(!emmittedConflictOrSplit && - (Options::current()->arithPropagationMode == Options::UNATE_PROP || - Options::current()->arithPropagationMode == Options::BOTH_PROP)){ + (options::arithPropagationMode() == UNATE_PROP || + options::arithPropagationMode() == BOTH_PROP)){ TimerStat::CodeTimer codeTimer(d_statistics.d_newPropTime); Assert(d_qflraStatus != Result::UNSAT); @@ -1600,7 +1602,7 @@ void TheoryArith::check(Effort effortLevel){ if(!emmittedConflictOrSplit && fullEffort(effortLevel) && !hasIntegerModel()){ Node possibleConflict = Node::null(); - if(!emmittedConflictOrSplit && Options::current()->arithDioSolver){ + if(!emmittedConflictOrSplit && options::arithDioSolver()){ possibleConflict = callDioSolver(); if(possibleConflict != Node::null()){ revertOutOfConflict(); @@ -1610,7 +1612,7 @@ void TheoryArith::check(Effort effortLevel){ } } - if(!emmittedConflictOrSplit && d_hasDoneWorkSinceCut && Options::current()->arithDioSolver){ + if(!emmittedConflictOrSplit && d_hasDoneWorkSinceCut && options::arithDioSolver()){ Node possibleLemma = dioCutting(); if(!possibleLemma.isNull()){ Debug("arith") << "dio cut " << possibleLemma << endl; @@ -1791,8 +1793,8 @@ Node TheoryArith::explain(TNode n) { void TheoryArith::propagate(Effort e) { // This uses model values for safety. Disable for now. if(d_qflraStatus == Result::SAT && - (Options::current()->arithPropagationMode == Options::BOUND_INFERENCE_PROP || - Options::current()->arithPropagationMode == Options::BOTH_PROP) + (options::arithPropagationMode() == BOUND_INFERENCE_PROP || + options::arithPropagationMode() == BOTH_PROP) && hasAnyUpdates()){ propagateCandidates(); }else{ @@ -2039,21 +2041,21 @@ void TheoryArith::presolve(){ } vector<Node> lemmas; - switch(Options::current()->arithUnateLemmaMode){ - case Options::NO_PRESOLVE_LEMMAS: + switch(options::arithUnateLemmaMode()){ + case NO_PRESOLVE_LEMMAS: break; - case Options::INEQUALITY_PRESOLVE_LEMMAS: + case INEQUALITY_PRESOLVE_LEMMAS: d_constraintDatabase.outputUnateInequalityLemmas(lemmas); break; - case Options::EQUALITY_PRESOLVE_LEMMAS: + case EQUALITY_PRESOLVE_LEMMAS: d_constraintDatabase.outputUnateEqualityLemmas(lemmas); break; - case Options::ALL_PRESOLVE_LEMMAS: + case ALL_PRESOLVE_LEMMAS: d_constraintDatabase.outputUnateInequalityLemmas(lemmas); d_constraintDatabase.outputUnateEqualityLemmas(lemmas); break; default: - Unhandled(Options::current()->arithUnateLemmaMode); + Unhandled(options::arithUnateLemmaMode()); } vector<Node>::const_iterator i = lemmas.begin(), i_end = lemmas.end(); @@ -2063,7 +2065,7 @@ void TheoryArith::presolve(){ d_out->lemma(lem); } - // if(Options::current()->arithUnateLemmaMode == Options::ALL_UNATE){ + // if(options::arithUnateLemmaMode() == Options::ALL_UNATE){ // vector<Node> lemmas; // d_constraintDatabase.outputAllUnateLemmas(lemmas); // vector<Node>::const_iterator i = lemmas.begin(), i_end = lemmas.end(); @@ -2187,7 +2189,7 @@ void TheoryArith::propagateCandidates(){ for(; i != end; ++i){ ArithVar var = *i; if(d_tableau.isBasic(var) && - d_tableau.getRowLength(d_tableau.basicToRowIndex(var)) <= Options::current()->arithPropagateMaxLength){ + d_tableau.getRowLength(d_tableau.basicToRowIndex(var)) <= options::arithPropagateMaxLength()){ d_candidateBasics.softAdd(var); }else{ Tableau::ColIterator basicIter = d_tableau.colIterator(var); @@ -2197,7 +2199,7 @@ void TheoryArith::propagateCandidates(){ ArithVar rowVar = d_tableau.rowIndexToBasic(ridx); Assert(entry.getColVar() == var); Assert(d_tableau.isBasic(rowVar)); - if(d_tableau.getRowLength(ridx) <= Options::current()->arithPropagateMaxLength){ + if(d_tableau.getRowLength(ridx) <= options::arithPropagateMaxLength()){ d_candidateBasics.softAdd(rowVar); } } diff --git a/src/theory/arith/theory_arith_instantiator.cpp b/src/theory/arith/theory_arith_instantiator.cpp index ab3a1548e..1682897ae 100644 --- a/src/theory/arith/theory_arith_instantiator.cpp +++ b/src/theory/arith/theory_arith_instantiator.cpp @@ -17,6 +17,7 @@ #include "theory/arith/theory_arith_instantiator.h" #include "theory/arith/theory_arith.h" #include "theory/theory_engine.h" +#include "theory/quantifiers/options.h" #include "theory/quantifiers/term_database.h" using namespace std; @@ -179,7 +180,7 @@ int InstStrategySimplex::process( Node f, Theory::Effort effort, int e ){ InstantiatorTheoryArith::InstantiatorTheoryArith(context::Context* c, QuantifiersEngine* ie, Theory* th) : Instantiator( c, ie, th ){ - if( Options::current()->cbqi ){ + if( options::cbqi() ){ addInstStrategy( new InstStrategySimplex( this, d_quantEngine ) ); } } @@ -191,7 +192,7 @@ void InstantiatorTheoryArith::preRegisterTerm( Node t ){ void InstantiatorTheoryArith::assertNode( Node assertion ){ Debug("quant-arith-assert") << "InstantiatorTheoryArith::check: " << assertion << std::endl; d_quantEngine->addTermToDatabase( assertion ); - if( Options::current()->cbqi ){ + if( options::cbqi() ){ if( assertion.hasAttribute(InstConstantAttribute()) ){ setHasConstraintsFrom( assertion.getAttribute(InstConstantAttribute()) ); }else if( assertion.getKind()==NOT && assertion[0].hasAttribute(InstConstantAttribute()) ){ @@ -201,7 +202,7 @@ void InstantiatorTheoryArith::assertNode( Node assertion ){ } void InstantiatorTheoryArith::processResetInstantiationRound( Theory::Effort effort ){ - if( Options::current()->cbqi ){ + if( options::cbqi() ){ Debug("quant-arith") << "Setting up simplex for instantiator... " << std::endl; d_instRows.clear(); d_tableaux_term.clear(); diff --git a/src/theory/arrays/Makefile.am b/src/theory/arrays/Makefile.am index e4c814660..8b8a5bd48 100644 --- a/src/theory/arrays/Makefile.am +++ b/src/theory/arrays/Makefile.am @@ -22,4 +22,5 @@ libarrays_la_SOURCES = \ theory_arrays_model.h \ theory_arrays_model.cpp -EXTRA_DIST = kinds +EXTRA_DIST = \ + kinds diff --git a/src/theory/arrays/options b/src/theory/arrays/options new file mode 100644 index 000000000..bf8afc589 --- /dev/null +++ b/src/theory/arrays/options @@ -0,0 +1,8 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module ARRAYS "theory/arrays/options.h" Arrays theory + +endmodule diff --git a/src/theory/arrays/theory_arrays_instantiator.cpp b/src/theory/arrays/theory_arrays_instantiator.cpp index 67c42d124..f5a722737 100644 --- a/src/theory/arrays/theory_arrays_instantiator.cpp +++ b/src/theory/arrays/theory_arrays_instantiator.cpp @@ -17,6 +17,7 @@ #include "theory/theory_engine.h" #include "theory/arrays/theory_arrays_instantiator.h" #include "theory/arrays/theory_arrays.h" +#include "theory/quantifiers/options.h" #include "theory/rr_candidate_generator.h" using namespace std; @@ -38,7 +39,7 @@ void InstantiatorTheoryArrays::preRegisterTerm( Node t ){ void InstantiatorTheoryArrays::assertNode( Node assertion ){ Debug("quant-arrays-assert") << "InstantiatorTheoryArrays::assertNode: " << assertion << std::endl; d_quantEngine->addTermToDatabase( assertion ); - if( Options::current()->cbqi ){ + if( options::cbqi() ){ if( assertion.hasAttribute(InstConstantAttribute()) ){ setHasConstraintsFrom( assertion.getAttribute(InstConstantAttribute()) ); }else if( assertion.getKind()==NOT && assertion[0].hasAttribute(InstConstantAttribute()) ){ diff --git a/src/theory/booleans/Makefile.am b/src/theory/booleans/Makefile.am index c591ef7fb..a68ee62cd 100644 --- a/src/theory/booleans/Makefile.am +++ b/src/theory/booleans/Makefile.am @@ -15,4 +15,5 @@ libbooleans_la_SOURCES = \ circuit_propagator.h \ circuit_propagator.cpp -EXTRA_DIST = kinds +EXTRA_DIST = \ + kinds diff --git a/src/theory/booleans/options b/src/theory/booleans/options new file mode 100644 index 000000000..ae14de58b --- /dev/null +++ b/src/theory/booleans/options @@ -0,0 +1,8 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module BOOLEANS "theory/booleans/options.h" Boolean theory + +endmodule diff --git a/src/theory/builtin/Makefile.am b/src/theory/builtin/Makefile.am index 4b2d566b4..ad471bae7 100644 --- a/src/theory/builtin/Makefile.am +++ b/src/theory/builtin/Makefile.am @@ -13,4 +13,5 @@ libbuiltin_la_SOURCES = \ theory_builtin.h \ theory_builtin.cpp -EXTRA_DIST = kinds +EXTRA_DIST = \ + kinds diff --git a/src/theory/builtin/options b/src/theory/builtin/options new file mode 100644 index 000000000..699f361c9 --- /dev/null +++ b/src/theory/builtin/options @@ -0,0 +1,8 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module BUILTIN "theory/builtin/options.h" Builtin theory + +endmodule diff --git a/src/theory/bv/Makefile.am b/src/theory/bv/Makefile.am index 1f698de0f..669cbe9e0 100644 --- a/src/theory/bv/Makefile.am +++ b/src/theory/bv/Makefile.am @@ -32,4 +32,5 @@ libbv_la_SOURCES = \ theory_bv_rewriter.cpp \ cd_set_collection.h -EXTRA_DIST = kinds +EXTRA_DIST = \ + kinds diff --git a/src/theory/bv/bitblaster.cpp b/src/theory/bv/bitblaster.cpp index 60a98e6e5..c86f14398 100644 --- a/src/theory/bv/bitblaster.cpp +++ b/src/theory/bv/bitblaster.cpp @@ -25,6 +25,7 @@ #include "prop/sat_solver_factory.h" #include "theory/bv/theory_bv_rewrite_rules_simplification.h" #include "theory/bv/theory_bv.h" +#include "theory/bv/options.h" using namespace std; @@ -98,7 +99,7 @@ void Bitblaster::bbAtom(TNode node) { // asserting that the atom is true iff the definition holds Node atom_definition = mkNode(kind::IFF, node, atom_bb); - if (!Options::current()->bitvectorEagerBitblast) { + if (!options::bitvectorEagerBitblast()) { d_cnfStream->convertAndAssert(atom_definition, true, false); d_bitblastedAtoms.insert(node); } else { @@ -150,7 +151,7 @@ Node Bitblaster::bbOptimize(TNode node) { /// Public methods void Bitblaster::addAtom(TNode atom) { - if (!Options::current()->bitvectorEagerBitblast) { + if (!options::bitvectorEagerBitblast()) { d_cnfStream->ensureLiteral(atom); SatLiteral lit = d_cnfStream->getLiteral(atom); d_satSolver->addMarkerLiteral(lit); diff --git a/src/theory/bv/bv_subtheory_bitblast.cpp b/src/theory/bv/bv_subtheory_bitblast.cpp index 24d6b300b..b0d04f952 100644 --- a/src/theory/bv/bv_subtheory_bitblast.cpp +++ b/src/theory/bv/bv_subtheory_bitblast.cpp @@ -20,6 +20,7 @@ #include "theory/bv/theory_bv.h" #include "theory/bv/theory_bv_utils.h" #include "theory/bv/bitblaster.h" +#include "theory/bv/options.h" using namespace std; using namespace CVC4; @@ -57,7 +58,7 @@ bool BitblastSolver::addAssertions(const std::vector<TNode>& assertions, Theory: BVDebug("bitvector::bitblaster") << "BitblastSolver::addAssertions (" << e << ")" << std::endl; //// Eager bit-blasting - if (Options::current()->bitvectorEagerBitblast) { + if (options::bitvectorEagerBitblast()) { for (unsigned i = 0; i < assertions.size(); ++i) { TNode atom = assertions[i].getKind() == kind::NOT ? assertions[i][0] : assertions[i]; if (atom.getKind() != kind::BITVECTOR_BITOF) { @@ -105,7 +106,7 @@ bool BitblastSolver::addAssertions(const std::vector<TNode>& assertions, Theory: } // solving - if (e == Theory::EFFORT_FULL || Options::current()->bitvectorEagerFullcheck) { + if (e == Theory::EFFORT_FULL || options::bitvectorEagerFullcheck()) { Assert(!d_bv->inConflict()); BVDebug("bitvector::bitblaster") << "BitblastSolver::addAssertions solving. \n"; bool ok = d_bitblaster->solve(); diff --git a/src/theory/bv/options b/src/theory/bv/options new file mode 100644 index 000000000..72db63c09 --- /dev/null +++ b/src/theory/bv/options @@ -0,0 +1,17 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module BV "theory/bv/options.h" Bitvector theory + +option bitvectorEagerBitblast --bitblast-eager bool + eagerly bitblast the bitvectors to the main SAT solver + +option bitvectorShareLemmas --bitblast-share-lemmas bool + share lemmas from the bitblasting solver with the main solver + +option bitvectorEagerFullcheck --bitblast-eager-fullcheck bool + check the bitblasting eagerly + +endmodule diff --git a/src/theory/bv/theory_bv.cpp b/src/theory/bv/theory_bv.cpp index da2dd77f6..b6dcc6662 100644 --- a/src/theory/bv/theory_bv.cpp +++ b/src/theory/bv/theory_bv.cpp @@ -21,6 +21,7 @@ #include "theory/bv/theory_bv_utils.h" #include "theory/valuation.h" #include "theory/bv/bitblaster.h" +#include "theory/bv/options.h" #include "theory/bv/theory_bv_rewrite_rules_normalization.h" using namespace CVC4; @@ -69,7 +70,7 @@ TheoryBV::Statistics::~Statistics() { void TheoryBV::preRegisterTerm(TNode node) { BVDebug("bitvector-preregister") << "TheoryBV::preRegister(" << node << ")" << std::endl; - if (Options::current()->bitvectorEagerBitblast) { + if (options::bitvectorEagerBitblast()) { // don't use the equality engine in the eager bit-blasting return; } @@ -261,7 +262,7 @@ Node TheoryBV::explain(TNode node) { void TheoryBV::addSharedTerm(TNode t) { Debug("bitvector::sharing") << indent() << "TheoryBV::addSharedTerm(" << t << ")" << std::endl; d_sharedTermsSet.insert(t); - if (!Options::current()->bitvectorEagerBitblast && d_useEqualityEngine) { + if (!options::bitvectorEagerBitblast() && d_useEqualityEngine) { d_equalitySolver.addSharedTerm(t); } } @@ -269,7 +270,7 @@ void TheoryBV::addSharedTerm(TNode t) { EqualityStatus TheoryBV::getEqualityStatus(TNode a, TNode b) { - if (Options::current()->bitvectorEagerBitblast) { + if (options::bitvectorEagerBitblast()) { return EQUALITY_UNKNOWN; } diff --git a/src/theory/candidate_generator.cpp b/src/theory/candidate_generator.cpp index a0f303c21..2563ef0d7 100644 --- a/src/theory/candidate_generator.cpp +++ b/src/theory/candidate_generator.cpp @@ -29,7 +29,7 @@ using namespace CVC4::theory; using namespace CVC4::theory::inst; bool CandidateGenerator::isLegalCandidate( Node n ){ - return ( !n.getAttribute(NoMatchAttribute()) && ( !Options::current()->cbqi || !n.hasAttribute(InstConstantAttribute()) ) ); + return ( !n.getAttribute(NoMatchAttribute()) && ( !options::cbqi() || !n.hasAttribute(InstConstantAttribute()) ) ); } void CandidateGeneratorQueue::addCandidate( Node n ) { diff --git a/src/theory/datatypes/Makefile.am b/src/theory/datatypes/Makefile.am index 8b5fbe979..b3aa318d5 100644 --- a/src/theory/datatypes/Makefile.am +++ b/src/theory/datatypes/Makefile.am @@ -14,4 +14,5 @@ libdatatypes_la_SOURCES = \ theory_datatypes_instantiator.h \ theory_datatypes_instantiator.cpp -EXTRA_DIST = kinds +EXTRA_DIST = \ + kinds diff --git a/src/theory/datatypes/options b/src/theory/datatypes/options new file mode 100644 index 000000000..8a76e8134 --- /dev/null +++ b/src/theory/datatypes/options @@ -0,0 +1,8 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module DATATYPES "theory/datatypes/options.h" Datatypes theory + +endmodule diff --git a/src/theory/datatypes/theory_datatypes_instantiator.cpp b/src/theory/datatypes/theory_datatypes_instantiator.cpp index b4b85c9fb..8ecf37fe2 100644 --- a/src/theory/datatypes/theory_datatypes_instantiator.cpp +++ b/src/theory/datatypes/theory_datatypes_instantiator.cpp @@ -17,6 +17,7 @@ #include "theory/datatypes/theory_datatypes_instantiator.h" #include "theory/datatypes/theory_datatypes.h" #include "theory/theory_engine.h" +#include "theory/quantifiers/options.h" #include "theory/quantifiers/term_database.h" #include "theory/rr_candidate_generator.h" @@ -35,7 +36,7 @@ Instantiator( c, ie, th ){ void InstantiatorTheoryDatatypes::assertNode( Node assertion ){ Debug("quant-datatypes-assert") << "InstantiatorTheoryDatatypes::check: " << assertion << std::endl; d_quantEngine->addTermToDatabase( assertion ); - if( Options::current()->cbqi ){ + if( options::cbqi() ){ if( assertion.hasAttribute(InstConstantAttribute()) ){ setHasConstraintsFrom( assertion.getAttribute(InstConstantAttribute()) ); }else if( assertion.getKind()==NOT && assertion[0].hasAttribute(InstConstantAttribute()) ){ @@ -51,7 +52,7 @@ void InstantiatorTheoryDatatypes::processResetInstantiationRound( Theory::Effort int InstantiatorTheoryDatatypes::process( Node f, Theory::Effort effort, int e ){ Debug("quant-datatypes") << "Datatypes: Try to solve (" << e << ") for " << f << "... " << std::endl; - if( Options::current()->cbqi ){ + if( options::cbqi() ){ if( e<2 ){ return InstStrategy::STATUS_UNFINISHED; }else if( e==2 ){ diff --git a/src/theory/inst_match.cpp b/src/theory/inst_match.cpp index bad7e34cb..f7c21c555 100644 --- a/src/theory/inst_match.cpp +++ b/src/theory/inst_match.cpp @@ -20,6 +20,7 @@ #include "theory/candidate_generator.h" #include "theory/uf/theory_uf_instantiator.h" #include "theory/uf/equality_engine.h" +#include "theory/quantifiers/options.h" #include "theory/quantifiers/model_engine.h" #include "theory/quantifiers/term_database.h" #include "theory/quantifiers/first_order_model.h" @@ -106,7 +107,7 @@ void InstMatch::makeComplete( Node f, QuantifiersEngine* qe ){ } void InstMatch::makeInternal( QuantifiersEngine* qe ){ - if( Options::current()->cbqi ){ + if( options::cbqi() ){ for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){ if( it->second.hasAttribute(InstConstantAttribute()) ){ d_map[ it->first ] = qe->getEqualityQuery()->getInternalRepresentative( it->second ); @@ -121,7 +122,7 @@ void InstMatch::makeInternal( QuantifiersEngine* qe ){ void InstMatch::makeRepresentative( QuantifiersEngine* qe ){ for( std::map< Node, Node >::iterator it = d_map.begin(); it != d_map.end(); ++it ){ d_map[ it->first ] = qe->getEqualityQuery()->getInternalRepresentative( it->second ); - if( Options::current()->cbqi && it->second.hasAttribute(InstConstantAttribute()) ){ + if( options::cbqi() && it->second.hasAttribute(InstConstantAttribute()) ){ d_map[ it->first ] = qe->getTermDatabase()->getFreeVariableForInstConstant( it->first ); } } @@ -591,7 +592,7 @@ int InstMatchGenerator::addInstantiations( Node f, InstMatch& baseMatch, Quantif } int InstMatchGenerator::addTerm( Node f, Node t, QuantifiersEngine* qe ){ - Assert( Options::current()->eagerInstQuant ); + Assert( options::eagerInstQuant() ); if( !d_match_pattern.isNull() ){ InstMatch m; if( getMatch( t, m, qe ) ){ @@ -808,7 +809,7 @@ void InstMatchGeneratorMulti::processNewInstantiations2( QuantifiersEngine* qe, } int InstMatchGeneratorMulti::addTerm( Node f, Node t, QuantifiersEngine* qe ){ - Assert( Options::current()->eagerInstQuant ); + Assert( options::eagerInstQuant() ); int addedLemmas = 0; for( int i=0; i<(int)d_children.size(); i++ ){ if( ((InstMatchGenerator*)d_children[i])->d_match_pattern.getOperator()==t.getOperator() ){ @@ -866,7 +867,7 @@ void InstMatchGeneratorSimple::addInstantiations( InstMatch& m, QuantifiersEngin } int InstMatchGeneratorSimple::addTerm( Node f, Node t, QuantifiersEngine* qe ){ - Assert( Options::current()->eagerInstQuant ); + Assert( options::eagerInstQuant() ); InstMatch m; for( int i=0; i<(int)t.getNumChildren(); i++ ){ if( d_match_pattern[i].getKind()==INST_CONSTANT ){ diff --git a/src/theory/ite_simplifier.h b/src/theory/ite_simplifier.h index ae11f429c..fb42909e0 100644 --- a/src/theory/ite_simplifier.h +++ b/src/theory/ite_simplifier.h @@ -39,7 +39,6 @@ #include "theory/shared_terms_database.h" #include "theory/term_registration_visitor.h" #include "theory/valuation.h" -#include "util/options.h" #include "util/stats.h" #include "util/hash.h" #include "util/cache.h" diff --git a/src/theory/options b/src/theory/options new file mode 100644 index 000000000..40d26472f --- /dev/null +++ b/src/theory/options @@ -0,0 +1,14 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module THEORY "theory/options.h" Theory layer + +expert-option theoryRegistration /--no-theory-registration bool :default true + disable theory reg (not safe for some theories) + +expert-option theoryOfMode --theoryof-mode=MODE CVC4::theory::TheoryOfMode :handler CVC4::theory::stringToTheoryOfMode :handler-include "theory/options_handlers.h" :default CVC4::theory::THEORY_OF_TYPE_BASED :include "theory/theoryof_mode.h" + mode for theoryof + +endmodule diff --git a/src/theory/options_handlers.h b/src/theory/options_handlers.h new file mode 100644 index 000000000..b5c8a1fc0 --- /dev/null +++ b/src/theory/options_handlers.h @@ -0,0 +1,54 @@ +/********************* */ +/*! \file options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009, 2010, 2011, 2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Custom handlers and predicates for TheoryEngine options + ** + ** Custom handlers and predicates for TheoryEngine options. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__OPTIONS_HANDLERS_H +#define __CVC4__THEORY__OPTIONS_HANDLERS_H + +namespace CVC4 { +namespace theory { + +static const std::string theoryOfModeHelp = "\ +TheoryOf modes currently supported by the --theoryof-mode option:\n\ +\n\ +type (default) \n\ ++ type variables, constants and equalities by type\n\ +\n\ +term \n\ ++ type variables as uninterpreted, equalities by the parametric theory\n\ +"; + +inline TheoryOfMode stringToTheoryOfMode(std::string option, std::string optarg, SmtEngine* smt) { + if(optarg == "type") { + return THEORY_OF_TYPE_BASED; + } else if(optarg == "term") { + return THEORY_OF_TERM_BASED; + } else if(optarg == "help") { + puts(theoryOfModeHelp.c_str()); + exit(1); + } else { + throw OptionException(std::string("unknown option for --theoryof-mode: `") + + optarg + "'. Try --theoryof-mode help."); + } +} + +}/* CVC4::theory namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__OPTIONS_HANDLERS_H */ diff --git a/src/theory/quantifiers/Makefile.am b/src/theory/quantifiers/Makefile.am index 316e2fbff..5172001fc 100644 --- a/src/theory/quantifiers/Makefile.am +++ b/src/theory/quantifiers/Makefile.am @@ -17,6 +17,10 @@ libquantifiers_la_SOURCES = \ instantiation_engine.cpp \ model_engine.h \ model_engine.cpp \ + inst_when_mode.cpp \ + inst_when_mode.h \ + literal_match_mode.cpp \ + literal_match_mode.h \ relevant_domain.h \ relevant_domain.cpp \ rep_set_iterator.h \ @@ -28,4 +32,6 @@ libquantifiers_la_SOURCES = \ model_builder.h \ model_builder.cpp -EXTRA_DIST = kinds
\ No newline at end of file +EXTRA_DIST = \ + kinds \ + options_handlers.h diff --git a/src/theory/quantifiers/first_order_model.cpp b/src/theory/quantifiers/first_order_model.cpp index 1c6b47867..5d7317cbc 100644 --- a/src/theory/quantifiers/first_order_model.cpp +++ b/src/theory/quantifiers/first_order_model.cpp @@ -54,10 +54,10 @@ void FirstOrderModel::initialize(){ initializeModelForTerm( f[1] ); } //for debugging - if( Options::current()->printModelEngine ){ + if( Trace.isOn("model-engine") ){ for( std::map< TypeNode, std::vector< Node > >::iterator it = d_rep_set.d_type_reps.begin(); it != d_rep_set.d_type_reps.end(); ++it ){ if( it->first.isSort() ){ - Message() << "Cardinality( " << it->first << " )" << " = " << it->second.size() << std::endl; + Trace("model-engine") << "Cardinality( " << it->first << " )" << " = " << it->second.size() << std::endl; } } } @@ -181,4 +181,4 @@ void FirstOrderModel::toStream(std::ostream& out){ out << std::endl; } #endif -}
\ No newline at end of file +} diff --git a/src/theory/quantifiers/inst_when_mode.cpp b/src/theory/quantifiers/inst_when_mode.cpp new file mode 100644 index 000000000..b60148c21 --- /dev/null +++ b/src/theory/quantifiers/inst_when_mode.cpp @@ -0,0 +1,47 @@ +/********************* */ +/*! \file inst_when_mode.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include <iostream> +#include "theory/quantifiers/inst_when_mode.h" + +namespace CVC4 { + +std::ostream& operator<<(std::ostream& out, theory::quantifiers::InstWhenMode mode) { + switch(mode) { + case theory::quantifiers::INST_WHEN_PRE_FULL: + out << "INST_WHEN_PRE_FULL"; + break; + case theory::quantifiers::INST_WHEN_FULL: + out << "INST_WHEN_FULL"; + break; + case theory::quantifiers::INST_WHEN_FULL_LAST_CALL: + out << "INST_WHEN_FULL_LAST_CALL"; + break; + case theory::quantifiers::INST_WHEN_LAST_CALL: + out << "INST_WHEN_LAST_CALL"; + break; + default: + out << "InstWhenMode!UNKNOWN"; + } + + return out; +} + +}/* CVC4 namespace */ + diff --git a/src/theory/quantifiers/inst_when_mode.h b/src/theory/quantifiers/inst_when_mode.h new file mode 100644 index 000000000..2cfba4935 --- /dev/null +++ b/src/theory/quantifiers/inst_when_mode.h @@ -0,0 +1,49 @@ +/********************* */ +/*! \file inst_when_mode.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__QUANTIFIERS__INST_WHEN_MODE_H +#define __CVC4__THEORY__QUANTIFIERS__INST_WHEN_MODE_H + +#include <iostream> + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +typedef enum { + /** Apply instantiation round before full effort (possibly at standard effort) */ + INST_WHEN_PRE_FULL, + /** Apply instantiation round at full effort or above */ + INST_WHEN_FULL, + /** Apply instantiation round at full effort half the time, and last call always */ + INST_WHEN_FULL_LAST_CALL, + /** Apply instantiation round at last call only */ + INST_WHEN_LAST_CALL, +} InstWhenMode; + +}/* CVC4::theory::quantifiers namespace */ +}/* CVC4::theory namespace */ + +std::ostream& operator<<(std::ostream& out, theory::quantifiers::InstWhenMode mode) CVC4_PUBLIC; + +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__QUANTIFIERS__INST_WHEN_MODE_H */ diff --git a/src/theory/quantifiers/instantiation_engine.cpp b/src/theory/quantifiers/instantiation_engine.cpp index 2b79cd8b9..fb3e6fb36 100644 --- a/src/theory/quantifiers/instantiation_engine.cpp +++ b/src/theory/quantifiers/instantiation_engine.cpp @@ -18,6 +18,7 @@ #include "theory/theory_engine.h" #include "theory/uf/theory_uf_instantiator.h" +#include "theory/quantifiers/options.h" #include "theory/quantifiers/term_database.h" #include "theory/quantifiers/first_order_model.h" @@ -65,7 +66,7 @@ void InstantiationEngine::addCbqiLemma( Node f ){ bool InstantiationEngine::doInstantiationRound( Theory::Effort effort ){ //if counterexample-based quantifier instantiation is active - if( Options::current()->cbqi ){ + if( options::cbqi() ){ //check if any cbqi lemma has not been added yet bool addedLemma = false; for( int i=0; i<(int)d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){ @@ -136,9 +137,7 @@ bool InstantiationEngine::doInstantiationRound( Theory::Effort effort ){ return false; }else{ Debug("inst-engine-ctrl") << "---Done. " << (int)d_quantEngine->d_lemmas_waiting.size() << std::endl; - if( Options::current()->printInstEngine ){ - Message() << "Added lemmas = " << (int)d_quantEngine->d_lemmas_waiting.size() << std::endl; - } + Trace("inst-engine") << "Added lemmas = " << (int)d_quantEngine->d_lemmas_waiting.size() << std::endl; //flush lemmas to output channel d_quantEngine->flushLemmas( &d_quantEngine->getOutputChannel() ); return true; @@ -153,11 +152,11 @@ void InstantiationEngine::check( Theory::Effort e ){ } //determine if we should perform check, based on instWhenMode bool performCheck = false; - if( Options::current()->instWhenMode==Options::INST_WHEN_FULL ){ + if( options::instWhenMode()==INST_WHEN_FULL ){ performCheck = ( e >= Theory::EFFORT_FULL ); - }else if( Options::current()->instWhenMode==Options::INST_WHEN_FULL_LAST_CALL ){ + }else if( options::instWhenMode()==INST_WHEN_FULL_LAST_CALL ){ performCheck = ( ( e==Theory::EFFORT_FULL && ierCounter%2==0 ) || e==Theory::EFFORT_LAST_CALL ); - }else if( Options::current()->instWhenMode==Options::INST_WHEN_LAST_CALL ){ + }else if( options::instWhenMode()==INST_WHEN_LAST_CALL ){ performCheck = ( e >= Theory::EFFORT_LAST_CALL ); }else{ performCheck = true; @@ -165,9 +164,9 @@ void InstantiationEngine::check( Theory::Effort e ){ if( performCheck ){ Debug("inst-engine") << "IE: Check " << e << " " << ierCounter << std::endl; double clSet = 0; - if( Options::current()->printInstEngine ){ + if( Trace.isOn("inst-engine") ){ clSet = double(clock())/double(CLOCKS_PER_SEC); - Message() << "---Instantiation Engine Round, effort = " << e << "---" << std::endl; + Trace("inst-engine") << "---Instantiation Engine Round, effort = " << e << "---" << std::endl; } bool quantActive = false; //for each quantifier currently asserted, @@ -178,7 +177,7 @@ void InstantiationEngine::check( Theory::Effort e ){ << d_quantEngine->getModel()->getNumAssertedQuantifiers() << std::endl; for( int i=0; i<(int)d_quantEngine->getModel()->getNumAssertedQuantifiers(); i++ ){ Node n = d_quantEngine->getModel()->getAssertedQuantifier( i ); - if( Options::current()->cbqi && hasAddedCbqiLemma( n ) ){ + if( options::cbqi() && hasAddedCbqiLemma( n ) ){ Node cel = d_ce_lit[ n ]; bool active, value; bool ceValue = false; @@ -232,21 +231,21 @@ void InstantiationEngine::check( Theory::Effort e ){ Debug("inst-engine") << "No instantiation given, returning unknown..." << std::endl; d_quantEngine->getOutputChannel().setIncomplete(); }else{ - Assert( Options::current()->finiteModelFind ); + Assert( options::finiteModelFind() ); Debug("inst-engine") << "No instantiation given, defer to another engine..." << std::endl; } } } }else{ if( e==Theory::EFFORT_LAST_CALL ){ - if( Options::current()->cbqi ){ + if( options::cbqi() ){ debugSat( SAT_CBQI ); } } } - if( Options::current()->printInstEngine ){ + if( Trace.isOn("inst-engine") ){ double clSet2 = double(clock())/double(CLOCKS_PER_SEC); - Message() << "Finished instantiation engine, time = " << (clSet2-clSet) << std::endl; + Trace("inst-engine") << "Finished instantiation engine, time = " << (clSet2-clSet) << std::endl; } } } @@ -302,9 +301,9 @@ bool InstantiationEngine::hasNonArithmeticVariable( Node f ){ } bool InstantiationEngine::doCbqi( Node f ){ - if( Options::current()->cbqiSetByUser ){ - return Options::current()->cbqi; - }else if( Options::current()->cbqi ){ + if( options::cbqi.wasSetByUser() ){ + return options::cbqi(); + }else if( options::cbqi() ){ //if quantifier has a non-arithmetic variable, then do not use cbqi //if quantifier has an APPLY_UF term, then do not use cbqi return !hasNonArithmeticVariable( f ) && !hasApplyUf( f[1] ); diff --git a/src/theory/quantifiers/literal_match_mode.cpp b/src/theory/quantifiers/literal_match_mode.cpp new file mode 100644 index 000000000..87b4b94fe --- /dev/null +++ b/src/theory/quantifiers/literal_match_mode.cpp @@ -0,0 +1,43 @@ +/********************* */ +/*! \file literal_match_mode.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include <iostream> +#include "theory/quantifiers/literal_match_mode.h" + +namespace CVC4 { + +std::ostream& operator<<(std::ostream& out, theory::quantifiers::LiteralMatchMode mode) { + switch(mode) { + case theory::quantifiers::LITERAL_MATCH_NONE: + out << "LITERAL_MATCH_NONE"; + break; + case theory::quantifiers::LITERAL_MATCH_PREDICATE: + out << "LITERAL_MATCH_PREDICATE"; + break; + case theory::quantifiers::LITERAL_MATCH_EQUALITY: + out << "LITERAL_MATCH_EQUALITY"; + break; + default: + out << "LiteralMatchMode!UNKNOWN"; + } + + return out; +} + +}/* CVC4 namespace */ diff --git a/src/theory/quantifiers/literal_match_mode.h b/src/theory/quantifiers/literal_match_mode.h new file mode 100644 index 000000000..189f0a235 --- /dev/null +++ b/src/theory/quantifiers/literal_match_mode.h @@ -0,0 +1,47 @@ +/********************* */ +/*! \file literal_match_mode.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__QUANTIFIERS__LITERAL_MATCH_MODE_H +#define __CVC4__THEORY__QUANTIFIERS__LITERAL_MATCH_MODE_H + +#include <iostream> + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +typedef enum { + /** Do not consider polarity of patterns */ + LITERAL_MATCH_NONE, + /** Consider polarity of boolean predicates only */ + LITERAL_MATCH_PREDICATE, + /** Consider polarity of boolean predicates, as well as equalities */ + LITERAL_MATCH_EQUALITY, +} LiteralMatchMode; + +}/* CVC4::theory::quantifiers namespace */ +}/* CVC4::theory namespace */ + +std::ostream& operator<<(std::ostream& out, theory::quantifiers::LiteralMatchMode mode) CVC4_PUBLIC; + +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__QUANTIFIERS__LITERAL_MATCH_MODE_H */ diff --git a/src/theory/quantifiers/model_builder.cpp b/src/theory/quantifiers/model_builder.cpp index 9cd5020fb..5d49c914f 100644 --- a/src/theory/quantifiers/model_builder.cpp +++ b/src/theory/quantifiers/model_builder.cpp @@ -90,11 +90,11 @@ void ModelEngineBuilder::processBuildModel( TheoryModel* m ) { } } } - if( Options::current()->printModelEngine ){ + if( Trace.isOn("model-engine") ){ if( d_addedLemmas>0 ){ - Message() << "InstGen, added lemmas = " << d_addedLemmas << std::endl; + Trace("model-engine") << "InstGen, added lemmas = " << d_addedLemmas << std::endl; }else{ - Message() << "No InstGen lemmas..." << std::endl; + Trace("model-engine") << "No InstGen lemmas..." << std::endl; } } Debug("fmf-model-debug") << "---> Added lemmas = " << d_addedLemmas << std::endl; @@ -388,11 +388,11 @@ void ModelEngineBuilder::finishProcessBuildModel( TheoryModel* m ){ } bool ModelEngineBuilder::optUseModel() { - return Options::current()->fmfModelBasedInst; + return options::fmfModelBasedInst(); } bool ModelEngineBuilder::optInstGen(){ - return Options::current()->fmfInstGen; + return options::fmfInstGen(); } bool ModelEngineBuilder::optOneQuantPerRoundInstGen(){ diff --git a/src/theory/quantifiers/model_engine.cpp b/src/theory/quantifiers/model_engine.cpp index ddaaa5b6f..4d91c8c95 100644 --- a/src/theory/quantifiers/model_engine.cpp +++ b/src/theory/quantifiers/model_engine.cpp @@ -21,6 +21,7 @@ #include "theory/uf/theory_uf.h" #include "theory/uf/theory_uf_strong_solver.h" #include "theory/uf/theory_uf_instantiator.h" +#include "theory/quantifiers/options.h" #include "theory/arrays/theory_arrays_model.h" #include "theory/quantifiers/first_order_model.h" #include "theory/quantifiers/term_database.h" @@ -64,9 +65,9 @@ void ModelEngine::check( Theory::Effort e ){ if( addedLemmas==0 ){ //quantifiers are initialized, we begin an instantiation round double clSet = 0; - if( Options::current()->printModelEngine ){ + if( Trace.isOn("model-engine") ){ clSet = double(clock())/double(CLOCKS_PER_SEC); - Message() << "---Model Engine Round---" << std::endl; + Trace("model-engine") << "---Model Engine Round---" << std::endl; } Debug("fmf-model-debug") << "---Begin Instantiation Round---" << std::endl; ++(d_statistics.d_inst_rounds); @@ -108,11 +109,11 @@ void ModelEngine::check( Theory::Effort e ){ } Debug("fmf-model-debug") << "---> Added lemmas = " << addedLemmas << " / " << d_triedLemmas << " / "; Debug("fmf-model-debug") << d_testLemmas << " / " << d_relevantLemmas << " / " << d_totalLemmas << std::endl; - if( Options::current()->printModelEngine ){ - Message() << "Added Lemmas = " << addedLemmas << " / " << d_triedLemmas << " / "; - Message() << d_testLemmas << " / " << d_relevantLemmas << " / " << d_totalLemmas << std::endl; + if( Trace.isOn("model-engine") ){ + Trace("model-engine") << "Added Lemmas = " << addedLemmas << " / " << d_triedLemmas << " / "; + Trace("model-engine") << d_testLemmas << " / " << d_relevantLemmas << " / " << d_totalLemmas << std::endl; double clSet2 = double(clock())/double(CLOCKS_PER_SEC); - Message() << "Finished model engine, time = " << (clSet2-clSet) << std::endl; + Trace("model-engine") << "Finished model engine, time = " << (clSet2-clSet) << std::endl; } #ifdef ME_PRINT_WARNINGS if( addedLemmas>10000 ){ @@ -145,11 +146,11 @@ void ModelEngine::assertNode( Node f ){ } bool ModelEngine::optOneInstPerQuantRound(){ - return Options::current()->fmfOneInstPerRound; + return options::fmfOneInstPerRound(); } bool ModelEngine::optUseRelevantDomain(){ - return Options::current()->fmfRelevantDomain; + return options::fmfRelevantDomain(); } bool ModelEngine::optOneQuantPerRound(){ diff --git a/src/theory/quantifiers/options b/src/theory/quantifiers/options new file mode 100644 index 000000000..91e831092 --- /dev/null +++ b/src/theory/quantifiers/options @@ -0,0 +1,89 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module QUANTIFIERS "theory/quantifiers/options.h" Quantifiers + +# Whether to mini-scope quantifiers. +# For example, forall x. ( P( x ) ^ Q( x ) ) will be rewritten to +# ( forall x. P( x ) ) ^ ( forall x. Q( x ) ) +option miniscopeQuant /--disable-miniscope-quant bool :default true + disable miniscope quantifiers + +# Whether to mini-scope quantifiers based on formulas with no free variables. +# For example, forall x. ( P( x ) V Q ) will be rewritten to +# ( forall x. P( x ) ) V Q +option miniscopeQuantFreeVar /--disable-miniscope-quant-fv bool :default true + disable miniscope quantifiers for ground subformulas + +# Whether to prenex (nested universal) quantifiers +option prenexQuant /--disable-prenex-quant bool :default true + disable prenexing of quantified formulas + +# Whether to variable-eliminate quantifiers. +# For example, forall x y. ( P( x, y ) V x != c ) will be rewritten to +# forall y. P( c, y ) +option varElimQuant --var-elim-quant bool :default false + enable variable elimination of quantified formulas + +# Whether to CNF quantifier bodies +option cnfQuant --cnf-quant bool :default false + apply CNF conversion to quantified formulas + +# Whether to pre-skolemize quantifier bodies. +# For example, forall x. ( P( x ) => (exists y. f( y ) = x) ) will be rewritten to +# forall x. P( x ) => f( S( x ) ) = x +option preSkolemQuant --pre-skolem-quant bool :default false + apply skolemization eagerly to bodies of quantified formulas + +# Whether to use smart triggers +option smartTriggers /--disable-smart-triggers bool :default true + disable smart triggers + +# Whether to consider terms in the bodies of quantifiers for matching +option registerQuantBodyTerms --register-quant-body-terms bool :default false + consider ground terms within bodies of quantified formulas for matching + +option instWhenMode --inst-when=MODE CVC4::theory::quantifiers::InstWhenMode :default CVC4::theory::quantifiers::INST_WHEN_FULL_LAST_CALL :include "theory/quantifiers/inst_when_mode.h" :handler CVC4::theory::quantifiers::stringToInstWhenMode :handler-include "theory/quantifiers/options_handlers.h" :predicate CVC4::theory::quantifiers::checkInstWhenMode :predicate-include "theory/quantifiers/options_handlers.h" + when to apply instantiation + +option eagerInstQuant --eager-inst-quant bool :default false + apply quantifier instantiation eagerly + +option literalMatchMode --literal-matching=MODE CVC4::theory::quantifiers::LiteralMatchMode :default CVC4::theory::quantifiers::LITERAL_MATCH_NONE :include "theory/quantifiers/literal_match_mode.h" :handler CVC4::theory::quantifiers::stringToLiteralMatchMode :handler-include "theory/quantifiers/options_handlers.h" :predicate CVC4::theory::quantifiers::checkLiteralMatchMode :predicate-include "theory/quantifiers/options_handlers.h" + choose literal matching mode + +option cbqi --enable-cbqi/--disable-cbqi bool :default false + turns on counterexample-based quantifier instantiation [off by default] +/turns off counterexample-based quantifier instantiation + +option userPatternsQuant /--ignore-user-patterns bool :default true + ignore user-provided patterns for quantifier instantiation + +option flipDecision --enable-flip-decision/ bool :default false + turns on flip decision heuristic + +option finiteModelFind --finite-model-find bool :default false + use finite model finding heuristic for quantifier instantiation + +option ufssRegions /--disable-uf-ss-regions bool :default true + disable region-based method for discovering cliques and splits in uf strong solver +option ufssEagerSplits --uf-ss-eager-split bool :default false + add splits eagerly for uf strong solver +option ufssColoringSat --uf-ss-coloring-sat bool :default false + use coloring-based SAT heuristic for uf strong solver + +option fmfModelBasedInst /--disable-fmf-mbqi bool :default true + disable model-based quantifier instantiation for finite model finding + +option fmfInstGen /--disable-fmf-inst-gen bool :default true + disable Inst-Gen instantiation techniques for finite model finding +option fmfOneInstPerRound --fmf-one-inst-per-round bool :default false + only add one instantiation per quantifier per round for fmf +option fmfInstEngine --fmf-inst-engine bool :default false + use instantiation engine in conjunction with finite model finding +option fmfRelevantDomain --fmf-relevant-domain bool :default false + use relevant domain computation, similar to complete instantiation (Ge, deMoura 09) + +endmodule diff --git a/src/theory/quantifiers/options_handlers.h b/src/theory/quantifiers/options_handlers.h new file mode 100644 index 000000000..24734e8c8 --- /dev/null +++ b/src/theory/quantifiers/options_handlers.h @@ -0,0 +1,111 @@ +/********************* */ +/*! \file options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief [[ Add one-line brief description here ]] + ** + ** [[ Add lengthier description here ]] + ** \todo document this file + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__QUANTIFIERS__OPTIONS_HANDLERS_H +#define __CVC4__THEORY__QUANTIFIERS__OPTIONS_HANDLERS_H + +#include <string> + +namespace CVC4 { +namespace theory { +namespace quantifiers { + +static const std::string instWhenHelp = "\ +Modes currently supported by the --inst-when option:\n\ +\n\ +full\n\ ++ Run instantiation round at full effort, before theory combination.\n\ +\n\ +full-last-call (default)\n\ ++ Alternate running instantiation rounds at full effort and last\n\ + call. In other words, interleave instantiation and theory combination.\n\ +\n\ +last-call\n\ ++ Run instantiation at last call effort, after theory combination.\n\ +\n\ +"; + +static const std::string literalMatchHelp = "\ +Literal match modes currently supported by the --literal-match option:\n\ +\n\ +none (default)\n\ ++ Do not use literal matching.\n\ +\n\ +predicate\n\ ++ Consider the phase requirements of predicate literals when applying heuristic\n\ + quantifier instantiation. For example, the trigger P( x ) in the quantified \n\ + formula forall( x ). ( P( x ) V ~Q( x ) ) will only be matched with ground\n\ + terms P( t ) where P( t ) is in the equivalence class of false, and likewise\n\ + Q( x ) with Q( s ) where Q( s ) is in the equivalence class of true.\n\ +\n\ +"; + +inline InstWhenMode stringToInstWhenMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { + if(optarg == "pre-full") { + return INST_WHEN_PRE_FULL; + } else if(optarg == "full") { + return INST_WHEN_FULL; + } else if(optarg == "full-last-call") { + return INST_WHEN_FULL_LAST_CALL; + } else if(optarg == "last-call") { + return INST_WHEN_LAST_CALL; + } else if(optarg == "help") { + puts(instWhenHelp.c_str()); + exit(1); + } else { + throw OptionException(std::string("unknown option for --inst-when: `") + + optarg + "'. Try --inst-when help."); + } +} + +inline void checkInstWhenMode(std::string option, InstWhenMode mode, SmtEngine* smt) throw(OptionException) { + if(mode == INST_WHEN_PRE_FULL) { + throw OptionException(std::string("Mode pre-full for ") + option + " is not supported in this release."); + } +} + +inline LiteralMatchMode stringToLiteralMatchMode(std::string option, std::string optarg, SmtEngine* smt) throw(OptionException) { + if(optarg == "none") { + return LITERAL_MATCH_NONE; + } else if(optarg == "predicate") { + return LITERAL_MATCH_PREDICATE; + } else if(optarg == "equality") { + return LITERAL_MATCH_EQUALITY; + } else if(optarg == "help") { + puts(literalMatchHelp.c_str()); + exit(1); + } else { + throw OptionException(std::string("unknown option for --literal-matching: `") + + optarg + "'. Try --literal-matching help."); + } +} + +inline void checkLiteralMatchMode(std::string option, LiteralMatchMode mode, SmtEngine* smt) throw(OptionException) { + if(mode == LITERAL_MATCH_EQUALITY) { + throw OptionException(std::string("Mode equality for ") + option + " is not supported in this release."); + } +} + +}/* CVC4::theory::quantifiers namespace */ +}/* CVC4::theory namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__QUANTIFIERS__OPTIONS_HANDLERS_H */ diff --git a/src/theory/quantifiers/quantifiers_rewriter.cpp b/src/theory/quantifiers/quantifiers_rewriter.cpp index c397e9d05..800fa910c 100644 --- a/src/theory/quantifiers/quantifiers_rewriter.cpp +++ b/src/theory/quantifiers/quantifiers_rewriter.cpp @@ -15,6 +15,7 @@ **/ #include "theory/quantifiers/quantifiers_rewriter.h" +#include "theory/quantifiers/options.h" using namespace std; using namespace CVC4; @@ -690,14 +691,14 @@ Node QuantifiersRewriter::rewriteQuant( Node n, bool isNested, bool duringRewrit } bool QuantifiersRewriter::doMiniscopingNoFreeVar(){ - return Options::current()->miniscopeQuantFreeVar; + return options::miniscopeQuantFreeVar(); } bool QuantifiersRewriter::doMiniscopingAnd(){ - if( Options::current()->miniscopeQuant ){ + if( options::miniscopeQuant() ){ return true; }else{ - if( Options::current()->cbqi ){ + if( options::cbqi() ){ return true; }else{ return false; @@ -709,13 +710,13 @@ bool QuantifiersRewriter::doOperation( Node f, bool isNested, int computeOption, if( computeOption==COMPUTE_NNF ){ return false;//TODO: compute NNF (current bad idea since arithmetic rewrites equalities) }else if( computeOption==COMPUTE_PRE_SKOLEM ){ - return Options::current()->preSkolemQuant && !duringRewrite; + return options::preSkolemQuant() && !duringRewrite; }else if( computeOption==COMPUTE_PRENEX ){ - return Options::current()->prenexQuant; + return options::prenexQuant(); }else if( computeOption==COMPUTE_VAR_ELIMINATION ){ - return Options::current()->varElimQuant; + return options::varElimQuant(); }else if( computeOption==COMPUTE_CNF ){ - return Options::current()->cnfQuant && !duringRewrite;// || Options::current()->finiteModelFind; + return options::cnfQuant() && !duringRewrite;// || options::finiteModelFind(); }else{ return false; } diff --git a/src/theory/quantifiers/term_database.cpp b/src/theory/quantifiers/term_database.cpp index 945c82bf9..bb8fafb14 100644 --- a/src/theory/quantifiers/term_database.cpp +++ b/src/theory/quantifiers/term_database.cpp @@ -61,7 +61,7 @@ void TermDb::addTermEfficient( Node n, std::set< Node >& added){ void TermDb::addTerm( Node n, std::set< Node >& added, bool withinQuant ){ //don't add terms in quantifier bodies - if( withinQuant && !Options::current()->registerQuantBodyTerms ){ + if( withinQuant && !options::registerQuantBodyTerms() ){ return; } if( d_processed.find( n )==d_processed.end() ){ @@ -82,7 +82,7 @@ void TermDb::addTerm( Node n, std::set< Node >& added, bool withinQuant ){ uf::InstantiatorTheoryUf* d_ith = (uf::InstantiatorTheoryUf*)d_quantEngine->getInstantiator( THEORY_UF ); for( int i=0; i<(int)n.getNumChildren(); i++ ){ addTerm( n[i], added, withinQuant ); - if( Options::current()->efficientEMatching ){ + if( options::efficientEMatching() ){ if( d_parents[n[i]][op].empty() ){ //must add parent to equivalence class info Node nir = d_ith->getRepresentative( n[i] ); @@ -97,7 +97,7 @@ void TermDb::addTerm( Node n, std::set< Node >& added, bool withinQuant ){ Assert(!getParents(n[i],op,i).empty()); } } - if( Options::current()->eagerInstQuant ){ + if( options::eagerInstQuant() ){ if( !n.hasAttribute(InstLevelAttribute()) && n.getAttribute(InstLevelAttribute())==0 ){ int addedLemmas = 0; for( int i=0; i<(int)d_ith->d_op_triggers[op].size(); i++ ){ @@ -115,7 +115,7 @@ void TermDb::addTerm( Node n, std::set< Node >& added, bool withinQuant ){ } } }else{ - if( Options::current()->efficientEMatching && !n.hasAttribute(InstConstantAttribute())){ + if( options::efficientEMatching() && !n.hasAttribute(InstConstantAttribute())){ //Efficient e-matching must be notified //The term in triggers are not important here Debug("term-db") << "New in this branch term " << n << std::endl; @@ -196,7 +196,7 @@ Node TermDb::getModelBasisTerm( TypeNode tn, int i ){ Node mbt; if( d_type_map[ tn ].empty() ){ std::stringstream ss; - ss << Expr::setlanguage(Options::current()->outputLanguage); + ss << Expr::setlanguage(options::outputLanguage()); ss << "e_" << tn; mbt = NodeManager::currentNM()->mkVar( ss.str(), tn ); }else{ diff --git a/src/theory/quantifiers/theory_quantifiers.cpp b/src/theory/quantifiers/theory_quantifiers.cpp index 27310e21b..3d41d28b7 100644 --- a/src/theory/quantifiers/theory_quantifiers.cpp +++ b/src/theory/quantifiers/theory_quantifiers.cpp @@ -27,6 +27,7 @@ #include <map> #include <time.h> #include "theory/quantifiers/theory_quantifiers_instantiator.h" +#include "theory/quantifiers/options.h" #include "theory/quantifiers/term_database.h" using namespace std; diff --git a/src/theory/quantifiers/theory_quantifiers_instantiator.cpp b/src/theory/quantifiers/theory_quantifiers_instantiator.cpp index 84b6c65c7..8486a3a84 100644 --- a/src/theory/quantifiers/theory_quantifiers_instantiator.cpp +++ b/src/theory/quantifiers/theory_quantifiers_instantiator.cpp @@ -16,6 +16,7 @@ #include "theory/quantifiers/theory_quantifiers_instantiator.h" #include "theory/quantifiers/theory_quantifiers.h" +#include "theory/quantifiers/options.h" #include "theory/theory_engine.h" using namespace std; @@ -32,7 +33,7 @@ Instantiator( c, ie, th ){ void InstantiatorTheoryQuantifiers::assertNode( Node assertion ){ Debug("quant-quant-assert") << "InstantiatorTheoryQuantifiers::check: " << assertion << std::endl; - if( Options::current()->cbqi ){ + if( options::cbqi() ){ if( assertion.hasAttribute(InstConstantAttribute()) ){ Debug("quant-quant-assert") << " -> has constraints from " << assertion.getAttribute(InstConstantAttribute()) << std::endl; setHasConstraintsFrom( assertion.getAttribute(InstConstantAttribute()) ); diff --git a/src/theory/quantifiers_engine.cpp b/src/theory/quantifiers_engine.cpp index 471bc9ac1..4d94d8d83 100644 --- a/src/theory/quantifiers_engine.cpp +++ b/src/theory/quantifiers_engine.cpp @@ -22,6 +22,7 @@ #include "theory/arrays/theory_arrays.h" #include "theory/datatypes/theory_datatypes.h" #include "theory/quantifiers/quantifiers_rewriter.h" +#include "theory/quantifiers/options.h" #include "theory/quantifiers/model_engine.h" #include "theory/quantifiers/instantiation_engine.h" #include "theory/quantifiers/first_order_model.h" @@ -72,14 +73,14 @@ d_active( c ){ d_model = new quantifiers::FirstOrderModel( this, c, "FirstOrderModel" ); //add quantifiers modules - if( !Options::current()->finiteModelFind || Options::current()->fmfInstEngine ){ + if( !options::finiteModelFind() || options::fmfInstEngine() ){ //the instantiation must set incomplete flag unless finite model finding is turned on - d_inst_engine = new quantifiers::InstantiationEngine( this, !Options::current()->finiteModelFind ); + d_inst_engine = new quantifiers::InstantiationEngine( this, !options::finiteModelFind() ); d_modules.push_back( d_inst_engine ); }else{ d_inst_engine = NULL; } - if( Options::current()->finiteModelFind ){ + if( options::finiteModelFind() ){ d_model_engine = new quantifiers::ModelEngine( this ); d_modules.push_back( d_model_engine ); }else{ @@ -130,7 +131,7 @@ void QuantifiersEngine::check( Theory::Effort e ){ } //build the model if not done so already // this happens if no quantifiers are currently asserted and no model-building module is enabled - if( Options::current()->produceModels && e==Theory::EFFORT_LAST_CALL && !d_hasAddedLemma && !d_model_set ){ + if( options::produceModels() && e==Theory::EFFORT_LAST_CALL && !d_hasAddedLemma && !d_model_set ){ d_te->getModelBuilder()->buildModel( d_model ); } } @@ -209,7 +210,7 @@ void QuantifiersEngine::registerQuantifier( Node f ){ Node ceBody = d_term_db->getCounterexampleBody( quants[q] ); generatePhaseReqs( quants[q], ceBody ); //also register it with the strong solver - if( Options::current()->finiteModelFind ){ + if( options::finiteModelFind() ){ ((uf::TheoryUF*)d_te->getTheory( THEORY_UF ))->getStrongSolver()->registerQuantifier( quants[q] ); } } @@ -253,7 +254,7 @@ void QuantifiersEngine::resetInstantiationRound( Theory::Effort level ){ void QuantifiersEngine::addTermToDatabase( Node n, bool withinQuant ){ std::set< Node > added; getTermDatabase()->addTerm( n, added, withinQuant ); - if( Options::current()->efficientEMatching ){ + if( options::efficientEMatching() ){ uf::InstantiatorTheoryUf* d_ith = (uf::InstantiatorTheoryUf*)getInstantiator( THEORY_UF ); d_ith->newTerms(added); } @@ -423,7 +424,7 @@ void QuantifiersEngine::flushLemmas( OutputChannel* out ){ } void QuantifiersEngine::getPhaseReqTerms( Node f, std::vector< Node >& nodes ){ - if( Options::current()->literalMatchMode!=Options::LITERAL_MATCH_NONE ){ + if( options::literalMatchMode()!=quantifiers::LITERAL_MATCH_NONE ){ bool printed = false; // doing literal-based matching (consider polarity of literals) for( int i=0; i<(int)nodes.size(); i++ ){ diff --git a/src/theory/rewriterules/options b/src/theory/rewriterules/options new file mode 100644 index 000000000..285e489be --- /dev/null +++ b/src/theory/rewriterules/options @@ -0,0 +1,14 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module REWRITE_RULES "theory/rewriterules/options.h" Rewrite Rules + +option efficientEMatching --efficient-e-matching bool :default false + use efficient E-matching (only for rewrite rules) + +option rewriteRulesAsAxioms --rewrite-rules-as-axioms bool :default false + whether to convert rewrite rules to usual axioms (for debugging only) + +endmodule diff --git a/src/theory/rewriterules/theory_rewriterules.cpp b/src/theory/rewriterules/theory_rewriterules.cpp index 57bc6d9cf..b4ae93653 100644 --- a/src/theory/rewriterules/theory_rewriterules.cpp +++ b/src/theory/rewriterules/theory_rewriterules.cpp @@ -23,7 +23,7 @@ #include "theory/rewriterules/theory_rewriterules_preprocess.h" #include "theory/rewriter.h" -#include "util/options.h" +#include "theory/rewriterules/options.h" using namespace std; @@ -292,13 +292,13 @@ Trigger TheoryRewriteRules::createTrigger( TNode n, std::vector<Node> & pattern // Debug("rewriterules") << "createTrigger:"; getQuantifiersEngine()->registerPattern(pattern); return *Trigger::mkTrigger(getQuantifiersEngine(),n,pattern, - Options::current()->efficientEMatching? + options::efficientEMatching()? Trigger::MATCH_GEN_EFFICIENT_E_MATCH : Trigger::MATCH_GEN_DEFAULT, true, Trigger::TR_MAKE_NEW, false); - // Options::current()->smartMultiTriggers); + // options::smartMultiTriggers()); }; bool TheoryRewriteRules::notifyIfKnown(const GList * const ltested, diff --git a/src/theory/rewriterules/theory_rewriterules_rules.cpp b/src/theory/rewriterules/theory_rewriterules_rules.cpp index 1ad8fdaa7..edea7a3c0 100644 --- a/src/theory/rewriterules/theory_rewriterules_rules.cpp +++ b/src/theory/rewriterules/theory_rewriterules_rules.cpp @@ -21,7 +21,7 @@ #include "theory/rewriterules/theory_rewriterules_params.h" #include "theory/rewriterules/theory_rewriterules_preprocess.h" #include "theory/rewriterules/theory_rewriterules.h" -#include "util/options.h" +#include "theory/rewriterules/options.h" #include "theory/quantifiers/term_database.h" @@ -110,7 +110,7 @@ inline void addPattern(TheoryRewriteRules & re, if (tri.getKind() == kind::NOT && tri[0].getKind() == kind::APPLY_UF) tri = tri[0]; pattern.push_back( - Options::current()->rewriteRulesAsAxioms? + options::rewriteRulesAsAxioms()? static_cast<Node>(tri): re.getQuantifiersEngine()->getTermDatabase()-> convertNodeToPattern(tri,r,vars,inst_constants)); @@ -224,7 +224,7 @@ void TheoryRewriteRules::addRewriteRule(const Node r) //If we convert to usual axioms - if(Options::current()->rewriteRulesAsAxioms){ + if(options::rewriteRulesAsAxioms()){ NodeBuilder<> forallB(kind::FORALL); forallB << r[0]; NodeBuilder<> guardsB(kind::AND); diff --git a/src/theory/rr_inst_match.h b/src/theory/rr_inst_match.h index d89b221bb..68b6e1bfd 100644 --- a/src/theory/rr_inst_match.h +++ b/src/theory/rr_inst_match.h @@ -35,6 +35,9 @@ #include "expr/node_manager.h" #include "expr/node_builder.h" +#include "theory/quantifiers/options.h" +#include "theory/rewriterules/options.h" + //#define USE_EFFICIENT_E_MATCHING namespace CVC4 { @@ -65,8 +68,8 @@ public: /** legal candidate */ static inline bool isLegalCandidate( TNode n ){ return !n.getAttribute(NoMatchAttribute()) && - ( !Options::current()->cbqi || !n.hasAttribute(InstConstantAttribute())) && - ( !Options::current()->efficientEMatching || n.hasAttribute(AvailableInTermDb()) ); + ( !options::cbqi() || !n.hasAttribute(InstConstantAttribute())) && + ( !options::efficientEMatching() || n.hasAttribute(AvailableInTermDb()) ); } }; diff --git a/src/theory/theory.h b/src/theory/theory.h index 24551637b..f3a9db394 100644 --- a/src/theory/theory.h +++ b/src/theory/theory.h @@ -32,7 +32,7 @@ #include "context/context.h" #include "context/cdlist.h" #include "context/cdo.h" -#include "util/options.h" +#include "options/options.h" #include "util/stats.h" #include "util/dump.h" diff --git a/src/theory/theory_engine.cpp b/src/theory/theory_engine.cpp index 1fb7305d4..6fbd4a417 100644 --- a/src/theory/theory_engine.cpp +++ b/src/theory/theory_engine.cpp @@ -24,7 +24,7 @@ #include "expr/attribute.h" #include "expr/node.h" #include "expr/node_builder.h" -#include "util/options.h" +#include "options/options.h" #include "util/lemma_output_channel.h" #include "theory/theory.h" @@ -38,6 +38,7 @@ #include "theory/model.h" #include "theory/quantifiers_engine.h" #include "theory/quantifiers/theory_quantifiers.h" +#include "theory/quantifiers/options.h" #include "theory/quantifiers/model_engine.h" #include "theory/quantifiers/first_order_model.h" @@ -349,7 +350,7 @@ void TheoryEngine::check(Theory::Effort effort) { if( d_logicInfo.isQuantified() ){ ((theory::quantifiers::TheoryQuantifiers*) d_theoryTable[THEORY_QUANTIFIERS])->performCheck(Theory::EFFORT_LAST_CALL); // if we have given up, then possibly flip decision - if(Options::current()->flipDecision) { + if(options::flipDecision()) { if(d_incomplete && !d_inConflict && !d_lemmasAdded) { if( ((theory::quantifiers::TheoryQuantifiers*) d_theoryTable[THEORY_QUANTIFIERS])->flipDecision() ) { d_incomplete = false; @@ -357,7 +358,7 @@ void TheoryEngine::check(Theory::Effort effort) { } } //if returning incomplete or SAT, we have ensured that the model in the quantifiers engine has been built - }else if( Options::current()->produceModels ){ + }else if( options::produceModels() ){ //must build model at this point d_curr_model_builder->buildModel( d_curr_model ); } @@ -1114,8 +1115,8 @@ theory::LemmaStatus TheoryEngine::lemma(TNode node, bool negated, bool removable } // Share with other portfolio threads - if(Options::current()->lemmaOutputChannel != NULL) { - Options::current()->lemmaOutputChannel->notifyNewLemma(node.toExpr()); + if(options::lemmaOutputChannel() != NULL) { + options::lemmaOutputChannel()->notifyNewLemma(node.toExpr()); } // Remove the ITEs diff --git a/src/theory/theory_engine.h b/src/theory/theory_engine.h index 449f4adc3..de04c878c 100644 --- a/src/theory/theory_engine.h +++ b/src/theory/theory_engine.h @@ -36,7 +36,8 @@ #include "theory/shared_terms_database.h" #include "theory/term_registration_visitor.h" #include "theory/valuation.h" -#include "util/options.h" +#include "options/options.h" +#include "smt/options.h" #include "util/stats.h" #include "util/hash.h" #include "util/cache.h" diff --git a/src/theory/trigger.cpp b/src/theory/trigger.cpp index 92573d464..f895f6814 100644 --- a/src/theory/trigger.cpp +++ b/src/theory/trigger.cpp @@ -20,6 +20,7 @@ #include "theory/uf/theory_uf_instantiator.h" #include "theory/candidate_generator.h" #include "theory/uf/equality_engine.h" +#include "theory/quantifiers/options.h" using namespace std; using namespace CVC4; @@ -95,7 +96,7 @@ d_quantEngine( qe ), d_f( f ){ ++(qe->d_statistics.d_multi_triggers); } //Notice() << "Trigger : " << (*this) << " for " << f << std::endl; - if( Options::current()->eagerInstQuant ){ + if( options::eagerInstQuant() ){ Theory* th_uf = qe->getTheoryEngine()->getTheory( theory::THEORY_UF ); uf::InstantiatorTheoryUf* ith = (uf::InstantiatorTheoryUf*)th_uf->getInstantiator(); for( int i=0; i<(int)d_nodes.size(); i++ ){ diff --git a/src/theory/uf/Makefile.am b/src/theory/uf/Makefile.am index 61330bbde..e027f8909 100644 --- a/src/theory/uf/Makefile.am +++ b/src/theory/uf/Makefile.am @@ -24,4 +24,6 @@ libuf_la_SOURCES = \ theory_uf_model.h \ theory_uf_model.cpp -EXTRA_DIST = kinds +EXTRA_DIST = \ + kinds \ + options_handlers.h diff --git a/src/theory/uf/inst_strategy.cpp b/src/theory/uf/inst_strategy.cpp index 5696251ed..9d644ae8d 100644 --- a/src/theory/uf/inst_strategy.cpp +++ b/src/theory/uf/inst_strategy.cpp @@ -20,6 +20,7 @@ #include "theory/theory_engine.h" #include "theory/uf/theory_uf.h" #include "theory/uf/equality_engine.h" +#include "theory/quantifiers/options.h" #include "theory/quantifiers/term_database.h" using namespace std; @@ -144,9 +145,9 @@ void InstStrategyUserPatterns::addUserPattern( Node f, Node pat ){ //extend to literal matching d_quantEngine->getPhaseReqTerms( f, nodes ); //check match option - int matchOption = Options::current()->efficientEMatching ? InstMatchGenerator::MATCH_GEN_EFFICIENT_E_MATCH : 0; + int matchOption = options::efficientEMatching() ? InstMatchGenerator::MATCH_GEN_EFFICIENT_E_MATCH : 0; d_user_gen[f].push_back( Trigger::mkTrigger( d_quantEngine, f, nodes, matchOption, true, Trigger::TR_MAKE_NEW, - Options::current()->smartTriggers ) ); + options::smartTriggers() ) ); } } @@ -298,11 +299,11 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){ //} } //now, generate the trigger... - int matchOption = Options::current()->efficientEMatching ? InstMatchGenerator::MATCH_GEN_EFFICIENT_E_MATCH : 0; + int matchOption = options::efficientEMatching() ? InstMatchGenerator::MATCH_GEN_EFFICIENT_E_MATCH : 0; Trigger* tr = NULL; if( d_is_single_trigger[ patTerms[0] ] ){ tr = Trigger::mkTrigger( d_quantEngine, f, patTerms[0], matchOption, false, Trigger::TR_RETURN_NULL, - Options::current()->smartTriggers ); + options::smartTriggers() ); d_single_trigger_gen[ patTerms[0] ] = true; }else{ //if we are re-generating triggers, shuffle based on some method @@ -316,7 +317,7 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){ } //will possibly want to get an old trigger tr = Trigger::mkTrigger( d_quantEngine, f, patTerms, matchOption, false, Trigger::TR_GET_OLD, - Options::current()->smartTriggers ); + options::smartTriggers() ); } if( tr ){ if( tr->isMultiTrigger() ){ @@ -347,7 +348,7 @@ void InstStrategyAutoGenTriggers::generateTriggers( Node f ){ if( d_quantEngine->getNumQuantifiersForSymbol( patTerms[index].getOperator() )<=nqfs_curr ){ d_single_trigger_gen[ patTerms[index] ] = true; Trigger* tr2 = Trigger::mkTrigger( d_quantEngine, f, patTerms[index], matchOption, false, Trigger::TR_RETURN_NULL, - Options::current()->smartTriggers ); + options::smartTriggers() ); if( tr2 ){ //Notice() << "Add additional trigger " << patTerms[index] << std::endl; tr2->resetInstantiationRound(); diff --git a/src/theory/uf/options b/src/theory/uf/options new file mode 100644 index 000000000..6f6900da0 --- /dev/null +++ b/src/theory/uf/options @@ -0,0 +1,12 @@ +# +# Option specification file for CVC4 +# See src/options/base_options for a description of this file format +# + +module UF "theory/uf/options.h" Uninterpreted functions theory + +option ufSymmetryBreaker uf-symmetry-breaker --enable-symmetry-breaker/--disable-symmetry-breaker bool :read-write :default true + use UF symmetry breaker (Deharbe et al., CADE 2011) +/turns off UF symmetry breaker (Deharbe et al., CADE 2011) + +endmodule diff --git a/src/theory/uf/options_handlers.h b/src/theory/uf/options_handlers.h new file mode 100644 index 000000000..b08ae9d64 --- /dev/null +++ b/src/theory/uf/options_handlers.h @@ -0,0 +1,33 @@ +/********************* */ +/*! \file options_handlers.h + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief Custom handlers and predicates for TheoryUF options + ** + ** Custom handlers and predicates for TheoryUF options. + **/ + +#include "cvc4_private.h" + +#ifndef __CVC4__THEORY__UF__OPTIONS_HANDLERS_H +#define __CVC4__THEORY__UF__OPTIONS_HANDLERS_H + +namespace CVC4 { +namespace theory { +namespace uf { + +}/* CVC4::theory::uf namespace */ +}/* CVC4::theory namespace */ +}/* CVC4 namespace */ + +#endif /* __CVC4__THEORY__UF__OPTIONS_HANDLERS_H */ + diff --git a/src/theory/uf/theory_uf.cpp b/src/theory/uf/theory_uf.cpp index d24878a62..5b8470567 100644 --- a/src/theory/uf/theory_uf.cpp +++ b/src/theory/uf/theory_uf.cpp @@ -18,6 +18,8 @@ **/ #include "theory/uf/theory_uf.h" +#include "theory/uf/options.h" +#include "theory/quantifiers/options.h" #include "theory/uf/theory_uf_instantiator.h" #include "theory/uf/theory_uf_strong_solver.h" #include "theory/model.h" @@ -33,7 +35,7 @@ TheoryUF::TheoryUF(context::Context* c, context::UserContext* u, OutputChannel& d_notify(*this), /* The strong theory solver can be notified by EqualityEngine::init(), * so make sure it's initialized first. */ - d_thss(Options::current()->finiteModelFind ? new StrongSolverTheoryUf(c, u, out, this) : NULL), + d_thss(options::finiteModelFind() ? new StrongSolverTheoryUf(c, u, out, this) : NULL), d_equalityEngine(d_notify, c, "theory::uf::TheoryUF"), d_conflict(c, false), d_literalsToPropagate(c), @@ -179,7 +181,7 @@ void TheoryUF::presolve() { // TimerStat::CodeTimer codeTimer(d_presolveTimer); Debug("uf") << "uf: begin presolve()" << endl; - if(Options::current()->ufSymmetryBreaker) { + if(options::ufSymmetryBreaker()) { vector<Node> newClauses; d_symb.apply(newClauses); for(vector<Node>::const_iterator i = newClauses.begin(); @@ -299,7 +301,7 @@ void TheoryUF::ppStaticLearn(TNode n, NodeBuilder<>& learned) { } } - if(Options::current()->ufSymmetryBreaker) { + if(options::ufSymmetryBreaker()) { d_symb.assertFormula(n); } }/* TheoryUF::ppStaticLearn() */ diff --git a/src/theory/uf/theory_uf_instantiator.cpp b/src/theory/uf/theory_uf_instantiator.cpp index 48092b340..ea253cbdb 100644 --- a/src/theory/uf/theory_uf_instantiator.cpp +++ b/src/theory/uf/theory_uf_instantiator.cpp @@ -19,6 +19,8 @@ #include "theory/uf/theory_uf.h" #include "theory/rr_candidate_generator.h" #include "theory/uf/equality_engine.h" +#include "theory/quantifiers/options.h" +#include "theory/rewriterules/options.h" #include "theory/quantifiers/term_database.h" using namespace std; @@ -91,11 +93,11 @@ inline void outputEqClassInfo( const char* c, const EqClassInfo* eci){ InstantiatorTheoryUf::InstantiatorTheoryUf(context::Context* c, CVC4::theory::QuantifiersEngine* qe, Theory* th) : Instantiator( c, qe, th ) { - if( !Options::current()->finiteModelFind || Options::current()->fmfInstEngine ){ - if( Options::current()->cbqi ){ + if( !options::finiteModelFind() || options::fmfInstEngine() ){ + if( options::cbqi() ){ addInstStrategy( new InstStrategyCheckCESolved( this, qe ) ); } - if( Options::current()->userPatternsQuant ){ + if( options::userPatternsQuant() ){ d_isup = new InstStrategyUserPatterns( this, qe ); addInstStrategy( d_isup ); }else{ @@ -106,7 +108,7 @@ Instantiator( c, qe, th ) i_ag->setGenerateAdditional( true ); addInstStrategy( i_ag ); //addInstStrategy( new InstStrategyAddFailSplits( this, ie ) ); - if( !Options::current()->finiteModelFind ){ + if( !options::finiteModelFind() ){ addInstStrategy( new InstStrategyFreeVariable( this, qe ) ); } //d_isup->setPriorityOver( i_ag ); @@ -124,7 +126,7 @@ void InstantiatorTheoryUf::assertNode( Node assertion ) Debug("quant-uf-assert") << "InstantiatorTheoryUf::check: " << assertion << std::endl; //preRegisterTerm( assertion ); d_quantEngine->addTermToDatabase( assertion ); - if( Options::current()->cbqi ){ + if( options::cbqi() ){ if( assertion.hasAttribute(InstConstantAttribute()) ){ setHasConstraintsFrom( assertion.getAttribute(InstConstantAttribute()) ); }else if( assertion.getKind()==NOT && assertion[0].hasAttribute(InstConstantAttribute()) ){ @@ -337,7 +339,7 @@ void InstantiatorTheoryUf::newTerms(SetNode& s){ /** merge */ void InstantiatorTheoryUf::merge( TNode a, TNode b ){ - if( Options::current()->efficientEMatching ){ + if( options::efficientEMatching() ){ //merge eqc_ops of b into a EqClassInfo* eci_a = getOrCreateEquivalenceClassInfo( a ); EqClassInfo* eci_b = getOrCreateEquivalenceClassInfo( b ); diff --git a/src/theory/uf/theory_uf_strong_solver.cpp b/src/theory/uf/theory_uf_strong_solver.cpp index 895a7d056..70b07daa6 100644 --- a/src/theory/uf/theory_uf_strong_solver.cpp +++ b/src/theory/uf/theory_uf_strong_solver.cpp @@ -19,6 +19,7 @@ #include "theory/uf/equality_engine.h" #include "theory/uf/theory_uf_instantiator.h" #include "theory/theory_engine.h" +#include "theory/quantifiers/options.h" #include "theory/quantifiers/term_database.h" //#define USE_SMART_SPLITS @@ -194,7 +195,7 @@ struct sortExternalDegree { }; bool StrongSolverTheoryUf::ConflictFind::Region::getMustCombine( int cardinality ){ - if( Options::current()->ufssRegions && d_total_diseq_external>=long(cardinality) ){ + if( options::ufssRegions() && d_total_diseq_external>=long(cardinality) ){ //The number of external disequalities is greater than or equal to cardinality. //Thus, a clique of size cardinality+1 may exist between nodes in d_regions[i] and other regions //Check if this is actually the case: must have n nodes with outgoing degree (cardinality+1-n) for some n>0 @@ -243,7 +244,7 @@ bool StrongSolverTheoryUf::ConflictFind::Region::check( Theory::Effort level, in } } return true; - }else if( Options::current()->ufssRegions || Options::current()->ufssEagerSplits || level==Theory::EFFORT_FULL ){ + }else if( options::ufssRegions() || options::ufssEagerSplits() || level==Theory::EFFORT_FULL ){ //build test clique, up to size cardinality+1 if( d_testCliqueSize<=long(cardinality) ){ std::vector< Node > newClique; @@ -584,7 +585,7 @@ void StrongSolverTheoryUf::ConflictFind::explainClique( std::vector< Node >& cli /** new node */ void StrongSolverTheoryUf::ConflictFind::newEqClass( Node n ){ if( d_regions_map.find( n )==d_regions_map.end() ){ - if( !Options::current()->ufssRegions ){ + if( !options::ufssRegions() ){ //if not using regions, always add new equivalence classes to region index = 0 d_regions_index = 0; } @@ -594,7 +595,7 @@ void StrongSolverTheoryUf::ConflictFind::newEqClass( Node n ){ if( d_regions_index<d_regions.size() ){ d_regions[ d_regions_index ]->debugPrint("uf-ss-debug",true); d_regions[ d_regions_index ]->d_valid = true; - Assert( !Options::current()->ufssRegions || d_regions[ d_regions_index ]->getNumReps()==0 ); + Assert( !options::ufssRegions() || d_regions[ d_regions_index ]->getNumReps()==0 ); }else{ d_regions.push_back( new Region( this, d_th->getSatContext() ) ); } @@ -882,7 +883,7 @@ void StrongSolverTheoryUf::ConflictFind::check( Theory::Effort level, OutputChan } bool addedLemma = false; //do splitting on demand - if( level==Theory::EFFORT_FULL || Options::current()->ufssEagerSplits ){ + if( level==Theory::EFFORT_FULL || options::ufssEagerSplits() ){ Debug("uf-ss-debug") << "Add splits?" << std::endl; //see if we have any recommended splits from large regions for( int i=0; i<(int)d_regions_index; i++ ){ @@ -902,7 +903,7 @@ void StrongSolverTheoryUf::ConflictFind::check( Theory::Effort level, OutputChan if( level==Theory::EFFORT_FULL ){ if( !addedLemma ){ Debug("uf-ss") << "No splits added." << std::endl; - if( Options::current()->ufssColoringSat ){ + if( options::ufssColoringSat() ){ //otherwise, try to disambiguate individual terms if( !disambiguateTerms( out ) ){ //no disequalities can be propagated @@ -1000,7 +1001,7 @@ void StrongSolverTheoryUf::ConflictFind::setCardinality( int c, OutputChannel* o } void StrongSolverTheoryUf::ConflictFind::getRepresentatives( std::vector< Node >& reps ){ - if( !Options::current()->ufssColoringSat ){ + if( !options::ufssColoringSat() ){ bool foundRegion = false; for( int i=0; i<(int)d_regions_index; i++ ){ //should not have multiple regions at this point @@ -1045,7 +1046,7 @@ Node StrongSolverTheoryUf::ConflictFind::getCardinalityLemma(){ if( d_cardinality_lemma.find( d_cardinality )==d_cardinality_lemma.end() ){ if( d_cardinality_lemma_term.isNull() ){ std::stringstream ss; - ss << Expr::setlanguage(Options::current()->outputLanguage); + ss << Expr::setlanguage(options::outputLanguage()); ss << "t_" << d_type; d_cardinality_lemma_term = NodeManager::currentNM()->mkVar( ss.str(), d_type ); } diff --git a/src/util/Makefile.am b/src/util/Makefile.am index 85c5f9657..7f469c68b 100644 --- a/src/util/Makefile.am +++ b/src/util/Makefile.am @@ -28,8 +28,6 @@ libutil_la_SOURCES = \ hash.h \ bool.h \ proof.h \ - options.h \ - options.cpp \ output.cpp \ output.h \ result.h \ @@ -170,19 +168,10 @@ EXTRA_DIST = \ exception.i \ language.i \ array.i \ - options.i \ ascription_type.i \ rational.i \ hash.i -MOSTLYCLEANFILES = \ - Debug_tags \ - Trace_tags \ - Debug_tags.tmp \ - Trace_tags.tmp \ - Debug_tags.h \ - Trace_tags.h - DISTCLEANFILES = \ integer.h.tmp \ rational.h.tmp \ @@ -190,3 +179,4 @@ DISTCLEANFILES = \ integer.h \ rational.h \ tls.h + diff --git a/src/util/configuration.cpp b/src/util/configuration.cpp index d0fc3cd1d..6fe2e2af0 100644 --- a/src/util/configuration.cpp +++ b/src/util/configuration.cpp @@ -28,11 +28,11 @@ #include "cvc4autoconfig.h" #if defined(CVC4_DEBUG) && defined(CVC4_TRACING) -# include "util/Debug_tags.h" +# include "options/Debug_tags.h" #endif /* CVC4_DEBUG && CVC4_TRACING */ #ifdef CVC4_TRACING -# include "util/Trace_tags.h" +# include "options/Trace_tags.h" #endif /* CVC4_TRACING */ using namespace std; diff --git a/src/util/options.cpp b/src/util/options.cpp deleted file mode 100644 index c2b632b32..000000000 --- a/src/util/options.cpp +++ /dev/null @@ -1,1801 +0,0 @@ -/********************* */ -/*! \file options.cpp - ** \verbatim - ** Original author: mdeters - ** Major contributors: cconway, taking - ** Minor contributors (to current version): barrett, dejan - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim - ** - ** \brief Contains code for handling command-line options. - ** - ** Contains code for handling command-line options - **/ - -#include <cstdio> -#include <cstdlib> -#include <new> -#include <unistd.h> -#include <string.h> -#include <stdint.h> -#include <time.h> -#include <sstream> - -#include <getopt.h> - -#include "expr/expr.h" -#include "expr/command.h" -#include "util/configuration.h" -#include "util/exception.h" -#include "util/language.h" -#include "util/options.h" -#include "util/output.h" -#include "util/dump.h" -#include "prop/sat_solver_factory.h" - -#include "cvc4autoconfig.h" - -using namespace std; -using namespace CVC4; - -namespace CVC4 { - -CVC4_THREADLOCAL(const Options*) Options::s_current = NULL; - -#ifdef CVC4_DEBUG -# define USE_EARLY_TYPE_CHECKING_BY_DEFAULT true -#else /* CVC4_DEBUG */ -# define USE_EARLY_TYPE_CHECKING_BY_DEFAULT false -#endif /* CVC4_DEBUG */ - -#if defined(CVC4_MUZZLED) || defined(CVC4_COMPETITION_MODE) -# define DO_SEMANTIC_CHECKS_BY_DEFAULT false -#else /* CVC4_MUZZLED || CVC4_COMPETITION_MODE */ -# define DO_SEMANTIC_CHECKS_BY_DEFAULT true -#endif /* CVC4_MUZZLED || CVC4_COMPETITION_MODE */ - -/** default decision options */ -const Options::DecisionOptions defaultDecOpt = { - false, // relevancyLeaves - 1000, // maxRelTimeAsPermille - true, // computeRelevancy - false, // mustRelevancy - false, // stopOnly -}; - -Options::Options() : - binary_name(), - statistics(false), - in(&std::cin), - out(&std::cout), - err(&std::cerr), - verbosity(0), - inputLanguage(language::input::LANG_AUTO), - outputLanguage(language::output::LANG_AUTO), - help(false), - version(false), - languageHelp(false), - parseOnly(false), - preprocessOnly(false), - semanticChecks(DO_SEMANTIC_CHECKS_BY_DEFAULT), - theoryRegistration(true), - memoryMap(false), - strictParsing(false), - lazyDefinitionExpansion(false), - printWinner(false), - defaultExprDepth(0), - simplificationMode(SIMPLIFICATION_MODE_BATCH), - simplificationModeSetByUser(false), - decisionMode(DECISION_STRATEGY_INTERNAL), - decisionModeSetByUser(false), - decisionOptions(DecisionOptions(defaultDecOpt)), - doStaticLearning(true), - doITESimp(false), - doITESimpSetByUser(false), - unconstrainedSimp(false), - unconstrainedSimpSetByUser(false), - repeatSimp(false), - repeatSimpSetByUser(false), - interactive(false), - interactiveSetByUser(false), - perCallResourceLimit(0), - cumulativeResourceLimit(0), - perCallMillisecondLimit(0), - cumulativeMillisecondLimit(0), - segvNoSpin(false), - produceModels(false), - proof(false), - produceAssignments(false), - typeChecking(DO_SEMANTIC_CHECKS_BY_DEFAULT), - earlyTypeChecking(USE_EARLY_TYPE_CHECKING_BY_DEFAULT), - incrementalSolving(false), - replayFilename(""), - replayStream(NULL), - replayLog(NULL), - satRandomFreq(0.0), - satRandomSeed(91648253),// Minisat's default value - satVarDecay(0.95), - satClauseDecay(0.999), - satRestartFirst(25), - satRestartInc(3.0), - arithUnateLemmaMode(ALL_PRESOLVE_LEMMAS), - arithPropagationMode(BOTH_PROP), - arithHeuristicPivots(0), - arithHeuristicPivotsSetByUser(false), - arithStandardCheckVarOrderPivots(-1), - arithStandardCheckVarOrderPivotsSetByUser(false), - arithHeuristicPivotRule(MINIMUM), - arithSimplexCheckPeriod(200), - arithPivotThreshold(2), - arithPivotThresholdSetByUser(false), - arithPropagateMaxLength(16), - arithDioSolver(true), - arithRewriteEq(false), - arithRewriteEqSetByUser(false), - ufSymmetryBreaker(false), - ufSymmetryBreakerSetByUser(false), - miniscopeQuant(true), - miniscopeQuantFreeVar(true), - prenexQuant(true), - varElimQuant(false), - cnfQuant(false), - preSkolemQuant(false), - smartTriggers(true), - registerQuantBodyTerms(false), - instWhenMode(INST_WHEN_FULL_LAST_CALL), - eagerInstQuant(false), - finiteModelFind(false), - ufssEagerSplits(false), - ufssRegions(true), - ufssColoringSat(false), - fmfModelBasedInst(true), - fmfInstGen(true), - fmfOneInstPerRound(false), - fmfInstEngine(false), - fmfRelevantDomain(false), - efficientEMatching(false), - literalMatchMode(LITERAL_MATCH_NONE), - cbqi(false), - cbqiSetByUser(false), - rewriteRulesAsAxioms(false), - userPatternsQuant(true), - flipDecision(false), - printInstEngine(false), - printModelEngine(false), - lemmaOutputChannel(NULL), - lemmaInputChannel(NULL), - threads(2),// default should be 1 probably, but say 2 for now - threadArgv(), - thread_id(-1), - separateOutput(false), - sharingFilterByLength(-1), - bitvectorEagerBitblast(false), - bitvectorEagerFullcheck(false), - bitvectorShareLemmas(false), - sat_refine_conflicts(false), - theoryOfModeSetByUser(false), - theoryOfMode(theory::THEORY_OF_TYPE_BASED) -{ -} - - -static const string mostCommonOptionsDescription = "\ -Most commonly-used CVC4 options:\n\ - --version | -V identify this CVC4 binary\n\ - --help | -h full command line reference\n\ - --lang | -L force input language\n\ - (default is `auto'; see --lang help)\n\ - --output-lang force output language\n\ - (default is `auto'; see --lang help)\n\ - --verbose | -v increase verbosity (may be repeated)\n\ - --quiet | -q decrease verbosity (may be repeated)\n\ - --stats give statistics on exit\n\ - --parse-only exit after parsing input\n\ - --preprocess-only exit after preproc (useful with --stats or --dump)\n\ - --dump=MODE dump preprocessed assertions, etc., see --dump=help\n\ - --dump-to=FILE all dumping goes to FILE (instead of stdout)\n\ - --show-config show CVC4 static configuration\n\ - --strict-parsing be less tolerant of non-conforming inputs\n\ - --interactive force interactive mode\n\ - --no-interactive force non-interactive mode\n\ - --produce-models | -m support the get-value command\n\ - --produce-assignments support the get-assignment command\n\ - --print-success print the \"success\" output required of SMT-LIBv2\n\ - --smtlib2 SMT-LIBv2 conformance mode (implies other options)\n\ - --proof turn on proof generation\n\ - --incremental | -i enable incremental solving\n\ - --tlimit=MS enable time limiting (give milliseconds)\n\ - --tlimit-per=MS enable time limiting per query (give milliseconds)\n\ - --rlimit=N enable resource limiting\n\ - --rlimit-per=N enable resource limiting per query\n\ -"; - -static const string optionsDescription = mostCommonOptionsDescription + "\ -\n\ -Additional CVC4 options:\n\ - --mmap memory map file input\n\ - --segv-nospin don't spin on segfault waiting for gdb\n\ - --lazy-type-checking type check expressions only when necessary (default)\n\ - --eager-type-checking type check expressions immediately on creation\n\ - (debug builds only)\n\ - --no-type-checking never type check expressions\n\ - --no-checking disable ALL semantic checks, including type checks\n\ - --no-theory-registration disable theory reg (not safe for some theories)\n\ - --print-winner enable printing the winning thread (pcvc4 only)\n\ - --trace | -t trace something (e.g. -t pushpop), can repeat\n\ - --debug | -d debug something (e.g. -d arith), can repeat\n\ - --show-debug-tags show all available tags for debugging\n\ - --show-trace-tags show all available tags for tracing\n\ - --show-sat-solvers show all available SAT solvers\n\ - --default-expr-depth=N print exprs to depth N (0 == default, -1 == no limit)\n\ - --default-dag-thresh=N dagify common subexprs appearing > N times\n\ - (1 == default, 0 == don't dagify)\n\ - --print-expr-types print types with variables when printing exprs\n\ - --lazy-definition-expansion expand define-funs/LAMBDAs lazily\n\ - --simplification=MODE choose simplification mode, see --simplification=help\n\ - --decision=MODE choose decision mode, see --decision=help\n\ - --decision-budget=N impose a budget for relevancy heuristic which increases linearly with\n\ - each decision. N between 0 and 1000. (default: 1000, no budget)\n\ - --no-static-learning turn off static learning (e.g. diamond-breaking)\n\ - --ite-simp turn on ite simplification (Kim (and Somenzi) et al., SAT 2009)\n\ - --no-ite-simp turn off ite simplification (Kim (and Somenzi) et al., SAT 2009)\n\ - --unconstrained-simp turn on unconstrained simplification (see Bruttomesso/Brummayer PhD thesis)\n\ - --no-unconstrained-simp turn off unconstrained simplification (see Bruttomesso/Brummayer PhD thesis)\n\ - --repeat-simp make multiple passes with nonclausal simplifier\n\ - --no-repeat-simp do not make multiple passes with nonclausal simplifier\n\ - --replay=file replay decisions from file\n\ - --replay-log=file log decisions and propagations to file\n\ - --theoryof-mode=mode mode for theoryof\n\ - SAT:\n\ - --random-freq=P frequency of random decisions in the sat solver\n\ - (P=0.0 by default)\n\ - --random-seed=S sets the random seed for the sat solver\n\ - --restart-int-base=I sets the base restart interval for the sat solver\n\ - (I=25 by default)\n\ - --restart-int-inc=F restart interval increase factor for the sat solver\n\ - (F=3.0 by default)\n\ - ARITHMETIC:\n\ - --unate-lemmas=MODE determines which lemmas to add before solving\n\ - (default is 'all', see --unate-lemmas=help)\n\ - --arith-prop=MODE turns on arithmetic propagation\n\ - (default is 'old', see --arith-prop=help)\n\ - --heuristic-pivot-rule=RULE change the pivot rule for the basic variable\n\ - (default is 'min', see --heuristic-pivot-rule help)\n\ - --heuristic-pivots=N the number of times to apply the heuristic pivot rule.\n\ - If N < 0, this defaults to the number of variables\n\ - If this is unset, this is tuned by the logic selection.\n\ - --simplex-check-period=N The number of pivots to do in simplex before rechecking for\n\ - a conflict on all variables.\n\ - --pivot-threshold=N sets the number of pivots using --pivot-rule\n\ - per basic variable per simplex instance before\n\ - using variable order\n\ - --prop-row-length=N sets the maximum row length to be used in propagation\n\ - --disable-dio-solver turns off Linear Diophantine Equation solver \n\ - (Griggio, JSAT 2012)\n\ - --enable-arith-rewrite-equalities turns on the preprocessing rewrite\n\ - turning equalities into a conjunction of inequalities.\n \ - --disable-arith-rewrite-equalities turns off the preprocessing rewrite\n\ - turning equalities into a conjunction of inequalities.\n \ - UF:\n\ - --enable-symmetry-breaker turns on UF symmetry breaker (Deharbe et al.,\n\ - CADE 2011) [on by default only for QF_UF]\n\ - --disable-symmetry-breaker turns off UF symmetry breaker\n\ - QUANTIFIERS:\n\ - --disable-miniscope-quant disable miniscope quantifiers\n\ - --disable-miniscope-quant-fv disable miniscope quantifiers for ground subformulas\n\ - --disable-prenex-quant disable prenexing of quantified formulas\n\ - --var-elim-quant enable variable elimination of quantified formulas\n\ - --cnf-quant apply CNF conversion to quantified formulas\n\ - --pre-skolem-quant apply skolemization eagerly to bodies of quantified formulas\n\ - --disable-smart-triggers disable smart triggers\n\ - --register-quant-body-terms consider ground terms within bodies of quantified formulas for matching\n\ - --inst-when=MODE when to apply instantiation\n\ - --eager-inst-quant apply quantifier instantiation eagerly\n\ - --literal-matching=MODE choose literal matching mode\n\ - --enable-cbqi turns on counterexample-based quantifier instantiation [off by default]\n\ - --disable-cbqi turns off counterexample-based quantifier instantiation\n\ - --ignore-user-patterns ignore user-provided patterns for quantifier instantiation\n\ - --enable-flip-decision turns on flip decision heuristic\n\ - REWRITERULES:\n\ - --efficient-e-matching use efficient E-matching (only for rewrite rules)\n\ - --rewrite-rules-as-axioms convert rewrite rules into usual axioms (for debugging only)\n\ - FINITE_MODEL_FINDING:\n\ - --finite-model-find use finite model finding heuristic for quantifier instantiation\n\ - --disable-uf-ss-regions disable region-based method for discovering cliques and splits in uf strong solver\n\ - --uf-ss-eager-split add splits eagerly for uf strong solver\n\ - --uf-ss-coloring-sat use coloring-based SAT heuristic for uf strong solver\n\ - --disable-fmf-mbqi disable model-based quantifier instantiation for finite model finding\n\ - --disable-fmf-inst-gen disable Inst-Gen instantiation techniques for finite model finding\n\ - --fmf-one-inst-per-round only add one instantiation per quantifier per round for fmf\n\ - --fmf-inst-engine use instantiation engine in conjunction with finite model finding\n\ - --fmf-relevant-domain use relevant domain computation, similar to complete instantiation (Ge, deMoura 09)\n\ - OTHER:\n\ - --disable-dio-solver turns off Linear Diophantine Equation solver (Griggio, JSAT 2012)\n\ - --disable-arith-rewrite-equalities turns off the preprocessing rewrite turning equalities into a conjunction of inequalities.\n\ - --threads=N sets the number of solver threads\n\ - --threadN=string configures thread N (0..#threads-1)\n\ - --filter-lemma-length=N don't share lemmas strictly longer than N\n\ - --bitblast-eager eagerly bitblast the bitvectors to the main SAT solver\n\ - --bitblast-share-lemmas share lemmas from the bitblasting solver with the main solver\n\ - --bitblast-eager-fullcheck check the bitblasting eagerly\n\ - --refine-conflicts refine theory conflict clauses\n\ -"; - - - -static const string languageDescription = "\ -Languages currently supported as arguments to the -L / --lang option:\n\ - auto attempt to automatically determine the input language\n\ - pl | cvc4 CVC4 presentation language\n\ - smt | smtlib SMT-LIB format 1.2\n\ - smt2 | smtlib2 SMT-LIB format 2.0\n\ - tptp TPTP format (cnf and fof)\n\ -\n\ -Languages currently supported as arguments to the --output-lang option:\n\ - auto match the output language to the input language\n\ - pl | cvc4 CVC4 presentation language\n\ - smt | smtlib SMT-LIB format 1.2\n\ - smt2 | smtlib2 SMT-LIB format 2.0\n\ - tptp TPTP format\n\ - ast internal format (simple syntax-tree language)\n\ -"; - -static const string simplificationHelp = "\ -Simplification modes currently supported by the --simplification option:\n\ -\n\ -batch (default) \n\ -+ save up all ASSERTions; run nonclausal simplification and clausal\n\ - (MiniSat) propagation for all of them only after reaching a querying command\n\ - (CHECKSAT or QUERY or predicate SUBTYPE declaration)\n\ -\n\ -incremental\n\ -+ run nonclausal simplification and clausal propagation at each ASSERT\n\ - (and at CHECKSAT/QUERY/SUBTYPE)\n\ -\n\ -none\n\ -+ do not perform nonclausal simplification\n\ -"; - -static const string theoryofHelp = "\ -TheoryOf modes currently supported by the --theoryof-mode option:\n\ -\n\ -type (default) \n\ -+ type variables, constants and equalities by type\n\ -\n\ -term \n\ -+ type variables as uninterpreted, equalities by the parametric theory\n\ -"; - -static const string decisionHelp = "\ -Decision modes currently supported by the --decision option:\n\ -\n\ -internal (default)\n\ -+ Use the internal decision heuristics of the SAT solver\n\ -\n\ -justification\n\ -+ An ATGP-inspired justification heuristic\n\ -\n\ -justification-stoponly\n\ -+ Use the justification heuristic only to stop early, not for decisions\n\ -\n\ -relevancy\n\ -+ Under development may-relevancy\n\ -\n\ -relevancy-leaves\n\ -+ May-relevancy, but decide only on leaves\n\ -\n\ -Developer modes:\n\ -\n\ -justification-rel\n\ -+ Use the relevancy code to do the justification stuff\n\ -+ (This should do exact same thing as justification)\n\ -\n\ -justification-must\n\ -+ Start deciding on literals close to root instead of those\n\ -+ near leaves (don't expect it to work well) [Unimplemented]\n\ -"; - -static const string instWhenHelp = "\ -Modes currently supported by the --inst-when option:\n\ -\n\ -full\n\ -+ Run instantiation round at full effort, before theory combination.\n\ -\n\ -full-last-call (default)\n\ -+ Alternate running instantiation rounds at full effort and last\n\ - call. In other words, interleave instantiation and theory combination.\n\ -\n\ -last-call\n\ -+ Run instantiation at last call effort, after theory combination.\n\ -\n\ -"; - -static const string literalMatchHelp = "\ -Literal match modes currently supported by the --literal-match option:\n\ -\n\ -none (default)\n\ -+ Do not use literal matching.\n\ -\n\ -predicate\n\ -+ Consider the phase requirements of predicate literals when applying heuristic\n\ - quantifier instantiation. For example, the trigger P( x ) in the quantified \n\ - formula forall( x ). ( P( x ) V ~Q( x ) ) will only be matched with ground\n\ - terms P( t ) where P( t ) is in the equivalence class of false, and likewise\n\ - Q( x ) with Q( s ) where Q( s ) is in the equivalence class of true.\n\ -\n\ -"; - -static const string dumpHelp = "\ -Dump modes currently supported by the --dump option:\n\ -\n\ -benchmark\n\ -+ Dump the benchmark structure (set-logic, push/pop, queries, etc.), but\n\ - does not include any declarations or assertions. Implied by all following\n\ - modes.\n\ -\n\ -declarations\n\ -+ Dump declarations. Implied by all following modes.\n\ -\n\ -assertions\n\ -+ Output the assertions after non-clausal simplification and static\n\ - learning phases, but before presolve-time T-lemmas arrive. If\n\ - non-clausal simplification and static learning are off\n\ - (--simplification=none --no-static-learning), the output\n\ - will closely resemble the input (with term-level ITEs removed).\n\ -\n\ -learned\n\ -+ Output the assertions after non-clausal simplification, static\n\ - learning, and presolve-time T-lemmas. This should include all eager\n\ - T-lemmas (in the form provided by the theory, which my or may not be\n\ - clausal). Also includes level-0 BCP done by Minisat.\n\ -\n\ -clauses\n\ -+ Do all the preprocessing outlined above, and dump the CNF-converted\n\ - output\n\ -\n\ -state\n\ -+ Dump all contextual assertions (e.g., SAT decisions, propagations..).\n\ - Implied by all \"stateful\" modes below and conflicts with all\n\ - non-stateful modes below.\n\ -\n\ -t-conflicts [non-stateful]\n\ -+ Output correctness queries for all theory conflicts\n\ -\n\ -missed-t-conflicts [stateful]\n\ -+ Output completeness queries for theory conflicts\n\ -\n\ -t-propagations [stateful]\n\ -+ Output correctness queries for all theory propagations\n\ -\n\ -missed-t-propagations [stateful]\n\ -+ Output completeness queries for theory propagations (LARGE and EXPENSIVE)\n\ -\n\ -t-lemmas [non-stateful]\n\ -+ Output correctness queries for all theory lemmas\n\ -\n\ -t-explanations [non-stateful]\n\ -+ Output correctness queries for all theory explanations\n\ -\n\ -Dump modes can be combined with multiple uses of --dump. Generally you want\n\ -one from the assertions category (either assertions, learned, or clauses), and\n\ -perhaps one or more stateful or non-stateful modes for checking correctness\n\ -and completeness of decision procedure implementations. Stateful modes dump\n\ -the contextual assertions made by the core solver (all decisions and\n\ -propagations as assertions; that affects the validity of the resulting\n\ -correctness and completeness queries, so of course stateful and non-stateful\n\ -modes cannot be mixed in the same run.\n\ -\n\ -The --output-language option controls the language used for dumping, and\n\ -this allows you to connect CVC4 to another solver implementation via a UNIX\n\ -pipe to perform on-line checking. The --dump-to option can be used to dump\n\ -to a file.\n\ -"; - -static const string arithUnateLemmasHelp = "\ -Presolve lemmas are generated before SAT search begins using the relationship\n\ -of constant terms and polynomials.\n\ -Modes currently supported by the --unate-lemmas option:\n\ -+ none \n\ -+ ineqs \n\ - Outputs lemmas of the general form (<= p c) implies (<= p d) for c < d.\n\ -+ eqs \n\ - Outputs lemmas of the general forms\n\ - (= p c) implies (<= p d) for c < d, or\n\ - (= p c) implies (not (= p d)) for c != d.\n\ -+ all \n\ - A combination of inequalities and equalities.\n\ -"; - -static const string propagationModeHelp = "\ -This decides on kind of propagation arithmetic attempts to do during the search.\n\ -+ none\n\ -+ unate\n\ - use constraints to do unate propagation\n\ -+ bi (Bounds Inference)\n\ - infers bounds on basic variables using the upper and lower bounds of the\n\ - non-basic variables in the tableau.\n\ -+both\n\ -"; - -static const string pivotRulesHelp = "\ -This decides on the rule used by simplex during heuristic rounds\n\ -for deciding the next basic variable to select.\n\ -Pivot rules available:\n\ -+min\n\ - The minimum abs() value of the variable's violation of its bound. (default)\n\ -+min-break-ties\n\ - The minimum violation with ties broken by variable order (total)\n\ -+max\n\ - The maximum violation the bound\n\ -"; - -string Options::getDescription() const { - return optionsDescription; -} - -void Options::printUsage(const std::string msg, std::ostream& out) { - out << msg << optionsDescription << endl << flush; -} - -void Options::printShortUsage(const std::string msg, std::ostream& out) { - out << msg << mostCommonOptionsDescription << endl - << "For full usage, please use --help." << endl << flush; -} - -void Options::printLanguageHelp(std::ostream& out) { - out << languageDescription << flush; -} - -/** - * For the main getopt() routine, we need ways to switch on long - * options without clashing with short option characters. This is an - * enum of those long options. For long options (e.g. "--verbose") - * with a short option equivalent ("-v"), we use the single-letter - * short option; therefore, this enumeration starts at 256 to avoid - * any collision. - */ -enum OptionValue { - OPTION_VALUE_BEGIN = 256, /* avoid clashing with char options */ - SMTCOMP, - STATS, - SEGV_NOSPIN, - OUTPUT_LANGUAGE, - PARSE_ONLY, - PREPROCESS_ONLY, - DUMP, - DUMP_TO, - NO_CHECKING, - NO_THEORY_REGISTRATION, - USE_MMAP, - SHOW_DEBUG_TAGS, - SHOW_TRACE_TAGS, - SHOW_SAT_SOLVERS, - SHOW_CONFIG, - STRICT_PARSING, - DEFAULT_EXPR_DEPTH, - DEFAULT_DAG_THRESH, - PRINT_EXPR_TYPES, - UF_THEORY, - LAZY_DEFINITION_EXPANSION, - SIMPLIFICATION_MODE, - DECISION_MODE, - DECISION_BUDGET, - NO_STATIC_LEARNING, - ITE_SIMP, - NO_ITE_SIMP, - UNCONSTRAINED_SIMP, - NO_UNCONSTRAINED_SIMP, - REPEAT_SIMP, - NO_REPEAT_SIMP, - INTERACTIVE, - NO_INTERACTIVE, - PRODUCE_ASSIGNMENTS, - PRINT_SUCCESS, - SMTLIB2, - PROOF, - NO_TYPE_CHECKING, - LAZY_TYPE_CHECKING, - EAGER_TYPE_CHECKING, - REPLAY, - REPLAY_LOG, - PRINT_WINNER, - RANDOM_FREQUENCY, - RANDOM_SEED, - SAT_RESTART_FIRST, - SAT_RESTART_INC, - ARITHMETIC_UNATE_LEMMA_MODE, - ARITHMETIC_PROPAGATION_MODE, - ARITHMETIC_HEURISTIC_PIVOTS, - ARITHMETIC_VAR_ORDER_PIVOTS, - ARITHMETIC_PIVOT_RULE, - ARITHMETIC_CHECK_PERIOD, - ARITHMETIC_PIVOT_THRESHOLD, - ARITHMETIC_PROP_MAX_LENGTH, - ARITHMETIC_DIO_SOLVER, - ENABLE_ARITHMETIC_REWRITE_EQUALITIES, - DISABLE_ARITHMETIC_REWRITE_EQUALITIES, - ENABLE_SYMMETRY_BREAKER, - DISABLE_SYMMETRY_BREAKER, - DISABLE_MINISCOPE_QUANT, - DISABLE_MINISCOPE_QUANT_FV, - DISABLE_PRENEX_QUANT, - VAR_ELIM_QUANT, - CNF_QUANT, - PRE_SKOLEM_QUANT, - DISABLE_SMART_TRIGGERS, - REGISTER_QUANT_BODY_TERMS, - INST_WHEN, - EAGER_INST_QUANT, - FINITE_MODEL_FIND, - DISABLE_UF_SS_REGIONS, - UF_SS_EAGER_SPLIT, - UF_SS_COLORING_SAT, - DISABLE_FMF_MODEL_BASED_INST, - DISABLE_FMF_INST_GEN, - FMF_ONE_INST_PER_ROUND, - FMF_INST_ENGINE, - FMF_RELEVANT_DOMAIN, - EFFICIENT_E_MATCHING, - LITERAL_MATCHING, - ENABLE_CBQI, - DISABLE_CBQI, - IGNORE_USER_PATTERNS, - ENABLE_FLIP_DECISION, - REWRITE_RULES_AS_AXIOMS, - PRINT_MODEL_ENGINE, - PRINT_INST_ENGINE, - PARALLEL_THREADS, - PARALLEL_SEPARATE_OUTPUT, - PORTFOLIO_FILTER_LENGTH, - TIME_LIMIT, - TIME_LIMIT_PER, - RESOURCE_LIMIT, - RESOURCE_LIMIT_PER, - BITVECTOR_EAGER_BITBLAST, - BITVECTOR_SHARE_LEMMAS, - BITVECTOR_EAGER_FULLCHECK, - SAT_REFINE_CONFLICTS, - THEORYOF_MODE, - OPTION_VALUE_END -};/* enum OptionValue */ - -/** - * This is a table of long options. By policy, each short option - * should have an equivalent long option (but the reverse isn't the - * case), so this table should thus contain all command-line options. - * - * Each option in this array has four elements: - * - * 1. the long option string - * 2. argument behavior for the option: - * no_argument - no argument permitted - * required_argument - an argument is expected - * optional_argument - an argument is permitted but not required - * 3. this is a pointer to an int which is set to the 4th entry of the - * array if the option is present; or NULL, in which case - * getopt_long() returns the 4th entry - * 4. the return value for getopt_long() when this long option (or the - * value to set the 3rd entry to; see #3) - * - * If you add something here, you should add it in src/main/usage.h - * also, to document it. - * - * If you add something that has a short option equivalent, you should - * add it to the getopt_long() call in parseOptions(). - */ -static struct option cmdlineOptions[] = { - // name, has_arg, *flag, val - { "verbose" , no_argument , NULL, 'v' }, - { "quiet" , no_argument , NULL, 'q' }, - { "debug" , required_argument, NULL, 'd' }, - { "trace" , required_argument, NULL, 't' }, - { "stats" , no_argument , NULL, STATS }, - { "no-checking", no_argument , NULL, NO_CHECKING }, - { "no-theory-registration", no_argument, NULL, NO_THEORY_REGISTRATION }, - { "show-debug-tags", no_argument , NULL, SHOW_DEBUG_TAGS }, - { "show-trace-tags", no_argument , NULL, SHOW_TRACE_TAGS }, - { "show-sat-solvers", no_argument , NULL, SHOW_SAT_SOLVERS }, - { "show-config", no_argument , NULL, SHOW_CONFIG }, - { "segv-nospin", no_argument , NULL, SEGV_NOSPIN }, - { "help" , no_argument , NULL, 'h' }, - { "version" , no_argument , NULL, 'V' }, - { "about" , no_argument , NULL, 'V' }, - { "lang" , required_argument, NULL, 'L' }, - { "output-lang", required_argument, NULL, OUTPUT_LANGUAGE }, - { "parse-only" , no_argument , NULL, PARSE_ONLY }, - { "preprocess-only", no_argument , NULL, PREPROCESS_ONLY }, - { "dump" , required_argument, NULL, DUMP }, - { "dump-to" , required_argument, NULL, DUMP_TO }, - { "mmap" , no_argument , NULL, USE_MMAP }, - { "strict-parsing", no_argument , NULL, STRICT_PARSING }, - { "default-expr-depth", required_argument, NULL, DEFAULT_EXPR_DEPTH }, - { "default-dag-thresh", required_argument, NULL, DEFAULT_DAG_THRESH }, - { "print-expr-types", no_argument , NULL, PRINT_EXPR_TYPES }, - { "uf" , required_argument, NULL, UF_THEORY }, - { "lazy-definition-expansion", no_argument, NULL, LAZY_DEFINITION_EXPANSION }, - { "simplification", required_argument, NULL, SIMPLIFICATION_MODE }, - { "decision", required_argument, NULL, DECISION_MODE }, - { "decision-budget", required_argument, NULL, DECISION_BUDGET }, - { "no-static-learning", no_argument, NULL, NO_STATIC_LEARNING }, - { "ite-simp", no_argument, NULL, ITE_SIMP }, - { "no-ite-simp", no_argument, NULL, NO_ITE_SIMP }, - { "unconstrained-simp", no_argument, NULL, UNCONSTRAINED_SIMP }, - { "no-unconstrained-simp", no_argument, NULL, NO_UNCONSTRAINED_SIMP }, - { "repeat-simp", no_argument, NULL, REPEAT_SIMP }, - { "no-repeat-simp", no_argument, NULL, NO_REPEAT_SIMP }, - { "interactive", no_argument , NULL, INTERACTIVE }, - { "no-interactive", no_argument , NULL, NO_INTERACTIVE }, - { "produce-models", no_argument , NULL, 'm' }, - { "produce-assignments", no_argument, NULL, PRODUCE_ASSIGNMENTS }, - { "print-success", no_argument, NULL, PRINT_SUCCESS }, - { "smtlib2", no_argument, NULL, SMTLIB2 }, - { "proof", no_argument, NULL, PROOF }, - { "no-type-checking", no_argument , NULL, NO_TYPE_CHECKING }, - { "lazy-type-checking", no_argument, NULL, LAZY_TYPE_CHECKING }, - { "eager-type-checking", no_argument, NULL, EAGER_TYPE_CHECKING }, - { "incremental", no_argument , NULL, 'i' }, - { "replay" , required_argument, NULL, REPLAY }, - { "replay-log" , required_argument, NULL, REPLAY_LOG }, - { "random-freq" , required_argument, NULL, RANDOM_FREQUENCY }, - { "random-seed" , required_argument, NULL, RANDOM_SEED }, - { "restart-int-base", required_argument, NULL, SAT_RESTART_FIRST }, - { "restart-int-inc", required_argument, NULL, SAT_RESTART_INC }, - { "print-winner", no_argument , NULL, PRINT_WINNER }, - { "unate-lemmas", required_argument, NULL, ARITHMETIC_UNATE_LEMMA_MODE }, - { "arith-prop", required_argument, NULL, ARITHMETIC_PROPAGATION_MODE }, - { "heuristic-pivots", required_argument, NULL, ARITHMETIC_HEURISTIC_PIVOTS }, - { "heuristic-pivot-rule" , required_argument, NULL, ARITHMETIC_PIVOT_RULE }, - { "standard-effort-variable-order-pivots", required_argument, NULL, ARITHMETIC_VAR_ORDER_PIVOTS }, - { "simplex-check-period" , required_argument, NULL, ARITHMETIC_CHECK_PERIOD }, - { "pivot-threshold" , required_argument, NULL, ARITHMETIC_PIVOT_THRESHOLD }, - { "prop-row-length" , required_argument, NULL, ARITHMETIC_PROP_MAX_LENGTH }, - { "disable-dio-solver", no_argument, NULL, ARITHMETIC_DIO_SOLVER }, - { "enable-arith-rewrite-equalities", no_argument, NULL, ENABLE_ARITHMETIC_REWRITE_EQUALITIES }, - { "disable-arith-rewrite-equalities", no_argument, NULL, DISABLE_ARITHMETIC_REWRITE_EQUALITIES }, - { "enable-symmetry-breaker", no_argument, NULL, ENABLE_SYMMETRY_BREAKER }, - { "disable-symmetry-breaker", no_argument, NULL, DISABLE_SYMMETRY_BREAKER }, - { "disable-miniscope-quant", no_argument, NULL, DISABLE_MINISCOPE_QUANT }, - { "disable-miniscope-quant-fv", no_argument, NULL, DISABLE_MINISCOPE_QUANT_FV }, - { "disable-prenex-quant", no_argument, NULL, DISABLE_PRENEX_QUANT }, - { "var-elim-quant", no_argument, NULL, VAR_ELIM_QUANT }, - { "cnf-quant", no_argument, NULL, CNF_QUANT }, - { "pre-skolem-quant", no_argument, NULL, PRE_SKOLEM_QUANT }, - { "disable-smart-triggers", no_argument, NULL, DISABLE_SMART_TRIGGERS }, - { "register-quant-body-terms", no_argument, NULL, REGISTER_QUANT_BODY_TERMS }, - { "inst-when", required_argument, NULL, INST_WHEN }, - { "eager-inst-quant", no_argument, NULL, EAGER_INST_QUANT }, - { "finite-model-find", no_argument, NULL, FINITE_MODEL_FIND }, - { "disable-uf-ss-regions", no_argument, NULL, DISABLE_UF_SS_REGIONS }, - { "uf-ss-eager-split", no_argument, NULL, UF_SS_EAGER_SPLIT }, - { "uf-ss-coloring-sat", no_argument, NULL, UF_SS_COLORING_SAT }, - { "disable-fmf-mbqi", no_argument, NULL, DISABLE_FMF_MODEL_BASED_INST }, - { "disable-fmf-inst-gen", no_argument, NULL, DISABLE_FMF_INST_GEN }, - { "fmf-one-inst-per-round", no_argument, NULL, FMF_ONE_INST_PER_ROUND }, - { "fmf-inst-engine", no_argument, NULL, FMF_INST_ENGINE }, - { "fmf-relevant-domain", no_argument, NULL, FMF_RELEVANT_DOMAIN }, - { "efficient-e-matching", no_argument, NULL, EFFICIENT_E_MATCHING }, - { "literal-matching", required_argument, NULL, LITERAL_MATCHING }, - { "enable-cbqi", no_argument, NULL, ENABLE_CBQI }, - { "disable-cbqi", no_argument, NULL, DISABLE_CBQI }, - { "ignore-user-patterns", no_argument, NULL, IGNORE_USER_PATTERNS }, - { "enable-flip-decision", no_argument, NULL, ENABLE_FLIP_DECISION }, - { "rewrite-rules-as-axioms", no_argument, NULL, REWRITE_RULES_AS_AXIOMS }, - { "print-m-e", no_argument, NULL, PRINT_MODEL_ENGINE }, - { "print-i-e", no_argument, NULL, PRINT_INST_ENGINE }, - { "threads", required_argument, NULL, PARALLEL_THREADS }, - { "separate-output", no_argument, NULL, PARALLEL_SEPARATE_OUTPUT }, - { "filter-lemma-length", required_argument, NULL, PORTFOLIO_FILTER_LENGTH }, - { "tlimit" , required_argument, NULL, TIME_LIMIT }, - { "tlimit-per" , required_argument, NULL, TIME_LIMIT_PER }, - { "rlimit" , required_argument, NULL, RESOURCE_LIMIT }, - { "rlimit-per" , required_argument, NULL, RESOURCE_LIMIT_PER }, - { "bitblast-eager", no_argument, NULL, BITVECTOR_EAGER_BITBLAST }, - { "bitblast-share-lemmas", no_argument, NULL, BITVECTOR_SHARE_LEMMAS }, - { "bitblast-eager-fullcheck", no_argument, NULL, BITVECTOR_EAGER_FULLCHECK }, - { "refine-conflicts", no_argument, NULL, SAT_REFINE_CONFLICTS }, - { "theoryof-mode", required_argument, NULL, THEORYOF_MODE }, - { NULL , no_argument , NULL, '\0' } -};/* if you add things to the above, please remember to update usage.h! */ - - -/** Parse argc/argv and put the result into a CVC4::Options struct. */ -int Options::parseOptions(int argc, char* argv[]) -throw(OptionException) { - const char *progName = argv[0]; - int c; - - // Reset getopt(), in the case of multiple calls. - // This can be = 1 in newer GNU getopt, but older (< 2007) require = 0. - optind = 0; -#if HAVE_DECL_OPTRESET - optreset = 1; // on BSD getopt() (e.g. Mac OS), might also need this -#endif /* HAVE_DECL_OPTRESET */ - - // find the base name of the program - const char *x = strrchr(progName, '/'); - if(x != NULL) { - progName = x + 1; - } - binary_name = string(progName); - - // The strange string in this call is the short option string. An - // initial '+' means that option processing stops as soon as a - // non-option argument is encountered (it is not present, by design). - // The initial ':' indicates that getopt_long() should return ':' - // instead of '?' for a missing option argument. Then, each letter - // is a valid short option for getopt_long(), and if it's encountered, - // getopt_long() returns that character. A ':' after an option - // character means an argument is required; two colons indicates an - // argument is optional; no colons indicate an argument is not - // permitted. cmdlineOptions specifies all the long-options and the - // return value for getopt_long() should they be encountered. - while((c = getopt_long(argc, argv, - ":himVvqL:d:t:", - cmdlineOptions, NULL)) != -1) { - switch(c) { - - case 'h': - help = true; - break; - - case 'V': - version = true; - break; - - case 'v': - ++verbosity; - break; - - case 'q': - --verbosity; - break; - - case 'L': - setInputLanguage(optarg); - break; - - case OUTPUT_LANGUAGE: - setOutputLanguage(optarg); - break; - - case 't': - if(Configuration::isTracingBuild()) { - if(!Configuration::isTraceTag(optarg)) - throw OptionException(string("trace tag ") + optarg + - string(" not available")); - } else { - throw OptionException("trace tags not available in non-tracing builds"); - } - Trace.on(optarg); - break; - - case 'd': - if(Configuration::isDebugBuild() && Configuration::isTracingBuild()) { - if(!Configuration::isDebugTag(optarg) && !Configuration::isTraceTag(optarg)) { - throw OptionException(string("debug tag ") + optarg + - string(" not available")); - } - } else if(! Configuration::isDebugBuild()) { - throw OptionException("debug tags not available in non-debug builds"); - } else { - throw OptionException("debug tags not available in non-tracing builds"); - } - Debug.on(optarg); - Trace.on(optarg); - break; - - case STATS: - statistics = true; - break; - - case SEGV_NOSPIN: - segvNoSpin = true; - break; - - case PARSE_ONLY: - parseOnly = true; - break; - - case PREPROCESS_ONLY: - preprocessOnly = true; - break; - - case DUMP: { -#ifdef CVC4_DUMPING - char* tokstr = optarg; - char* toksave; - while((optarg = strtok_r(tokstr, ",", &toksave)) != NULL) { - tokstr = NULL; - if(!strcmp(optarg, "benchmark")) { - } else if(!strcmp(optarg, "declarations")) { - } else if(!strcmp(optarg, "assertions")) { - } else if(!strcmp(optarg, "learned")) { - } else if(!strcmp(optarg, "clauses")) { - } else if(!strcmp(optarg, "t-conflicts") || - !strcmp(optarg, "t-lemmas") || - !strcmp(optarg, "t-explanations") || - !strcmp(optarg, "bv-rewrites") || - !strcmp(optarg, "theory::fullcheck")) { - // These are "non-state-dumping" modes. If state (SAT decisions, - // propagations, etc.) is dumped, it will interfere with the validity - // of these generated queries. - if(Dump.isOn("state")) { - throw OptionException(string("dump option `") + optarg + - "' conflicts with a previous, " - "state-dumping dump option. You cannot " - "mix stateful and non-stateful dumping modes; " - "see --dump help."); - } else { - Dump.on("no-permit-state"); - } - } else if(!strcmp(optarg, "state") || - !strcmp(optarg, "missed-t-conflicts") || - !strcmp(optarg, "t-propagations") || - !strcmp(optarg, "missed-t-propagations")) { - // These are "state-dumping" modes. If state (SAT decisions, - // propagations, etc.) is not dumped, it will interfere with the - // validity of these generated queries. - if(Dump.isOn("no-permit-state")) { - throw OptionException(string("dump option `") + optarg + - "' conflicts with a previous, " - "non-state-dumping dump option. You cannot " - "mix stateful and non-stateful dumping modes; " - "see --dump help."); - } else { - Dump.on("state"); - } - } else if(!strcmp(optarg, "help")) { - puts(dumpHelp.c_str()); - exit(1); - } else { - throw OptionException(string("unknown option for --dump: `") + - optarg + "'. Try --dump help."); - } - - Dump.on(optarg); - Dump.on("benchmark"); - if(strcmp(optarg, "benchmark")) { - Dump.on("declarations"); - } - } -#else /* CVC4_DUMPING */ - throw OptionException("The dumping feature was disabled in this build of CVC4."); -#endif /* CVC4_DUMPING */ - break; - } - - case DUMP_TO: { -#ifdef CVC4_DUMPING - size_t dagSetting = expr::ExprDag::getDag(Dump.getStream()); - if(optarg == NULL || *optarg == '\0') { - throw OptionException(string("Bad file name for --dump-to")); - } else if(!strcmp(optarg, "-")) { - Dump.setStream(DumpOutC::dump_cout); - } else { - ostream* dumpTo = new ofstream(optarg, ofstream::out | ofstream::trunc); - if(!*dumpTo) { - throw OptionException(string("Cannot open dump-to file (maybe it exists): `") + optarg + "'"); - } - Dump.setStream(*dumpTo); - } - expr::ExprDag::setDag(Dump.getStream(), dagSetting); -#else /* CVC4_DUMPING */ - throw OptionException("The dumping feature was disabled in this build of CVC4."); -#endif /* CVC4_DUMPING */ - } - break; - - case NO_THEORY_REGISTRATION: - theoryRegistration = false; - break; - - case NO_CHECKING: - semanticChecks = false; - typeChecking = false; - earlyTypeChecking = false; - break; - - case USE_MMAP: - memoryMap = true; - break; - - case PRINT_WINNER: - printWinner = true; - break; - - case STRICT_PARSING: - strictParsing = true; - break; - - case DEFAULT_EXPR_DEPTH: - { - int depth = atoi(optarg); - Debug.getStream() << Expr::setdepth(depth); - Trace.getStream() << Expr::setdepth(depth); - Notice.getStream() << Expr::setdepth(depth); - Chat.getStream() << Expr::setdepth(depth); - Message.getStream() << Expr::setdepth(depth); - Warning.getStream() << Expr::setdepth(depth); - defaultExprDepth = depth; - } - break; - - case DEFAULT_DAG_THRESH: - { - int dag = atoi(optarg); - if(dag < 0) { - throw OptionException("--default-dag-thresh requires a nonnegative argument."); - } - Debug.getStream() << Expr::dag(dag); - Trace.getStream() << Expr::dag(dag); - Notice.getStream() << Expr::dag(dag); - Chat.getStream() << Expr::dag(dag); - Message.getStream() << Expr::dag(dag); - Warning.getStream() << Expr::dag(dag); - Dump.getStream() << Expr::dag(dag); - } - break; - - case PRINT_EXPR_TYPES: - Debug.getStream() << Expr::printtypes(true); - Trace.getStream() << Expr::printtypes(true); - Notice.getStream() << Expr::printtypes(true); - Chat.getStream() << Expr::printtypes(true); - Message.getStream() << Expr::printtypes(true); - Warning.getStream() << Expr::printtypes(true); - break; - - case LAZY_DEFINITION_EXPANSION: - lazyDefinitionExpansion = true; - break; - - case SIMPLIFICATION_MODE: - if(!strcmp(optarg, "batch")) { - simplificationMode = SIMPLIFICATION_MODE_BATCH; - simplificationModeSetByUser = true; - } else if(!strcmp(optarg, "incremental")) { - simplificationMode = SIMPLIFICATION_MODE_INCREMENTAL; - simplificationModeSetByUser = true; - } else if(!strcmp(optarg, "none")) { - simplificationMode = SIMPLIFICATION_MODE_NONE; - simplificationModeSetByUser = true; - } else if(!strcmp(optarg, "help")) { - puts(simplificationHelp.c_str()); - exit(1); - } else { - throw OptionException(string("unknown option for --simplification: `") + - optarg + "'. Try --simplification help."); - } - break; - - case THEORYOF_MODE: - if (!strcmp(optarg, "type")) { - theoryOfModeSetByUser = true; - theoryOfMode = theory::THEORY_OF_TYPE_BASED; - } else if (!strcmp(optarg, "term")) { - theoryOfModeSetByUser = true; - theoryOfMode = theory::THEORY_OF_TERM_BASED; - } else if (!strcmp(optarg, "help")) { - puts(theoryofHelp.c_str()); - exit(1); - } else { - throw OptionException(string("unknown option for --theoryof-mode: `") + - optarg + "'. Try --theoryof-mode help."); - } - break; - case DECISION_MODE: - decisionOptions = defaultDecOpt; // reset all options - if(!strcmp(optarg, "internal")) { - decisionMode = DECISION_STRATEGY_INTERNAL; - decisionModeSetByUser = true; - } else if(!strcmp(optarg, "justification")) { - decisionMode = DECISION_STRATEGY_JUSTIFICATION; - decisionModeSetByUser = true; - } else if(!strcmp(optarg, "justification-stoponly")) { - decisionMode = DECISION_STRATEGY_JUSTIFICATION; - decisionModeSetByUser = true; - decisionOptions.stopOnly = true; - } else if(!strcmp(optarg, "relevancy")) { - decisionMode = DECISION_STRATEGY_RELEVANCY; - decisionModeSetByUser = true; - decisionOptions.relevancyLeaves = false; - } else if(!strcmp(optarg, "relevancy-leaves")) { - decisionMode = DECISION_STRATEGY_RELEVANCY; - decisionModeSetByUser = true; - decisionOptions.relevancyLeaves = true; - } else if(!strcmp(optarg, "justification-rel")) { - decisionMode = DECISION_STRATEGY_RELEVANCY; - decisionModeSetByUser = true; - // relevancyLeaves : irrelevant - // maxRelTimeAsPermille : irrelevant - decisionOptions.computeRelevancy = false; - decisionOptions.mustRelevancy = false; - } else if(!strcmp(optarg, "justification-must")) { - decisionMode = DECISION_STRATEGY_RELEVANCY; - decisionModeSetByUser = true; - // relevancyLeaves : irrelevant - // maxRelTimeAsPermille : irrelevant - decisionOptions.computeRelevancy = false; - decisionOptions.mustRelevancy = true; - } else if(!strcmp(optarg, "help")) { - puts(decisionHelp.c_str()); - exit(1); - } else { - throw OptionException(string("unknown option for --decision: `") + - optarg + "'. Try --decision help."); - } - break; - - case DECISION_BUDGET: { - int i = atoi(optarg); - if(i < 0 || i > 1000) { - throw OptionException(string("invalid value for --decision-budget: `") + - optarg + "'. Must be between 0 and 1000."); - } - if(i == 0) { - Warning() << "Decision budget is 0. Consider using internal decision heuristic and " - << std::endl << " removing this option." << std::endl; - - } - decisionOptions.maxRelTimeAsPermille = (unsigned short)i; - } - break; - - case NO_STATIC_LEARNING: - doStaticLearning = false; - break; - - case ITE_SIMP: - doITESimp = true; - doITESimpSetByUser = true; - break; - - case NO_ITE_SIMP: - doITESimp = false; - doITESimpSetByUser = true; - break; - - case UNCONSTRAINED_SIMP: - unconstrainedSimp = true; - unconstrainedSimpSetByUser = true; - break; - - case NO_UNCONSTRAINED_SIMP: - unconstrainedSimp = false; - unconstrainedSimpSetByUser = true; - break; - - case REPEAT_SIMP: - repeatSimp = true; - repeatSimpSetByUser = true; - break; - - case NO_REPEAT_SIMP: - repeatSimp = false; - repeatSimpSetByUser = true; - break; - - case INTERACTIVE: - interactive = true; - interactiveSetByUser = true; - break; - - case NO_INTERACTIVE: - interactive = false; - interactiveSetByUser = true; - break; - - case 'm': - produceModels = true; - break; - - case PRODUCE_ASSIGNMENTS: - produceAssignments = true; - break; - - case SMTLIB2: // smtlib v2 compliance mode - inputLanguage = language::input::LANG_SMTLIB_V2; - outputLanguage = language::output::LANG_SMTLIB_V2; - strictParsing = true; - // make sure entire expressions are printed on all the non-debug, non-trace streams - Notice.getStream() << Expr::setdepth(-1); - Chat.getStream() << Expr::setdepth(-1); - Message.getStream() << Expr::setdepth(-1); - Warning.getStream() << Expr::setdepth(-1); - /* intentionally fall through */ - - case PRINT_SUCCESS: - Debug.getStream() << Command::printsuccess(true); - Trace.getStream() << Command::printsuccess(true); - Notice.getStream() << Command::printsuccess(true); - Chat.getStream() << Command::printsuccess(true); - Message.getStream() << Command::printsuccess(true); - Warning.getStream() << Command::printsuccess(true); - break; - - case PROOF: -#ifdef CVC4_PROOF - proof = true; -#else /* CVC4_PROOF */ - throw OptionException("This is not a proof-enabled build of CVC4; --proof cannot be used"); -#endif /* CVC4_PROOF */ - break; - - case NO_TYPE_CHECKING: - typeChecking = false; - earlyTypeChecking = false; - break; - - case LAZY_TYPE_CHECKING: - typeChecking = true; - earlyTypeChecking = false; - break; - - case EAGER_TYPE_CHECKING: - typeChecking = true; - earlyTypeChecking = true; - break; - - case 'i': - incrementalSolving = true; - break; - - case REPLAY: -#ifdef CVC4_REPLAY - if(optarg == NULL || *optarg == '\0') { - throw OptionException(string("Bad file name for --replay")); - } else { - replayFilename = optarg; - } -#else /* CVC4_REPLAY */ - throw OptionException("The replay feature was disabled in this build of CVC4."); -#endif /* CVC4_REPLAY */ - break; - - case REPLAY_LOG: -#ifdef CVC4_REPLAY - if(optarg == NULL || *optarg == '\0') { - throw OptionException(string("Bad file name for --replay-log")); - } else if(!strcmp(optarg, "-")) { - replayLog = &cout; - } else { - replayLog = new ofstream(optarg, ofstream::out | ofstream::trunc); - if(!*replayLog) { - throw OptionException(string("Cannot open replay-log file: `") + optarg + "'"); - } - } -#else /* CVC4_REPLAY */ - throw OptionException("The replay feature was disabled in this build of CVC4."); -#endif /* CVC4_REPLAY */ - break; - - case ENABLE_SYMMETRY_BREAKER: - ufSymmetryBreaker = true; - ufSymmetryBreakerSetByUser = true; - break; - case DISABLE_SYMMETRY_BREAKER: - ufSymmetryBreaker = false; - ufSymmetryBreakerSetByUser = true; - break; - case DISABLE_MINISCOPE_QUANT: - miniscopeQuant = false; - break; - case DISABLE_MINISCOPE_QUANT_FV: - miniscopeQuantFreeVar = false; - break; - case DISABLE_PRENEX_QUANT: - prenexQuant = false; - break; - case VAR_ELIM_QUANT: - varElimQuant = true; - break; - case CNF_QUANT: - cnfQuant = true; - break; - case PRE_SKOLEM_QUANT: - preSkolemQuant = true; - break; - case DISABLE_SMART_TRIGGERS: - smartTriggers = false; - break; - case REGISTER_QUANT_BODY_TERMS: - registerQuantBodyTerms = true; - break; - case INST_WHEN: - if(!strcmp(optarg, "pre-full")) { - instWhenMode = INST_WHEN_PRE_FULL; - } else if(!strcmp(optarg, "full")) { - instWhenMode = INST_WHEN_FULL; - } else if(!strcmp(optarg, "full-last-call")) { - instWhenMode = INST_WHEN_FULL_LAST_CALL; - } else if(!strcmp(optarg, "last-call")) { - instWhenMode = INST_WHEN_LAST_CALL; - } else if(!strcmp(optarg, "help")) { - puts(instWhenHelp.c_str()); - exit(1); - } else { - throw OptionException(string("unknown option for --inst-when: `") + - optarg + "'. Try --inst-when help."); - } - break; - case EAGER_INST_QUANT: - eagerInstQuant = true; - break; - case FINITE_MODEL_FIND: - finiteModelFind = true; - break; - case DISABLE_UF_SS_REGIONS: - ufssRegions = false; - break; - case UF_SS_EAGER_SPLIT: - ufssEagerSplits = true; - break; - case UF_SS_COLORING_SAT: - ufssColoringSat = true; - break; - case DISABLE_FMF_MODEL_BASED_INST: - fmfModelBasedInst = false; - break; - case DISABLE_FMF_INST_GEN: - fmfInstGen = false; - break; - case FMF_ONE_INST_PER_ROUND: - fmfOneInstPerRound = true; - break; - case FMF_INST_ENGINE: - fmfInstEngine = true; - break; - case FMF_RELEVANT_DOMAIN: - fmfRelevantDomain = true; - break; - case EFFICIENT_E_MATCHING: - efficientEMatching = true; - break; - case LITERAL_MATCHING: - if(!strcmp(optarg, "none")) { - literalMatchMode = LITERAL_MATCH_NONE; - } else if(!strcmp(optarg, "predicate")) { - literalMatchMode = LITERAL_MATCH_PREDICATE; - } else if(!strcmp(optarg, "equality")) { - literalMatchMode = LITERAL_MATCH_EQUALITY; - } else if(!strcmp(optarg, "help")) { - puts(literalMatchHelp.c_str()); - exit(1); - } else { - throw OptionException(string("unknown option for --literal-matching: `") + - optarg + "'. Try --literal-matching help."); - } - break; - case ENABLE_CBQI: - cbqi = true; - cbqiSetByUser = true; - break; - case DISABLE_CBQI: - cbqi = false; - cbqiSetByUser = true; - break; - case IGNORE_USER_PATTERNS: - userPatternsQuant = false; - break; - case ENABLE_FLIP_DECISION: - flipDecision = true; - break; - case REWRITE_RULES_AS_AXIOMS: - rewriteRulesAsAxioms = true; - break; - case PRINT_MODEL_ENGINE: - printModelEngine = true; - break; - case PRINT_INST_ENGINE: - printInstEngine = true; - break; - case TIME_LIMIT: - { - int i = atoi(optarg); - if(i < 0) { - throw OptionException("--time-limit requires a nonnegative argument."); - } - cumulativeMillisecondLimit = (unsigned long) i; - } - break; - case TIME_LIMIT_PER: - { - int i = atoi(optarg); - if(i < 0) { - throw OptionException("--time-limit-per requires a nonnegative argument."); - } - perCallMillisecondLimit = (unsigned long) i; - } - break; - case RESOURCE_LIMIT: - { - int i = atoi(optarg); - if(i < 0) { - throw OptionException("--limit requires a nonnegative argument."); - } - cumulativeResourceLimit = (unsigned long) i; - } - break; - case RESOURCE_LIMIT_PER: - { - int i = atoi(optarg); - if(i < 0) { - throw OptionException("--limit-per requires a nonnegative argument."); - } - perCallResourceLimit = (unsigned long) i; - break; - } - case BITVECTOR_EAGER_BITBLAST: - { - bitvectorEagerBitblast = true; - break; - } - case BITVECTOR_EAGER_FULLCHECK: - { - bitvectorEagerFullcheck = true; - break; - } - case BITVECTOR_SHARE_LEMMAS: - { - bitvectorShareLemmas = true; - break; - } - case SAT_REFINE_CONFLICTS: - { - sat_refine_conflicts = true; - break; - } - case RANDOM_SEED: - satRandomSeed = atof(optarg); - break; - - case RANDOM_FREQUENCY: - satRandomFreq = atof(optarg); - if(! (0.0 <= satRandomFreq && satRandomFreq <= 1.0)){ - throw OptionException(string("--random-freq: `") + - optarg + "' is not between 0.0 and 1.0."); - } - break; - - case SAT_RESTART_FIRST: - { - int i = atoi(optarg); - if(i < 1) { - throw OptionException("--restart-int-base requires a number bigger than 1"); - } - satRestartFirst = i; - break; - } - - case SAT_RESTART_INC: - { - int i = atoi(optarg); - if(i < 1) { - throw OptionException("--restart-int-inc requires a number bigger than 1.0"); - } - satRestartInc = i; - } - break; - - case ARITHMETIC_UNATE_LEMMA_MODE: - if(!strcmp(optarg, "all")) { - arithUnateLemmaMode = ALL_PRESOLVE_LEMMAS; - break; - } else if(!strcmp(optarg, "none")) { - arithUnateLemmaMode = NO_PRESOLVE_LEMMAS; - break; - } else if(!strcmp(optarg, "ineqs")) { - arithUnateLemmaMode = INEQUALITY_PRESOLVE_LEMMAS; - break; - } else if(!strcmp(optarg, "eqs")) { - arithUnateLemmaMode = EQUALITY_PRESOLVE_LEMMAS; - break; - } else if(!strcmp(optarg, "help")) { - puts(arithUnateLemmasHelp.c_str()); - exit(1); - } else { - throw OptionException(string("unknown option for --unate-lemmas: `") + - optarg + "'. Try --unate-lemmas=help."); - } - break; - - case ARITHMETIC_PROPAGATION_MODE: - if(!strcmp(optarg, "none")) { - arithPropagationMode = NO_PROP; - break; - } else if(!strcmp(optarg, "unate")) { - arithPropagationMode = UNATE_PROP; - break; - } else if(!strcmp(optarg, "bi")) { - arithPropagationMode = BOUND_INFERENCE_PROP; - break; - } else if(!strcmp(optarg, "both")) { - arithPropagationMode = BOTH_PROP; - break; - } else if(!strcmp(optarg, "help")) { - puts(propagationModeHelp.c_str()); - exit(1); - } else { - throw OptionException(string("unknown option for --arith-prop: `") + - optarg + "'. Try --arith-prop help."); - } - break; - - case ARITHMETIC_HEURISTIC_PIVOTS: - arithHeuristicPivots = atoi(optarg); - arithHeuristicPivotsSetByUser = true; - break; - - case ARITHMETIC_VAR_ORDER_PIVOTS: - arithStandardCheckVarOrderPivots = atoi(optarg); - arithStandardCheckVarOrderPivotsSetByUser = true; - break; - - case ARITHMETIC_PIVOT_RULE: - if(!strcmp(optarg, "min")) { - arithHeuristicPivotRule = MINIMUM; - break; - } else if(!strcmp(optarg, "min-break-ties")) { - arithHeuristicPivotRule = BREAK_TIES; - break; - } else if(!strcmp(optarg, "max")) { - arithHeuristicPivotRule = MAXIMUM; - break; - } else if(!strcmp(optarg, "help")) { - puts(pivotRulesHelp.c_str()); - exit(1); - } else { - throw OptionException(string("unknown option for --heuristic-pivot-rule: `") + - optarg + "'. Try --heuristic-pivot-rule help."); - } - break; - - case ARITHMETIC_CHECK_PERIOD: - arithSimplexCheckPeriod = atoi(optarg); - break; - - case ARITHMETIC_PIVOT_THRESHOLD: - arithPivotThreshold = atoi(optarg); - arithPivotThresholdSetByUser = true; - break; - - case ARITHMETIC_PROP_MAX_LENGTH: - arithPropagateMaxLength = atoi(optarg); - break; - - case ARITHMETIC_DIO_SOLVER: - arithDioSolver = false; - break; - - case ENABLE_ARITHMETIC_REWRITE_EQUALITIES: - arithRewriteEq = true; - arithRewriteEqSetByUser = true; - break; - - case DISABLE_ARITHMETIC_REWRITE_EQUALITIES: - arithRewriteEq = false; - arithRewriteEqSetByUser = true; - break; - - case SHOW_DEBUG_TAGS: - if(Configuration::isDebugBuild() && Configuration::isTracingBuild()) { - printf("available tags:"); - unsigned ntags = Configuration::getNumDebugTags(); - char const* const* tags = Configuration::getDebugTags(); - for(unsigned i = 0; i < ntags; ++ i) { - printf(" %s", tags[i]); - } - printf("\n"); - } else if(! Configuration::isDebugBuild()) { - throw OptionException("debug tags not available in non-debug builds"); - } else { - throw OptionException("debug tags not available in non-tracing builds"); - } - exit(0); - break; - - case SHOW_TRACE_TAGS: - if(Configuration::isTracingBuild()) { - printf("available tags:"); - unsigned ntags = Configuration::getNumTraceTags(); - char const* const* tags = Configuration::getTraceTags(); - for (unsigned i = 0; i < ntags; ++ i) { - printf(" %s", tags[i]); - } - printf("\n"); - } else { - throw OptionException("trace tags not available in non-tracing builds"); - } - exit(0); - break; - - case SHOW_SAT_SOLVERS: - { - vector<string> solvers; - prop::SatSolverFactory::getSolverIds(solvers); - printf("Available SAT solvers: "); - for (unsigned i = 0; i < solvers.size(); ++ i) { - if (i > 0) { - printf(", "); - } - printf("%s", solvers[i].c_str()); - } - printf("\n"); - exit(0); - break; - } - case SHOW_CONFIG: - fputs(Configuration::about().c_str(), stdout); - printf("\n"); - printf("version : %s\n", Configuration::getVersionString().c_str()); - if(Configuration::isSubversionBuild()) { - printf("subversion : yes [%s r%u%s]\n", - Configuration::getSubversionBranchName(), - Configuration::getSubversionRevision(), - Configuration::hasSubversionModifications() ? - " (with modifications)" : ""); - } else { - printf("subversion : %s\n", Configuration::isSubversionBuild() ? "yes" : "no"); - } - printf("\n"); - printf("library : %u.%u.%u\n", - Configuration::getVersionMajor(), - Configuration::getVersionMinor(), - Configuration::getVersionRelease()); - printf("\n"); - printf("debug code : %s\n", Configuration::isDebugBuild() ? "yes" : "no"); - printf("statistics : %s\n", Configuration::isStatisticsBuild() ? "yes" : "no"); - printf("replay : %s\n", Configuration::isReplayBuild() ? "yes" : "no"); - printf("tracing : %s\n", Configuration::isTracingBuild() ? "yes" : "no"); - printf("dumping : %s\n", Configuration::isDumpingBuild() ? "yes" : "no"); - printf("muzzled : %s\n", Configuration::isMuzzledBuild() ? "yes" : "no"); - printf("assertions : %s\n", Configuration::isAssertionBuild() ? "yes" : "no"); - printf("proof : %s\n", Configuration::isProofBuild() ? "yes" : "no"); - printf("coverage : %s\n", Configuration::isCoverageBuild() ? "yes" : "no"); - printf("profiling : %s\n", Configuration::isProfilingBuild() ? "yes" : "no"); - printf("competition: %s\n", Configuration::isCompetitionBuild() ? "yes" : "no"); - printf("\n"); - printf("cudd : %s\n", Configuration::isBuiltWithCudd() ? "yes" : "no"); - printf("cln : %s\n", Configuration::isBuiltWithCln() ? "yes" : "no"); - printf("gmp : %s\n", Configuration::isBuiltWithGmp() ? "yes" : "no"); - printf("tls : %s\n", Configuration::isBuiltWithTlsSupport() ? "yes" : "no"); - exit(0); - - case PARALLEL_THREADS: - threads = atoi(optarg); - break; - - case PARALLEL_SEPARATE_OUTPUT: - separateOutput = true; - break; - - case PORTFOLIO_FILTER_LENGTH: - sharingFilterByLength = atoi(optarg); - break; - - case ':': - // This can be a long or short option, and the way to get at the name of it is different. - if(optopt == 0 || // was a long option - (optopt >= OPTION_VALUE_BEGIN && optopt <= OPTION_VALUE_END)) { // OptionValue option - throw OptionException(string("option `") + argv[optind - 1] + "' missing its required argument"); - } else { // was a short option - throw OptionException(string("option `-") + char(optopt) + "' missing its required argument"); - } - - case '?': - default: - if(optopt == 0 && - !strncmp(argv[optind - 1], "--thread", 8) && - strlen(argv[optind - 1]) > 8 && - isdigit(argv[optind - 1][8])) { - int tnum = atoi(argv[optind - 1] + 8); - threadArgv.resize(tnum + 1); - if(threadArgv[tnum] != "") { - threadArgv[tnum] += " "; - } - const char* p = strchr(argv[optind - 1] + 9, '='); - if(p == NULL) { // e.g., we have --thread0 "foo" - threadArgv[tnum] += argv[optind++]; - } else { // e.g., we have --thread0="foo" - threadArgv[tnum] += p + 1; - } - break; - } - - // This can be a long or short option, and the way to get at the name of it is different. - if(optopt == 0) { // was a long option - throw OptionException(string("can't understand option `") + argv[optind - 1] + "'"); - } else { // was a short option - throw OptionException(string("can't understand option `-") + char(optopt) + "'"); - } - } - } - - if(incrementalSolving && proof) { - throw OptionException(string("The use of --incremental with --proof is not yet supported")); - } - - return optind; -} - -void Options::setOutputLanguage(const char* str) throw(OptionException) { - if(!strcmp(str, "cvc4") || !strcmp(str, "pl")) { - outputLanguage = language::output::LANG_CVC4; - return; - } else if(!strcmp(str, "smtlib") || !strcmp(str, "smt")) { - outputLanguage = language::output::LANG_SMTLIB; - return; - } else if(!strcmp(str, "smtlib2") || !strcmp(str, "smt2")) { - outputLanguage = language::output::LANG_SMTLIB_V2; - return; - } else if(!strcmp(str, "tptp")) { - outputLanguage = language::output::LANG_TPTP; - return; - } else if(!strcmp(str, "ast")) { - outputLanguage = language::output::LANG_AST; - return; - } else if(!strcmp(str, "auto")) { - outputLanguage = language::output::LANG_AUTO; - return; - } - - if(strcmp(str, "help")) { - throw OptionException(string("unknown language for --output-lang: `") + - str + "'. Try --output-lang help."); - } - - languageHelp = true; -} - -void Options::setInputLanguage(const char* str) throw(OptionException) { - if(!strcmp(str, "cvc4") || !strcmp(str, "pl") || !strcmp(str, "presentation")) { - inputLanguage = language::input::LANG_CVC4; - return; - } else if(!strcmp(str, "smtlib") || !strcmp(str, "smt")) { - inputLanguage = language::input::LANG_SMTLIB; - return; - } else if(!strcmp(str, "smtlib2") || !strcmp(str, "smt2")) { - inputLanguage = language::input::LANG_SMTLIB_V2; - return; - } else if(!strcmp(str, "tptp")) { - inputLanguage = language::input::LANG_TPTP; - return; - } else if(!strcmp(str, "auto")) { - inputLanguage = language::input::LANG_AUTO; - return; - } - - if(strcmp(str, "help")) { - throw OptionException(string("unknown language for --lang: `") + - str + "'. Try --lang help."); - } - - languageHelp = true; -} - -std::ostream& operator<<(std::ostream& out, Options::ArithHeuristicPivotRule rule) { - switch(rule) { - case Options::MINIMUM: - out << "MINIMUM"; - break; - case Options::BREAK_TIES: - out << "BREAK_TIES"; - break; - case Options::MAXIMUM: - out << "MAXIMUM"; - break; - default: - out << "ArithPivotRule!UNKNOWN"; - } - - return out; -} - -#undef USE_EARLY_TYPE_CHECKING_BY_DEFAULT -#undef DO_SEMANTIC_CHECKS_BY_DEFAULT - -}/* CVC4 namespace */ diff --git a/src/util/options.h b/src/util/options.h deleted file mode 100644 index 17d393e88..000000000 --- a/src/util/options.h +++ /dev/null @@ -1,615 +0,0 @@ -/********************* */ -/*! \file options.h - ** \verbatim - ** Original author: mdeters - ** Major contributors: taking, cconway - ** Minor contributors (to current version): dejan - ** This file is part of the CVC4 prototype. - ** Copyright (c) 2009, 2010, 2011 The Analysis of Computer Systems Group (ACSys) - ** Courant Institute of Mathematical Sciences - ** New York University - ** See the file COPYING in the top-level source directory for licensing - ** information.\endverbatim - ** - ** \brief Global (command-line, set-option, ...) parameters for SMT. - ** - ** Global (command-line, set-option, ...) parameters for SMT. - **/ - -#include "cvc4_public.h" - -#ifndef __CVC4__OPTIONS_H -#define __CVC4__OPTIONS_H - -#include <iostream> -#include <fstream> -#include <string> - -#include "util/exception.h" -#include "util/language.h" -#include "util/tls.h" -#include "theory/theoryof_mode.h" - -#include <vector> - -namespace CVC4 { - -class ExprStream; -class LemmaInputChannel; -class LemmaOutputChannel; - -/** Class representing an option-parsing exception. */ -class CVC4_PUBLIC OptionException : public CVC4::Exception { -public: - OptionException(const std::string& s) throw() : - CVC4::Exception("Error in option parsing: " + s) { - } -};/* class OptionException */ - -struct CVC4_PUBLIC Options { - - /** The current Options in effect */ - static CVC4_THREADLOCAL(const Options*) s_current; - - /** Get the current Options in effect */ - static inline const Options* current() { - return s_current; - } - - /** The name of the binary (e.g. "cvc4") */ - std::string binary_name; - - /** Whether to collect statistics during this run */ - bool statistics; - - std::istream* in; /*< The input stream to use */ - std::ostream* out; /*< The output stream to use */ - std::ostream* err; /*< The error stream to use */ - - /* -1 means no output */ - /* 0 is normal (and default) -- warnings only */ - /* 1 is warnings + notices so the user doesn't get too bored */ - /* 2 is chatty, giving statistical things etc. */ - /* with 3, the solver is slowed down by all the scrolling */ - int verbosity; - - /** The input language */ - InputLanguage inputLanguage; - - /** The output language */ - OutputLanguage outputLanguage; - - /** Should we print the help message? */ - bool help; - - /** Should we print the release information? */ - bool version; - - /** Should we print the language help information? */ - bool languageHelp; - - /** Should we exit after parsing? */ - bool parseOnly; - - /** Should we exit after preprocessing? */ - bool preprocessOnly; - - /** Should the parser do semantic checks? */ - bool semanticChecks; - - /** Should the TheoryEngine do theory registration? */ - bool theoryRegistration; - - /** Should the parser memory-map file input? */ - bool memoryMap; - - /** Should we strictly enforce the language standard while parsing? */ - bool strictParsing; - - /** Should we expand function definitions lazily? */ - bool lazyDefinitionExpansion; - - /** Parallel Only: Whether the winner is printed at the end or not. */ - bool printWinner; - - /** The default expression depth to print on ostreams. */ - int defaultExprDepth; - - /** Enumeration of simplification modes (when to simplify). */ - typedef enum { - /** Simplify the assertions as they come in */ - SIMPLIFICATION_MODE_INCREMENTAL, - /** Simplify the assertions all together once a check is requested */ - SIMPLIFICATION_MODE_BATCH, - /** Don't do simplification */ - SIMPLIFICATION_MODE_NONE - } SimplificationMode; - - /** When/whether to perform nonclausal simplifications. */ - SimplificationMode simplificationMode; - /** Whether the user set the nonclausal simplification mode. */ - bool simplificationModeSetByUser; - - /** Enumeration of decision strategies */ - typedef enum { - /** - * Decision engine doesn't do anything. Use sat solver's internal - * heuristics - */ - DECISION_STRATEGY_INTERNAL, - /** - * Use the justification heuristic - */ - DECISION_STRATEGY_JUSTIFICATION, - DECISION_STRATEGY_RELEVANCY - } DecisionMode; - /** When/whether to use any decision strategies */ - DecisionMode decisionMode; - /** Whether the user set the decision strategy */ - bool decisionModeSetByUser; - /** - * Extra settings for decision stuff, varies by strategy enabled - * - With DECISION_STRATEGY_RELEVANCY - * > Least significant bit: true if one should only decide on leaves - */ - - /** DecisionOption along */ - struct DecisionOptions { - bool relevancyLeaves; - unsigned short maxRelTimeAsPermille; /* permille = part per thousand */ - bool computeRelevancy; /* if false, do justification stuff using relevancy.h */ - bool mustRelevancy; /* use the must be relevant */ - bool stopOnly; /* only use decision stuff to stop early, not to decide */ - }; - DecisionOptions decisionOptions; - - /** Whether to perform the static learning pass. */ - bool doStaticLearning; - - /** Whether to do the ite-simplification pass */ - bool doITESimp; - - /** - * Whether the user explicitly requested ite simplification - */ - bool doITESimpSetByUser; - - /** Whether to do the unconstrained simplification pass */ - bool unconstrainedSimp; - - /** - * Whether the user explicitly requested unconstrained simplification - */ - bool unconstrainedSimpSetByUser; - - /** Whether to do multiple rounds of nonclausal simplification */ - bool repeatSimp; - - /** - * Whether the user explicitly requested multiple rounds of nonclausal simplification - */ - bool repeatSimpSetByUser; - - /** Whether we're in interactive mode or not */ - bool interactive; - - /** - * Whether we're in interactive mode (or not) due to explicit user - * setting (if false, we inferred the proper default setting). - */ - bool interactiveSetByUser; - - /** Per-query resource limit. */ - unsigned long perCallResourceLimit; - /** Cumulative resource limit. */ - unsigned long cumulativeResourceLimit; - - /** Per-query time limit in milliseconds. */ - unsigned long perCallMillisecondLimit; - /** Cumulative time limit in milliseconds. */ - unsigned long cumulativeMillisecondLimit; - - /** Whether we should "spin" on a SIG_SEGV. */ - bool segvNoSpin; - - /** Whether we support SmtEngine::getValue() for this run. */ - bool produceModels; - - /** Whether we produce proofs. */ - bool proof; - - /** Whether we support SmtEngine::getAssignment() for this run. */ - bool produceAssignments; - - /** Whether we do typechecking at all. */ - bool typeChecking; - - /** Whether we do typechecking at Expr creation time. */ - bool earlyTypeChecking; - - /** Whether incemental solving (push/pop) */ - bool incrementalSolving; - - /** Replay file to use (for decisions); empty if no replay file. */ - std::string replayFilename; - - /** Replay stream to use (for decisions); NULL if no replay file. */ - ExprStream* replayStream; - - /** Log to write replay instructions to; NULL if not logging. */ - std::ostream* replayLog; - - /** - * Frequency for the sat solver to make random decisions. - * Should be between 0 and 1. - */ - double satRandomFreq; - - /** - * Seed for Minisat's random decision procedure. - * If this is 0, no random decisions will occur. - **/ - double satRandomSeed; - - /** Variable activity decay factor for Minisat */ - double satVarDecay; - - /** Clause activity decay factor for Minisat */ - double satClauseDecay; - - /** Base restart interval for Minisat */ - int satRestartFirst; - - /** Restart interval increase factor for Minisat */ - double satRestartInc; - - /** Determines the type of Arithmetic Presolve Lemmas are generated.*/ - typedef enum { NO_PRESOLVE_LEMMAS, INEQUALITY_PRESOLVE_LEMMAS, EQUALITY_PRESOLVE_LEMMAS, ALL_PRESOLVE_LEMMAS} ArithUnateLemmaMode; - ArithUnateLemmaMode arithUnateLemmaMode; - - /** Determines the mode of arithmetic propagation. */ - typedef enum { NO_PROP, UNATE_PROP, BOUND_INFERENCE_PROP, BOTH_PROP} ArithPropagationMode; - ArithPropagationMode arithPropagationMode; - - /** - * The maximum number of difference pivots to do per invocation of simplex. - * If this is negative, the number of pivots done is the number of variables. - * If this is not set by the user, different logics are free to chose different - * defaults. - */ - int16_t arithHeuristicPivots; - bool arithHeuristicPivotsSetByUser; - - /** - * The maximum number of variable order pivots to do per invocation of simplex. - * If this is negative, the number of pivots done is unlimited. - * If this is not set by the user, different logics are free to chose different - * defaults. - */ - int16_t arithStandardCheckVarOrderPivots; - bool arithStandardCheckVarOrderPivotsSetByUser; - - /** The heuristic pivot rule for arithmetic. */ - typedef enum { MINIMUM, BREAK_TIES, MAXIMUM } ArithHeuristicPivotRule; - ArithHeuristicPivotRule arithHeuristicPivotRule; - - /** - * The number of pivots before simplex rechecks every basic variable for a conflict. - */ - uint16_t arithSimplexCheckPeriod; - - /** - * This is the pivots per basic variable that can be done using heuristic choices - * before variable order must be used. - * If this is not set by the user, different logics are free to chose different - * defaults. - */ - uint16_t arithPivotThreshold; - bool arithPivotThresholdSetByUser; - - /** - * The maximum row length that arithmetic will use for propagation. - */ - uint16_t arithPropagateMaxLength; - - /** - * Whether to do the linear diophantine equation solver - * in Arith as described by Griggio JSAT 2012 (on by default). - */ - bool arithDioSolver; - - /** - * Whether to split (= x y) into (and (<= x y) (>= x y)) in - * arithmetic preprocessing. - */ - bool arithRewriteEq; - - /** - * Whether the flag was set by the user - */ - bool arithRewriteEqSetByUser; - - /** - * Whether to do the symmetry-breaking preprocessing in UF as - * described by Deharbe et al. in CADE 2011 (on by default). - */ - bool ufSymmetryBreaker; - - /** - * Whether the user explicitly requested that the symmetry - * breaker be enabled or disabled. - */ - bool ufSymmetryBreakerSetByUser; - - /** - * Whether to mini-scope quantifiers. - * For example, forall x. ( P( x ) ^ Q( x ) ) will be rewritten to - * ( forall x. P( x ) ) ^ ( forall x. Q( x ) ) - */ - bool miniscopeQuant; - - /** - * Whether to mini-scope quantifiers based on formulas with no free variables. - * For example, forall x. ( P( x ) V Q ) will be rewritten to - * ( forall x. P( x ) ) V Q - */ - bool miniscopeQuantFreeVar; - - /** - * Whether to prenex (nested universal) quantifiers - */ - bool prenexQuant; - - /** - * Whether to variable-eliminate quantifiers. - * For example, forall x y. ( P( x, y ) V x != c ) will be rewritten to - * forall y. P( c, y ) - */ - bool varElimQuant; - - /** - * Whether to CNF quantifier bodies - */ - bool cnfQuant; - - /** - * Whether to pre-skolemize quantifier bodies. - * For example, forall x. ( P( x ) => (exists y. f( y ) = x) ) will be rewritten to - * forall x. P( x ) => f( S( x ) ) = x - */ - bool preSkolemQuant; - - /** - * Whether to use smart triggers - */ - bool smartTriggers; - - /** - * Whether to consider terms in the bodies of quantifiers for matching - */ - bool registerQuantBodyTerms; - - /** Enumeration of inst_when modes (when to instantiate). */ - typedef enum { - /** Apply instantiation round before full effort (possibly at standard effort) */ - INST_WHEN_PRE_FULL, - /** Apply instantiation round at full effort or above */ - INST_WHEN_FULL, - /** Apply instantiation round at full effort half the time, and last call always */ - INST_WHEN_FULL_LAST_CALL, - /** Apply instantiation round at last call only */ - INST_WHEN_LAST_CALL, - } InstWhenMode; - /** When to perform instantiation round. */ - InstWhenMode instWhenMode; - - /** - * Whether to eagerly instantiate quantifiers - */ - bool eagerInstQuant; - - /** - * Whether to use finite model find heuristic - */ - bool finiteModelFind; - - /** - * Whether to use eager splitting on demand for finite model finding - */ - bool ufssEagerSplits; - - /** - * Whether to use region-based approach for finite model finding - */ - bool ufssRegions; - - /** - * Whether to use coloring-based methods for determining whether a model of - * currently cardinality exists. - */ - bool ufssColoringSat; - - /** - * Whether to use model-based exhaustive instantiation for finite model finding - */ - bool fmfModelBasedInst; - - /** - * Whether to use Inst-Gen techniques for finite model finding - */ - bool fmfInstGen; - - /* - * Whether to only add only instantiation per quantifier per round for finite model finding - */ - bool fmfOneInstPerRound; - - /* - * Whether to use instantiation engine in conjunction with finite model finding - */ - bool fmfInstEngine; - - /* - * Whether to compute relevant domains, in the manner of Complete Instantiation for Quantified Formulas [Ge, deMoura 09] - */ - bool fmfRelevantDomain; - - /** - * Whether to use efficient E-matching - */ - bool efficientEMatching; - - /** Enumeration of literal matching modes. */ - typedef enum { - /** Do not consider polarity of patterns */ - LITERAL_MATCH_NONE, - /** Consider polarity of boolean predicates only */ - LITERAL_MATCH_PREDICATE, - /** Consider polarity of boolean predicates, as well as equalities */ - LITERAL_MATCH_EQUALITY, - } LiteralMatchMode; - - /** Which literal matching mode to use. */ - LiteralMatchMode literalMatchMode; - - /** - * Whether to do counterexample-based quantifier instantiation - */ - bool cbqi; - - /** - * Whether the user explicitly requested that counterexample-based - * quantifier instantiation be enabled or disabled. - */ - bool cbqiSetByUser; - - /** - * Whether to convert rewrite rules to usual axioms (for debugging only) - */ - bool rewriteRulesAsAxioms; - - /** - * Whether to use user patterns for pattern-based instantiation - */ - bool userPatternsQuant; - - /** - * Whether to use flip decision (useful when cbqi=true) - */ - bool flipDecision; - - /** - * print details for instantiation/model engine - */ - bool printInstEngine; - bool printModelEngine; - - /** The output channel to receive notfication events for new lemmas */ - LemmaOutputChannel* lemmaOutputChannel; - LemmaInputChannel* lemmaInputChannel; - - /** Total number of threads */ - int threads; - - /** Thread configuration (a string to be passed to parseOptions) */ - std::vector<std::string> threadArgv; - - /** Thread ID, for internal use in case of multi-threaded run */ - int thread_id; - - /** - * In multi-threaded setting print output of each thread at the - * end of run, separated by a divider ("----"). - **/ - bool separateOutput; - - /** Filter depending on length of lemma */ - int sharingFilterByLength; - - /** Bitblast eagerly to the main sat solver */ - bool bitvectorEagerBitblast; - - /** Fullcheck at each check */ - bool bitvectorEagerFullcheck; - - /** Bitblast eagerly to the main sat solver */ - bool bitvectorShareLemmas; - - /** Refine conflicts by doing another full check after a conflict */ - bool sat_refine_conflicts; - - /** Was theoryOf mode set by user */ - bool theoryOfModeSetByUser; - - /** Which theoryOf mode are we using */ - theory::TheoryOfMode theoryOfMode; - - Options(); - - /** - * Get a description of the command-line flags accepted by - * parseOptions. The returned string will be escaped so that it is - * suitable as an argument to printf. */ - std::string getDescription() const; - - /** - * Print overall command-line option usage message, prefixed by - * "msg"---which could be an error message causing the usage - * output in the first place, e.g. "no such option --foo" - */ - static void printUsage(const std::string msg, std::ostream& out); - - /** - * Print command-line option usage message for only the most-commonly - * used options. The message is prefixed by "msg"---which could be - * an error message causing the usage output in the first place, e.g. - * "no such option --foo" - */ - static void printShortUsage(const std::string msg, std::ostream& out); - - /** Print help for the --lang command line option */ - static void printLanguageHelp(std::ostream& out); - - /** - * Initialize the options based on the given command-line arguments. - */ - int parseOptions(int argc, char* argv[]) throw(OptionException); - - /** - * Set the output language based on the given string. - */ - void setOutputLanguage(const char* str) throw(OptionException); - - /** - * Set the input language based on the given string. - */ - void setInputLanguage(const char* str) throw(OptionException); - -};/* struct Options */ - -inline std::ostream& operator<<(std::ostream& out, - Options::SimplificationMode mode) CVC4_PUBLIC; -inline std::ostream& operator<<(std::ostream& out, - Options::SimplificationMode mode) { - switch(mode) { - case Options::SIMPLIFICATION_MODE_INCREMENTAL: - out << "SIMPLIFICATION_MODE_INCREMENTAL"; - break; - case Options::SIMPLIFICATION_MODE_BATCH: - out << "SIMPLIFICATION_MODE_BATCH"; - break; - case Options::SIMPLIFICATION_MODE_NONE: - out << "SIMPLIFICATION_MODE_NONE"; - break; - default: - out << "SimplificationMode:UNKNOWN![" << unsigned(mode) << "]"; - } - - return out; -} - -std::ostream& operator<<(std::ostream& out, Options::ArithHeuristicPivotRule rule) CVC4_PUBLIC; - -}/* CVC4 namespace */ - -#endif /* __CVC4__OPTIONS_H */ diff --git a/src/util/options.i b/src/util/options.i deleted file mode 100644 index bdafefd07..000000000 --- a/src/util/options.i +++ /dev/null @@ -1,10 +0,0 @@ -%{ -#include "util/options.h" -%} - -%ignore CVC4::operator<<(std::ostream&, Options::SimplificationMode); -%ignore CVC4::operator<<(std::ostream&, Options::ArithPivotRule); - -%apply char** STRING_ARRAY { char* argv[] } -%include "util/options.h" -%clear char* argv[]; diff --git a/src/util/rational_cln_imp.h b/src/util/rational_cln_imp.h index 583983829..ea9f7d055 100644 --- a/src/util/rational_cln_imp.h +++ b/src/util/rational_cln_imp.h @@ -69,7 +69,8 @@ private: public: - /** Creates a rational from a decimal string (e.g., <code>"1.5"</code>). + /** + * Creates a rational from a decimal string (e.g., <code>"1.5"</code>). * * @param dec a string encoding a decimal number in the format * <code>[0-9]*\.[0-9]*</code> @@ -166,10 +167,19 @@ public: * Returns the value of denominator of the Rational. * Note that this makes a deep copy of the denominator. */ - Integer getDenominator() const{ + Integer getDenominator() const { return Integer(cln::denominator(d_value)); } + /** + * Get a double representation of this Rational, which is + * approximate: truncation may occur, overflow may result in + * infinity, and underflow may result in zero. + */ + double getDouble() const { + return cln::double_approx(d_value); + } + Rational inverse() const { return Rational(cln::recip(d_value)); } diff --git a/src/util/rational_gmp_imp.h b/src/util/rational_gmp_imp.h index 95a15bc5a..ed9c57a80 100644 --- a/src/util/rational_gmp_imp.h +++ b/src/util/rational_gmp_imp.h @@ -62,7 +62,8 @@ private: public: - /** Creates a rational from a decimal string (e.g., <code>"1.5"</code>). + /** + * Creates a rational from a decimal string (e.g., <code>"1.5"</code>). * * @param dec a string encoding a decimal number in the format * <code>[0-9]*\.[0-9]*</code> @@ -155,6 +156,15 @@ public: return Integer(d_value.get_den()); } + /** + * Get a double representation of this Rational, which is + * approximate: truncation may occur, overflow may result in + * infinity, and underflow may result in zero. + */ + double getDouble() const { + return d_value.get_d(); + } + Rational inverse() const { return Rational(getDenominator(), getNumerator()); } diff --git a/src/util/stats.cpp b/src/util/stats.cpp index 96e300197..7ac430da8 100644 --- a/src/util/stats.cpp +++ b/src/util/stats.cpp @@ -93,10 +93,18 @@ void StatisticsRegistry::flushStat(std::ostream &out) const {; #endif /* CVC4_STATISTICS_ON */ } +StatisticsRegistry::const_iterator StatisticsRegistry::begin_() const { + return d_registeredStats.begin(); +}/* StatisticsRegistry::begin() */ + StatisticsRegistry::const_iterator StatisticsRegistry::begin() { return current()->d_registeredStats.begin(); }/* StatisticsRegistry::begin() */ +StatisticsRegistry::const_iterator StatisticsRegistry::end_() const { + return d_registeredStats.end(); +}/* StatisticsRegistry::end() */ + StatisticsRegistry::const_iterator StatisticsRegistry::end() { return current()->d_registeredStats.end(); }/* StatisticsRegistry::end() */ diff --git a/src/util/stats.h b/src/util/stats.h index aabf04dc0..082bdfeaa 100644 --- a/src/util/stats.h +++ b/src/util/stats.h @@ -558,12 +558,26 @@ public: * Get an iterator to the beginning of the range of the set of active * (registered) statistics. */ + const_iterator begin_() const; + + /** + * Get an iterator to the beginning of the range of the set of active + * (registered) statistics. This version uses the "current" + * statistics registry. + */ static const_iterator begin(); /** * Get an iterator to the end of the range of the set of active * (registered) statistics. */ + const_iterator end_() const; + + /** + * Get an iterator to the end of the range of the set of active + * (registered) statistics. This version uses the "current" + * statistics registry. + */ static const_iterator end(); };/* class StatisticsRegistry */ diff --git a/test/system/Makefile.am b/test/system/Makefile.am index 6430814a5..5fcc8833a 100644 --- a/test/system/Makefile.am +++ b/test/system/Makefile.am @@ -3,7 +3,8 @@ TEST_EXTENSIONS = .class CPLUSPLUS_TESTS = \ boilerplate \ ouroborous \ - two_smt_engines + two_smt_engines \ + smt2_compliance # cvc3_main TESTS = $(CPLUSPLUS_TESTS) diff --git a/test/system/smt2_compliance.cpp b/test/system/smt2_compliance.cpp new file mode 100644 index 000000000..65dd52193 --- /dev/null +++ b/test/system/smt2_compliance.cpp @@ -0,0 +1,74 @@ +/********************* */ +/*! \file smt2_compliance.cpp + ** \verbatim + ** Original author: mdeters + ** Major contributors: none + ** Minor contributors (to current version): none + ** This file is part of the CVC4 prototype. + ** Copyright (c) 2009-2012 The Analysis of Computer Systems Group (ACSys) + ** Courant Institute of Mathematical Sciences + ** New York University + ** See the file COPYING in the top-level source directory for licensing + ** information.\endverbatim + ** + ** \brief A test of SMT-LIBv2 commands, checks for compliant output + ** + ** A test of SMT-LIBv2 commands, checks for compliant output. + **/ + +#include <iostream> +#include <sstream> +#include <cassert> + +#include "smt/options.h" +#include "parser/parser.h" +#include "expr/expr_manager.h" +#include "expr/command.h" +#include "smt/smt_engine.h" +#include "parser/parser_builder.h" + +using namespace CVC4; +using namespace CVC4::parser; +using namespace std; + +void testGetInfo(SmtEngine& smt, const char* s); + +int main() { + Options opts; + opts.set(options::inputLanguage, language::input::LANG_SMTLIB_V2); + opts.set(options::outputLanguage, language::output::LANG_SMTLIB_V2); + + cout << Expr::setlanguage(language::output::LANG_SMTLIB_V2); + + ExprManager em(opts); + SmtEngine smt(&em); + + testGetInfo(smt, ":error-behavior"); + testGetInfo(smt, ":name"); + testGetInfo(smt, ":authors"); + testGetInfo(smt, ":version"); + testGetInfo(smt, ":status"); + testGetInfo(smt, ":reason-unknown"); + testGetInfo(smt, ":arbitrary-undefined-keyword"); + testGetInfo(smt, ":56");// legal + testGetInfo(smt, ":<=");// legal + testGetInfo(smt, ":->");// legal + testGetInfo(smt, ":all-statistics"); + + return 0; +} + +void testGetInfo(SmtEngine& smt, const char* s) { + ParserBuilder pb(smt.getExprManager(), "<internal>", smt.getExprManager()->getOptions()); + Parser* p = pb.withStringInput(string("(get-info ") + s + ")").build(); + assert(p != NULL); + Command* c = p->nextCommand(); + assert(c != NULL); + cout << c << endl; + stringstream ss; + c->invoke(&smt, ss); + assert(p->nextCommand() == NULL); + delete p; + + cout << ss.str() << endl << endl; +} diff --git a/test/unit/main/interactive_shell_black.h b/test/unit/main/interactive_shell_black.h index 7773644da..d905923e2 100644 --- a/test/unit/main/interactive_shell_black.h +++ b/test/unit/main/interactive_shell_black.h @@ -26,7 +26,7 @@ #include "main/interactive_shell.h" #include "parser/parser_builder.h" #include "util/language.h" -#include "util/options.h" +#include "options/options.h" using namespace CVC4; using namespace std; @@ -59,9 +59,9 @@ private: d_exprManager = new ExprManager; d_sin = new stringstream; d_sout = new stringstream; - d_options.in = d_sin; - d_options.out = d_sout; - d_options.inputLanguage = language::input::LANG_CVC4; + d_options.set(options::in, d_sin); + d_options.set(options::out, d_sout); + d_options.set(options::inputLanguage, language::input::LANG_CVC4); } void tearDown() { diff --git a/test/unit/parser/parser_black.h b/test/unit/parser/parser_black.h index 91af11561..01879ec49 100644 --- a/test/unit/parser/parser_black.h +++ b/test/unit/parser/parser_black.h @@ -27,7 +27,7 @@ #include "parser/parser_builder.h" #include "parser/smt2/smt2.h" #include "expr/command.h" -#include "util/options.h" +#include "options/options.h" #include "util/output.h" #include "util/language.h" @@ -184,7 +184,7 @@ protected: void setUp() { d_exprManager = new ExprManager; - d_options.parseOnly = true; + d_options.set(options::parseOnly, true); } void tearDown() { diff --git a/test/unit/theory/theory_engine_white.h b/test/unit/theory/theory_engine_white.h index ee637daac..eb6e5eefb 100644 --- a/test/unit/theory/theory_engine_white.h +++ b/test/unit/theory/theory_engine_white.h @@ -38,7 +38,7 @@ #include "smt/smt_engine_scope.h" #include "util/rational.h" #include "util/integer.h" -#include "util/options.h" +#include "options/options.h" #include "util/Assert.h" using namespace CVC4; |