summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAndres Noetzli <andres.noetzli@gmail.com>2021-06-22 18:01:22 -0700
committerGitHub <noreply@github.com>2021-06-22 18:01:22 -0700
commit474faec211db41b626ed29d8dde26ff861f40d87 (patch)
tree3c5e68fb24113fca9e74c002614a388698d9a5f5 /src
parent0bb3e14b46a4b2f5cacfadb313c947da73ba7df6 (diff)
parent21ee0f18c288d430d08c133f601173be25411187 (diff)
Merge branch 'master' into rmTearDownIncrementalrmTearDownIncremental
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt13
-rw-r--r--src/api/cpp/cvc5.cpp47
-rw-r--r--src/api/cpp/cvc5.h6
-rw-r--r--src/api/cpp/cvc5_kind.h16
-rw-r--r--src/api/java/cvc5/Grammar.java87
-rw-r--r--src/api/java/jni/cvc5_Grammar.cpp120
-rw-r--r--src/api/python/cvc5.pxd26
-rw-r--r--src/api/python/cvc5.pxi116
-rw-r--r--src/base/configuration.cpp32
-rw-r--r--src/base/configuration.h4
-rw-r--r--src/base/configuration_private.h12
-rw-r--r--src/expr/attribute.h81
-rw-r--r--src/expr/attribute_internals.h41
-rw-r--r--src/main/command_executor.cpp43
-rw-r--r--src/main/driver_unified.cpp58
-rw-r--r--src/main/interactive_shell.cpp17
-rw-r--r--src/main/main.cpp16
-rw-r--r--src/main/time_limit.cpp4
-rw-r--r--src/omt/bitvector_optimizer.cpp128
-rw-r--r--src/omt/integer_optimizer.cpp13
-rw-r--r--src/options/CMakeLists.txt2
-rw-r--r--src/options/README127
-rw-r--r--src/options/README.md211
-rw-r--r--src/options/base_handlers.h87
-rw-r--r--src/options/base_options.toml59
-rw-r--r--src/options/main_options.toml48
-rw-r--r--src/options/mkoptions.py51
-rw-r--r--src/options/options_handler.cpp131
-rw-r--r--src/options/options_handler.h145
-rw-r--r--src/options/options_public.cpp108
-rw-r--r--src/options/options_public.h36
-rw-r--r--src/options/options_template.cpp91
-rw-r--r--src/options/parser_options.toml1
-rw-r--r--src/options/prop_options.toml8
-rw-r--r--src/options/resource_manager_options.toml51
-rw-r--r--src/options/smt_options.toml57
-rw-r--r--src/parser/parser.cpp4
-rw-r--r--src/parser/parser_builder.cpp17
-rw-r--r--src/parser/smt2/smt2.cpp3
-rw-r--r--src/preprocessing/passes/ackermann.cpp2
-rw-r--r--src/preprocessing/passes/int_to_bv.cpp1
-rw-r--r--src/preprocessing/passes/ite_simp.cpp1
-rw-r--r--src/preprocessing/passes/miplib_trick.cpp2
-rw-r--r--src/proof/proof_rule.h4
-rw-r--r--src/prop/cadical.cpp4
-rw-r--r--src/prop/cadical.h3
-rw-r--r--src/prop/cnf_stream.cpp193
-rw-r--r--src/prop/cnf_stream.h28
-rw-r--r--src/prop/minisat/core/Solver.cc1
-rw-r--r--src/prop/proof_cnf_stream.h1
-rw-r--r--src/prop/prop_engine.cpp3
-rw-r--r--src/prop/sat_solver_factory.cpp4
-rw-r--r--src/smt/command.cpp1
-rw-r--r--src/smt/optimization_solver.cpp91
-rw-r--r--src/smt/optimization_solver.h121
-rw-r--r--src/smt/preprocessor.cpp1
-rw-r--r--src/smt/set_defaults.cpp2
-rw-r--r--src/smt/smt_engine.cpp7
-rw-r--r--src/smt/smt_engine_state.cpp1
-rw-r--r--src/smt/smt_engine_stats.cpp2
-rw-r--r--src/smt/smt_engine_stats.h2
-rw-r--r--src/smt/smt_solver.cpp1
-rw-r--r--src/smt/sygus_solver.cpp1
-rw-r--r--src/theory/arith/arith_ite_utils.cpp1
-rw-r--r--src/theory/arith/kinds2
-rw-r--r--src/theory/arith/nl/cad/lazard_evaluation.cpp4
-rw-r--r--src/theory/arith/nl/cad/lazard_evaluation.h5
-rw-r--r--src/theory/arith/nl/pow2_solver.cpp73
-rw-r--r--src/theory/arith/theory_arith_private.cpp2
-rw-r--r--src/theory/arrays/theory_arrays.cpp2
-rw-r--r--src/theory/bv/bitblast/eager_bitblaster.cpp1
-rw-r--r--src/theory/bv/bitblast/simple_bitblaster.cpp10
-rw-r--r--src/theory/bv/bitblast/simple_bitblaster.h2
-rw-r--r--src/theory/bv/bv_eager_solver.cpp1
-rw-r--r--src/theory/bv/bv_solver.h13
-rw-r--r--src/theory/bv/bv_solver_bitblast.cpp23
-rw-r--r--src/theory/bv/bv_solver_bitblast.h2
-rw-r--r--src/theory/bv/int_blaster.cpp240
-rw-r--r--src/theory/bv/int_blaster.h27
-rw-r--r--src/theory/bv/theory_bv.cpp5
-rw-r--r--src/theory/bv/theory_bv.h2
-rw-r--r--src/theory/datatypes/theory_datatypes.cpp3
-rw-r--r--src/theory/ee_setup_info.h21
-rw-r--r--src/theory/fp/fp_converter.cpp33
-rw-r--r--src/theory/fp/fp_converter.h10
-rw-r--r--src/theory/fp/theory_fp.cpp2
-rw-r--r--src/theory/fp/theory_fp_rewriter.cpp14
-rw-r--r--src/theory/fp/theory_fp_type_rules.cpp8
-rw-r--r--src/theory/inference_id.cpp4
-rw-r--r--src/theory/inference_id.h5
-rw-r--r--src/theory/logic_info.cpp4
-rw-r--r--src/theory/quantifiers/fmf/full_model_check.cpp5
-rw-r--r--src/theory/quantifiers/instantiate.cpp1
-rw-r--r--src/theory/quantifiers/term_registry.cpp1
-rw-r--r--src/theory/sep/theory_sep.cpp1
-rw-r--r--src/theory/sets/theory_sets.cpp3
-rw-r--r--src/theory/strings/regexp_entail.cpp4
-rw-r--r--src/theory/strings/term_registry.cpp3
-rw-r--r--src/theory/strings/theory_strings.cpp3
-rw-r--r--src/theory/theory.cpp12
-rw-r--r--src/theory/theory_model.cpp18
-rw-r--r--src/theory/uf/equality_engine.cpp59
-rw-r--r--src/theory/uf/equality_engine.h3
-rw-r--r--src/theory/uf/theory_uf.cpp8
-rw-r--r--src/util/CMakeLists.txt3
-rw-r--r--src/util/floatingpoint_literal_symfpu.cpp185
-rw-r--r--src/util/floatingpoint_literal_symfpu.h (renamed from src/util/floatingpoint_literal_symfpu.h.in)38
-rw-r--r--src/util/floatingpoint_literal_symfpu_traits.cpp3
-rw-r--r--src/util/floatingpoint_literal_symfpu_traits.h (renamed from src/util/floatingpoint_literal_symfpu_traits.h.in)9
-rw-r--r--src/util/resource_manager.cpp36
110 files changed, 1908 insertions, 1600 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index bec3a8345..74db7c941 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -441,6 +441,7 @@ libcvc5_add_sources(
theory/arith/nl/nonlinear_extension.h
theory/arith/nl/poly_conversion.cpp
theory/arith/nl/poly_conversion.h
+ theory/arith/nl/pow2_solver.cpp
theory/arith/nl/pow2_solver.h
theory/arith/nl/stats.cpp
theory/arith/nl/stats.h
@@ -595,6 +596,7 @@ libcvc5_add_sources(
theory/bv/bv_subtheory_core.h
theory/bv/bv_subtheory_inequality.cpp
theory/bv/bv_subtheory_inequality.h
+ theory/bv/int_blaster.cpp
theory/bv/int_blaster.h
theory/bv/proof_checker.cpp
theory/bv/proof_checker.h
@@ -1184,9 +1186,9 @@ if(USE_ABC)
target_link_libraries(cvc5 PRIVATE ${ABC_LIBRARIES})
target_include_directories(cvc5 PRIVATE ${ABC_INCLUDE_DIR})
endif()
-if(USE_CADICAL)
- target_link_libraries(cvc5 PRIVATE CaDiCaL)
-endif()
+
+target_link_libraries(cvc5 PRIVATE CaDiCaL)
+
if(USE_CLN)
target_link_libraries(cvc5 PRIVATE CLN)
endif()
@@ -1203,9 +1205,8 @@ endif()
if(USE_POLY)
target_link_libraries(cvc5 PRIVATE Polyxx)
endif()
-if(USE_SYMFPU)
- target_link_libraries(cvc5 PRIVATE SymFPU)
-endif()
+
+target_link_libraries(cvc5 PRIVATE SymFPU)
# Note: When linked statically GMP needs to be linked after CLN since CLN
# depends on GMP.
diff --git a/src/api/cpp/cvc5.cpp b/src/api/cpp/cvc5.cpp
index 668fc9382..43bb3d2dc 100644
--- a/src/api/cpp/cvc5.cpp
+++ b/src/api/cpp/cvc5.cpp
@@ -55,6 +55,7 @@
#include "expr/sequence.h"
#include "expr/type_node.h"
#include "expr/uninterpreted_constant.h"
+#include "options/base_options.h"
#include "options/main_options.h"
#include "options/option_exception.h"
#include "options/options.h"
@@ -5196,18 +5197,6 @@ void Solver::checkMkTerm(Kind kind, uint32_t nchildren) const
<< " children (the one under construction has " << nchildren << ")";
}
-/* Solver Configuration */
-/* -------------------------------------------------------------------------- */
-
-bool Solver::supportsFloatingPoint() const
-{
- CVC5_API_TRY_CATCH_BEGIN;
- //////// all checks before this line
- return Configuration::isBuiltWithSymFPU();
- ////////
- CVC5_API_TRY_CATCH_END;
-}
-
/* Sorts Handling */
/* -------------------------------------------------------------------------- */
@@ -5275,8 +5264,6 @@ Sort Solver::getRoundingModeSort(void) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(Configuration::isBuiltWithSymFPU())
- << "Expected cvc5 to be compiled with SymFPU support";
//////// all checks before this line
return Sort(this, getNodeManager()->roundingModeType());
////////
@@ -5313,8 +5300,6 @@ Sort Solver::mkFloatingPointSort(uint32_t exp, uint32_t sig) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(Configuration::isBuiltWithSymFPU())
- << "Expected cvc5 to be compiled with SymFPU support";
CVC5_API_ARG_CHECK_EXPECTED(exp > 0, exp) << "exponent size > 0";
CVC5_API_ARG_CHECK_EXPECTED(sig > 0, sig) << "significand size > 0";
//////// all checks before this line
@@ -5793,8 +5778,6 @@ Term Solver::mkPosInf(uint32_t exp, uint32_t sig) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(Configuration::isBuiltWithSymFPU())
- << "Expected cvc5 to be compiled with SymFPU support";
//////// all checks before this line
return mkValHelper<cvc5::FloatingPoint>(
FloatingPoint::makeInf(FloatingPointSize(exp, sig), false));
@@ -5806,8 +5789,6 @@ Term Solver::mkNegInf(uint32_t exp, uint32_t sig) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(Configuration::isBuiltWithSymFPU())
- << "Expected cvc5 to be compiled with SymFPU support";
//////// all checks before this line
return mkValHelper<cvc5::FloatingPoint>(
FloatingPoint::makeInf(FloatingPointSize(exp, sig), true));
@@ -5819,8 +5800,6 @@ Term Solver::mkNaN(uint32_t exp, uint32_t sig) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(Configuration::isBuiltWithSymFPU())
- << "Expected cvc5 to be compiled with SymFPU support";
//////// all checks before this line
return mkValHelper<cvc5::FloatingPoint>(
FloatingPoint::makeNaN(FloatingPointSize(exp, sig)));
@@ -5832,8 +5811,6 @@ Term Solver::mkPosZero(uint32_t exp, uint32_t sig) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(Configuration::isBuiltWithSymFPU())
- << "Expected cvc5 to be compiled with SymFPU support";
//////// all checks before this line
return mkValHelper<cvc5::FloatingPoint>(
FloatingPoint::makeZero(FloatingPointSize(exp, sig), false));
@@ -5845,8 +5822,6 @@ Term Solver::mkNegZero(uint32_t exp, uint32_t sig) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(Configuration::isBuiltWithSymFPU())
- << "Expected cvc5 to be compiled with SymFPU support";
//////// all checks before this line
return mkValHelper<cvc5::FloatingPoint>(
FloatingPoint::makeZero(FloatingPointSize(exp, sig), true));
@@ -5858,8 +5833,6 @@ Term Solver::mkRoundingMode(RoundingMode rm) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(Configuration::isBuiltWithSymFPU())
- << "Expected cvc5 to be compiled with SymFPU support";
//////// all checks before this line
return mkValHelper<cvc5::RoundingMode>(s_rmodes.at(rm));
////////
@@ -5913,8 +5886,6 @@ Term Solver::mkFloatingPoint(uint32_t exp, uint32_t sig, Term val) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(Configuration::isBuiltWithSymFPU())
- << "Expected cvc5 to be compiled with SymFPU support";
CVC5_API_SOLVER_CHECK_TERM(val);
CVC5_API_ARG_CHECK_EXPECTED(exp > 0, exp) << "a value > 0";
CVC5_API_ARG_CHECK_EXPECTED(sig > 0, sig) << "a value > 0";
@@ -6452,7 +6423,7 @@ Result Solver::checkEntailed(const Term& term) const
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
CVC5_API_CHECK(!d_smtEngine->isQueryMade()
- || d_smtEngine->getOptions().smt.incrementalSolving)
+ || d_smtEngine->getOptions().base.incrementalSolving)
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
CVC5_API_SOLVER_CHECK_TERM(term);
@@ -6468,7 +6439,7 @@ Result Solver::checkEntailed(const std::vector<Term>& terms) const
CVC5_API_TRY_CATCH_BEGIN;
NodeManagerScope scope(getNodeManager());
CVC5_API_CHECK(!d_smtEngine->isQueryMade()
- || d_smtEngine->getOptions().smt.incrementalSolving)
+ || d_smtEngine->getOptions().base.incrementalSolving)
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
CVC5_API_SOLVER_CHECK_TERMS(terms);
@@ -6497,7 +6468,7 @@ Result Solver::checkSat(void) const
CVC5_API_TRY_CATCH_BEGIN;
NodeManagerScope scope(getNodeManager());
CVC5_API_CHECK(!d_smtEngine->isQueryMade()
- || d_smtEngine->getOptions().smt.incrementalSolving)
+ || d_smtEngine->getOptions().base.incrementalSolving)
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
//////// all checks before this line
@@ -6512,7 +6483,7 @@ Result Solver::checkSatAssuming(const Term& assumption) const
CVC5_API_TRY_CATCH_BEGIN;
NodeManagerScope scope(getNodeManager());
CVC5_API_CHECK(!d_smtEngine->isQueryMade()
- || d_smtEngine->getOptions().smt.incrementalSolving)
+ || d_smtEngine->getOptions().base.incrementalSolving)
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
CVC5_API_SOLVER_CHECK_TERM_WITH_SORT(assumption, getBooleanSort());
@@ -6528,7 +6499,7 @@ Result Solver::checkSatAssuming(const std::vector<Term>& assumptions) const
CVC5_API_TRY_CATCH_BEGIN;
NodeManagerScope scope(getNodeManager());
CVC5_API_CHECK(!d_smtEngine->isQueryMade() || assumptions.size() == 0
- || d_smtEngine->getOptions().smt.incrementalSolving)
+ || d_smtEngine->getOptions().base.incrementalSolving)
<< "Cannot make multiple queries unless incremental solving is enabled "
"(try --incremental)";
CVC5_API_SOLVER_CHECK_TERMS_WITH_SORT(assumptions, getBooleanSort());
@@ -6863,7 +6834,7 @@ std::vector<Term> Solver::getUnsatAssumptions(void) const
{
CVC5_API_TRY_CATCH_BEGIN;
NodeManagerScope scope(getNodeManager());
- CVC5_API_CHECK(d_smtEngine->getOptions().smt.incrementalSolving)
+ CVC5_API_CHECK(d_smtEngine->getOptions().base.incrementalSolving)
<< "Cannot get unsat assumptions unless incremental solving is enabled "
"(try --incremental)";
CVC5_API_CHECK(d_smtEngine->getOptions().smt.unsatAssumptions)
@@ -7044,7 +7015,7 @@ void Solver::pop(uint32_t nscopes) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(d_smtEngine->getOptions().smt.incrementalSolving)
+ CVC5_API_CHECK(d_smtEngine->getOptions().base.incrementalSolving)
<< "Cannot pop when not solving incrementally (use --incremental)";
CVC5_API_CHECK(nscopes <= d_smtEngine->getNumUserLevels())
<< "Cannot pop beyond first pushed context";
@@ -7176,7 +7147,7 @@ void Solver::push(uint32_t nscopes) const
{
NodeManagerScope scope(getNodeManager());
CVC5_API_TRY_CATCH_BEGIN;
- CVC5_API_CHECK(d_smtEngine->getOptions().smt.incrementalSolving)
+ CVC5_API_CHECK(d_smtEngine->getOptions().base.incrementalSolving)
<< "Cannot push when not solving incrementally (use --incremental)";
//////// all checks before this line
for (uint32_t n = 0; n < nscopes; ++n)
diff --git a/src/api/cpp/cvc5.h b/src/api/cpp/cvc5.h
index a1421cf12..161522654 100644
--- a/src/api/cpp/cvc5.h
+++ b/src/api/cpp/cvc5.h
@@ -2752,12 +2752,6 @@ class CVC5_EXPORT Solver
Solver& operator=(const Solver&) = delete;
/* .................................................................... */
- /* Solver Configuration */
- /* .................................................................... */
-
- bool supportsFloatingPoint() const;
-
- /* .................................................................... */
/* Sorts Handling */
/* .................................................................... */
diff --git a/src/api/cpp/cvc5_kind.h b/src/api/cpp/cvc5_kind.h
index 2ec190360..2c5d2873e 100644
--- a/src/api/cpp/cvc5_kind.h
+++ b/src/api/cpp/cvc5_kind.h
@@ -412,6 +412,22 @@ enum CVC5_EXPORT Kind : int32_t
* - `Solver::mkTerm(const Op& op, const std::vector<Term>& children) const`
*/
IAND,
+ /**
+ * Operator for raising 2 to a non-negative integer power
+ *
+ * Create with:
+ * - `Solver::mkOp(Kind kind) const`
+ *
+
+ * Parameters:
+ * - 1: Op of kind IAND
+ * - 2: Integer term
+ *
+ * Create with:
+ * - `Solver::mkTerm(const Op& op, const Term& child) const`
+ * - `Solver::mkTerm(const Op& op, const std::vector<Term>& children) const`
+ */
+ POW2,
#if 0
/* Synonym for MULT. */
NONLINEAR_MULT,
diff --git a/src/api/java/cvc5/Grammar.java b/src/api/java/cvc5/Grammar.java
new file mode 100644
index 000000000..f8c6b05c5
--- /dev/null
+++ b/src/api/java/cvc5/Grammar.java
@@ -0,0 +1,87 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ * Aina Niemetz, Andrew Reynolds, Abdalrhman Mohamed, Mudathir Mohamed
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved. See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * The cvc5 java API.
+ */
+
+package cvc5;
+
+public class Grammar extends AbstractPointer {
+ // region construction and destruction
+ Grammar(Solver solver, long pointer) {
+ super(solver, pointer);
+ }
+
+ protected static native void deletePointer(long pointer);
+
+ public long getPointer() {
+ return pointer;
+ }
+
+ @Override
+ public void finalize() {
+ deletePointer(pointer);
+ }
+
+ // endregion
+
+ /**
+ * Add \p rule to the set of rules corresponding to \p ntSymbol.
+ * @param ntSymbol the non-terminal to which the rule is added
+ * @param rule the rule to add
+ */
+ public void addRule(Term ntSymbol, Term rule) {
+ addRule(pointer, ntSymbol.getPointer(), rule.getPointer());
+ }
+
+ private native void addRule(
+ long pointer, long ntSymbolPointer, long rulePointer);
+
+ /**
+ * Add \p rules to the set of rules corresponding to \p ntSymbol.
+ * @param ntSymbol the non-terminal to which the rules are added
+ * @param rules the rules to add
+ */
+ public void addRules(Term ntSymbol, Term[] rules) {
+ long[] pointers = Utils.getPointers(rules);
+ addRules(pointer, ntSymbol.getPointer(), pointers);
+ }
+
+ public native void addRules(
+ long pointer, long ntSymbolPointer, long[] rulePointers);
+
+ /**
+ * Allow \p ntSymbol to be an arbitrary constant.
+ * @param ntSymbol the non-terminal allowed to be any constant
+ */
+ void addAnyConstant(Term ntSymbol) {
+ addAnyConstant(pointer, ntSymbol.getPointer());
+ }
+
+ private native void addAnyConstant(long pointer, long ntSymbolPointer);
+
+ /**
+ * Allow \p ntSymbol to be any input variable to corresponding
+ * synth-fun/synth-inv with the same sort as \p ntSymbol.
+ * @param ntSymbol the non-terminal allowed to be any input constant
+ */
+ void addAnyVariable(Term ntSymbol) {
+ addAnyVariable(pointer, ntSymbol.getPointer());
+ }
+
+ private native void addAnyVariable(long pointer, long ntSymbolPointer);
+
+ /**
+ * @return a string representation of this grammar.
+ */
+ protected native String toString(long pointer);
+}
diff --git a/src/api/java/jni/cvc5_Grammar.cpp b/src/api/java/jni/cvc5_Grammar.cpp
new file mode 100644
index 000000000..95af2108f
--- /dev/null
+++ b/src/api/java/jni/cvc5_Grammar.cpp
@@ -0,0 +1,120 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ * Mudathir Mohamed
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved. See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * The cvc5 Java API.
+ */
+
+#include "cvc5_Grammar.h"
+
+#include "api/cpp/cvc5.h"
+#include "cvc5JavaApi.h"
+
+using namespace cvc5::api;
+
+/*
+ * Class: cvc5_Grammar
+ * Method: deletePointer
+ * Signature: (J)V
+ */
+JNIEXPORT void JNICALL Java_cvc5_Grammar_deletePointer(JNIEnv*,
+ jclass,
+ jlong pointer)
+{
+ delete reinterpret_cast<Grammar*>(pointer);
+}
+
+/*
+ * Class: cvc5_Grammar
+ * Method: addRule
+ * Signature: (JJJ)V
+ */
+JNIEXPORT void JNICALL Java_cvc5_Grammar_addRule(JNIEnv* env,
+ jobject,
+ jlong pointer,
+ jlong ntSymbolPointer,
+ jlong rulePointer)
+{
+ CVC5_JAVA_API_TRY_CATCH_BEGIN;
+ Grammar* current = reinterpret_cast<Grammar*>(pointer);
+ Term* ntSymbol = reinterpret_cast<Term*>(ntSymbolPointer);
+ Term* rule = reinterpret_cast<Term*>(rulePointer);
+ current->addRule(*ntSymbol, *rule);
+ CVC5_JAVA_API_TRY_CATCH_END(env);
+}
+
+/*
+ * Class: cvc5_Grammar
+ * Method: addRules
+ * Signature: (JJ[J)V
+ */
+JNIEXPORT void JNICALL Java_cvc5_Grammar_addRules(JNIEnv* env,
+ jobject,
+ jlong pointer,
+ jlong ntSymbolPointer,
+ jlongArray rulePointers)
+{
+ CVC5_JAVA_API_TRY_CATCH_BEGIN;
+ Grammar* current = reinterpret_cast<Grammar*>(pointer);
+ Term* ntSymbol = reinterpret_cast<Term*>(ntSymbolPointer);
+ std::vector<Term> rules = getObjectsFromPointers<Term>(env, rulePointers);
+ current->addRules(*ntSymbol, rules);
+ CVC5_JAVA_API_TRY_CATCH_END(env);
+}
+
+/*
+ * Class: cvc5_Grammar
+ * Method: addAnyConstant
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_cvc5_Grammar_addAnyConstant(JNIEnv* env,
+ jobject,
+ jlong pointer,
+ jlong ntSymbolPointer)
+{
+ CVC5_JAVA_API_TRY_CATCH_BEGIN;
+ Grammar* current = reinterpret_cast<Grammar*>(pointer);
+ Term* ntSymbol = reinterpret_cast<Term*>(ntSymbolPointer);
+ current->addAnyConstant(*ntSymbol);
+ CVC5_JAVA_API_TRY_CATCH_END(env);
+}
+
+/*
+ * Class: cvc5_Grammar
+ * Method: addAnyVariable
+ * Signature: (JJ)V
+ */
+JNIEXPORT void JNICALL Java_cvc5_Grammar_addAnyVariable(JNIEnv* env,
+ jobject,
+ jlong pointer,
+ jlong ntSymbolPointer)
+{
+ CVC5_JAVA_API_TRY_CATCH_BEGIN;
+ Grammar* current = reinterpret_cast<Grammar*>(pointer);
+ Term* ntSymbol = reinterpret_cast<Term*>(ntSymbolPointer);
+ current->addAnyVariable(*ntSymbol);
+ CVC5_JAVA_API_TRY_CATCH_END(env);
+}
+
+/*
+ * Class: cvc5_Grammar
+ * Method: toString
+ * Signature: (J)Ljava/lang/String;
+ */
+JNIEXPORT jstring JNICALL Java_cvc5_Grammar_toString(JNIEnv* env,
+ jobject,
+ jlong pointer)
+{
+ CVC5_JAVA_API_TRY_CATCH_BEGIN;
+ Grammar* current = reinterpret_cast<Grammar*>(pointer);
+ return env->NewStringUTF(current->toString().c_str());
+ CVC5_JAVA_API_TRY_CATCH_END_RETURN(env, nullptr);
+}
diff --git a/src/api/python/cvc5.pxd b/src/api/python/cvc5.pxd
index fdc1872e7..99e471b0a 100644
--- a/src/api/python/cvc5.pxd
+++ b/src/api/python/cvc5.pxd
@@ -122,6 +122,7 @@ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api":
Sort getSort() except +
bint isNull() except +
bint isIndexed() except +
+ size_t getNumIndices() except +
T getIndices[T]() except +
string toString() except +
@@ -141,19 +142,23 @@ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api":
bint isEntailmentUnknown() except +
bint operator==(const Result& r) except +
bint operator!=(const Result& r) except +
- string getUnknownExplanation() except +
+ UnknownExplanation getUnknownExplanation() except +
string toString() except +
cdef cppclass RoundingMode:
pass
+ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api::Result":
+ cdef cppclass UnknownExplanation:
+ pass
+
cdef cppclass Solver:
Solver(Options*) except +
- bint supportsFloatingPoint() except +
Sort getBooleanSort() except +
Sort getIntegerSort() except +
+ Sort getNullSort() except +
Sort getRealSort() except +
Sort getRegExpSort() except +
Sort getRoundingModeSort() except +
@@ -179,10 +184,10 @@ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api":
Term mkTerm(Op op, const vector[Term]& children) except +
Term mkTuple(const vector[Sort]& sorts, const vector[Term]& terms) except +
Op mkOp(Kind kind) except +
- Op mkOp(Kind kind, Kind k) except +
Op mkOp(Kind kind, const string& arg) except +
Op mkOp(Kind kind, uint32_t arg) except +
Op mkOp(Kind kind, uint32_t arg1, uint32_t arg2) except +
+ Op mkOp(Kind kind, const vector[uint32_t]& args) except +
# Sygus related functions
Grammar mkSygusGrammar(const vector[Term]& boundVars, const vector[Term]& ntSymbols) except +
Term mkSygusVar(Sort sort, const string& symbol) except +
@@ -208,9 +213,11 @@ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api":
Term mkRegexpEmpty() except +
Term mkRegexpSigma() except +
Term mkEmptySet(Sort s) except +
+ Term mkEmptyBag(Sort s) except +
Term mkSepNil(Sort sort) except +
Term mkString(const string& s) except +
Term mkString(const wstring& s) except +
+ Term mkString(const string& s, bint useEscSequences) except +
Term mkEmptySequence(Sort sort) except +
Term mkUniverseSet(Sort sort) except +
Term mkBitVector(uint32_t size) except +
@@ -433,3 +440,16 @@ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api::RoundingMode":
cdef RoundingMode ROUND_TOWARD_NEGATIVE,
cdef RoundingMode ROUND_TOWARD_ZERO,
cdef RoundingMode ROUND_NEAREST_TIES_TO_AWAY
+
+
+cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api::Result::UnknownExplanation":
+ cdef UnknownExplanation REQUIRES_FULL_CHECK
+ cdef UnknownExplanation INCOMPLETE
+ cdef UnknownExplanation TIMEOUT
+ cdef UnknownExplanation RESOURCEOUT
+ cdef UnknownExplanation MEMOUT
+ cdef UnknownExplanation INTERRUPTED
+ cdef UnknownExplanation NO_STATUS
+ cdef UnknownExplanation UNSUPPORTED
+ cdef UnknownExplanation OTHER
+ cdef UnknownExplanation UNKNOWN_REASON
diff --git a/src/api/python/cvc5.pxi b/src/api/python/cvc5.pxi
index 258005207..d31fdc126 100644
--- a/src/api/python/cvc5.pxi
+++ b/src/api/python/cvc5.pxi
@@ -18,6 +18,7 @@ from cvc5 cimport DatatypeDecl as c_DatatypeDecl
from cvc5 cimport DatatypeSelector as c_DatatypeSelector
from cvc5 cimport Result as c_Result
from cvc5 cimport RoundingMode as c_RoundingMode
+from cvc5 cimport UnknownExplanation as c_UnknownExplanation
from cvc5 cimport Op as c_Op
from cvc5 cimport Solver as c_Solver
from cvc5 cimport Grammar as c_Grammar
@@ -25,6 +26,10 @@ from cvc5 cimport Sort as c_Sort
from cvc5 cimport ROUND_NEAREST_TIES_TO_EVEN, ROUND_TOWARD_POSITIVE
from cvc5 cimport ROUND_TOWARD_NEGATIVE, ROUND_TOWARD_ZERO
from cvc5 cimport ROUND_NEAREST_TIES_TO_AWAY
+from cvc5 cimport REQUIRES_FULL_CHECK, INCOMPLETE, TIMEOUT
+from cvc5 cimport RESOURCEOUT, MEMOUT, INTERRUPTED
+from cvc5 cimport NO_STATUS, UNSUPPORTED, UNKNOWN_REASON
+from cvc5 cimport OTHER
from cvc5 cimport Term as c_Term
from cvc5 cimport hash as c_hash
from cvc5 cimport wstring as c_wstring
@@ -340,10 +345,13 @@ cdef class Op:
def isNull(self):
return self.cop.isNull()
+ def getNumIndices(self):
+ return self.cop.getNumIndices()
+
def getIndices(self):
indices = None
try:
- indices = self.cop.getIndices[string]()
+ indices = self.cop.getIndices[string]().decode()
except:
pass
@@ -418,7 +426,7 @@ cdef class Result:
return self.cr != other.cr
def getUnknownExplanation(self):
- return self.cr.getUnknownExplanation().decode()
+ return UnknownExplanation(<int> self.cr.getUnknownExplanation())
def __str__(self):
return self.cr.toString().decode()
@@ -451,6 +459,30 @@ cdef class RoundingMode:
return self.name
+cdef class UnknownExplanation:
+ cdef c_UnknownExplanation cue
+ cdef str name
+ def __cinit__(self, int ue):
+ # crm always assigned externally
+ self.cue = <c_UnknownExplanation> ue
+ self.name = __unknown_explanations[ue]
+
+ def __eq__(self, UnknownExplanation other):
+ return (<int> self.cue) == (<int> other.cue)
+
+ def __ne__(self, UnknownExplanation other):
+ return not self.__eq__(other)
+
+ def __hash__(self):
+ return hash((<int> self.crm, self.name))
+
+ def __str__(self):
+ return self.name
+
+ def __repr__(self):
+ return self.name
+
+
cdef class Solver:
cdef c_Solver* csolver
@@ -460,9 +492,6 @@ cdef class Solver:
def __dealloc__(self):
del self.csolver
- def supportsFloatingPoint(self):
- return self.csolver.supportsFloatingPoint()
-
def getBooleanSort(self):
cdef Sort sort = Sort(self)
sort.csort = self.csolver.getBooleanSort()
@@ -473,6 +502,11 @@ cdef class Solver:
sort.csort = self.csolver.getIntegerSort()
return sort
+ def getNullSort(self):
+ cdef Sort sort = Sort(self)
+ sort.csort = self.csolver.getNullSort()
+ return sort
+
def getRealSort(self):
cdef Sort sort = Sort(self)
sort.csort = self.csolver.getRealSort()
@@ -675,8 +709,8 @@ cdef class Solver:
result.cterm = self.csolver.mkTuple(csorts, cterms)
return result
-
- def mkOp(self, kind k, arg0=None, arg1 = None):
+ @expand_list_arg(num_req_args=0)
+ def mkOp(self, kind k, *args):
'''
Supports the following uses:
Op mkOp(Kind kind)
@@ -686,28 +720,30 @@ cdef class Solver:
Op mkOp(Kind kind, uint32_t arg0, uint32_t arg1)
'''
cdef Op op = Op(self)
+ cdef vector[int] v
- if arg0 is None:
+ if len(args) == 0:
op.cop = self.csolver.mkOp(k.k)
- elif arg1 is None:
- if isinstance(arg0, kind):
- op.cop = self.csolver.mkOp(k.k, (<kind?> arg0).k)
- elif isinstance(arg0, str):
+ elif len(args) == 1:
+ if isinstance(args[0], str):
op.cop = self.csolver.mkOp(k.k,
<const string &>
- arg0.encode())
- elif isinstance(arg0, int):
- op.cop = self.csolver.mkOp(k.k, <int?> arg0)
+ args[0].encode())
+ elif isinstance(args[0], int):
+ op.cop = self.csolver.mkOp(k.k, <int?> args[0])
+ elif isinstance(args[0], list):
+ for a in args[0]:
+ v.push_back((<int?> a))
+ op.cop = self.csolver.mkOp(k.k, <const vector[uint32_t]&> v)
else:
raise ValueError("Unsupported signature"
- " mkOp: {}".format(" X ".join([str(k), str(arg0)])))
- else:
- if isinstance(arg0, int) and isinstance(arg1, int):
- op.cop = self.csolver.mkOp(k.k, <int> arg0,
- <int> arg1)
+ " mkOp: {}".format(" X ".join([str(k), str(args[0])])))
+ elif len(args) == 2:
+ if isinstance(args[0], int) and isinstance(args[1], int):
+ op.cop = self.csolver.mkOp(k.k, <int> args[0], <int> args[1])
else:
raise ValueError("Unsupported signature"
- " mkOp: {}".format(" X ".join([k, arg0, arg1])))
+ " mkOp: {}".format(" X ".join([k, args[0], args[1]])))
return op
def mkTrue(self):
@@ -781,17 +817,24 @@ cdef class Solver:
term.cterm = self.csolver.mkEmptySet(s.csort)
return term
+ def mkEmptyBag(self, Sort s):
+ cdef Term term = Term(self)
+ term.cterm = self.csolver.mkEmptyBag(s.csort)
+ return term
def mkSepNil(self, Sort sort):
cdef Term term = Term(self)
term.cterm = self.csolver.mkSepNil(sort.csort)
return term
- def mkString(self, str s):
+ def mkString(self, str s, useEscSequences = None):
cdef Term term = Term(self)
cdef Py_ssize_t size
cdef wchar_t* tmp = PyUnicode_AsWideCharString(s, &size)
- term.cterm = self.csolver.mkString(c_wstring(tmp, size))
+ if isinstance(useEscSequences, bool):
+ term.cterm = self.csolver.mkString(s.encode(), <bint> useEscSequences)
+ else:
+ term.cterm = self.csolver.mkString(c_wstring(tmp, size))
PyMem_Free(tmp)
return term
@@ -1867,3 +1910,30 @@ for rm_int, name in __rounding_modes.items():
del r
del rm_int
del name
+
+
+# Generate unknown explanations
+cdef __unknown_explanations = {
+ <int> REQUIRES_FULL_CHECK: "RequiresFullCheck",
+ <int> INCOMPLETE: "Incomplete",
+ <int> TIMEOUT: "Timeout",
+ <int> RESOURCEOUT: "Resourceout",
+ <int> MEMOUT: "Memout",
+ <int> INTERRUPTED: "Interrupted",
+ <int> NO_STATUS: "NoStatus",
+ <int> UNSUPPORTED: "Unsupported",
+ <int> OTHER: "Other",
+ <int> UNKNOWN_REASON: "UnknownReason"
+}
+
+for ue_int, name in __unknown_explanations.items():
+ u = UnknownExplanation(ue_int)
+
+ if name in dir(mod_ref):
+ raise RuntimeError("Redefinition of Python UnknownExplanation %s."%name)
+
+ setattr(mod_ref, name, u)
+
+del u
+del ue_int
+del name
diff --git a/src/base/configuration.cpp b/src/base/configuration.cpp
index 61951841b..c6b004574 100644
--- a/src/base/configuration.cpp
+++ b/src/base/configuration.cpp
@@ -120,25 +120,23 @@ std::string Configuration::copyright() {
<< "See licenses/antlr3-LICENSE for copyright and licensing information."
<< "\n\n";
- if (Configuration::isBuiltWithAbc() || Configuration::isBuiltWithCadical()
+ ss << "This version of cvc5 is linked against the following non-(L)GPL'ed\n"
+ << "third party libraries.\n\n";
+
+ ss << " CaDiCaL - Simplified Satisfiability Solver\n"
+ << " See https://github.com/arminbiere/cadical for copyright "
+ << "information.\n\n";
+
+ if (Configuration::isBuiltWithAbc()
|| Configuration::isBuiltWithCryptominisat()
|| Configuration::isBuiltWithKissat()
- || Configuration::isBuiltWithSymFPU()
|| Configuration::isBuiltWithEditline())
{
- ss << "This version of cvc5 is linked against the following non-(L)GPL'ed\n"
- << "third party libraries.\n\n";
if (Configuration::isBuiltWithAbc()) {
ss << " ABC - A System for Sequential Synthesis and Verification\n"
<< " See http://bitbucket.org/alanmi/abc for copyright and\n"
<< " licensing information.\n\n";
}
- if (Configuration::isBuiltWithCadical())
- {
- ss << " CaDiCaL - Simplified Satisfiability Solver\n"
- << " See https://github.com/arminbiere/cadical for copyright "
- << "information.\n\n";
- }
if (Configuration::isBuiltWithCryptominisat())
{
ss << " CryptoMiniSat - An Advanced SAT Solver\n"
@@ -151,12 +149,6 @@ std::string Configuration::copyright() {
<< " See https://fmv.jku.at/kissat for copyright "
<< "information.\n\n";
}
- if (Configuration::isBuiltWithSymFPU())
- {
- ss << " SymFPU - The Symbolic Floating Point Unit\n"
- << " See https://github.com/martin-cs/symfpu/tree/cvc5 for copyright "
- << "information.\n\n";
- }
if (Configuration::isBuiltWithEditline())
{
ss << " Editline Library\n"
@@ -165,6 +157,10 @@ std::string Configuration::copyright() {
}
}
+ ss << " SymFPU - The Symbolic Floating Point Unit\n"
+ << " See https://github.com/martin-cs/symfpu/tree/cvc5 for copyright "
+ << "information.\n\n";
+
if (Configuration::isBuiltWithGmp() || Configuration::isBuiltWithPoly())
{
ss << "This version of cvc5 is linked against the following third party\n"
@@ -244,8 +240,6 @@ bool Configuration::isBuiltWithAbc() {
return IS_ABC_BUILD;
}
-bool Configuration::isBuiltWithCadical() { return IS_CADICAL_BUILD; }
-
bool Configuration::isBuiltWithCryptominisat() {
return IS_CRYPTOMINISAT_BUILD;
}
@@ -259,8 +253,6 @@ bool Configuration::isBuiltWithPoly()
return IS_POLY_BUILD;
}
-bool Configuration::isBuiltWithSymFPU() { return IS_SYMFPU_BUILD; }
-
unsigned Configuration::getNumDebugTags() {
#if defined(CVC5_DEBUG) && defined(CVC5_TRACING)
/* -1 because a NULL pointer is inserted as the last value */
diff --git a/src/base/configuration.h b/src/base/configuration.h
index 78e86f920..71c79c22e 100644
--- a/src/base/configuration.h
+++ b/src/base/configuration.h
@@ -103,8 +103,6 @@ public:
static bool isBuiltWithAbc();
- static bool isBuiltWithCadical();
-
static bool isBuiltWithCryptominisat();
static bool isBuiltWithKissat();
@@ -113,8 +111,6 @@ public:
static bool isBuiltWithPoly();
- static bool isBuiltWithSymFPU();
-
/* Return the number of debug tags */
static unsigned getNumDebugTags();
/* Return a sorted array of the debug tags name */
diff --git a/src/base/configuration_private.h b/src/base/configuration_private.h
index 3027b23bc..b348da380 100644
--- a/src/base/configuration_private.h
+++ b/src/base/configuration_private.h
@@ -96,12 +96,6 @@ namespace cvc5 {
# define IS_ABC_BUILD false
#endif /* CVC5_USE_ABC */
-#if CVC5_USE_CADICAL
-#define IS_CADICAL_BUILD true
-#else /* CVC5_USE_CADICAL */
-#define IS_CADICAL_BUILD false
-#endif /* CVC5_USE_CADICAL */
-
#if CVC5_USE_CRYPTOMINISAT
# define IS_CRYPTOMINISAT_BUILD true
#else /* CVC5_USE_CRYPTOMINISAT */
@@ -126,12 +120,6 @@ namespace cvc5 {
#define IS_EDITLINE_BUILD false
#endif /* HAVE_LIBEDITLINE */
-#ifdef CVC5_USE_SYMFPU
-#define IS_SYMFPU_BUILD true
-#else /* HAVE_SYMFPU_HEADERS */
-#define IS_SYMFPU_BUILD false
-#endif /* HAVE_SYMFPU_HEADERS */
-
#if CVC5_GPL_DEPS
# define IS_GPL_BUILD true
#else /* CVC5_GPL_DEPS */
diff --git a/src/expr/attribute.h b/src/expr/attribute.h
index b58cd45a9..e41b63191 100644
--- a/src/expr/attribute.h
+++ b/src/expr/attribute.h
@@ -38,14 +38,13 @@ namespace attr {
/**
* Attributes are roughly speaking [almost] global hash tables from Nodes
* (TNodes) to data. Attributes can be thought of as additional fields used to
- * extend NodeValues. Attributes are mutable and come in both sat
- * context-dependent and non-context dependent varieties. Attributes live only
- * as long as the node itself does. If a Node is garbage-collected, Attributes
- * associated with it will automatically be garbage collected. (Being in the
- * domain of an Attribute does not increase a Node's reference count.) To
- * achieve this special relationship with Nodes, Attributes are mapped by hash
- * tables (AttrHash<> and CDAttrHash<>) that live in the AttributeManager. The
- * AttributeManager is owned by the NodeManager.
+ * extend NodeValues. Attributes are mutable. Attributes live only as long as
+ * the node itself does. If a Node is garbage-collected, Attributes associated
+ * with it will automatically be garbage collected. (Being in the domain of an
+ * Attribute does not increase a Node's reference count.) To achieve this
+ * special relationship with Nodes, Attributes are mapped by hash tables
+ * (AttrHash<>) that live in the AttributeManager. The AttributeManager is
+ * owned by the NodeManager.
*
* Example:
*
@@ -67,11 +66,11 @@ namespace attr {
* ```
*
* To separate Attributes of the same type in the same table, each of the
- * structures `struct InstLevelAttributeId {};` is given a different unique value
- * at load time. An example is the empty struct InstLevelAttributeId. These
- * should be unique for each Attribute. Then via some template messiness when
- * InstLevelAttribute() is passed as the argument to getAttribute(...) the load
- * time id is instantiated.
+ * structures `struct InstLevelAttributeId {};` is given a different unique
+ * value at load time. An example is the empty struct InstLevelAttributeId.
+ * These should be unique for each Attribute. Then via some template messiness
+ * when InstLevelAttribute() is passed as the argument to getAttribute(...) the
+ * load time id is instantiated.
*/
// ATTRIBUTE MANAGER ===========================================================
@@ -97,7 +96,7 @@ class AttributeManager {
* getTable<> is a helper template that gets the right table from an
* AttributeManager given its type.
*/
- template <class T, bool context_dep, class Enable>
+ template <class T, class Enable>
friend struct getTable;
bool d_inGarbageCollection;
@@ -232,12 +231,13 @@ namespace attr {
* `std::enable_if` in the template parameter and the condition is false), the
* instantiation is ignored due to the SFINAE rule.
*/
-template <class T, bool context_dep, class Enable = void>
+template <class T, class Enable = void>
struct getTable;
/** Access the "d_bools" member of AttributeManager. */
template <>
-struct getTable<bool, false> {
+struct getTable<bool>
+{
static const AttrTableId id = AttrTableBool;
typedef AttrHash<bool> table_type;
static inline table_type& get(AttributeManager& am) {
@@ -251,7 +251,6 @@ struct getTable<bool, false> {
/** Access the "d_ints" member of AttributeManager. */
template <class T>
struct getTable<T,
- false,
// Use this specialization only for unsigned integers
typename std::enable_if<std::is_unsigned<T>::value>::type>
{
@@ -267,7 +266,8 @@ struct getTable<T,
/** Access the "d_tnodes" member of AttributeManager. */
template <>
-struct getTable<TNode, false> {
+struct getTable<TNode>
+{
static const AttrTableId id = AttrTableTNode;
typedef AttrHash<TNode> table_type;
static inline table_type& get(AttributeManager& am) {
@@ -280,7 +280,8 @@ struct getTable<TNode, false> {
/** Access the "d_nodes" member of AttributeManager. */
template <>
-struct getTable<Node, false> {
+struct getTable<Node>
+{
static const AttrTableId id = AttrTableNode;
typedef AttrHash<Node> table_type;
static inline table_type& get(AttributeManager& am) {
@@ -293,7 +294,8 @@ struct getTable<Node, false> {
/** Access the "d_types" member of AttributeManager. */
template <>
-struct getTable<TypeNode, false> {
+struct getTable<TypeNode>
+{
static const AttrTableId id = AttrTableTypeNode;
typedef AttrHash<TypeNode> table_type;
static inline table_type& get(AttributeManager& am) {
@@ -306,7 +308,8 @@ struct getTable<TypeNode, false> {
/** Access the "d_strings" member of AttributeManager. */
template <>
-struct getTable<std::string, false> {
+struct getTable<std::string>
+{
static const AttrTableId id = AttrTableString;
typedef AttrHash<std::string> table_type;
static inline table_type& get(AttributeManager& am) {
@@ -329,11 +332,9 @@ typename AttrKind::value_type
AttributeManager::getAttribute(NodeValue* nv, const AttrKind&) const {
typedef typename AttrKind::value_type value_type;
typedef KindValueToTableValueMapping<value_type> mapping;
- typedef typename getTable<value_type, AttrKind::context_dependent>::
- table_type table_type;
+ typedef typename getTable<value_type>::table_type table_type;
- const table_type& ah =
- getTable<value_type, AttrKind::context_dependent>::get(*this);
+ const table_type& ah = getTable<value_type>::get(*this);
typename table_type::const_iterator i =
ah.find(std::make_pair(AttrKind::getId(), nv));
@@ -371,12 +372,9 @@ struct HasAttribute<true, AttrKind> {
typename AttrKind::value_type& ret) {
typedef typename AttrKind::value_type value_type;
typedef KindValueToTableValueMapping<value_type> mapping;
- typedef typename getTable<value_type,
- AttrKind::context_dependent>::table_type
- table_type;
+ typedef typename getTable<value_type>::table_type table_type;
- const table_type& ah =
- getTable<value_type, AttrKind::context_dependent>::get(*am);
+ const table_type& ah = getTable<value_type>::get(*am);
typename table_type::const_iterator i =
ah.find(std::make_pair(AttrKind::getId(), nv));
@@ -400,11 +398,9 @@ struct HasAttribute<false, AttrKind> {
NodeValue* nv) {
typedef typename AttrKind::value_type value_type;
//typedef KindValueToTableValueMapping<value_type> mapping;
- typedef typename getTable<value_type, AttrKind::context_dependent>::
- table_type table_type;
+ typedef typename getTable<value_type>::table_type table_type;
- const table_type& ah =
- getTable<value_type, AttrKind::context_dependent>::get(*am);
+ const table_type& ah = getTable<value_type>::get(*am);
typename table_type::const_iterator i =
ah.find(std::make_pair(AttrKind::getId(), nv));
@@ -420,11 +416,9 @@ struct HasAttribute<false, AttrKind> {
typename AttrKind::value_type& ret) {
typedef typename AttrKind::value_type value_type;
typedef KindValueToTableValueMapping<value_type> mapping;
- typedef typename getTable<value_type, AttrKind::context_dependent>::
- table_type table_type;
+ typedef typename getTable<value_type>::table_type table_type;
- const table_type& ah =
- getTable<value_type, AttrKind::context_dependent>::get(*am);
+ const table_type& ah = getTable<value_type>::get(*am);
typename table_type::const_iterator i =
ah.find(std::make_pair(AttrKind::getId(), nv));
@@ -460,11 +454,9 @@ AttributeManager::setAttribute(NodeValue* nv,
const typename AttrKind::value_type& value) {
typedef typename AttrKind::value_type value_type;
typedef KindValueToTableValueMapping<value_type> mapping;
- typedef typename getTable<value_type, AttrKind::context_dependent>::
- table_type table_type;
+ typedef typename getTable<value_type>::table_type table_type;
- table_type& ah =
- getTable<value_type, AttrKind::context_dependent>::get(*this);
+ table_type& ah = getTable<value_type>::get(*this);
ah[std::make_pair(AttrKind::getId(), nv)] = mapping::convert(value);
}
@@ -473,7 +465,7 @@ template <class T>
inline void AttributeManager::deleteFromTable(AttrHash<T>& table,
NodeValue* nv) {
// This cannot use nv as anything other than a pointer!
- const uint64_t last = attr::LastAttributeId<T, false>::getId();
+ const uint64_t last = attr::LastAttributeId<T>::getId();
for (uint64_t id = 0; id < last; ++id)
{
table.erase(std::make_pair(id, nv));
@@ -493,8 +485,7 @@ inline void AttributeManager::deleteAllFromTable(AttrHash<T>& table) {
template <class AttrKind>
AttributeUniqueId AttributeManager::getAttributeId(const AttrKind& attr){
typedef typename AttrKind::value_type value_type;
- AttrTableId tableId = getTable<value_type,
- AttrKind::context_dependent>::id;
+ AttrTableId tableId = getTable<value_type>::id;
return AttributeUniqueId(tableId, attr.getId());
}
diff --git a/src/expr/attribute_internals.h b/src/expr/attribute_internals.h
index c82e62836..2ae216d3c 100644
--- a/src/expr/attribute_internals.h
+++ b/src/expr/attribute_internals.h
@@ -372,8 +372,9 @@ namespace attr {
* This is the last-attribute-assigner. IDs are not globally
* unique; rather, they are unique for each table_value_type.
*/
-template <class T, bool context_dep>
-struct LastAttributeId {
+template <class T>
+struct LastAttributeId
+{
public:
static uint64_t getNextId() {
uint64_t* id = raw_id();
@@ -402,11 +403,8 @@ struct LastAttributeId {
* @param T the tag for the attribute kind.
*
* @param value_t the underlying value_type for the attribute kind
- *
- * @param context_dep whether this attribute kind is
- * context-dependent
*/
-template <class T, class value_t, bool context_dep = false>
+template <class T, class value_t>
class Attribute
{
/**
@@ -432,11 +430,6 @@ public:
static const bool has_default_value = false;
/**
- * Expose this setting to the users of this Attribute kind.
- */
- static const bool context_dependent = context_dep;
-
- /**
* Register this attribute kind and check that the ID is a valid ID
* for bool-valued attributes. Fail an assert if not. Otherwise
* return the id.
@@ -444,15 +437,15 @@ public:
static inline uint64_t registerAttribute() {
typedef typename attr::KindValueToTableValueMapping<value_t>::
table_value_type table_value_type;
- return attr::LastAttributeId<table_value_type, context_dep>::getNextId();
+ return attr::LastAttributeId<table_value_type>::getNextId();
}
};/* class Attribute<> */
/**
* An "attribute type" structure for boolean flags (special).
*/
-template <class T, bool context_dep>
-class Attribute<T, bool, context_dep>
+template <class T>
+class Attribute<T, bool>
{
/** IDs for bool-valued attributes are actually bit assignments. */
static const uint64_t s_id;
@@ -480,17 +473,12 @@ public:
static const bool default_value = false;
/**
- * Expose this setting to the users of this Attribute kind.
- */
- static const bool context_dependent = context_dep;
-
- /**
* Register this attribute kind and check that the ID is a valid ID
* for bool-valued attributes. Fail an assert if not. Otherwise
* return the id.
*/
static inline uint64_t registerAttribute() {
- const uint64_t id = attr::LastAttributeId<bool, context_dep>::getNextId();
+ const uint64_t id = attr::LastAttributeId<bool>::getNextId();
AlwaysAssert(id <= 63) << "Too many boolean node attributes registered "
"during initialization !";
return id;
@@ -500,15 +488,14 @@ public:
// ATTRIBUTE IDENTIFIER ASSIGNMENT =============================================
/** Assign unique IDs to attributes at load time. */
-template <class T, class value_t, bool context_dep>
-const uint64_t Attribute<T, value_t, context_dep>::s_id =
- Attribute<T, value_t, context_dep>::registerAttribute();
-
+template <class T, class value_t>
+const uint64_t Attribute<T, value_t>::s_id =
+ Attribute<T, value_t>::registerAttribute();
/** Assign unique IDs to attributes at load time. */
-template <class T, bool context_dep>
-const uint64_t Attribute<T, bool, context_dep>::s_id =
- Attribute<T, bool, context_dep>::registerAttribute();
+template <class T>
+const uint64_t Attribute<T, bool>::s_id =
+ Attribute<T, bool>::registerAttribute();
} // namespace expr
} // namespace cvc5
diff --git a/src/main/command_executor.cpp b/src/main/command_executor.cpp
index 6bdc1abc9..b6ead1b70 100644
--- a/src/main/command_executor.cpp
+++ b/src/main/command_executor.cpp
@@ -26,7 +26,8 @@
#include <vector>
#include "main/main.h"
-#include "options/options_public.h"
+#include "options/base_options.h"
+#include "options/main_options.h"
#include "smt/command.h"
#include "smt/smt_engine.h"
@@ -65,7 +66,7 @@ CommandExecutor::~CommandExecutor()
void CommandExecutor::printStatistics(std::ostream& out) const
{
- if (options::getStatistics(d_options))
+ if (d_options.base.statistics)
{
getSmtEngine()->printStatistics(out);
}
@@ -73,7 +74,7 @@ void CommandExecutor::printStatistics(std::ostream& out) const
void CommandExecutor::printStatisticsSafe(int fd) const
{
- if (options::getStatistics(d_options))
+ if (d_options.base.statistics)
{
getSmtEngine()->printStatisticsSafe(fd);
}
@@ -81,7 +82,7 @@ void CommandExecutor::printStatisticsSafe(int fd) const
bool CommandExecutor::doCommand(Command* cmd)
{
- if (options::getParseOnly(d_options))
+ if (d_options.base.parseOnly)
{
return true;
}
@@ -100,9 +101,9 @@ bool CommandExecutor::doCommand(Command* cmd)
return status;
} else {
- if (options::getVerbosity(d_options) > 2)
+ if (d_options.base.verbosity > 2)
{
- *options::getOut(d_options) << "Invoking: " << *cmd << std::endl;
+ *d_options.base.out << "Invoking: " << *cmd << std::endl;
}
return doCommandSingleton(cmd);
@@ -111,7 +112,7 @@ bool CommandExecutor::doCommand(Command* cmd)
void CommandExecutor::reset()
{
- printStatistics(*options::getErr(d_options));
+ printStatistics(*d_options.base.err);
/* We have to keep options passed via CL on reset. These options are stored
* in CommandExecutor::d_options (populated and created in the driver), and
* CommandExecutor::d_options only contains *these* options since the
@@ -124,10 +125,10 @@ void CommandExecutor::reset()
bool CommandExecutor::doCommandSingleton(Command* cmd)
{
bool status = true;
- if (options::getVerbosity(d_options) >= -1)
+ if (d_options.base.verbosity >= -1)
{
status = solverInvoke(
- d_solver.get(), d_symman.get(), cmd, options::getOut(d_options));
+ d_solver.get(), d_symman.get(), cmd, d_options.base.out);
}
else
{
@@ -150,9 +151,9 @@ bool CommandExecutor::doCommandSingleton(Command* cmd)
d_result = res = q->getResult();
}
- if ((cs != nullptr || q != nullptr) && options::getStatsEveryQuery(d_options))
+ if ((cs != nullptr || q != nullptr) && d_options.base.statisticsEveryQuery)
{
- getSmtEngine()->printStatisticsDiff(*options::getErr(d_options));
+ getSmtEngine()->printStatisticsDiff(*d_options.base.err);
}
bool isResultUnsat = res.isUnsat() || res.isEntailed();
@@ -160,32 +161,32 @@ bool CommandExecutor::doCommandSingleton(Command* cmd)
// dump the model/proof/unsat core if option is set
if (status) {
std::vector<std::unique_ptr<Command> > getterCommands;
- if (options::getDumpModels(d_options)
+ if (d_options.driver.dumpModels
&& (res.isSat()
|| (res.isSatUnknown()
&& res.getUnknownExplanation() == api::Result::INCOMPLETE)))
{
getterCommands.emplace_back(new GetModelCommand());
}
- if (options::getDumpProofs(d_options) && isResultUnsat)
+ if (d_options.driver.dumpProofs && isResultUnsat)
{
getterCommands.emplace_back(new GetProofCommand());
}
- if (options::getDumpInstantiations(d_options)
+ if (d_options.driver.dumpInstantiations
&& GetInstantiationsCommand::isEnabled(d_solver.get(), res))
{
getterCommands.emplace_back(new GetInstantiationsCommand());
}
- if (options::getDumpUnsatCores(d_options) && isResultUnsat)
+ if ((d_options.driver.dumpUnsatCores || d_options.driver.dumpUnsatCoresFull) && isResultUnsat)
{
getterCommands.emplace_back(new GetUnsatCoreCommand());
}
if (!getterCommands.empty()) {
// set no time limit during dumping if applicable
- if (options::getForceNoLimitCpuWhileDump(d_options))
+ if (d_options.driver.forceNoLimitCpuWhileDump)
{
setNoLimitCPU();
}
@@ -225,17 +226,17 @@ bool solverInvoke(api::Solver* solver,
}
void CommandExecutor::flushOutputStreams() {
- printStatistics(*(options::getErr(d_options)));
+ printStatistics(*d_options.base.err);
// make sure out and err streams are flushed too
- if (options::getOut(d_options) != nullptr)
+ if (d_options.base.out != nullptr)
{
- *options::getOut(d_options) << std::flush;
+ *d_options.base.out << std::flush;
}
- if (options::getErr(d_options) != nullptr)
+ if (d_options.base.err != nullptr)
{
- *options::getErr(d_options) << std::flush;
+ *d_options.base.err << std::flush;
}
}
diff --git a/src/main/driver_unified.cpp b/src/main/driver_unified.cpp
index 75c7b2a01..2bc5c59f3 100644
--- a/src/main/driver_unified.cpp
+++ b/src/main/driver_unified.cpp
@@ -33,8 +33,9 @@
#include "main/main.h"
#include "main/signal_handlers.h"
#include "main/time_limit.h"
+#include "options/base_options.h"
#include "options/options.h"
-#include "options/options_public.h"
+#include "options/parser_options.h"
#include "options/main_options.h"
#include "options/set_language.h"
#include "parser/parser.h"
@@ -88,9 +89,9 @@ void printUsage(Options& opts, bool full) {
<< endl
<< "cvc5 options:" << endl;
if(full) {
- Options::printUsage(ss.str(), *(options::getOut(opts)));
+ Options::printUsage(ss.str(), *opts.base.out);
} else {
- Options::printShortUsage(ss.str(), *(options::getOut(opts)));
+ Options::printShortUsage(ss.str(), *opts.base.out);
}
}
@@ -116,14 +117,14 @@ int runCvc5(int argc, char* argv[], Options& opts)
printUsage(opts, true);
exit(1);
}
- else if (options::getLanguageHelp(opts))
+ else if (opts.base.languageHelp)
{
- Options::printLanguageHelp(*(options::getOut(opts)));
+ Options::printLanguageHelp(*opts.base.out);
exit(1);
}
else if (opts.driver.version)
{
- *(options::getOut(opts)) << Configuration::about().c_str() << flush;
+ *opts.base.out << Configuration::about().c_str() << flush;
exit(0);
}
@@ -131,7 +132,7 @@ int runCvc5(int argc, char* argv[], Options& opts)
// If in competition mode, set output stream option to flush immediately
#ifdef CVC5_COMPETITION_MODE
- *(options::getOut(opts)) << unitbuf;
+ *opts.base.out << unitbuf;
#endif /* CVC5_COMPETITION_MODE */
// We only accept one input file
@@ -143,7 +144,7 @@ int runCvc5(int argc, char* argv[], Options& opts)
const bool inputFromStdin = filenames.empty() || filenames[0] == "-";
// if we're reading from stdin on a TTY, default to interactive mode
- if (!options::wasSetByUserInteractive(opts))
+ if (!opts.driver.interactiveWasSetByUser)
{
opts.driver.interactive = inputFromStdin && isatty(fileno(stdin));
}
@@ -157,33 +158,32 @@ int runCvc5(int argc, char* argv[], Options& opts)
}
const char* filename = filenameStr.c_str();
- if (options::getInputLanguage(opts) == language::input::LANG_AUTO)
+ if (opts.base.inputLanguage == language::input::LANG_AUTO)
{
if( inputFromStdin ) {
// We can't do any fancy detection on stdin
- options::setInputLanguage(language::input::LANG_CVC, opts);
+ opts.base.inputLanguage = language::input::LANG_CVC;
} else {
size_t len = filenameStr.size();
if(len >= 5 && !strcmp(".smt2", filename + len - 5)) {
- options::setInputLanguage(language::input::LANG_SMTLIB_V2_6, opts);
+ opts.base.inputLanguage = language::input::LANG_SMTLIB_V2_6;
} else if((len >= 2 && !strcmp(".p", filename + len - 2))
|| (len >= 5 && !strcmp(".tptp", filename + len - 5))) {
- options::setInputLanguage(language::input::LANG_TPTP, opts);
+ opts.base.inputLanguage = language::input::LANG_TPTP;
} else if(( len >= 4 && !strcmp(".cvc", filename + len - 4) )
|| ( len >= 5 && !strcmp(".cvc4", filename + len - 5) )) {
- options::setInputLanguage(language::input::LANG_CVC, opts);
+ opts.base.inputLanguage = language::input::LANG_CVC;
} else if((len >= 3 && !strcmp(".sy", filename + len - 3))
|| (len >= 3 && !strcmp(".sl", filename + len - 3))) {
// version 2 sygus is the default
- options::setInputLanguage(language::input::LANG_SYGUS_V2, opts);
+ opts.base.inputLanguage = language::input::LANG_SYGUS_V2;
}
}
}
- if (options::getOutputLanguage(opts) == language::output::LANG_AUTO)
+ if (opts.base.outputLanguage == language::output::LANG_AUTO)
{
- options::setOutputLanguage(
- language::toOutputLanguage(options::getInputLanguage(opts)), opts);
+ opts.base.outputLanguage = language::toOutputLanguage(opts.base.inputLanguage);
}
// Determine which messages to show based on smtcomp_mode and verbosity
@@ -197,8 +197,8 @@ int runCvc5(int argc, char* argv[], Options& opts)
}
// important even for muzzled builds (to get result output right)
- (*(options::getOut(opts)))
- << language::SetLanguage(options::getOutputLanguage(opts));
+ (*opts.base.out)
+ << language::SetLanguage(opts.base.outputLanguage);
// Create the command executor to execute the parsed commands
pExecutor = std::make_unique<CommandExecutor>(opts);
@@ -213,7 +213,7 @@ int runCvc5(int argc, char* argv[], Options& opts)
bool status = true;
if (opts.driver.interactive && inputFromStdin)
{
- if (!options::wasSetByUserIncrementalSolving(opts))
+ if (!opts.base.incrementalSolvingWasSetByUser)
{
cmd.reset(new SetOptionCommand("incremental", "true"));
cmd->setMuted(true);
@@ -240,7 +240,7 @@ int runCvc5(int argc, char* argv[], Options& opts)
try {
cmd.reset(shell.readCommand());
} catch(UnsafeInterruptException& e) {
- (*options::getOut(opts)) << CommandInterrupted();
+ *opts.base.out << CommandInterrupted();
break;
}
if (cmd == nullptr)
@@ -253,7 +253,7 @@ int runCvc5(int argc, char* argv[], Options& opts)
}
else
{
- if (!options::wasSetByUserIncrementalSolving(opts))
+ if (!opts.base.incrementalSolvingWasSetByUser)
{
cmd.reset(new SetOptionCommand("incremental", "false"));
cmd->setMuted(true);
@@ -266,20 +266,20 @@ int runCvc5(int argc, char* argv[], Options& opts)
std::unique_ptr<Parser> parser(parserBuilder.build());
if( inputFromStdin ) {
parser->setInput(Input::newStreamInput(
- options::getInputLanguage(opts), cin, filename));
+ opts.base.inputLanguage, cin, filename));
}
else
{
- parser->setInput(Input::newFileInput(options::getInputLanguage(opts),
+ parser->setInput(Input::newFileInput(opts.base.inputLanguage,
filename,
- options::getMemoryMap(opts)));
+ opts.parser.memoryMap));
}
bool interrupted = false;
while (status)
{
if (interrupted) {
- (*options::getOut(opts)) << CommandInterrupted();
+ *opts.base.out << CommandInterrupted();
pExecutor->reset();
break;
}
@@ -313,9 +313,9 @@ int runCvc5(int argc, char* argv[], Options& opts)
}
#ifdef CVC5_COMPETITION_MODE
- if (cvc5::options::getOut(opts) != nullptr)
+ if (opts.base.out != nullptr)
{
- *cvc5::options::getOut(opts) << std::flush;
+ *opts.base.out << std::flush;
}
// exit, don't return (don't want destructors to run)
// _exit() from unistd.h doesn't run global destructors
@@ -327,7 +327,7 @@ int runCvc5(int argc, char* argv[], Options& opts)
pExecutor->flushOutputStreams();
#ifdef CVC5_DEBUG
- if (opts.driver.earlyExit && options::wasSetByUserEarlyExit(opts))
+ if (opts.driver.earlyExit && opts.driver.earlyExitWasSetByUser)
{
_exit(returnValue);
}
diff --git a/src/main/interactive_shell.cpp b/src/main/interactive_shell.cpp
index 048c101f0..964b88ea0 100644
--- a/src/main/interactive_shell.cpp
+++ b/src/main/interactive_shell.cpp
@@ -40,10 +40,11 @@
#include "base/check.h"
#include "base/output.h"
#include "expr/symbol_manager.h"
+#include "options/base_options.h"
#include "options/language.h"
#include "options/main_options.h"
#include "options/options.h"
-#include "options/options_public.h"
+#include "options/parser_options.h"
#include "parser/input.h"
#include "parser/parser.h"
#include "parser/parser_builder.h"
@@ -89,16 +90,16 @@ static set<string> s_declarations;
InteractiveShell::InteractiveShell(api::Solver* solver, SymbolManager* sm)
: d_options(solver->getOptions()),
- d_in(*options::getIn(d_options)),
- d_out(*options::getOut(d_options)),
+ d_in(*d_options.base.in),
+ d_out(*d_options.base.out),
d_quit(false)
{
ParserBuilder parserBuilder(solver, sm, d_options);
/* Create parser with bogus input. */
d_parser = parserBuilder.build();
- if (options::wasSetByUserForceLogicString(d_options))
+ if (d_options.parser.forceLogicStringWasSetByUser)
{
- LogicInfo tmp(options::getForceLogicString(d_options));
+ LogicInfo tmp(d_options.parser.forceLogicString);
d_parser->forceLogic(tmp.getLogicString());
}
@@ -113,7 +114,7 @@ InteractiveShell::InteractiveShell(api::Solver* solver, SymbolManager* sm)
::using_history();
OutputLanguage lang =
- toOutputLanguage(options::getInputLanguage(d_options));
+ toOutputLanguage(d_options.base.inputLanguage);
switch(lang) {
case output::LANG_CVC:
d_historyFilename = string(getenv("HOME")) + "/.cvc5_history";
@@ -314,7 +315,7 @@ restart:
}
d_parser->setInput(Input::newStringInput(
- options::getInputLanguage(d_options), input, INPUT_FILENAME));
+ d_options.base.inputLanguage, input, INPUT_FILENAME));
/* There may be more than one command in the input. Build up a
sequence. */
@@ -365,7 +366,7 @@ restart:
}
catch (ParserException& pe)
{
- if (language::isOutputLang_smt2(options::getOutputLanguage(d_options)))
+ if (language::isOutputLang_smt2(d_options.base.outputLanguage))
{
d_out << "(error \"" << pe << "\")" << endl;
}
diff --git a/src/main/main.cpp b/src/main/main.cpp
index 2b25e6c93..a00e29b04 100644
--- a/src/main/main.cpp
+++ b/src/main/main.cpp
@@ -26,10 +26,10 @@
#include "base/output.h"
#include "main/command_executor.h"
#include "main/interactive_shell.h"
+#include "options/base_options.h"
#include "options/language.h"
#include "options/option_exception.h"
#include "options/options.h"
-#include "options/options_public.h"
#include "parser/parser.h"
#include "parser/parser_builder.h"
#include "parser/parser_exception.h"
@@ -53,25 +53,25 @@ int main(int argc, char* argv[]) {
return runCvc5(argc, argv, opts);
} catch(OptionException& e) {
#ifdef CVC5_COMPETITION_MODE
- *options::getOut(opts) << "unknown" << endl;
+ *opts.base.out << "unknown" << endl;
#endif
cerr << "(error \"" << e << "\")" << endl
<< endl
<< "Please use --help to get help on command-line options." << endl;
} catch(Exception& e) {
#ifdef CVC5_COMPETITION_MODE
- *options::getOut(opts) << "unknown" << endl;
+ *opts.base.out << "unknown" << endl;
#endif
- if (language::isOutputLang_smt2(options::getOutputLanguage(opts)))
+ if (language::isOutputLang_smt2(opts.base.outputLanguage))
{
- *options::getOut(opts) << "(error \"" << e << "\")" << endl;
+ *opts.base.out << "(error \"" << e << "\")" << endl;
} else {
- *options::getErr(opts) << "(error \"" << e << "\")" << endl;
+ *opts.base.err << "(error \"" << e << "\")" << endl;
}
- if (options::getStatistics(opts) && pExecutor != nullptr)
+ if (opts.base.statistics && pExecutor != nullptr)
{
totalTime.reset();
- pExecutor->printStatistics(*options::getErr(opts));
+ pExecutor->printStatistics(*opts.base.err);
}
}
exit(1);
diff --git a/src/main/time_limit.cpp b/src/main/time_limit.cpp
index c0fc6846a..28a0087bb 100644
--- a/src/main/time_limit.cpp
+++ b/src/main/time_limit.cpp
@@ -56,7 +56,7 @@
#include <cstring>
#include "base/exception.h"
-#include "options/options_public.h"
+#include "options/base_options.h"
#include "signal_handlers.h"
namespace cvc5 {
@@ -80,7 +80,7 @@ TimeLimit::~TimeLimit()
TimeLimit install_time_limit(const Options& opts)
{
- unsigned long ms = options::getCumulativeTimeLimit(opts);
+ uint64_t ms = opts.base.cumulativeMillisecondLimit;
// Skip if no time limit shall be set.
if (ms == 0) {
return TimeLimit();
diff --git a/src/omt/bitvector_optimizer.cpp b/src/omt/bitvector_optimizer.cpp
index bce6c9b6d..01cb6da42 100644
--- a/src/omt/bitvector_optimizer.cpp
+++ b/src/omt/bitvector_optimizer.cpp
@@ -53,15 +53,13 @@ OptimizationResult OMTOptimizerBitVector::minimize(SmtEngine* optChecker,
Result intermediateSatResult = optChecker->checkSat();
// Model-value of objective (used in optimization loop)
Node value;
- if (intermediateSatResult.isUnknown())
+ if (intermediateSatResult.isUnknown()
+ || intermediateSatResult.isSat() == Result::UNSAT)
{
- return OptimizationResult(OptimizationResult::UNKNOWN, value);
+ return OptimizationResult(intermediateSatResult, value);
}
- if (intermediateSatResult.isSat() == Result::UNSAT)
- {
- return OptimizationResult(OptimizationResult::UNSAT, value);
- }
-
+ // the last result that is SAT
+ Result lastSatResult = intermediateSatResult;
// value equals to upperBound
value = optChecker->getValue(target);
@@ -104,39 +102,35 @@ OptimizationResult OMTOptimizerBitVector::minimize(SmtEngine* optChecker,
nm->mkNode(LTOperator, target, nm->mkConst(pivot))));
}
intermediateSatResult = optChecker->checkSat();
- if (intermediateSatResult.isUnknown() || intermediateSatResult.isNull())
- {
- optChecker->pop();
- return OptimizationResult(OptimizationResult::UNKNOWN, value);
- }
- if (intermediateSatResult.isSat() == Result::SAT)
+ switch (intermediateSatResult.isSat())
{
- value = optChecker->getValue(target);
- upperBound = value.getConst<BitVector>();
- }
- else if (intermediateSatResult.isSat() == Result::UNSAT)
- {
- if (lowerBound == pivot)
- {
- // lowerBound == pivot ==> upperbound = lowerbound + 1
- // and lowerbound <= target < upperbound is UNSAT
- // return the upperbound
+ case Result::SAT_UNKNOWN:
optChecker->pop();
- return OptimizationResult(OptimizationResult::OPTIMAL, value);
- }
- else
- {
- lowerBound = pivot;
- }
- }
- else
- {
- optChecker->pop();
- return OptimizationResult(OptimizationResult::UNKNOWN, value);
+ return OptimizationResult(intermediateSatResult, value);
+ case Result::SAT:
+ lastSatResult = intermediateSatResult;
+ value = optChecker->getValue(target);
+ upperBound = value.getConst<BitVector>();
+ break;
+ case Result::UNSAT:
+ if (lowerBound == pivot)
+ {
+ // lowerBound == pivot ==> upperbound = lowerbound + 1
+ // and lowerbound <= target < upperbound is UNSAT
+ // return the upperbound
+ optChecker->pop();
+ return OptimizationResult(lastSatResult, value);
+ }
+ else
+ {
+ lowerBound = pivot;
+ }
+ break;
+ default: Unreachable();
}
optChecker->pop();
}
- return OptimizationResult(OptimizationResult::OPTIMAL, value);
+ return OptimizationResult(lastSatResult, value);
}
OptimizationResult OMTOptimizerBitVector::maximize(SmtEngine* optChecker,
@@ -148,15 +142,13 @@ OptimizationResult OMTOptimizerBitVector::maximize(SmtEngine* optChecker,
Result intermediateSatResult = optChecker->checkSat();
// Model-value of objective (used in optimization loop)
Node value;
- if (intermediateSatResult.isUnknown())
+ if (intermediateSatResult.isUnknown()
+ || intermediateSatResult.isSat() == Result::UNSAT)
{
- return OptimizationResult(OptimizationResult::UNKNOWN, value);
+ return OptimizationResult(intermediateSatResult, value);
}
- if (intermediateSatResult.isSat() == Result::UNSAT)
- {
- return OptimizationResult(OptimizationResult::UNSAT, value);
- }
-
+ // the last result that is SAT
+ Result lastSatResult = intermediateSatResult;
// value equals to upperBound
value = optChecker->getValue(target);
@@ -196,39 +188,35 @@ OptimizationResult OMTOptimizerBitVector::maximize(SmtEngine* optChecker,
nm->mkNode(GTOperator, target, nm->mkConst(pivot)),
nm->mkNode(LEOperator, target, nm->mkConst(upperBound))));
intermediateSatResult = optChecker->checkSat();
- if (intermediateSatResult.isUnknown() || intermediateSatResult.isNull())
- {
- optChecker->pop();
- return OptimizationResult(OptimizationResult::UNKNOWN, value);
- }
- if (intermediateSatResult.isSat() == Result::SAT)
+ switch (intermediateSatResult.isSat())
{
- value = optChecker->getValue(target);
- lowerBound = value.getConst<BitVector>();
- }
- else if (intermediateSatResult.isSat() == Result::UNSAT)
- {
- if (lowerBound == pivot)
- {
- // upperbound = lowerbound + 1
- // and lowerbound < target <= upperbound is UNSAT
- // return the lowerbound
+ case Result::SAT_UNKNOWN:
optChecker->pop();
- return OptimizationResult(OptimizationResult::OPTIMAL, value);
- }
- else
- {
- upperBound = pivot;
- }
- }
- else
- {
- optChecker->pop();
- return OptimizationResult(OptimizationResult::UNKNOWN, value);
+ return OptimizationResult(intermediateSatResult, value);
+ case Result::SAT:
+ lastSatResult = intermediateSatResult;
+ value = optChecker->getValue(target);
+ lowerBound = value.getConst<BitVector>();
+ break;
+ case Result::UNSAT:
+ if (lowerBound == pivot)
+ {
+ // upperbound = lowerbound + 1
+ // and lowerbound < target <= upperbound is UNSAT
+ // return the lowerbound
+ optChecker->pop();
+ return OptimizationResult(lastSatResult, value);
+ }
+ else
+ {
+ upperBound = pivot;
+ }
+ break;
+ default: Unreachable();
}
optChecker->pop();
}
- return OptimizationResult(OptimizationResult::OPTIMAL, value);
+ return OptimizationResult(lastSatResult, value);
}
} // namespace cvc5::omt
diff --git a/src/omt/integer_optimizer.cpp b/src/omt/integer_optimizer.cpp
index 045268337..379b0cd43 100644
--- a/src/omt/integer_optimizer.cpp
+++ b/src/omt/integer_optimizer.cpp
@@ -33,13 +33,10 @@ OptimizationResult OMTOptimizerInteger::optimize(SmtEngine* optChecker,
Result intermediateSatResult = optChecker->checkSat();
// Model-value of objective (used in optimization loop)
Node value;
- if (intermediateSatResult.isUnknown())
+ if (intermediateSatResult.isUnknown()
+ || intermediateSatResult.isSat() == Result::UNSAT)
{
- return OptimizationResult(OptimizationResult::UNKNOWN, value);
- }
- if (intermediateSatResult.isSat() == Result::UNSAT)
- {
- return OptimizationResult(OptimizationResult::UNSAT, value);
+ return OptimizationResult(intermediateSatResult, value);
}
// node storing target > old_value (used in optimization loop)
Node increment;
@@ -56,12 +53,14 @@ OptimizationResult OMTOptimizerInteger::optimize(SmtEngine* optChecker,
// then assert optimization_target > current_model_value
incrementalOperator = kind::GT;
}
+ Result lastSatResult = intermediateSatResult;
// Workhorse of linear search:
// This loop will keep incrmenting/decrementing the objective until unsat
// When unsat is hit,
// the optimized value is the model value just before the unsat call
while (intermediateSatResult.isSat() == Result::SAT)
{
+ lastSatResult = intermediateSatResult;
value = optChecker->getValue(target);
Assert(!value.isNull());
increment = nm->mkNode(incrementalOperator, target, value);
@@ -69,7 +68,7 @@ OptimizationResult OMTOptimizerInteger::optimize(SmtEngine* optChecker,
intermediateSatResult = optChecker->checkSat();
}
optChecker->pop();
- return OptimizationResult(OptimizationResult::OPTIMAL, value);
+ return OptimizationResult(lastSatResult, value);
}
OptimizationResult OMTOptimizerInteger::minimize(SmtEngine* optChecker,
diff --git a/src/options/CMakeLists.txt b/src/options/CMakeLists.txt
index 978c32888..cc7b621a8 100644
--- a/src/options/CMakeLists.txt
+++ b/src/options/CMakeLists.txt
@@ -17,7 +17,6 @@
check_python_module("toml")
libcvc5_add_sources(
- base_handlers.h
decision_weight.h
didyoumean.cpp
didyoumean.h
@@ -55,7 +54,6 @@ set(options_toml_files
proof_options.toml
prop_options.toml
quantifiers_options.toml
- resource_manager_options.toml
sep_options.toml
sets_options.toml
smt_options.toml
diff --git a/src/options/README b/src/options/README
deleted file mode 100644
index 868690b85..000000000
--- a/src/options/README
+++ /dev/null
@@ -1,127 +0,0 @@
-Modules
-=======
-
- Each options module starts with the following required attributes:
-
- id ... (string) ID of the module (e.g., "ARITH")
- name ... (string) name of the module (e.g., "Arithmetic Theory")
- header ... (string) name of the options header to generated (e.g., "options/arith_options.h")
-
- A module defines 0 or more options.
-
- In general, each attribute/value pair is required to be in one line.
- Comments start with # and are not allowed in attribute/value lines.
-
-
-Options
-=======
-
- Options can be defined with the [[option]] tag, the required attributes for
- an option are:
-
- category ... (string) common | expert | regular | undocumented
- type ... (string) C++ type of the option value
-
- Optional attributes are:
-
- name ... (string) option name that is used to access via
- options::<name>()
- smt_name ... (string) alternative name to access option via
- set-option/get-option commands
- short ... (string) short option name consisting of one character
- (no '-' prefix required)
- long ... (string) long option name (required if short is specified,
- no '--' prefix required).
- long option names may have a suffix '=XXX' where
- 'XXX' can be used to indicate the type of the
- option value, e.g., '=MODE', '=LANG', '=N', ...
- default ... (string) default value of type 'type'
- handler ... (string) handler for parsing option values before setting
- option
- predicates ... (list) functions that check whether given option value is
- valid
- includes ... (list) header files required by handler/predicates
- alternate ... (bool) true (default): add --no-<long> alternative option
- false: omit --no-<long> alternative option
- help ... (string) documentation (required if category is not
- undocumented)
-
- Note that if an option defines a long option name with type 'bool',
- mkoptions.py automatically generates a --no-<long> option to set the option
- to false.
- This behaviour can be explicitely disabled for options with attribute
- alternate = false.
- More information on how to use handler and predicates can be found
- at the end of the README.
-
-
- Example:
-
- [[option]]
- name = "outputLanguage"
- smt_name = "output-language"
- category = "common"
- short = ""
- long = "output-lang=LANG"
- type = "OutputLanguage"
- default = "language::output::LANG_AUTO"
- handler = "stringToOutputLanguage"
- predicates = []
- includes = ["options/language.h"]
- help = "force output language (default is \"auto\"; see --output-lang help)"
-
-
-Further information (the old option package)
-============================================
-
- The options/ package supports a wide range of operations for responding to
- an option being set. Roughly the three major concepts are:
-
- - handler to parse an option before setting its value.
- - predicates to reject bad values for the option.
-
- More details on each class of custom handlers.
-
- - handler = ""
-
- Handlers provide support for parsing custom option types.
- The signature for a handler call is:
-
- T custom-option-handler(std::string option, std::string optarg,
- OptionsHandler* handler);
-
- where T is the type of the option. The suggested implementation is to
- implement custom-handler as a dispatch into a function on handler with the
- signature:
-
- T OptionsHandler::custom-option-handler(std::string option,
- std::string optarg);
-
- The handlers are run before predicates.
- Having multiple handlers is considered bad practice and is unsupported.
- Handlers may have arbitrary side effects, but should call no code
- inaccessible to liboptions. For side effects that are not required in order
- to parse the option, using :predicate is recommended. Memory
- management done by a handler needs to either be encapsulated by the type
- and the destructor for the type or should *always* be owned by handler.
- More elaborate memory management schemes are not currently supported.
-
- - predicates = [...]
-
- Predicates provide support for checking whether or not the value of an
- option is acceptable. Predicates are run after handlers.
- The signature for a predicate call is:
-
- void custom-predicate(std::string option, T value,
- OptionsHandler* handler);
-
- where T is the type of the option. The suggested implementation is to
- implement custom-predicate as a dispatch into a function on handler with
- the signature:
-
- void OptionsHandler::custom-predicate(std::string option, T value);
-
- The predicates are run after handlers. Multiple
- predicates may be defined for the same option, but the order they are run
- is not guaranteed. Predicates may have arbitrary side effects, but should
- call no code inaccessible to liboptions.
diff --git a/src/options/README.md b/src/options/README.md
new file mode 100644
index 000000000..df5686abc
--- /dev/null
+++ b/src/options/README.md
@@ -0,0 +1,211 @@
+Specifying Modules
+==================
+
+Every options module, that is a group of options that belong together in some
+way, is declared in its own file in `options/{module name}_options.toml`. Each
+options module starts with the following required attributes:
+
+* `id` (string): ID of the module (e.g., `"arith"`)
+* `name` (string): name of the module (e.g., `"Arithmetic Theory"`)
+
+Additional, a module can optionally be defined to be public. A public module
+includes `cvc5_public.h` instead of `cvc5_private.h` can thus be included from
+"external" code like the parser or the main driver.
+
+* `public` (bool): make option module public
+
+A module defines 0 or more options.
+
+In general, each attribute/value pair is required to be in one line. Comments
+start with # and are not allowed in attribute/value lines.
+
+After parsing, a module is extended to have the following attributes:
+
+* `id`: lower-case version of the parsed `id`
+* `id_cap`: upper-case version of `id` (used for the `Holder{id_cap}` class)
+* `filename`: base filename for generated files (`"{id}_options"`)
+* `header`: generated header name (`"options/{filename}.h"`)
+
+
+Specifying Options
+==================
+
+Options can be defined within a module file with the `[[option]]` tag, the
+required attributes for an option are:
+
+* `category` (string): one of `common`, `expert`, `regular`, or `undocumented`
+* `type` (string): the C++ type of the option value
+
+Optional attributes are:
+
+* `name` (string): the option name used to access the option internally
+ (`d_option.{module.id}.{name}`)
+* `long` (string): long option name (without `--` prefix). Long option names may
+ have a suffix `=XXX` where `XXX` can be used to indicate the type of the
+ option value, e.g., `=MODE`, `=LANG`, `=N`, ...
+* `short` (string): short option name consisting of one character (no `-` prefix
+ required), can be given if `long` is specified
+* `alias` (list): alternative names that can be used instead of `long`
+* `default` (string): default value, needs to be a valid C++ expression of type
+ `type`
+* `alternate` (bool, default `true`): if `true`, adds `--no-{long}` alternative
+ option
+* `mode` (list): used to define options whose type shall be an auto-generated
+ enum, more details below
+* `handler` (string): alternate parsing routine for option types not covered by
+ the default parsers, more details below
+* `predicates` (list): custom validation function to check whether an option
+ value is valid, more details below
+* `includes` (list): additional header files required by handler or predicate
+ functions
+* `help` (string): documentation string (required, unless the `category` is
+ `undocumented`)
+* `help_mode` (string): documentation for the mode enum (required if `mode` is
+ given)
+
+
+Handler functions
+-----------------
+
+Custom handler functions are used to turn the option value from a `std::string`
+into the type specified by `type`. Standard handler functions are provided for
+basic types (`std::string`, `bool`, integer types and floating point types) as
+well as enums specified by `mode`. A custom handler function needs to be member
+function of `options::OptionsHandler` with signature `{type} {handler}(const
+std::string& option, const std::string& flag, const std::string& optionvalue)`,
+or alternatively `void {handler}(const std::string& option, const std::string&
+flag)` if the `type` is `void`. The two parameters `option` and `flag` hold the
+canonical and the actually used option names, respectively, and they may differ
+if an alternative name (from `alias`) was used. While `option` should be used to
+identify an option (e.g. by comparing against `*__name`), `flag` should be
+usually used in user messages.
+
+
+Predicate functions
+-------------------
+
+Predicate functions are used to check whether an option value is valid after it
+has been parsed by a (standard or custom) handler function. Like a handler
+function, a predicate function needs to be a member function of
+`options::OptionsHandler` with signature `void {predicate}(const std::string&
+option, const std::string& flag, {type} value)`. If the check fails, the
+predicate should raise an `OptionException`.
+
+
+Mode options
+------------
+
+An option can be defined to hold one of a given set of values we call modes.
+Doing so automatically defines an `enum class` for the set of modes and makes
+the option accept one of the values from the enum. The enum class will be called
+`{type}` and methods `operator<<` and `stringTo{enum}` are automatically
+generated. A mode is defined by specifying `[[option.mode.{NAME}]]` after the
+main `[[option]]` section with the following attributes:
+
+* `name` (string): the string value that corresponds to the enum value
+* `help` (string): documentation about this mode
+
+Example:
+
+ [[option]]
+ name = "bitblastMode"
+ category = "regular"
+ long = "bitblast=MODE"
+ type = "BitblastMode"
+ default = "LAZY"
+ help = "choose bitblasting mode, see --bitblast=help"
+ help_mode = "Bit-blasting modes."
+ [[option.mode.LAZY]]
+ name = "lazy"
+ help = "Separate boolean structure and term reasoning between the core SAT solver and the bit-vector SAT solver."
+ [[option.mode.EAGER]]
+ name = "eager"
+ help = "Bitblast eagerly to bit-vector SAT solver."
+
+The option can now be set with `--bitblast=lazy`, `(set-option :bitblast
+eager)`, or `options::set("bitblast", "eager")`.
+
+
+Generated code
+==============
+
+The entire options setup heavily relies on generating a lot of code from the
+information retrieved from the `*_options.toml` files. After code generation,
+files related to options live either in `src/options/` (if not changed) or in
+`build/src/options/` (if automatically generated). After all code has been
+generated, the entire options setup consists of the following components:
+
+* `options.h`: core `Options` class
+* `options_api.h`: utility methods used by the API (`parse()`, `set()`, `get()`,
+ ...)
+* `options_public.h`: utility methods used to access options from outside of
+ libcvc5
+* `{module}_options.h`: specifics for one single options module
+
+
+`Options` class
+---------------
+
+The `Options` class is the central entry point for regular usage of options. It
+holds a `std::unique_ptr` to an "option holder" for every option module, that
+can be accessed using references `{module}` (either as `const&` or `&`). These
+holders hold the actual option data for the specific module.
+
+The holder types are forward declared and can thus only be accessed if one also
+includes the appropriate `{module}_options.h`, which contains the proper
+declaration for the holder class.
+
+
+Option modules
+--------------
+
+Every option module declares an "option holder" class, which is a simple struct
+that has two members for every option (that is not declared as `type = void`):
+the actual option value as `{option.type} {option.name}` and a Boolean flag
+`bool {option.name}__setByUser` that indicates whether the option value was
+explicitly set by the user. If any of the options of a module is a mode option,
+the option module also defines an enum class that corresponds to the mode,
+including `operator<<()` and `stringTo{mode type}`.
+
+For convenience, the option modules also provide methods `void
+{module.id}::setDefault{option.name}(Options& opts, {option.type} value)`. Each
+such method sets the option value to the given value, if the option was not yet
+set by the user, i.e., the `__setByUser` flag is false. Additionally, every
+option module exports the `long` option name as `static constexpr const char*
+{module.id}::{option.name}__name`.
+
+
+Full Example
+============
+
+ [[option]]
+ category = "regular"
+ name = "decisionMode"
+ long = "decision=MODE"
+ alias = ["decision-mode"]
+ type = "DecisionMode"
+ default = "INTERNAL"
+ predicates = ["setDecisionModeStopOnly"]
+ help = "choose decision mode, see --decision=help"
+ help_mode = "Decision modes."
+ [[option.mode.INTERNAL]]
+ name = "internal"
+ help = "Use the internal decision heuristics of the SAT solver."
+ [[option.mode.JUSTIFICATION]]
+ name = "justification"
+ help = "An ATGP-inspired justification heuristic."
+ [[option.mode.RELEVANCY]]
+ name = "justification-stoponly"
+ help = "Use the justification heuristic only to stop early, not for decisions."
+
+This defines a new option that is accessible via
+`d_options.{module.id}.decisionMode` and stores an automatically generated mode
+`DecisionMode`, an enum class with the values `INTERNAL`, `JUSTIFICATION` and
+`RELEVANCY`. From the outside, it can be set by `--decision=internal`, but also
+with `--decision-mode=justification`, and similarly from an SMT-LIB input with
+`(set-option :decision internal)` and `(set-option :decision-mode
+justification)`. The command-line help for this option looks as follows:
+
+ --output-lang=LANG | --output-language=LANG
+ force output language (default is "auto"; see
+ --output-lang help)
diff --git a/src/options/base_handlers.h b/src/options/base_handlers.h
deleted file mode 100644
index 86112a907..000000000
--- a/src/options/base_handlers.h
+++ /dev/null
@@ -1,87 +0,0 @@
-/******************************************************************************
- * Top contributors (to current version):
- * Morgan Deters, Tim King, Mathias Preiner
- *
- * This file is part of the cvc5 project.
- *
- * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
- * in the top-level source directory and their institutional affiliations.
- * All rights reserved. See the file COPYING in the top-level source
- * directory for licensing information.
- * ****************************************************************************
- *
- * [[ Add one-line brief description here ]]
- *
- * [[ Add lengthier description here ]]
- * \todo document this file
- */
-
-#include "cvc5_private.h"
-
-#ifndef CVC5__BASE_HANDLERS_H
-#define CVC5__BASE_HANDLERS_H
-
-#include <iostream>
-#include <string>
-#include <sstream>
-
-#include "options/option_exception.h"
-
-namespace cvc5 {
-namespace options {
-
-template <template <class U> class Cmp>
-class comparator {
- long d_lbound;
- double d_dbound;
- bool d_hasLbound;
-
- public:
- comparator(int i) : d_lbound(i), d_dbound(0.0), d_hasLbound(true) {}
- comparator(long l) : d_lbound(l), d_dbound(0.0), d_hasLbound(true) {}
- comparator(double d) : d_lbound(0), d_dbound(d), d_hasLbound(false) {}
- template <class T>
- void operator()(std::string option, const T& value) {
- 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(int i) : comparator<std::greater>(i) {}
- greater(long l) : comparator<std::greater>(l) {}
- greater(double d) : comparator<std::greater>(d) {}
-};/* struct greater */
-
-struct greater_equal : public comparator<std::greater_equal> {
- greater_equal(int i) : comparator<std::greater_equal>(i) {}
- greater_equal(long l) : comparator<std::greater_equal>(l) {}
- greater_equal(double d) : comparator<std::greater_equal>(d) {}
-};/* struct greater_equal */
-
-struct less : public comparator<std::less> {
- less(int i) : comparator<std::less>(i) {}
- less(long l) : comparator<std::less>(l) {}
- less(double d) : comparator<std::less>(d) {}
-};/* struct less */
-
-struct less_equal : public comparator<std::less_equal> {
- less_equal(int i) : comparator<std::less_equal>(i) {}
- less_equal(long l) : comparator<std::less_equal>(l) {}
- less_equal(double d) : comparator<std::less_equal>(d) {}
-};/* struct less_equal */
-
-struct not_equal : public comparator<std::not_equal_to> {
- not_equal(int i) : comparator<std::not_equal_to>(i) {}
- not_equal(long l) : comparator<std::not_equal_to>(l) {}
- not_equal(double d) : comparator<std::not_equal_to>(d) {}
-};/* struct not_equal_to */
-
-} // namespace options
-} // namespace cvc5
-
-#endif /* CVC5__BASE_HANDLERS_H */
diff --git a/src/options/base_options.toml b/src/options/base_options.toml
index f9d1c1a18..64d373509 100644
--- a/src/options/base_options.toml
+++ b/src/options/base_options.toml
@@ -1,5 +1,6 @@
id = "BASE"
name = "Base"
+public = true
[[option]]
name = "in"
@@ -76,6 +77,15 @@ name = "Base"
help = "decrease verbosity (may be repeated)"
[[option]]
+ name = "incrementalSolving"
+ category = "common"
+ short = "i"
+ long = "incremental"
+ type = "bool"
+ default = "true"
+ help = "enable incremental solving"
+
+[[option]]
name = "statistics"
long = "stats"
category = "common"
@@ -144,3 +154,52 @@ name = "Base"
long = "print-success"
type = "bool"
help = "print the \"success\" output required of SMT-LIBv2"
+
+[[option]]
+ name = "cumulativeMillisecondLimit"
+ category = "common"
+ long = "tlimit=MS"
+ type = "uint64_t"
+ help = "set time limit in milliseconds of wall clock time"
+
+[[option]]
+ name = "perCallMillisecondLimit"
+ category = "common"
+ long = "tlimit-per=MS"
+ type = "uint64_t"
+ help = "set time limit per query in milliseconds"
+
+[[option]]
+ name = "cumulativeResourceLimit"
+ category = "common"
+ long = "rlimit=N"
+ type = "uint64_t"
+ help = "set resource limit"
+
+[[option]]
+ name = "perCallResourceLimit"
+ alias = ["reproducible-resource-limit"]
+ category = "common"
+ long = "rlimit-per=N"
+ type = "uint64_t"
+ help = "set resource limit per query"
+
+# --rweight is used to override the default of one particular resource weight.
+# It can be given multiple times to override multiple weights. When options are
+# parsed, the resource manager might now be created yet, and it is not clear
+# how an option handler would access it in a reasonable way. The option handler
+# thus merely puts the data in another option that holds a vector of strings.
+# This other option "resourceWeightHolder" has the sole purpose of storing
+# this data in a way so that the resource manager can access it in its
+# constructor.
+[[option]]
+ category = "expert"
+ long = "rweight=VAL=N"
+ type = "std::string"
+ handler = "setResourceWeight"
+ help = "set a single resource weight"
+
+[[option]]
+ name = "resourceWeightHolder"
+ category = "undocumented"
+ type = "std::vector<std::string>"
diff --git a/src/options/main_options.toml b/src/options/main_options.toml
index e8bb8ea72..19bb97f34 100644
--- a/src/options/main_options.toml
+++ b/src/options/main_options.toml
@@ -87,3 +87,51 @@ public = true
type = "bool"
default = "false"
help = "spin on segfault/other crash waiting for gdb"
+
+[[option]]
+ name = "dumpModels"
+ category = "regular"
+ long = "dump-models"
+ type = "bool"
+ default = "false"
+ help = "output models after every SAT/INVALID/UNKNOWN response"
+
+[[option]]
+ name = "dumpProofs"
+ category = "regular"
+ long = "dump-proofs"
+ type = "bool"
+ default = "false"
+ help = "output proofs after every UNSAT/VALID response"
+
+[[option]]
+ name = "dumpInstantiations"
+ category = "regular"
+ long = "dump-instantiations"
+ type = "bool"
+ default = "false"
+ help = "output instantiations of quantified formulas after every UNSAT/VALID response"
+
+[[option]]
+ name = "dumpUnsatCores"
+ category = "regular"
+ long = "dump-unsat-cores"
+ type = "bool"
+ default = "false"
+ help = "output unsat cores after every UNSAT/VALID response"
+
+[[option]]
+ name = "dumpUnsatCoresFull"
+ category = "regular"
+ long = "dump-unsat-cores-full"
+ type = "bool"
+ default = "false"
+ help = "dump the full unsat core, including unlabeled assertions"
+
+[[option]]
+ name = "forceNoLimitCpuWhileDump"
+ category = "regular"
+ long = "force-no-limit-cpu-while-dump"
+ type = "bool"
+ default = "false"
+ help = "Force no CPU limit when dumping models and proofs" \ No newline at end of file
diff --git a/src/options/mkoptions.py b/src/options/mkoptions.py
index 7e1cf68e4..e2fbd4cf1 100644
--- a/src/options/mkoptions.py
+++ b/src/options/mkoptions.py
@@ -210,6 +210,30 @@ def get_holder_ref_decls(modules):
return concat_format(' options::Holder{id_cap}& {id};', modules)
+def get_handler(option):
+ """Render handler call for assignment functions"""
+ optname = option.long_name if option.long else ""
+ if option.handler:
+ if option.type == 'void':
+ return 'opts.handler().{}("{}", option)'.format(option.handler, optname)
+ else:
+ return 'opts.handler().{}("{}", option, optionarg)'.format(option.handler, optname)
+ elif option.mode:
+ return 'stringTo{}(optionarg)'.format(option.type)
+ elif option.type != 'bool':
+ return 'handleOption<{}>("{}", option, optionarg)'.format(option.type, optname)
+ return None
+
+
+def get_predicates(option):
+ """Render predicate calls for assignment functions"""
+ if not option.predicates:
+ return []
+ optname = option.long_name if option.long else ""
+ assert option.type != 'void'
+ return ['opts.handler().{}("{}", option, value);'.format(x, optname)
+ for x in option.predicates]
+
class Module(object):
"""Options module.
@@ -713,31 +737,10 @@ def codegen_all_modules(modules, build_dir, dst_dir, tpl_options_h, tpl_options_
sphinxgen.add(module, option)
# Generate handler call
- handler = None
- if option.handler:
- if option.type == 'void':
- handler = 'opts.handler().{}(option)'.format(option.handler)
- else:
- handler = \
- 'opts.handler().{}(option, optionarg)'.format(option.handler)
- elif option.mode:
- handler = 'stringTo{}(optionarg)'.format(option.type)
- elif option.type != 'bool':
- handler = \
- 'handleOption<{}>(option, optionarg)'.format(option.type)
+ handler = get_handler(option)
# Generate predicate calls
- predicates = []
- if option.predicates:
- if option.type == 'bool':
- predicates = \
- ['opts.handler().{}(option, value);'.format(x) \
- for x in option.predicates]
- else:
- assert option.type != 'void'
- predicates = \
- ['opts.handler().{}(option, value);'.format(x) \
- for x in option.predicates]
+ predicates = get_predicates(option)
# Generate options_handler and getopt_long
cases = []
@@ -813,7 +816,7 @@ def codegen_all_modules(modules, build_dir, dst_dir, tpl_options_h, tpl_options_
name=option.name,
option='key'))
elif option.handler:
- h = 'handler->{handler}("{smtname}"'
+ h = 'handler->{handler}("{smtname}", key'
if argument_req:
h += ', optionarg'
h += ');'
diff --git a/src/options/options_handler.cpp b/src/options/options_handler.cpp
index c1c843802..07138dce3 100644
--- a/src/options/options_handler.cpp
+++ b/src/options/options_handler.cpp
@@ -33,7 +33,6 @@
#include "options/didyoumean.h"
#include "options/language.h"
#include "options/option_exception.h"
-#include "options/resource_manager_options.h"
#include "options/smt_options.h"
#include "options/theory_options.h"
@@ -68,10 +67,11 @@ void throwLazyBBUnsupported(options::SatSolverMode m)
OptionsHandler::OptionsHandler(Options* options) : d_options(options) { }
-unsigned long OptionsHandler::limitHandler(std::string option,
- std::string optarg)
+uint64_t OptionsHandler::limitHandler(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg)
{
- unsigned long ms;
+ uint64_t ms;
std::istringstream convert(optarg);
if (!(convert >> ms))
{
@@ -81,14 +81,18 @@ unsigned long OptionsHandler::limitHandler(std::string option,
return ms;
}
-void OptionsHandler::setResourceWeight(std::string option, std::string optarg)
+void OptionsHandler::setResourceWeight(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg)
{
- d_options->resman.resourceWeightHolder.emplace_back(optarg);
+ d_options->base.resourceWeightHolder.emplace_back(optarg);
}
// theory/quantifiers/options_handlers.h
-void OptionsHandler::checkInstWhenMode(std::string option, InstWhenMode mode)
+void OptionsHandler::checkInstWhenMode(const std::string& option,
+ const std::string& flag,
+ InstWhenMode mode)
{
if (mode == InstWhenMode::PRE_FULL)
{
@@ -98,7 +102,9 @@ void OptionsHandler::checkInstWhenMode(std::string option, InstWhenMode mode)
}
// theory/bv/options_handlers.h
-void OptionsHandler::abcEnabledBuild(std::string option, bool value)
+void OptionsHandler::abcEnabledBuild(const std::string& option,
+ const std::string& flag,
+ bool value)
{
#ifndef CVC5_USE_ABC
if(value) {
@@ -111,7 +117,9 @@ void OptionsHandler::abcEnabledBuild(std::string option, bool value)
#endif /* CVC5_USE_ABC */
}
-void OptionsHandler::abcEnabledBuild(std::string option, std::string value)
+void OptionsHandler::abcEnabledBuild(const std::string& option,
+ const std::string& flag,
+ const std::string& value)
{
#ifndef CVC5_USE_ABC
if(!value.empty()) {
@@ -124,7 +132,9 @@ void OptionsHandler::abcEnabledBuild(std::string option, std::string value)
#endif /* CVC5_USE_ABC */
}
-void OptionsHandler::checkBvSatSolver(std::string option, SatSolverMode m)
+void OptionsHandler::checkBvSatSolver(const std::string& option,
+ const std::string& flag,
+ SatSolverMode m)
{
if (m == SatSolverMode::CRYPTOMINISAT
&& !Configuration::isBuiltWithCryptominisat())
@@ -136,15 +146,6 @@ void OptionsHandler::checkBvSatSolver(std::string option, SatSolverMode m)
throw OptionException(ss.str());
}
- if (m == SatSolverMode::CADICAL && !Configuration::isBuiltWithCadical())
- {
- std::stringstream ss;
- ss << "option `" << option
- << "' requires a CaDiCaL build of cvc5; this binary was not built with "
- "CaDiCaL support";
- throw OptionException(ss.str());
- }
-
if (m == SatSolverMode::KISSAT && !Configuration::isBuiltWithKissat())
{
std::stringstream ss;
@@ -167,7 +168,9 @@ void OptionsHandler::checkBvSatSolver(std::string option, SatSolverMode m)
}
}
-void OptionsHandler::checkBitblastMode(std::string option, BitblastMode m)
+void OptionsHandler::checkBitblastMode(const std::string& option,
+ const std::string& flag,
+ BitblastMode m)
{
if (m == options::BitblastMode::LAZY)
{
@@ -186,7 +189,9 @@ void OptionsHandler::checkBitblastMode(std::string option, BitblastMode m)
}
}
-void OptionsHandler::setBitblastAig(std::string option, bool arg)
+void OptionsHandler::setBitblastAig(const std::string& option,
+ const std::string& flag,
+ bool arg)
{
if(arg) {
if (d_options->bv.bitblastModeWasSetByUser) {
@@ -212,8 +217,9 @@ szs\n\
+ Print instantiations as SZS compliant proof.\n\
";
-InstFormatMode OptionsHandler::stringToInstFormatMode(std::string option,
- std::string optarg)
+InstFormatMode OptionsHandler::stringToInstFormatMode(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg)
{
if(optarg == "default") {
return InstFormatMode::DEFAULT;
@@ -229,24 +235,30 @@ InstFormatMode OptionsHandler::stringToInstFormatMode(std::string option,
}
// decision/options_handlers.h
-void OptionsHandler::setDecisionModeStopOnly(std::string option, DecisionMode m)
+void OptionsHandler::setDecisionModeStopOnly(const std::string& option,
+ const std::string& flag,
+ DecisionMode m)
{
d_options->decision.decisionStopOnly = (m == DecisionMode::RELEVANCY);
}
-void OptionsHandler::setProduceAssertions(std::string option, bool value)
+void OptionsHandler::setProduceAssertions(const std::string& option,
+ const std::string& flag,
+ bool value)
{
d_options->smt.produceAssertions = value;
d_options->smt.interactiveMode = value;
}
-void OptionsHandler::setStats(const std::string& option, bool value)
+void OptionsHandler::setStats(const std::string& option,
+ const std::string& flag,
+ bool value)
{
#ifndef CVC5_STATISTICS_ON
if (value)
{
std::stringstream ss;
- ss << "option `" << option
+ ss << "option `" << flag
<< "' requires a statistics-enabled build of cvc5; this binary was not "
"built with statistics support";
throw OptionException(ss.str());
@@ -283,18 +295,25 @@ void OptionsHandler::setStats(const std::string& option, bool value)
}
}
-void OptionsHandler::threadN(std::string option) {
- throw OptionException(option + " is not a real option by itself. Use e.g. --thread0=\"--random-seed=10 --random-freq=0.02\" --thread1=\"--random-seed=20 --random-freq=0.05\"");
+void OptionsHandler::threadN(const std::string& option, const std::string& flag)
+{
+ throw OptionException(flag + " is not a real option by itself. Use e.g. --thread0=\"--random-seed=10 --random-freq=0.02\" --thread1=\"--random-seed=20 --random-freq=0.05\"");
}
// expr/options_handlers.h
-void OptionsHandler::setDefaultExprDepthPredicate(std::string option, int depth) {
+void OptionsHandler::setDefaultExprDepthPredicate(const std::string& option,
+ const std::string& flag,
+ int depth)
+{
if(depth < -1) {
throw OptionException("--expr-depth requires a positive argument, or -1.");
}
}
-void OptionsHandler::setDefaultDagThreshPredicate(std::string option, int dag) {
+void OptionsHandler::setDefaultDagThreshPredicate(const std::string& option,
+ const std::string& flag,
+ int dag)
+{
if(dag < 0) {
throw OptionException("--dag-thresh requires a nonnegative argument.");
}
@@ -313,12 +332,16 @@ static void print_config_cond (const char * str, bool cond = false) {
print_config(str, cond ? "yes" : "no");
}
-void OptionsHandler::copyright(std::string option) {
+void OptionsHandler::copyright(const std::string& option,
+ const std::string& flag)
+{
std::cout << Configuration::copyright() << std::endl;
exit(0);
}
-void OptionsHandler::showConfiguration(std::string option) {
+void OptionsHandler::showConfiguration(const std::string& option,
+ const std::string& flag)
+{
std::cout << Configuration::about() << std::endl;
print_config ("version", Configuration::getVersionString());
@@ -365,13 +388,11 @@ void OptionsHandler::showConfiguration(std::string option) {
print_config_cond("abc", Configuration::isBuiltWithAbc());
print_config_cond("cln", Configuration::isBuiltWithCln());
print_config_cond("glpk", Configuration::isBuiltWithGlpk());
- print_config_cond("cadical", Configuration::isBuiltWithCadical());
print_config_cond("cryptominisat", Configuration::isBuiltWithCryptominisat());
print_config_cond("gmp", Configuration::isBuiltWithGmp());
print_config_cond("kissat", Configuration::isBuiltWithKissat());
print_config_cond("poly", Configuration::isBuiltWithPoly());
print_config_cond("editline", Configuration::isBuiltWithEditline());
- print_config_cond("symfpu", Configuration::isBuiltWithSymFPU());
exit(0);
}
@@ -386,7 +407,8 @@ static void printTags(unsigned ntags, char const* const* tags)
std::cout << std::endl;
}
-void OptionsHandler::showDebugTags(std::string option)
+void OptionsHandler::showDebugTags(const std::string& option,
+ const std::string& flag)
{
if (!Configuration::isDebugBuild())
{
@@ -400,7 +422,8 @@ void OptionsHandler::showDebugTags(std::string option)
exit(0);
}
-void OptionsHandler::showTraceTags(std::string option)
+void OptionsHandler::showTraceTags(const std::string& option,
+ const std::string& flag)
{
if (!Configuration::isTracingBuild())
{
@@ -432,7 +455,9 @@ static std::string suggestTags(char const* const* validTags,
return didYouMean.getMatchAsString(inputTag);
}
-void OptionsHandler::enableTraceTag(std::string option, std::string optarg)
+void OptionsHandler::enableTraceTag(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg)
{
if(!Configuration::isTracingBuild())
{
@@ -454,7 +479,9 @@ void OptionsHandler::enableTraceTag(std::string option, std::string optarg)
Trace.on(optarg);
}
-void OptionsHandler::enableDebugTag(std::string option, std::string optarg)
+void OptionsHandler::enableDebugTag(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg)
{
if (!Configuration::isDebugBuild())
{
@@ -485,8 +512,9 @@ void OptionsHandler::enableDebugTag(std::string option, std::string optarg)
Trace.on(optarg);
}
-OutputLanguage OptionsHandler::stringToOutputLanguage(std::string option,
- std::string optarg)
+OutputLanguage OptionsHandler::stringToOutputLanguage(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg)
{
if(optarg == "help") {
d_options->base.languageHelp = true;
@@ -503,8 +531,9 @@ OutputLanguage OptionsHandler::stringToOutputLanguage(std::string option,
Unreachable();
}
-InputLanguage OptionsHandler::stringToInputLanguage(std::string option,
- std::string optarg)
+InputLanguage OptionsHandler::stringToInputLanguage(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg)
{
if(optarg == "help") {
d_options->base.languageHelp = true;
@@ -521,7 +550,9 @@ InputLanguage OptionsHandler::stringToInputLanguage(std::string option,
}
/* options/base_options_handlers.h */
-void OptionsHandler::setVerbosity(std::string option, int value)
+void OptionsHandler::setVerbosity(const std::string& option,
+ const std::string& flag,
+ int value)
{
if(Configuration::isMuzzledBuild()) {
DebugChannel.setStream(&cvc5::null_os);
@@ -551,14 +582,18 @@ void OptionsHandler::setVerbosity(std::string option, int value)
}
}
-void OptionsHandler::increaseVerbosity(std::string option) {
+void OptionsHandler::increaseVerbosity(const std::string& option,
+ const std::string& flag)
+{
d_options->base.verbosity += 1;
- setVerbosity(option, options::verbosity());
+ setVerbosity(option, flag, d_options->base.verbosity);
}
-void OptionsHandler::decreaseVerbosity(std::string option) {
+void OptionsHandler::decreaseVerbosity(const std::string& option,
+ const std::string& flag)
+{
d_options->base.verbosity -= 1;
- setVerbosity(option, options::verbosity());
+ setVerbosity(option, flag, d_options->base.verbosity);
}
} // namespace options
diff --git a/src/options/options_handler.h b/src/options/options_handler.h
index 4b9b1c0ae..3b3f80e6c 100644
--- a/src/options/options_handler.h
+++ b/src/options/options_handler.h
@@ -19,9 +19,9 @@
#define CVC5__OPTIONS__OPTIONS_HANDLER_H
#include <ostream>
+#include <sstream>
#include <string>
-#include "options/base_handlers.h"
#include "options/bv_options.h"
#include "options/decision_options.h"
#include "options/language.h"
@@ -44,72 +44,117 @@ class OptionsHandler {
public:
OptionsHandler(Options* options);
- void unsignedGreater0(const std::string& option, unsigned value) {
- options::greater(0)(option, value);
+ template <typename T>
+ void geqZero(const std::string& option,
+ const std::string& flag,
+ T value) const
+ {
+ if (value < 0)
+ {
+ std::stringstream ss;
+ ss << flag << ": " << value << " is not a legal setting, should be "
+ << value << " >= 0.";
+ throw OptionException(ss.str());
+ }
}
-
- void unsignedLessEqual2(const std::string& option, unsigned value) {
- options::less_equal(2)(option, value);
- }
-
- void doubleGreaterOrEqual0(const std::string& option, double value) {
- options::greater_equal(0.0)(option, value);
- }
-
- void doubleLessOrEqual1(const std::string& option, double value) {
- options::less_equal(1.0)(option, value);
+ template <typename T>
+ void betweenZeroAndOne(const std::string& option,
+ const std::string& flag,
+ T value) const
+ {
+ if (value < 0 || value > 1)
+ {
+ std::stringstream ss;
+ ss << flag << ": " << value
+ << " is not a legal setting, should be 0 <= " << flag << " <= 1.";
+ throw OptionException(ss.str());
+ }
}
// theory/quantifiers/options_handlers.h
- void checkInstWhenMode(std::string option, InstWhenMode mode);
+ void checkInstWhenMode(const std::string& option,
+ const std::string& flag,
+ InstWhenMode mode);
// theory/bv/options_handlers.h
- void abcEnabledBuild(std::string option, bool value);
- void abcEnabledBuild(std::string option, std::string value);
-
- template<class T> void checkSatSolverEnabled(std::string option, T m);
-
- void checkBvSatSolver(std::string option, SatSolverMode m);
- void checkBitblastMode(std::string option, BitblastMode m);
-
- void setBitblastAig(std::string option, bool arg);
+ void abcEnabledBuild(const std::string& option,
+ const std::string& flag,
+ bool value);
+ void abcEnabledBuild(const std::string& option,
+ const std::string& flag,
+ const std::string& value);
+
+ void checkBvSatSolver(const std::string& option,
+ const std::string& flag,
+ SatSolverMode m);
+ void checkBitblastMode(const std::string& option,
+ const std::string& flag,
+ BitblastMode m);
+
+ void setBitblastAig(const std::string& option,
+ const std::string& flag,
+ bool arg);
// printer/options_handlers.h
- InstFormatMode stringToInstFormatMode(std::string option, std::string optarg);
+ InstFormatMode stringToInstFormatMode(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg);
// decision/options_handlers.h
- void setDecisionModeStopOnly(std::string option, DecisionMode m);
+ void setDecisionModeStopOnly(const std::string& option,
+ const std::string& flag,
+ DecisionMode m);
/**
* Throws a ModalException if this option is being set after final
* initialization.
*/
- void setProduceAssertions(std::string option, bool value);
+ void setProduceAssertions(const std::string& option,
+ const std::string& flag,
+ bool value);
- void setStats(const std::string& option, bool value);
+ void setStats(const std::string& option, const std::string& flag, bool value);
- unsigned long limitHandler(std::string option, std::string optarg);
- void setResourceWeight(std::string option, std::string optarg);
+ uint64_t limitHandler(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg);
+ void setResourceWeight(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg);
/* expr/options_handlers.h */
- void setDefaultExprDepthPredicate(std::string option, int depth);
- void setDefaultDagThreshPredicate(std::string option, int dag);
+ void setDefaultExprDepthPredicate(const std::string& option,
+ const std::string& flag,
+ int depth);
+ void setDefaultDagThreshPredicate(const std::string& option,
+ const std::string& flag,
+ int dag);
/* main/options_handlers.h */
- void copyright(std::string option);
- void showConfiguration(std::string option);
- void showDebugTags(std::string option);
- void showTraceTags(std::string option);
- void threadN(std::string option);
+ void copyright(const std::string& option, const std::string& flag);
+ void showConfiguration(const std::string& option, const std::string& flag);
+ void showDebugTags(const std::string& option, const std::string& flag);
+ void showTraceTags(const std::string& option, const std::string& flag);
+ void threadN(const std::string& option, const std::string& flag);
/* options/base_options_handlers.h */
- void setVerbosity(std::string option, int value);
- void increaseVerbosity(std::string option);
- void decreaseVerbosity(std::string option);
- OutputLanguage stringToOutputLanguage(std::string option, std::string optarg);
- InputLanguage stringToInputLanguage(std::string option, std::string optarg);
- void enableTraceTag(std::string option, std::string optarg);
- void enableDebugTag(std::string option, std::string optarg);
+ void setVerbosity(const std::string& option,
+ const std::string& flag,
+ int value);
+ void increaseVerbosity(const std::string& option, const std::string& flag);
+ void decreaseVerbosity(const std::string& option, const std::string& flag);
+ OutputLanguage stringToOutputLanguage(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg);
+ InputLanguage stringToInputLanguage(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg);
+ void enableTraceTag(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg);
+ void enableDebugTag(const std::string& option,
+ const std::string& flag,
+ const std::string& optarg);
private:
@@ -121,18 +166,6 @@ public:
}; /* class OptionHandler */
-template<class T>
-void OptionsHandler::checkSatSolverEnabled(std::string option, T m)
-{
-#if !defined(CVC5_USE_CRYPTOMINISAT) && !defined(CVC5_USE_CADICAL) \
- && !defined(CVC5_USE_KISSAT)
- std::stringstream ss;
- ss << "option `" << option
- << "' requires cvc5 to be built with CryptoMiniSat or CaDiCaL or Kissat";
- throw OptionException(ss.str());
-#endif
-}
-
} // namespace options
} // namespace cvc5
diff --git a/src/options/options_public.cpp b/src/options/options_public.cpp
index 35e891f5a..552058312 100644
--- a/src/options/options_public.cpp
+++ b/src/options/options_public.cpp
@@ -17,118 +17,10 @@
#include "options_public.h"
-#include <fstream>
-#include <ostream>
-#include <string>
-#include <vector>
-
-#include "base/listener.h"
-#include "base/modal_exception.h"
-#include "options/base_options.h"
-#include "options/language.h"
-#include "options/main_options.h"
-#include "options/option_exception.h"
-#include "options/options.h"
-#include "options/parser_options.h"
-#include "options/printer_modes.h"
-#include "options/printer_options.h"
-#include "options/resource_manager_options.h"
-#include "options/smt_options.h"
#include "options/uf_options.h"
namespace cvc5::options {
-InputLanguage getInputLanguage(const Options& opts)
-{
- return opts.base.inputLanguage;
-}
-InstFormatMode getInstFormatMode(const Options& opts)
-{
- return opts.printer.instFormatMode;
-}
-OutputLanguage getOutputLanguage(const Options& opts)
-{
- return opts.base.outputLanguage;
-}
bool getUfHo(const Options& opts) { return opts.uf.ufHo; }
-bool getDumpInstantiations(const Options& opts)
-{
- return opts.smt.dumpInstantiations;
-}
-bool getDumpModels(const Options& opts) { return opts.smt.dumpModels; }
-bool getDumpProofs(const Options& opts) { return opts.smt.dumpProofs; }
-bool getDumpUnsatCores(const Options& opts)
-{
- return opts.smt.dumpUnsatCores || opts.smt.dumpUnsatCoresFull;
-}
-bool getFilesystemAccess(const Options& opts)
-{
- return opts.parser.filesystemAccess;
-}
-bool getForceNoLimitCpuWhileDump(const Options& opts)
-{
- return opts.smt.forceNoLimitCpuWhileDump;
-}
-bool getIncrementalSolving(const Options& opts)
-{
- return opts.smt.incrementalSolving;
-}
-bool getLanguageHelp(const Options& opts) { return opts.base.languageHelp; }
-bool getMemoryMap(const Options& opts) { return opts.parser.memoryMap; }
-bool getParseOnly(const Options& opts) { return opts.base.parseOnly; }
-bool getProduceModels(const Options& opts) { return opts.smt.produceModels; }
-bool getSemanticChecks(const Options& opts)
-{
- return opts.parser.semanticChecks;
-}
-bool getStatistics(const Options& opts) { return opts.base.statistics; }
-bool getStatsEveryQuery(const Options& opts)
-{
- return opts.base.statisticsEveryQuery;
-}
-bool getStrictParsing(const Options& opts)
-{
- return opts.parser.strictParsing;
-}
-uint64_t getCumulativeTimeLimit(const Options& opts)
-{
- return opts.resman.cumulativeMillisecondLimit;
-}
-const std::string& getForceLogicString(const Options& opts)
-{
- return opts.parser.forceLogicString;
-}
-int32_t getVerbosity(const Options& opts) { return opts.base.verbosity; }
-
-std::istream* getIn(const Options& opts) { return opts.base.in; }
-std::ostream* getErr(const Options& opts) { return opts.base.err; }
-std::ostream* getOut(const Options& opts) { return opts.base.out; }
-
-void setInputLanguage(InputLanguage val, Options& opts)
-{
- opts.base.inputLanguage = val;
-}
-void setOut(std::ostream* val, Options& opts) { opts.base.out = val; }
-void setOutputLanguage(OutputLanguage val, Options& opts)
-{
- opts.base.outputLanguage = val;
-}
-
-bool wasSetByUserEarlyExit(const Options& opts)
-{
- return opts.driver.earlyExitWasSetByUser;
-}
-bool wasSetByUserForceLogicString(const Options& opts)
-{
- return opts.parser.forceLogicStringWasSetByUser;
-}
-bool wasSetByUserIncrementalSolving(const Options& opts)
-{
- return opts.smt.incrementalSolvingWasSetByUser;
-}
-bool wasSetByUserInteractive(const Options& opts)
-{
- return opts.driver.interactiveWasSetByUser;
-}
} // namespace cvc5::options
diff --git a/src/options/options_public.h b/src/options/options_public.h
index 1d2f9edba..60929c96c 100644
--- a/src/options/options_public.h
+++ b/src/options/options_public.h
@@ -23,47 +23,11 @@
#ifndef CVC5__OPTIONS__OPTIONS_PUBLIC_H
#define CVC5__OPTIONS__OPTIONS_PUBLIC_H
-#include "options/language.h"
#include "options/options.h"
-#include "options/printer_modes.h"
namespace cvc5::options {
-InputLanguage getInputLanguage(const Options& opts) CVC5_EXPORT;
-InstFormatMode getInstFormatMode(const Options& opts) CVC5_EXPORT;
-OutputLanguage getOutputLanguage(const Options& opts) CVC5_EXPORT;
bool getUfHo(const Options& opts) CVC5_EXPORT;
-bool getDumpInstantiations(const Options& opts) CVC5_EXPORT;
-bool getDumpModels(const Options& opts) CVC5_EXPORT;
-bool getDumpProofs(const Options& opts) CVC5_EXPORT;
-bool getDumpUnsatCores(const Options& opts) CVC5_EXPORT;
-bool getFilesystemAccess(const Options& opts) CVC5_EXPORT;
-bool getForceNoLimitCpuWhileDump(const Options& opts) CVC5_EXPORT;
-bool getIncrementalSolving(const Options& opts) CVC5_EXPORT;
-bool getLanguageHelp(const Options& opts) CVC5_EXPORT;
-bool getMemoryMap(const Options& opts) CVC5_EXPORT;
-bool getParseOnly(const Options& opts) CVC5_EXPORT;
-bool getProduceModels(const Options& opts) CVC5_EXPORT;
-bool getSemanticChecks(const Options& opts) CVC5_EXPORT;
-bool getStatistics(const Options& opts) CVC5_EXPORT;
-bool getStatsEveryQuery(const Options& opts) CVC5_EXPORT;
-bool getStrictParsing(const Options& opts) CVC5_EXPORT;
-uint64_t getCumulativeTimeLimit(const Options& opts) CVC5_EXPORT;
-const std::string& getForceLogicString(const Options& opts) CVC5_EXPORT;
-int32_t getVerbosity(const Options& opts) CVC5_EXPORT;
-
-std::istream* getIn(const Options& opts) CVC5_EXPORT;
-std::ostream* getErr(const Options& opts) CVC5_EXPORT;
-std::ostream* getOut(const Options& opts) CVC5_EXPORT;
-
-void setInputLanguage(InputLanguage val, Options& opts) CVC5_EXPORT;
-void setOut(std::ostream* val, Options& opts) CVC5_EXPORT;
-void setOutputLanguage(OutputLanguage val, Options& opts) CVC5_EXPORT;
-
-bool wasSetByUserEarlyExit(const Options& opts) CVC5_EXPORT;
-bool wasSetByUserForceLogicString(const Options& opts) CVC5_EXPORT;
-bool wasSetByUserIncrementalSolving(const Options& opts) CVC5_EXPORT;
-bool wasSetByUserInteractive(const Options& opts) CVC5_EXPORT;
} // namespace cvc5::options
diff --git a/src/options/options_template.cpp b/src/options/options_template.cpp
index e909a5f0a..2c22065c2 100644
--- a/src/options/options_template.cpp
+++ b/src/options/options_template.cpp
@@ -58,7 +58,6 @@ extern int optreset;
${headers_module}$
#include "base/cvc5config.h"
-#include "options/base_handlers.h"
${headers_handler}$
@@ -82,7 +81,9 @@ thread_local Options* Options::s_current = NULL;
*/
template <class T, bool is_numeric, bool is_integer>
struct OptionHandler {
- static T handle(std::string option, std::string optionarg);
+ static T handle(const std::string& option,
+ const std::string& flag,
+ const std::string& optionarg);
};/* struct OptionHandler<> */
/** Variant for integral C++ types */
@@ -99,32 +100,35 @@ struct OptionHandler<T, true, true> {
return str.find('-') != std::string::npos;
}
- static T handle(const std::string& option, const std::string& optionarg) {
+ static T handle(const std::string& option,
+ const std::string& flag,
+ const std::string& optionarg)
+ {
try {
T i;
bool success = stringToInt(i, optionarg);
if(!success){
- throw OptionException(option + ": failed to parse "+ optionarg +
- " as an integer of the appropriate type.");
+ throw OptionException(flag + ": failed to parse " + optionarg
+ + " as an integer of the appropriate type.");
}
// Depending in the platform unsigned numbers with '-' signs may parse.
// Reject these by looking for any minus if it is not signed.
if( (! std::numeric_limits<T>::is_signed) && containsMinus(optionarg) ) {
// unsigned type but user gave negative argument
- throw OptionException(option + " requires a nonnegative argument");
+ throw OptionException(flag + " 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();
+ ss << flag
+ << " 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();
+ ss << flag
+ << " requires an argument <= " << std::numeric_limits<T>::max();
throw OptionException(ss.str());
}
@@ -137,7 +141,7 @@ struct OptionHandler<T, true, true> {
// }
} catch(std::invalid_argument&) {
// user gave something other than an integer
- throw OptionException(option + " requires an integer argument");
+ throw OptionException(flag + " requires an integer argument");
}
}
};/* struct OptionHandler<T, true, true> */
@@ -145,29 +149,33 @@ 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 optionarg) {
- std::stringstream in(optionarg);
+ static T handle(const std::string& option,
+ const std::string& flag,
+ const std::string& optionarg)
+ {
+ std::stringstream inss(optionarg);
long double r;
- in >> r;
- if(! in.eof()) {
+ inss >> r;
+ if (!inss.eof())
+ {
// we didn't consume the whole string (junk at end)
- throw OptionException(option + " requires a numeric argument");
+ throw OptionException(flag + " 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");
+ throw OptionException(flag + " 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();
+ ss << flag
+ << " 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();
+ ss << flag
+ << " requires an argument <= " << std::numeric_limits<T>::max();
throw OptionException(ss.str());
}
@@ -178,7 +186,10 @@ 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 optionarg) {
+ static T handle(const std::string& option,
+ const std::string& flag,
+ const std::string& optionarg)
+ {
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
@@ -191,36 +202,26 @@ 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 optionarg) {
- return OptionHandler<T, std::numeric_limits<T>::is_specialized, std::numeric_limits<T>::is_integer>::handle(option, optionarg);
+T handleOption(const std::string& option,
+ const std::string& flag,
+ const std::string& optionarg)
+{
+ return OptionHandler<T,
+ std::numeric_limits<T>::is_specialized,
+ std::numeric_limits<T>::is_integer>::handle(option,
+ flag,
+ optionarg);
}
/** Handle an option of type std::string in the default way. */
template <>
-std::string handleOption<std::string>(std::string option, std::string optionarg) {
+std::string handleOption<std::string>(const std::string& option,
+ const std::string& flag,
+ const std::string& optionarg)
+{
return optionarg;
}
-/**
- * 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 optionarg, options::OptionsHandler* handler) {
- // 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, optionarg);
-}
-
-template <class T>
-void runBoolPredicates(T, std::string option, bool b, options::OptionsHandler* handler) {
- // By default, nothing to do for bool. Users add things with
- // :predicate in options files to provide custom checking routines
- // that can throw exceptions.
-}
-
Options::Options(OptionsListener* ol)
: d_handler(new options::OptionsHandler(this)),
// clang-format off
diff --git a/src/options/parser_options.toml b/src/options/parser_options.toml
index 6fc683368..f19b903a6 100644
--- a/src/options/parser_options.toml
+++ b/src/options/parser_options.toml
@@ -1,5 +1,6 @@
id = "PARSER"
name = "Parser"
+public = true
[[option]]
name = "strictParsing"
diff --git a/src/options/prop_options.toml b/src/options/prop_options.toml
index 26d7a451b..eda5ea963 100644
--- a/src/options/prop_options.toml
+++ b/src/options/prop_options.toml
@@ -8,7 +8,7 @@ name = "SAT Layer"
long = "random-freq=P"
type = "double"
default = "0.0"
- predicates = ["doubleGreaterOrEqual0", "doubleLessOrEqual1"]
+ predicates = ["betweenZeroAndOne"]
help = "sets the frequency of random decisions in the sat solver (P=0.0 by default)"
[[option]]
@@ -24,7 +24,7 @@ name = "SAT Layer"
category = "regular"
type = "double"
default = "0.95"
- predicates = ["doubleGreaterOrEqual0", "doubleLessOrEqual1"]
+ predicates = ["betweenZeroAndOne"]
help = "variable activity decay factor for Minisat"
[[option]]
@@ -32,7 +32,7 @@ name = "SAT Layer"
category = "regular"
type = "double"
default = "0.999"
- predicates = ["doubleGreaterOrEqual0", "doubleLessOrEqual1"]
+ predicates = ["betweenZeroAndOne"]
help = "clause activity decay factor for Minisat"
[[option]]
@@ -49,7 +49,7 @@ name = "SAT Layer"
long = "restart-int-inc=F"
type = "double"
default = "3.0"
- predicates = ["doubleGreaterOrEqual0"]
+ predicates = ["geqZero"]
help = "sets the restart interval increase factor for the sat solver (F=3.0 by default)"
[[option]]
diff --git a/src/options/resource_manager_options.toml b/src/options/resource_manager_options.toml
deleted file mode 100644
index 6d5c4d4cf..000000000
--- a/src/options/resource_manager_options.toml
+++ /dev/null
@@ -1,51 +0,0 @@
-id = "RESMAN"
-name = "Resource Manager"
-
-[[option]]
- name = "cumulativeMillisecondLimit"
- category = "common"
- long = "tlimit=MS"
- type = "uint64_t"
- help = "set time limit in milliseconds of wall clock time"
-
-[[option]]
- name = "perCallMillisecondLimit"
- category = "common"
- long = "tlimit-per=MS"
- type = "uint64_t"
- help = "set time limit per query in milliseconds"
-
-[[option]]
- name = "cumulativeResourceLimit"
- category = "common"
- long = "rlimit=N"
- type = "uint64_t"
- help = "set resource limit"
-
-[[option]]
- name = "perCallResourceLimit"
- alias = ["reproducible-resource-limit"]
- category = "common"
- long = "rlimit-per=N"
- type = "uint64_t"
- help = "set resource limit per query"
-
-# --rweight is used to override the default of one particular resource weight.
-# It can be given multiple times to override multiple weights. When options are
-# parsed, the resource manager might now be created yet, and it is not clear
-# how an option handler would access it in a reasonable way. The option handler
-# thus merely puts the data in another option that holds a vector of strings.
-# This other option "resourceWeightHolder" has the sole purpose of storing
-# this data in a way so that the resource manager can access it in its
-# constructor.
-[[option]]
- category = "expert"
- long = "rweight=VAL=N"
- type = "std::string"
- handler = "setResourceWeight"
- help = "set a single resource weight"
-
-[[option]]
- name = "resourceWeightHolder"
- category = "undocumented"
- type = "std::vector<std::string>"
diff --git a/src/options/smt_options.toml b/src/options/smt_options.toml
index d1354f777..4d08aa672 100644
--- a/src/options/smt_options.toml
+++ b/src/options/smt_options.toml
@@ -79,14 +79,6 @@ name = "SMT Layer"
help = "after SAT/INVALID/UNKNOWN, check that the generated model satisfies user and internal assertions"
[[option]]
- name = "dumpModels"
- category = "regular"
- long = "dump-models"
- type = "bool"
- default = "false"
- help = "output models after every SAT/INVALID/UNKNOWN response"
-
-[[option]]
name = "modelCoresMode"
category = "regular"
long = "model-cores=MODE"
@@ -131,14 +123,6 @@ name = "SMT Layer"
help = "produce proofs, support check-proofs and get-proof"
[[option]]
- name = "dumpProofs"
- category = "regular"
- long = "dump-proofs"
- type = "bool"
- default = "false"
- help = "output proofs after every UNSAT/VALID response"
-
-[[option]]
name = "checkProofs"
category = "regular"
long = "check-proofs"
@@ -146,14 +130,6 @@ name = "SMT Layer"
help = "after UNSAT/VALID, check the generated proof (with proof)"
[[option]]
- name = "dumpInstantiations"
- category = "regular"
- long = "dump-instantiations"
- type = "bool"
- default = "false"
- help = "output instantiations of quantified formulas after every UNSAT/VALID response"
-
-[[option]]
name = "sygusOut"
category = "regular"
long = "sygus-out=MODE"
@@ -218,22 +194,6 @@ name = "SMT Layer"
help = "after UNSAT/VALID, produce and check an unsat core (expensive)"
[[option]]
- name = "dumpUnsatCores"
- category = "regular"
- long = "dump-unsat-cores"
- type = "bool"
- default = "false"
- help = "output unsat cores after every UNSAT/VALID response"
-
-[[option]]
- name = "dumpUnsatCoresFull"
- category = "regular"
- long = "dump-unsat-cores-full"
- type = "bool"
- default = "false"
- help = "dump the full unsat core, including unlabeled assertions"
-
-[[option]]
name = "unsatAssumptions"
category = "regular"
long = "produce-unsat-assumptions"
@@ -360,15 +320,6 @@ name = "SMT Layer"
help = "calculate sort inference of input problem, convert the input based on monotonic sorts"
[[option]]
- name = "incrementalSolving"
- category = "common"
- short = "i"
- long = "incremental"
- type = "bool"
- default = "true"
- help = "enable incremental solving"
-
-[[option]]
name = "abstractValues"
category = "regular"
long = "abstract-values"
@@ -422,14 +373,6 @@ name = "SMT Layer"
help = "set the diagnostic output channel of the solver"
[[option]]
- name = "forceNoLimitCpuWhileDump"
- category = "regular"
- long = "force-no-limit-cpu-while-dump"
- type = "bool"
- default = "false"
- help = "Force no CPU limit when dumping models and proofs"
-
-[[option]]
name = "foreignTheoryRewrite"
category = "regular"
long = "foreign-theory-rewrite"
diff --git a/src/parser/parser.cpp b/src/parser/parser.cpp
index d96e94d43..eab982013 100644
--- a/src/parser/parser.cpp
+++ b/src/parser/parser.cpp
@@ -26,8 +26,8 @@
#include "base/check.h"
#include "base/output.h"
#include "expr/kind.h"
+#include "options/base_options.h"
#include "options/options.h"
-#include "options/options_public.h"
#include "parser/input.h"
#include "parser/parser_exception.h"
#include "smt/command.h"
@@ -900,7 +900,7 @@ std::wstring Parser::processAdHocStringEsc(const std::string& s)
api::Term Parser::mkStringConstant(const std::string& s)
{
if (language::isInputLang_smt2_6(
- options::getInputLanguage(d_solver->getOptions())))
+ d_solver->getOptions().base.inputLanguage))
{
return d_solver->mkString(s, true);
}
diff --git a/src/parser/parser_builder.cpp b/src/parser/parser_builder.cpp
index 1f25e00dd..816803ccc 100644
--- a/src/parser/parser_builder.cpp
+++ b/src/parser/parser_builder.cpp
@@ -21,8 +21,9 @@
#include "api/cpp/cvc5.h"
#include "base/check.h"
#include "cvc/cvc.h"
+#include "options/base_options.h"
#include "options/options.h"
-#include "options/options_public.h"
+#include "options/parser_options.h"
#include "parser/antlr_input.h"
#include "parser/input.h"
#include "parser/parser.h"
@@ -120,14 +121,14 @@ ParserBuilder& ParserBuilder::withParseOnly(bool flag) {
ParserBuilder& ParserBuilder::withOptions(const Options& opts)
{
ParserBuilder& retval = *this;
- retval = retval.withInputLanguage(options::getInputLanguage(opts))
- .withChecks(options::getSemanticChecks(opts))
- .withStrictMode(options::getStrictParsing(opts))
- .withParseOnly(options::getParseOnly(opts))
- .withIncludeFile(options::getFilesystemAccess(opts));
- if (options::wasSetByUserForceLogicString(opts))
+ retval = retval.withInputLanguage(opts.base.inputLanguage)
+ .withChecks(opts.parser.semanticChecks)
+ .withStrictMode(opts.parser.strictParsing)
+ .withParseOnly(opts.base.parseOnly)
+ .withIncludeFile(opts.parser.filesystemAccess);
+ if (opts.parser.forceLogicStringWasSetByUser)
{
- LogicInfo tmp(options::getForceLogicString(opts));
+ LogicInfo tmp(opts.parser.forceLogicString);
retval = retval.withForcedLogic(tmp.getLogicString());
}
return retval;
diff --git a/src/parser/smt2/smt2.cpp b/src/parser/smt2/smt2.cpp
index 56aebdcf7..282b72974 100644
--- a/src/parser/smt2/smt2.cpp
+++ b/src/parser/smt2/smt2.cpp
@@ -17,6 +17,7 @@
#include <algorithm>
#include "base/check.h"
+#include "options/base_options.h"
#include "options/options.h"
#include "options/options_public.h"
#include "parser/antlr_input.h"
@@ -846,7 +847,7 @@ api::Term Smt2::mkAbstractValue(const std::string& name)
InputLanguage Smt2::getLanguage() const
{
- return options::getInputLanguage(d_solver->getOptions());
+ return d_solver->getOptions().base.inputLanguage;
}
void Smt2::parseOpApplyTypeAscription(ParseOp& p, api::Sort type)
diff --git a/src/preprocessing/passes/ackermann.cpp b/src/preprocessing/passes/ackermann.cpp
index 89029b5eb..eb6410291 100644
--- a/src/preprocessing/passes/ackermann.cpp
+++ b/src/preprocessing/passes/ackermann.cpp
@@ -29,8 +29,8 @@
#include "base/check.h"
#include "expr/node_algorithm.h"
#include "expr/skolem_manager.h"
+#include "options/base_options.h"
#include "options/options.h"
-#include "options/smt_options.h"
#include "preprocessing/assertion_pipeline.h"
#include "preprocessing/preprocessing_pass_context.h"
diff --git a/src/preprocessing/passes/int_to_bv.cpp b/src/preprocessing/passes/int_to_bv.cpp
index 15a16888d..df9d44e39 100644
--- a/src/preprocessing/passes/int_to_bv.cpp
+++ b/src/preprocessing/passes/int_to_bv.cpp
@@ -26,6 +26,7 @@
#include "expr/node.h"
#include "expr/node_traversal.h"
#include "expr/skolem_manager.h"
+#include "options/base_options.h"
#include "options/smt_options.h"
#include "preprocessing/assertion_pipeline.h"
#include "theory/rewriter.h"
diff --git a/src/preprocessing/passes/ite_simp.cpp b/src/preprocessing/passes/ite_simp.cpp
index 5bfb2a79f..d1dd389ae 100644
--- a/src/preprocessing/passes/ite_simp.cpp
+++ b/src/preprocessing/passes/ite_simp.cpp
@@ -17,6 +17,7 @@
#include <vector>
+#include "options/base_options.h"
#include "options/smt_options.h"
#include "preprocessing/assertion_pipeline.h"
#include "preprocessing/preprocessing_pass_context.h"
diff --git a/src/preprocessing/passes/miplib_trick.cpp b/src/preprocessing/passes/miplib_trick.cpp
index 79fcc4028..a5720e758 100644
--- a/src/preprocessing/passes/miplib_trick.cpp
+++ b/src/preprocessing/passes/miplib_trick.cpp
@@ -22,7 +22,7 @@
#include "expr/node_self_iterator.h"
#include "expr/skolem_manager.h"
#include "options/arith_options.h"
-#include "options/smt_options.h"
+#include "options/base_options.h"
#include "preprocessing/assertion_pipeline.h"
#include "preprocessing/preprocessing_pass_context.h"
#include "smt/smt_statistics_registry.h"
diff --git a/src/proof/proof_rule.h b/src/proof/proof_rule.h
index a42b30773..c1cf0338a 100644
--- a/src/proof/proof_rule.h
+++ b/src/proof/proof_rule.h
@@ -688,9 +688,9 @@ enum class PfRule : uint32_t
//================================================= Array rules
// ======== Read over write
// Children: (P:(not (= i1 i2)))
- // Arguments: ((select (store a i2 e) i1))
+ // Arguments: ((select (store a i1 e) i2))
// ----------------------------------------
- // Conclusion: (= (select (store a i2 e) i1) (select a i1))
+ // Conclusion: (= (select (store a i1 e) i2) (select a i2))
ARRAYS_READ_OVER_WRITE,
// ======== Read over write, contrapositive
// Children: (P:(not (= (select (store a i2 e) i1) (select a i1)))
diff --git a/src/prop/cadical.cpp b/src/prop/cadical.cpp
index ec8919b0b..ddf20f5a1 100644
--- a/src/prop/cadical.cpp
+++ b/src/prop/cadical.cpp
@@ -17,8 +17,6 @@
#include "prop/cadical.h"
-#ifdef CVC5_USE_CADICAL
-
#include "base/check.h"
#include "util/statistics_registry.h"
@@ -191,5 +189,3 @@ CadicalSolver::Statistics::Statistics(StatisticsRegistry& registry,
} // namespace prop
} // namespace cvc5
-
-#endif // CVC5_USE_CADICAL
diff --git a/src/prop/cadical.h b/src/prop/cadical.h
index b5e26df9f..46c7c7e42 100644
--- a/src/prop/cadical.h
+++ b/src/prop/cadical.h
@@ -20,8 +20,6 @@
#ifndef CVC5__PROP__CADICAL_H
#define CVC5__PROP__CADICAL_H
-#ifdef CVC5_USE_CADICAL
-
#include "prop/sat_solver.h"
#include <cadical.hpp>
@@ -103,5 +101,4 @@ class CadicalSolver : public SatSolver
} // namespace prop
} // namespace cvc5
-#endif // CVC5_USE_CADICAL
#endif // CVC5__PROP__CADICAL_H
diff --git a/src/prop/cnf_stream.cpp b/src/prop/cnf_stream.cpp
index f8a34ec42..4897f8e6a 100644
--- a/src/prop/cnf_stream.cpp
+++ b/src/prop/cnf_stream.cpp
@@ -21,14 +21,15 @@
#include "base/output.h"
#include "expr/node.h"
#include "options/bv_options.h"
+#include "printer/printer.h"
#include "proof/clause_id.h"
#include "prop/minisat/minisat.h"
#include "prop/prop_engine.h"
#include "prop/theory_proxy.h"
#include "smt/dump.h"
#include "smt/smt_engine.h"
-#include "printer/printer.h"
#include "smt/smt_engine_scope.h"
+#include "smt/smt_statistics_registry.h"
#include "theory/theory.h"
#include "theory/theory_engine.h"
@@ -52,7 +53,8 @@ CnfStream::CnfStream(SatSolver* satSolver,
d_registrar(registrar),
d_name(name),
d_removable(false),
- d_resourceManager(rm)
+ d_resourceManager(rm),
+ d_stats(name)
{
}
@@ -139,6 +141,7 @@ void CnfStream::ensureLiteral(TNode n)
n.toString().c_str(),
n.getType().toString().c_str());
Trace("cnf") << "ensureLiteral(" << n << ")\n";
+ TimerStat::CodeTimer codeTimer(d_stats.d_cnfConversionTime, true);
if (hasLiteral(n))
{
ensureMappingForLiteral(n);
@@ -292,7 +295,7 @@ SatLiteral CnfStream::getLiteral(TNode node) {
return literal;
}
-SatLiteral CnfStream::handleXor(TNode xorNode)
+void CnfStream::handleXor(TNode xorNode)
{
Assert(!hasLiteral(xorNode)) << "Atom already mapped!";
Assert(xorNode.getKind() == kind::XOR) << "Expecting an XOR expression!";
@@ -300,8 +303,8 @@ SatLiteral CnfStream::handleXor(TNode xorNode)
Assert(!d_removable) << "Removable clauses can not contain Boolean structure";
Trace("cnf") << "CnfStream::handleXor(" << xorNode << ")\n";
- SatLiteral a = toCNF(xorNode[0]);
- SatLiteral b = toCNF(xorNode[1]);
+ SatLiteral a = getLiteral(xorNode[0]);
+ SatLiteral b = getLiteral(xorNode[1]);
SatLiteral xorLit = newLiteral(xorNode);
@@ -309,11 +312,9 @@ SatLiteral CnfStream::handleXor(TNode xorNode)
assertClause(xorNode.negate(), ~a, ~b, ~xorLit);
assertClause(xorNode, a, ~b, xorLit);
assertClause(xorNode, ~a, b, xorLit);
-
- return xorLit;
}
-SatLiteral CnfStream::handleOr(TNode orNode)
+void CnfStream::handleOr(TNode orNode)
{
Assert(!hasLiteral(orNode)) << "Atom already mapped!";
Assert(orNode.getKind() == kind::OR) << "Expecting an OR expression!";
@@ -322,37 +323,31 @@ SatLiteral CnfStream::handleOr(TNode orNode)
Trace("cnf") << "CnfStream::handleOr(" << orNode << ")\n";
// Number of children
- unsigned n_children = orNode.getNumChildren();
-
- // Transform all the children first
- TNode::const_iterator node_it = orNode.begin();
- TNode::const_iterator node_it_end = orNode.end();
- SatClause clause(n_children + 1);
- for(int i = 0; node_it != node_it_end; ++node_it, ++i) {
- clause[i] = toCNF(*node_it);
- }
+ size_t numChildren = orNode.getNumChildren();
// Get the literal for this node
SatLiteral orLit = newLiteral(orNode);
- // lit <- (a_1 | a_2 | a_3 | ... | a_n)
- // lit | ~(a_1 | a_2 | a_3 | ... | a_n)
- // (lit | ~a_1) & (lit | ~a_2) & (lit & ~a_3) & ... & (lit & ~a_n)
- for(unsigned i = 0; i < n_children; ++i) {
+ // Transform all the children first
+ SatClause clause(numChildren + 1);
+ for (size_t i = 0; i < numChildren; ++i)
+ {
+ clause[i] = getLiteral(orNode[i]);
+
+ // lit <- (a_1 | a_2 | a_3 | ... | a_n)
+ // lit | ~(a_1 | a_2 | a_3 | ... | a_n)
+ // (lit | ~a_1) & (lit | ~a_2) & (lit & ~a_3) & ... & (lit & ~a_n)
assertClause(orNode, orLit, ~clause[i]);
}
// lit -> (a_1 | a_2 | a_3 | ... | a_n)
// ~lit | a_1 | a_2 | a_3 | ... | a_n
- clause[n_children] = ~orLit;
+ clause[numChildren] = ~orLit;
// This needs to go last, as the clause might get modified by the SAT solver
assertClause(orNode.negate(), clause);
-
- // Return the literal
- return orLit;
}
-SatLiteral CnfStream::handleAnd(TNode andNode)
+void CnfStream::handleAnd(TNode andNode)
{
Assert(!hasLiteral(andNode)) << "Atom already mapped!";
Assert(andNode.getKind() == kind::AND) << "Expecting an AND expression!";
@@ -361,37 +356,32 @@ SatLiteral CnfStream::handleAnd(TNode andNode)
Trace("cnf") << "handleAnd(" << andNode << ")\n";
// Number of children
- unsigned n_children = andNode.getNumChildren();
-
- // Transform all the children first (remembering the negation)
- TNode::const_iterator node_it = andNode.begin();
- TNode::const_iterator node_it_end = andNode.end();
- SatClause clause(n_children + 1);
- for(int i = 0; node_it != node_it_end; ++node_it, ++i) {
- clause[i] = ~toCNF(*node_it);
- }
+ size_t numChildren = andNode.getNumChildren();
// Get the literal for this node
SatLiteral andLit = newLiteral(andNode);
- // lit -> (a_1 & a_2 & a_3 & ... & a_n)
- // ~lit | (a_1 & a_2 & a_3 & ... & a_n)
- // (~lit | a_1) & (~lit | a_2) & ... & (~lit | a_n)
- for(unsigned i = 0; i < n_children; ++i) {
+ // Transform all the children first (remembering the negation)
+ SatClause clause(numChildren + 1);
+ for (size_t i = 0; i < numChildren; ++i)
+ {
+ clause[i] = ~getLiteral(andNode[i]);
+
+ // lit -> (a_1 & a_2 & a_3 & ... & a_n)
+ // ~lit | (a_1 & a_2 & a_3 & ... & a_n)
+ // (~lit | a_1) & (~lit | a_2) & ... & (~lit | a_n)
assertClause(andNode.negate(), ~andLit, ~clause[i]);
}
// lit <- (a_1 & a_2 & a_3 & ... a_n)
// lit | ~(a_1 & a_2 & a_3 & ... & a_n)
// lit | ~a_1 | ~a_2 | ~a_3 | ... | ~a_n
- clause[n_children] = andLit;
+ clause[numChildren] = andLit;
// This needs to go last, as the clause might get modified by the SAT solver
assertClause(andNode, clause);
-
- return andLit;
}
-SatLiteral CnfStream::handleImplies(TNode impliesNode)
+void CnfStream::handleImplies(TNode impliesNode)
{
Assert(!hasLiteral(impliesNode)) << "Atom already mapped!";
Assert(impliesNode.getKind() == kind::IMPLIES)
@@ -401,8 +391,8 @@ SatLiteral CnfStream::handleImplies(TNode impliesNode)
Trace("cnf") << "handleImplies(" << impliesNode << ")\n";
// Convert the children to cnf
- SatLiteral a = toCNF(impliesNode[0]);
- SatLiteral b = toCNF(impliesNode[1]);
+ SatLiteral a = getLiteral(impliesNode[0]);
+ SatLiteral b = getLiteral(impliesNode[1]);
SatLiteral impliesLit = newLiteral(impliesNode);
@@ -415,11 +405,9 @@ SatLiteral CnfStream::handleImplies(TNode impliesNode)
// (a | l) & (~b | l)
assertClause(impliesNode, a, impliesLit);
assertClause(impliesNode, ~b, impliesLit);
-
- return impliesLit;
}
-SatLiteral CnfStream::handleIff(TNode iffNode)
+void CnfStream::handleIff(TNode iffNode)
{
Assert(!hasLiteral(iffNode)) << "Atom already mapped!";
Assert(iffNode.getKind() == kind::EQUAL) << "Expecting an EQUAL expression!";
@@ -428,8 +416,8 @@ SatLiteral CnfStream::handleIff(TNode iffNode)
Trace("cnf") << "handleIff(" << iffNode << ")\n";
// Convert the children to CNF
- SatLiteral a = toCNF(iffNode[0]);
- SatLiteral b = toCNF(iffNode[1]);
+ SatLiteral a = getLiteral(iffNode[0]);
+ SatLiteral b = getLiteral(iffNode[1]);
// Get the now literal
SatLiteral iffLit = newLiteral(iffNode);
@@ -447,11 +435,9 @@ SatLiteral CnfStream::handleIff(TNode iffNode)
// (~a | ~b | lit) & (a | b | lit)
assertClause(iffNode, ~a, ~b, iffLit);
assertClause(iffNode, a, b, iffLit);
-
- return iffLit;
}
-SatLiteral CnfStream::handleIte(TNode iteNode)
+void CnfStream::handleIte(TNode iteNode)
{
Assert(!hasLiteral(iteNode)) << "Atom already mapped!";
Assert(iteNode.getKind() == kind::ITE);
@@ -460,9 +446,9 @@ SatLiteral CnfStream::handleIte(TNode iteNode)
Trace("cnf") << "handleIte(" << iteNode[0] << " " << iteNode[1] << " "
<< iteNode[2] << ")\n";
- SatLiteral condLit = toCNF(iteNode[0]);
- SatLiteral thenLit = toCNF(iteNode[1]);
- SatLiteral elseLit = toCNF(iteNode[2]);
+ SatLiteral condLit = getLiteral(iteNode[0]);
+ SatLiteral thenLit = getLiteral(iteNode[1]);
+ SatLiteral elseLit = getLiteral(iteNode[2]);
SatLiteral iteLit = newLiteral(iteNode);
@@ -485,47 +471,79 @@ SatLiteral CnfStream::handleIte(TNode iteNode)
assertClause(iteNode, iteLit, ~thenLit, ~elseLit);
assertClause(iteNode, iteLit, ~condLit, ~thenLit);
assertClause(iteNode, iteLit, condLit, ~elseLit);
-
- return iteLit;
}
SatLiteral CnfStream::toCNF(TNode node, bool negated)
{
Trace("cnf") << "toCNF(" << node
<< ", negated = " << (negated ? "true" : "false") << ")\n";
+
+ TNode cur;
SatLiteral nodeLit;
- Node negatedNode = node.notNode();
-
- // If the non-negated node has already been translated, get the translation
- if(hasLiteral(node)) {
- Trace("cnf") << "toCNF(): already translated\n";
- nodeLit = getLiteral(node);
- // Return the (maybe negated) literal
- return !negated ? nodeLit : ~nodeLit;
- }
- // Handle each Boolean operator case
- switch (node.getKind())
+ std::vector<TNode> visit;
+ std::unordered_map<TNode, bool> cache;
+
+ visit.push_back(node);
+ while (!visit.empty())
{
- case kind::NOT: nodeLit = ~toCNF(node[0]); break;
- case kind::XOR: nodeLit = handleXor(node); break;
- case kind::ITE: nodeLit = handleIte(node); break;
- case kind::IMPLIES: nodeLit = handleImplies(node); break;
- case kind::OR: nodeLit = handleOr(node); break;
- case kind::AND: nodeLit = handleAnd(node); break;
- case kind::EQUAL:
- nodeLit =
- node[0].getType().isBoolean() ? handleIff(node) : convertAtom(node);
- break;
- default:
+ cur = visit.back();
+ Assert(cur.getType().isBoolean());
+
+ if (hasLiteral(cur))
{
- nodeLit = convertAtom(node);
+ visit.pop_back();
+ continue;
}
- break;
+
+ const auto& it = cache.find(cur);
+ if (it == cache.end())
+ {
+ cache.emplace(cur, false);
+ Kind k = cur.getKind();
+ // Only traverse Boolean nodes
+ if (k == kind::NOT || k == kind::XOR || k == kind::ITE
+ || k == kind::IMPLIES || k == kind::OR || k == kind::AND
+ || (k == kind::EQUAL && cur[0].getType().isBoolean()))
+ {
+ // Preserve the order of the recursive version
+ for (size_t i = 0, size = cur.getNumChildren(); i < size; ++i)
+ {
+ visit.push_back(cur[size - 1 - i]);
+ }
+ }
+ continue;
+ }
+ else if (!it->second)
+ {
+ it->second = true;
+ Kind k = cur.getKind();
+ switch (k)
+ {
+ case kind::NOT: Assert(hasLiteral(cur[0])); break;
+ case kind::XOR: handleXor(cur); break;
+ case kind::ITE: handleIte(cur); break;
+ case kind::IMPLIES: handleImplies(cur); break;
+ case kind::OR: handleOr(cur); break;
+ case kind::AND: handleAnd(cur); break;
+ default:
+ if (k == kind::EQUAL && cur[0].getType().isBoolean())
+ {
+ handleIff(cur);
+ }
+ else
+ {
+ convertAtom(cur);
+ }
+ break;
+ }
+ }
+ visit.pop_back();
}
- // Return the (maybe negated) literal
+
+ nodeLit = getLiteral(node);
Trace("cnf") << "toCNF(): resulting literal: "
<< (!negated ? nodeLit : ~nodeLit) << "\n";
- return !negated ? nodeLit : ~nodeLit;
+ return negated ? ~nodeLit : nodeLit;
}
void CnfStream::convertAndAssertAnd(TNode node, bool negated)
@@ -707,6 +725,7 @@ void CnfStream::convertAndAssert(TNode node,
<< ", negated = " << (negated ? "true" : "false")
<< ", removable = " << (removable ? "true" : "false") << ")\n";
d_removable = removable;
+ TimerStat::CodeTimer codeTimer(d_stats.d_cnfConversionTime, true);
convertAndAssert(node, negated);
}
@@ -745,5 +764,11 @@ void CnfStream::convertAndAssert(TNode node, bool negated)
}
}
+CnfStream::Statistics::Statistics(const std::string& name)
+ : d_cnfConversionTime(smtStatisticsRegistry().registerTimer(
+ name + "::CnfStream::cnfConversionTime"))
+{
+}
+
} // namespace prop
} // namespace cvc5
diff --git a/src/prop/cnf_stream.h b/src/prop/cnf_stream.h
index 264e26777..aeed97380 100644
--- a/src/prop/cnf_stream.h
+++ b/src/prop/cnf_stream.h
@@ -191,16 +191,16 @@ class CnfStream {
*/
SatLiteral toCNF(TNode node, bool negated = false);
- /** Specific clausifiers, based on the formula kinds, that clausify a formula,
- * by calling toCNF into each of the formula's children under the respective
- * kind, and introduce a literal definitionally equal to it. */
- SatLiteral handleNot(TNode node);
- SatLiteral handleXor(TNode node);
- SatLiteral handleImplies(TNode node);
- SatLiteral handleIff(TNode node);
- SatLiteral handleIte(TNode node);
- SatLiteral handleAnd(TNode node);
- SatLiteral handleOr(TNode node);
+ /**
+ * Specific clausifiers that clausify a formula based on the given formula
+ * kind and introduce a literal definitionally equal to it.
+ */
+ void handleXor(TNode node);
+ void handleImplies(TNode node);
+ void handleIff(TNode node);
+ void handleIte(TNode node);
+ void handleAnd(TNode node);
+ void handleOr(TNode node);
/** Stores the literal of the given node in d_literalToNodeMap.
*
@@ -309,6 +309,14 @@ class CnfStream {
/** Pointer to resource manager for associated SmtEngine */
ResourceManager* d_resourceManager;
+
+ private:
+ struct Statistics
+ {
+ Statistics(const std::string& name);
+ TimerStat d_cnfConversionTime;
+ } d_stats;
+
}; /* class CnfStream */
} // namespace prop
diff --git a/src/prop/minisat/core/Solver.cc b/src/prop/minisat/core/Solver.cc
index fd86d3a42..6f99a47f0 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 "base/check.h"
#include "base/output.h"
+#include "options/base_options.h"
#include "options/main_options.h"
#include "options/prop_options.h"
#include "options/smt_options.h"
diff --git a/src/prop/proof_cnf_stream.h b/src/prop/proof_cnf_stream.h
index 9972581c0..af131c2c3 100644
--- a/src/prop/proof_cnf_stream.h
+++ b/src/prop/proof_cnf_stream.h
@@ -133,7 +133,6 @@ class ProofCnfStream : public ProofGenerator
* Specific clausifiers, based on the formula kinds, that clausify a formula,
* by calling toCNF into each of the formula's children under the respective
* kind, and introduce a literal definitionally equal to it. */
- SatLiteral handleNot(TNode node);
SatLiteral handleXor(TNode node);
SatLiteral handleImplies(TNode node);
SatLiteral handleIff(TNode node);
diff --git a/src/prop/prop_engine.cpp b/src/prop/prop_engine.cpp
index fe3a5ecff..62b2f655c 100644
--- a/src/prop/prop_engine.cpp
+++ b/src/prop/prop_engine.cpp
@@ -107,7 +107,8 @@ PropEngine::PropEngine(TheoryEngine* te,
userContext,
&d_outMgr,
rm,
- FormulaLitPolicy::TRACK);
+ FormulaLitPolicy::TRACK,
+ "prop");
// connect theory proxy
d_theoryProxy->finishInit(d_cnfStream);
diff --git a/src/prop/sat_solver_factory.cpp b/src/prop/sat_solver_factory.cpp
index 446f72451..0855cbda5 100644
--- a/src/prop/sat_solver_factory.cpp
+++ b/src/prop/sat_solver_factory.cpp
@@ -53,13 +53,9 @@ SatSolver* SatSolverFactory::createCryptoMinisat(StatisticsRegistry& registry,
SatSolver* SatSolverFactory::createCadical(StatisticsRegistry& registry,
const std::string& name)
{
-#ifdef CVC5_USE_CADICAL
CadicalSolver* res = new CadicalSolver(registry, name);
res->init();
return res;
-#else
- Unreachable() << "cvc5 was not compiled with CaDiCaL support.";
-#endif
}
SatSolver* SatSolverFactory::createKissat(StatisticsRegistry& registry,
diff --git a/src/smt/command.cpp b/src/smt/command.cpp
index d672b79a6..5f0da7a0c 100644
--- a/src/smt/command.cpp
+++ b/src/smt/command.cpp
@@ -31,6 +31,7 @@
#include "expr/symbol_manager.h"
#include "expr/type_node.h"
#include "options/options.h"
+#include "options/main_options.h"
#include "options/printer_options.h"
#include "options/smt_options.h"
#include "printer/printer.h"
diff --git a/src/smt/optimization_solver.cpp b/src/smt/optimization_solver.cpp
index e85ea82ef..a46452004 100644
--- a/src/smt/optimization_solver.cpp
+++ b/src/smt/optimization_solver.cpp
@@ -32,12 +32,11 @@ OptimizationSolver::OptimizationSolver(SmtEngine* parent)
: d_parent(parent),
d_optChecker(),
d_objectives(parent->getUserContext()),
- d_results(),
- d_objectiveCombination(LEXICOGRAPHIC)
+ d_results()
{
}
-OptimizationResult::ResultType OptimizationSolver::checkOpt()
+Result OptimizationSolver::checkOpt(ObjectiveCombination combination)
{
// if the results of the previous call have different size than the
// objectives, then we should clear the pareto optimization context
@@ -48,7 +47,7 @@ OptimizationResult::ResultType OptimizationSolver::checkOpt()
{
d_results.emplace_back();
}
- switch (d_objectiveCombination)
+ switch (combination)
{
case BOX: return optimizeBox(); break;
case LEXICOGRAPHIC: return optimizeLexicographicIterative(); break;
@@ -76,16 +75,9 @@ void OptimizationSolver::addObjective(TNode target,
std::vector<OptimizationResult> OptimizationSolver::getValues()
{
- Assert(d_objectives.size() == d_results.size());
return d_results;
}
-void OptimizationSolver::setObjectiveCombination(
- ObjectiveCombination combination)
-{
- d_objectiveCombination = combination;
-}
-
std::unique_ptr<SmtEngine> OptimizationSolver::createOptCheckerWithTimeout(
SmtEngine* parentSMTSolver, bool needsTimeout, unsigned long timeout)
{
@@ -106,13 +98,12 @@ std::unique_ptr<SmtEngine> OptimizationSolver::createOptCheckerWithTimeout(
return optChecker;
}
-OptimizationResult::ResultType OptimizationSolver::optimizeBox()
+Result OptimizationSolver::optimizeBox()
{
// resets the optChecker
d_optChecker = createOptCheckerWithTimeout(d_parent);
OptimizationResult partialResult;
- OptimizationResult::ResultType aggregatedResultType =
- OptimizationResult::OPTIMAL;
+ Result aggregatedResult(Result::Sat::SAT);
std::unique_ptr<OMTOptimizer> optimizer;
for (size_t i = 0, numObj = d_objectives.size(); i < numObj; ++i)
{
@@ -134,18 +125,19 @@ OptimizationResult::ResultType OptimizationSolver::optimizeBox()
}
// match the optimization result type, and aggregate the results of
// subproblems
- switch (partialResult.getType())
+ switch (partialResult.getResult().isSat())
{
- case OptimizationResult::OPTIMAL: break;
- case OptimizationResult::UNBOUNDED: break;
- case OptimizationResult::UNSAT:
- if (aggregatedResultType == OptimizationResult::OPTIMAL)
+ case Result::SAT: break;
+ case Result::UNSAT:
+ // the assertions are unsatisfiable
+ for (size_t j = 0; j < numObj; ++j)
{
- aggregatedResultType = OptimizationResult::UNSAT;
+ d_results[j] = partialResult;
}
- break;
- case OptimizationResult::UNKNOWN:
- aggregatedResultType = OptimizationResult::UNKNOWN;
+ d_optChecker.reset();
+ return partialResult.getResult();
+ case Result::SAT_UNKNOWN:
+ aggregatedResult = partialResult.getResult();
break;
default: Unreachable();
}
@@ -154,15 +146,20 @@ OptimizationResult::ResultType OptimizationSolver::optimizeBox()
}
// kill optChecker after optimization ends
d_optChecker.reset();
- return aggregatedResultType;
+ return aggregatedResult;
}
-OptimizationResult::ResultType
-OptimizationSolver::optimizeLexicographicIterative()
+Result OptimizationSolver::optimizeLexicographicIterative()
{
// resets the optChecker
d_optChecker = createOptCheckerWithTimeout(d_parent);
- OptimizationResult partialResult;
+ // partialResult defaults to SAT if no objective is present
+ // NOTE: the parenthesis around Result(Result::SAT) is required,
+ // otherwise the compiler will report "parameter declarator cannot be
+ // qualified". For more details:
+ // https://stackoverflow.com/questions/44045257/c-compiler-error-c2751-what-exactly-causes-it
+ // https://en.wikipedia.org/wiki/Most_vexing_parse
+ OptimizationResult partialResult((Result(Result::SAT)), TNode());
std::unique_ptr<OMTOptimizer> optimizer;
for (size_t i = 0, numObj = d_objectives.size(); i < numObj; ++i)
{
@@ -186,26 +183,33 @@ OptimizationSolver::optimizeLexicographicIterative()
d_results[i] = partialResult;
// checks the optimization result of the current objective
- switch (partialResult.getType())
+ switch (partialResult.getResult().isSat())
{
- case OptimizationResult::OPTIMAL:
+ case Result::SAT:
// assert target[i] == value[i] and proceed
d_optChecker->assertFormula(d_optChecker->getNodeManager()->mkNode(
kind::EQUAL, d_objectives[i].getTarget(), d_results[i].getValue()));
break;
- case OptimizationResult::UNBOUNDED: return OptimizationResult::UNBOUNDED;
- case OptimizationResult::UNSAT: return OptimizationResult::UNSAT;
- case OptimizationResult::UNKNOWN: return OptimizationResult::UNKNOWN;
+ case Result::UNSAT:
+ d_optChecker.reset();
+ return partialResult.getResult();
+ case Result::SAT_UNKNOWN:
+ d_optChecker.reset();
+ return partialResult.getResult();
default: Unreachable();
}
+
+ // if the result for the current objective is unbounded
+ // then just stop
+ if (partialResult.isUnbounded()) break;
}
// kill optChecker in case pareto misuses it
d_optChecker.reset();
- // now all objectives are OPTIMAL, just return OPTIMAL as overall result
- return OptimizationResult::OPTIMAL;
+ // now all objectives are optimal, just return SAT as the overall result
+ return partialResult.getResult();
}
-OptimizationResult::ResultType OptimizationSolver::optimizeParetoNaiveGIA()
+Result OptimizationSolver::optimizeParetoNaiveGIA()
{
// initial call to Pareto optimizer, create the checker
if (!d_optChecker) d_optChecker = createOptCheckerWithTimeout(d_parent);
@@ -216,8 +220,8 @@ OptimizationResult::ResultType OptimizationSolver::optimizeParetoNaiveGIA()
switch (satResult.isSat())
{
- case Result::Sat::UNSAT: return OptimizationResult::UNSAT;
- case Result::Sat::SAT_UNKNOWN: return OptimizationResult::UNKNOWN;
+ case Result::Sat::UNSAT: return satResult;
+ case Result::Sat::SAT_UNKNOWN: return satResult;
case Result::Sat::SAT:
{
// if satisfied, use d_results to store the initial results
@@ -226,14 +230,15 @@ OptimizationResult::ResultType OptimizationSolver::optimizeParetoNaiveGIA()
for (size_t i = 0, numObj = d_objectives.size(); i < numObj; ++i)
{
d_results[i] = OptimizationResult(
- OptimizationResult::OPTIMAL,
- d_optChecker->getValue(d_objectives[i].getTarget()));
+ satResult, d_optChecker->getValue(d_objectives[i].getTarget()));
}
break;
}
default: Unreachable();
}
+ Result lastSatResult = satResult;
+
// a vector storing assertions saying that no objective is worse
std::vector<Node> noWorseObj;
// a vector storing assertions saying that there is at least one objective
@@ -278,15 +283,15 @@ OptimizationResult::ResultType OptimizationSolver::optimizeParetoNaiveGIA()
case Result::Sat::SAT_UNKNOWN:
// if result is UNKNOWN, abort the current session and return UNKNOWN
d_optChecker.reset();
- return OptimizationResult::UNKNOWN;
+ return satResult;
case Result::Sat::SAT:
{
+ lastSatResult = satResult;
// if result is SAT, update d_results to the more optimal values
for (size_t i = 0, numObj = d_objectives.size(); i < numObj; ++i)
{
d_results[i] = OptimizationResult(
- OptimizationResult::OPTIMAL,
- d_optChecker->getValue(d_objectives[i].getTarget()));
+ satResult, d_optChecker->getValue(d_objectives[i].getTarget()));
}
break;
}
@@ -302,7 +307,7 @@ OptimizationResult::ResultType OptimizationSolver::optimizeParetoNaiveGIA()
// for the next run.
d_optChecker->assertFormula(nm->mkOr(someObjBetter));
- return OptimizationResult::OPTIMAL;
+ return lastSatResult;
}
} // namespace smt
diff --git a/src/smt/optimization_solver.h b/src/smt/optimization_solver.h
index 6d138deb2..d13168780 100644
--- a/src/smt/optimization_solver.h
+++ b/src/smt/optimization_solver.h
@@ -33,63 +33,75 @@ namespace smt {
/**
* The optimization result of an optimization objective
* containing:
- * - whether it's optimal or not
- * - if so, the optimal value, otherwise the value might be empty node or
- * something suboptimal
+ * - the optimization result: SAT/UNSAT/UNKNOWN
+ * - the optimal value if SAT and bounded
+ * (optimal value reached and it's not infinity),
+ * or an empty node if SAT and unbounded
+ * (optimal value is +inf for maximum or -inf for minimum),
+ * otherwise the value might be empty node
+ * or something suboptimal
+ * - whether the objective is unbounded
*/
class OptimizationResult
{
public:
/**
- * Enum indicating whether the checkOpt result
- * is optimal or not.
- **/
- enum ResultType
- {
- // whether the value is optimal is UNKNOWN
- UNKNOWN,
- // the original set of assertions has result UNSAT
- UNSAT,
- // the value is optimal
- OPTIMAL,
- // the goal is unbounded,
- // if objective is maximize, it's +infinity
- // if objective is minimize, it's -infinity
- UNBOUNDED,
- };
-
- /**
* Constructor
* @param type the optimization outcome
* @param value the optimized value
+ * @param unbounded whether the objective is unbounded
**/
- OptimizationResult(ResultType type, TNode value)
- : d_type(type), d_value(value)
+ OptimizationResult(Result result, TNode value, bool unbounded = false)
+ : d_result(result), d_value(value), d_unbounded(unbounded)
+ {
+ }
+ OptimizationResult()
+ : d_result(Result::Sat::SAT_UNKNOWN,
+ Result::UnknownExplanation::NO_STATUS),
+ d_value(),
+ d_unbounded(false)
{
}
- OptimizationResult() : d_type(UNKNOWN), d_value() {}
~OptimizationResult() = default;
/**
* Returns an enum indicating whether
- * the result is optimal or not.
- * @return an enum showing whether the result is optimal, unbounded,
- * unsat or unknown.
+ * the result is SAT or not.
+ * @return whether the result is SAT, UNSAT or SAT_UNKNOWN
**/
- ResultType getType() const { return d_type; }
+ Result getResult() const { return d_result; }
+
/**
* Returns the optimal value.
* @return Node containing the optimal value,
- * if getType() is not OPTIMAL, it might return an empty node or a node
- * containing non-optimal value
+ * if result is unbounded, this will be an empty node,
+ * if getResult() is UNSAT, it will return an empty node,
+ * if getResult() is SAT_UNKNOWN, it will return something suboptimal
+ * or an empty node, depending on how the solver runs.
**/
Node getValue() const { return d_value; }
+ /**
+ * Checks whether the objective is unbouned
+ * @return whether the objective is unbounded
+ * if the objective is unbounded (this function returns true),
+ * then the optimal value is:
+ * +inf, if it's maximize;
+ * -inf, if it's minimize
+ **/
+ bool isUnbounded() const { return d_unbounded; }
+
private:
- /** the indicating whether the result is optimal or something else **/
- ResultType d_type;
- /** if the result is optimal, this is storing the optimal value **/
+ /** indicating whether the result is SAT, UNSAT or UNKNOWN **/
+ Result d_result;
+ /** if the result is bounded, this is storing the value **/
Node d_value;
+ /** whether the objective is unbounded
+ * If this is true, then:
+ * if objective is maximize, it's +infinity;
+ * if objective is minimize, it's -infinity
+ **/
+ bool d_unbounded;
};
/**
@@ -199,10 +211,10 @@ class OptimizationSolver
/**
* Run the optimization loop for the added objective
* For multiple objective combination, it defaults to lexicographic,
- * and combination could be set by calling
- * setObjectiveCombination(BOX/LEXICOGRAPHIC/PARETO)
+ * possible combinations: BOX, LEXICOGRAPHIC, PARETO
+ * @param combination BOX / LEXICOGRAPHIC / PARETO
*/
- OptimizationResult::ResultType checkOpt();
+ Result checkOpt(ObjectiveCombination combination = LEXICOGRAPHIC);
/**
* Add an optimization objective.
@@ -223,11 +235,6 @@ class OptimizationSolver
**/
std::vector<OptimizationResult> getValues();
- /**
- * Sets the objective combination
- **/
- void setObjectiveCombination(ObjectiveCombination combination);
-
private:
/**
* Initialize an SMT subsolver for offline optimization purpose
@@ -244,26 +251,26 @@ class OptimizationSolver
/**
* Optimize multiple goals in Box order
- * @return OPTIMAL if all of the objectives are either OPTIMAL or UNBOUNDED;
- * UNSAT if at least one objective is UNSAT and no objective is UNKNOWN;
- * UNKNOWN if any of the objective is UNKNOWN.
+ * @return SAT if all of the objectives are optimal or unbounded;
+ * UNSAT if at least one objective is UNSAT and no objective is SAT_UNKNOWN;
+ * SAT_UNKNOWN if any of the objective is SAT_UNKNOWN.
**/
- OptimizationResult::ResultType optimizeBox();
+ Result optimizeBox();
/**
* Optimize multiple goals in Lexicographic order,
* using iterative implementation
- * @return OPTIMAL if all objectives are OPTIMAL and bounded;
- * UNBOUNDED if one of the objectives is UNBOUNDED
+ * @return SAT if the objectives are optimal,
+ * if one of the objectives is unbounded,
+ * the optimization will stop at that objective;
+ * UNSAT if any of the objectives is UNSAT
* and optimization will stop at that objective;
- * UNSAT if one of the objectives is UNSAT
- * and optimization will stop at that objective;
- * UNKNOWN if one of the objectives is UNKNOWN
+ * SAT_UNKNOWN if any of the objectives is UNKNOWN
* and optimization will stop at that objective;
* If the optimization is stopped at an objective,
- * all objectives following that objective will be UNKNOWN.
+ * all objectives following that objective will be SAT_UNKNOWN.
**/
- OptimizationResult::ResultType optimizeLexicographicIterative();
+ Result optimizeLexicographicIterative();
/**
* Optimize multiple goals in Pareto order
@@ -277,11 +284,12 @@ class OptimizationSolver
* D. Rayside, H.-C. Estler, and D. Jackson. The Guided Improvement Algorithm.
* Technical Report MIT-CSAIL-TR-2009-033, MIT, 2009.
*
- * @return if it finds a new Pareto optimal result it will return OPTIMAL;
+ * @return if it finds a new Pareto optimal result it will return SAT;
* if it exhausts the results in the Pareto front it will return UNSAT;
- * if the underlying SMT solver returns UNKNOWN, it will return UNKNOWN.
+ * if the underlying SMT solver returns SAT_UNKNOWN,
+ * it will return SAT_UNKNOWN.
**/
- OptimizationResult::ResultType optimizeParetoNaiveGIA();
+ Result optimizeParetoNaiveGIA();
/** A pointer to the parent SMT engine **/
SmtEngine* d_parent;
@@ -294,9 +302,6 @@ class OptimizationSolver
/** The results of the optimizations from the last checkOpt call **/
std::vector<OptimizationResult> d_results;
-
- /** The current objective combination method **/
- ObjectiveCombination d_objectiveCombination;
};
} // namespace smt
diff --git a/src/smt/preprocessor.cpp b/src/smt/preprocessor.cpp
index 7406b922e..3c0a4ac5b 100644
--- a/src/smt/preprocessor.cpp
+++ b/src/smt/preprocessor.cpp
@@ -15,6 +15,7 @@
#include "smt/preprocessor.h"
+#include "options/base_options.h"
#include "options/expr_options.h"
#include "options/smt_options.h"
#include "preprocessing/preprocessing_pass_context.h"
diff --git a/src/smt/set_defaults.cpp b/src/smt/set_defaults.cpp
index cd05b84c4..e119ce4d4 100644
--- a/src/smt/set_defaults.cpp
+++ b/src/smt/set_defaults.cpp
@@ -66,7 +66,7 @@ void setDefaults(LogicInfo& logic, bool isInternalSubsolver)
// unsat cores and proofs shenanigans
if (options::dumpUnsatCoresFull())
{
- opts.smt.dumpUnsatCores = true;
+ opts.driver.dumpUnsatCores = true;
}
if (options::checkUnsatCores() || options::dumpUnsatCores()
|| options::unsatAssumptions()
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index bd48fe0ea..9056e7c94 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -29,7 +29,6 @@
#include "options/option_exception.h"
#include "options/printer_options.h"
#include "options/proof_options.h"
-#include "options/resource_manager_options.h"
#include "options/smt_options.h"
#include "options/theory_options.h"
#include "printer/printer.h"
@@ -1811,16 +1810,16 @@ void SmtEngine::setResourceLimit(uint64_t units, bool cumulative)
{
if (cumulative)
{
- d_env->d_options.resman.cumulativeResourceLimit = units;
+ d_env->d_options.base.cumulativeResourceLimit = units;
}
else
{
- d_env->d_options.resman.perCallResourceLimit = units;
+ d_env->d_options.base.perCallResourceLimit = units;
}
}
void SmtEngine::setTimeLimit(uint64_t millis)
{
- d_env->d_options.resman.perCallMillisecondLimit = millis;
+ d_env->d_options.base.perCallMillisecondLimit = millis;
}
unsigned long SmtEngine::getResourceUsage() const
diff --git a/src/smt/smt_engine_state.cpp b/src/smt/smt_engine_state.cpp
index 4afa15a3b..cb0a94123 100644
--- a/src/smt/smt_engine_state.cpp
+++ b/src/smt/smt_engine_state.cpp
@@ -16,6 +16,7 @@
#include "smt/smt_engine_state.h"
#include "base/modal_exception.h"
+#include "options/base_options.h"
#include "options/option_exception.h"
#include "options/smt_options.h"
#include "smt/smt_engine.h"
diff --git a/src/smt/smt_engine_stats.cpp b/src/smt/smt_engine_stats.cpp
index 417d345cb..c76a8a2e7 100644
--- a/src/smt/smt_engine_stats.cpp
+++ b/src/smt/smt_engine_stats.cpp
@@ -25,8 +25,6 @@ SmtEngineStatistics::SmtEngineStatistics(const std::string& name)
name + "definitionExpansionTime")),
d_numConstantProps(
smtStatisticsRegistry().registerInt(name + "numConstantProps")),
- d_cnfConversionTime(
- smtStatisticsRegistry().registerTimer(name + "cnfConversionTime")),
d_numAssertionsPre(smtStatisticsRegistry().registerInt(
name + "numAssertionsPreITERemoval")),
d_numAssertionsPost(smtStatisticsRegistry().registerInt(
diff --git a/src/smt/smt_engine_stats.h b/src/smt/smt_engine_stats.h
index 441721a54..db914b560 100644
--- a/src/smt/smt_engine_stats.h
+++ b/src/smt/smt_engine_stats.h
@@ -30,8 +30,6 @@ struct SmtEngineStatistics
TimerStat d_definitionExpansionTime;
/** number of constant propagations found during nonclausal simp */
IntStat d_numConstantProps;
- /** time spent converting to CNF */
- TimerStat d_cnfConversionTime;
/** Number of assertions before ite removal */
IntStat d_numAssertionsPre;
/** Number of assertions after ite removal */
diff --git a/src/smt/smt_solver.cpp b/src/smt/smt_solver.cpp
index d7b70f501..f5783ab6b 100644
--- a/src/smt/smt_solver.cpp
+++ b/src/smt/smt_solver.cpp
@@ -239,7 +239,6 @@ void SmtSolver::processAssertions(Assertions& as)
// Push the formula to SAT
{
Chat() << "converting to CNF..." << endl;
- TimerStat::CodeTimer codeTimer(d_stats.d_cnfConversionTime);
const std::vector<Node>& assertions = ap.ref();
// It is important to distinguish the input assertions from the skolem
// definitions, as the decision justification heuristic treates the latter
diff --git a/src/smt/sygus_solver.cpp b/src/smt/sygus_solver.cpp
index 8fa610cda..98278ef9e 100644
--- a/src/smt/sygus_solver.cpp
+++ b/src/smt/sygus_solver.cpp
@@ -20,6 +20,7 @@
#include "base/modal_exception.h"
#include "expr/dtype.h"
#include "expr/skolem_manager.h"
+#include "options/base_options.h"
#include "options/option_exception.h"
#include "options/quantifiers_options.h"
#include "options/smt_options.h"
diff --git a/src/theory/arith/arith_ite_utils.cpp b/src/theory/arith/arith_ite_utils.cpp
index 99b95719f..3dff64113 100644
--- a/src/theory/arith/arith_ite_utils.cpp
+++ b/src/theory/arith/arith_ite_utils.cpp
@@ -22,6 +22,7 @@
#include "base/output.h"
#include "expr/skolem_manager.h"
+#include "options/base_options.h"
#include "options/smt_options.h"
#include "preprocessing/util/ite_utilities.h"
#include "theory/arith/arith_utilities.h"
diff --git a/src/theory/arith/kinds b/src/theory/arith/kinds
index 396befb35..0c93db90f 100644
--- a/src/theory/arith/kinds
+++ b/src/theory/arith/kinds
@@ -26,6 +26,7 @@ operator INTS_MODULUS_TOTAL 2 "integer modulus with interpreted division by 0 (i
operator ABS 1 "absolute value"
parameterized DIVISIBLE DIVISIBLE_OP 1 "divisibility-by-k predicate; first parameter is a DIVISIBLE_OP, second is integer term"
operator POW 2 "arithmetic power"
+operator POW2 1 "arithmetic power of 2"
operator EXPONENTIAL 1 "exponential"
operator SINE 1 "sine"
@@ -148,6 +149,7 @@ typerule ARCTANGENT "SimpleTypeRule<RReal, AReal>"
typerule ARCCOSECANT "SimpleTypeRule<RReal, AReal>"
typerule ARCSECANT "SimpleTypeRule<RReal, AReal>"
typerule ARCCOTANGENT "SimpleTypeRule<RReal, AReal>"
+typerule POW2 "SimpleTypeRule<RInteger, AInteger>"
typerule SQRT "SimpleTypeRule<RReal, AReal>"
diff --git a/src/theory/arith/nl/cad/lazard_evaluation.cpp b/src/theory/arith/nl/cad/lazard_evaluation.cpp
index 82b127ed0..2fee21cbf 100644
--- a/src/theory/arith/nl/cad/lazard_evaluation.cpp
+++ b/src/theory/arith/nl/cad/lazard_evaluation.cpp
@@ -1,5 +1,7 @@
#include "theory/arith/nl/cad/lazard_evaluation.h"
+#ifdef CVC5_POLY_IMP
+
#include "base/check.h"
#include "base/output.h"
@@ -44,3 +46,5 @@ std::vector<poly::Interval> LazardEvaluation::infeasibleRegions(
}
} // namespace cvc5::theory::arith::nl::cad
+
+#endif
diff --git a/src/theory/arith/nl/cad/lazard_evaluation.h b/src/theory/arith/nl/cad/lazard_evaluation.h
index 0edb12010..3bb971c4c 100644
--- a/src/theory/arith/nl/cad/lazard_evaluation.h
+++ b/src/theory/arith/nl/cad/lazard_evaluation.h
@@ -19,6 +19,8 @@
#ifndef CVC5__THEORY__ARITH__NL__CAD__LAZARD_EVALUATION_H
#define CVC5__THEORY__ARITH__NL__CAD__LAZARD_EVALUATION_H
+#ifdef CVC5_POLY_IMP
+
#include <poly/polyxx.h>
#include <memory>
@@ -106,4 +108,5 @@ class LazardEvaluation
} // namespace cvc5::theory::arith::nl::cad
-#endif \ No newline at end of file
+#endif
+#endif
diff --git a/src/theory/arith/nl/pow2_solver.cpp b/src/theory/arith/nl/pow2_solver.cpp
new file mode 100644
index 000000000..534895c7f
--- /dev/null
+++ b/src/theory/arith/nl/pow2_solver.cpp
@@ -0,0 +1,73 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ * Andrew Reynolds, Makai Mann, Gereon Kremer
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved. See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Implementation of pow2 solver.
+ */
+
+#include "theory/arith/nl/pow2_solver.h"
+
+#include "theory/arith/arith_msum.h"
+#include "theory/arith/arith_state.h"
+#include "theory/arith/arith_utilities.h"
+#include "theory/arith/inference_manager.h"
+#include "theory/arith/nl/nl_model.h"
+#include "theory/rewriter.h"
+
+using namespace cvc5::kind;
+
+namespace cvc5 {
+namespace theory {
+namespace arith {
+namespace nl {
+
+Pow2Solver::Pow2Solver(InferenceManager& im, ArithState& state, NlModel& model)
+ : d_im(im), d_model(model), d_initRefine(state.getUserContext())
+{
+ NodeManager* nm = NodeManager::currentNM();
+ d_false = nm->mkConst(false);
+ d_true = nm->mkConst(true);
+ d_zero = nm->mkConst(Rational(0));
+ d_one = nm->mkConst(Rational(1));
+ d_two = nm->mkConst(Rational(2));
+}
+
+Pow2Solver::~Pow2Solver() {}
+
+void Pow2Solver::initLastCall(const std::vector<Node>& assertions,
+ const std::vector<Node>& false_asserts,
+ const std::vector<Node>& xts)
+{
+ d_pow2s.clear();
+ Trace("pow2-mv") << "POW2 terms : " << std::endl;
+ for (const Node& a : xts)
+ {
+ Kind ak = a.getKind();
+ if (ak != POW2)
+ {
+ // don't care about other terms
+ continue;
+ }
+ d_pow2s.push_back(a);
+ }
+ Trace("pow2") << "We have " << d_pow2s.size() << " pow2 terms." << std::endl;
+}
+
+void Pow2Solver::checkInitialRefine() {}
+
+void Pow2Solver::checkFullRefine() {}
+
+Node Pow2Solver::valueBasedLemma(Node i) { return Node(); }
+
+} // namespace nl
+} // namespace arith
+} // namespace theory
+} // namespace cvc5
diff --git a/src/theory/arith/theory_arith_private.cpp b/src/theory/arith/theory_arith_private.cpp
index a675c1bf4..97b29b6b3 100644
--- a/src/theory/arith/theory_arith_private.cpp
+++ b/src/theory/arith/theory_arith_private.cpp
@@ -35,7 +35,7 @@
#include "expr/node_builder.h"
#include "expr/skolem_manager.h"
#include "options/arith_options.h"
-#include "options/smt_options.h" // for incrementalSolving()
+#include "options/base_options.h"
#include "preprocessing/util/ite_utilities.h"
#include "proof/proof_generator.h"
#include "proof/proof_node_manager.h"
diff --git a/src/theory/arrays/theory_arrays.cpp b/src/theory/arrays/theory_arrays.cpp
index ea18b3180..be8e1a08e 100644
--- a/src/theory/arrays/theory_arrays.cpp
+++ b/src/theory/arrays/theory_arrays.cpp
@@ -151,6 +151,8 @@ bool TheoryArrays::needsEqualityEngine(EeSetupInfo& esi)
{
esi.d_notify = &d_notify;
esi.d_name = d_instanceName + "ee";
+ esi.d_notifyNewClass = true;
+ esi.d_notifyMerge = true;
return true;
}
diff --git a/src/theory/bv/bitblast/eager_bitblaster.cpp b/src/theory/bv/bitblast/eager_bitblaster.cpp
index 9871f2a92..55ed6c41d 100644
--- a/src/theory/bv/bitblast/eager_bitblaster.cpp
+++ b/src/theory/bv/bitblast/eager_bitblaster.cpp
@@ -16,6 +16,7 @@
#include "theory/bv/bitblast/eager_bitblaster.h"
#include "cvc5_private.h"
+#include "options/base_options.h"
#include "options/bv_options.h"
#include "options/smt_options.h"
#include "prop/cnf_stream.h"
diff --git a/src/theory/bv/bitblast/simple_bitblaster.cpp b/src/theory/bv/bitblast/simple_bitblaster.cpp
index a38dfdfe5..357a54b1a 100644
--- a/src/theory/bv/bitblast/simple_bitblaster.cpp
+++ b/src/theory/bv/bitblast/simple_bitblaster.cpp
@@ -17,6 +17,7 @@
#include "theory/theory_model.h"
#include "theory/theory_state.h"
+#include "options/bv_options.h"
namespace cvc5 {
namespace theory {
@@ -129,6 +130,15 @@ Node BBSimple::getModelFromSatSolver(TNode a, bool fullModel)
return utils::mkConst(bits.size(), value);
}
+void BBSimple::computeRelevantTerms(std::set<Node>& termSet)
+{
+ Assert(options::bitblastMode() == options::BitblastMode::EAGER);
+ for (const auto& var : d_variables)
+ {
+ termSet.insert(var);
+ }
+}
+
bool BBSimple::collectModelValues(TheoryModel* m,
const std::set<Node>& relevantTerms)
{
diff --git a/src/theory/bv/bitblast/simple_bitblaster.h b/src/theory/bv/bitblast/simple_bitblaster.h
index ebbb2891f..ec0899145 100644
--- a/src/theory/bv/bitblast/simple_bitblaster.h
+++ b/src/theory/bv/bitblast/simple_bitblaster.h
@@ -53,6 +53,8 @@ class BBSimple : public TBitblaster<Node>
/** Create 'bits' for variable 'var'. */
void makeVariable(TNode var, Bits& bits) override;
+ /** Add d_variables to termSet. */
+ void computeRelevantTerms(std::set<Node>& termSet);
/** Collect model values for all relevant terms given in 'relevantTerms'. */
bool collectModelValues(TheoryModel* m, const std::set<Node>& relevantTerms);
diff --git a/src/theory/bv/bv_eager_solver.cpp b/src/theory/bv/bv_eager_solver.cpp
index 2d0ae1931..b0082b992 100644
--- a/src/theory/bv/bv_eager_solver.cpp
+++ b/src/theory/bv/bv_eager_solver.cpp
@@ -15,6 +15,7 @@
#include "theory/bv/bv_eager_solver.h"
+#include "options/base_options.h"
#include "options/bv_options.h"
#include "options/smt_options.h"
#include "theory/bv/bitblast/aig_bitblaster.h"
diff --git a/src/theory/bv/bv_solver.h b/src/theory/bv/bv_solver.h
index 8ff4318c0..6ccc6c7c1 100644
--- a/src/theory/bv/bv_solver.h
+++ b/src/theory/bv/bv_solver.h
@@ -32,7 +32,7 @@ class BVSolver
BVSolver(TheoryState& state, TheoryInferenceManager& inferMgr)
: d_state(state), d_im(inferMgr){};
- virtual ~BVSolver(){};
+ virtual ~BVSolver() {}
/**
* Returns true if we need an equality engine. If so, we initialize the
@@ -71,7 +71,7 @@ class BVSolver
virtual bool needsCheckLastEffort() { return false; }
- virtual void propagate(Theory::Effort e){};
+ virtual void propagate(Theory::Effort e) {}
virtual TrustNode explain(TNode n)
{
@@ -80,17 +80,20 @@ class BVSolver
return TrustNode::null();
}
+ /** Additionally collect terms relevant for collecting model values. */
+ virtual void computeRelevantTerms(std::set<Node>& termSet) {}
+
/** Collect model values in m based on the relevant terms given by termSet */
virtual bool collectModelValues(TheoryModel* m,
const std::set<Node>& termSet) = 0;
virtual std::string identify() const = 0;
- virtual TrustNode ppRewrite(TNode t) { return TrustNode::null(); };
+ virtual TrustNode ppRewrite(TNode t) { return TrustNode::null(); }
- virtual void ppStaticLearn(TNode in, NodeBuilder& learned){};
+ virtual void ppStaticLearn(TNode in, NodeBuilder& learned) {}
- virtual void presolve(){};
+ virtual void presolve() {}
virtual void notifySharedTerm(TNode t) {}
diff --git a/src/theory/bv/bv_solver_bitblast.cpp b/src/theory/bv/bv_solver_bitblast.cpp
index dc2c7e2a3..3ae4a7f0a 100644
--- a/src/theory/bv/bv_solver_bitblast.cpp
+++ b/src/theory/bv/bv_solver_bitblast.cpp
@@ -96,17 +96,19 @@ BVSolverBitblast::BVSolverBitblast(TheoryState* s,
{
case options::SatSolverMode::CRYPTOMINISAT:
d_satSolver.reset(prop::SatSolverFactory::createCryptoMinisat(
- smtStatisticsRegistry(), "theory::bv::BVSolverBitblast"));
+ smtStatisticsRegistry(), "theory::bv::BVSolverBitblast::"));
break;
default:
d_satSolver.reset(prop::SatSolverFactory::createCadical(
- smtStatisticsRegistry(), "theory::bv::BVSolverBitblast"));
+ smtStatisticsRegistry(), "theory::bv::BVSolverBitblast::"));
}
d_cnfStream.reset(new prop::CnfStream(d_satSolver.get(),
d_bbRegistrar.get(),
d_nullContext.get(),
nullptr,
- smt::currentResourceManager()));
+ smt::currentResourceManager(),
+ prop::FormulaLitPolicy::INTERNAL,
+ "theory::bv::BVSolverBitblast"));
}
void BVSolverBitblast::postCheck(Theory::Effort level)
@@ -236,6 +238,21 @@ TrustNode BVSolverBitblast::explain(TNode n)
return d_im.explainLit(n);
}
+void BVSolverBitblast::computeRelevantTerms(std::set<Node>& termSet)
+{
+ /* BITVECTOR_EAGER_ATOM wraps input assertions that may also contain
+ * equalities. As a result, these equalities are not handled by the equality
+ * engine and terms below these equalities do not appear in `termSet`.
+ * We need to make sure that we compute model values for all relevant terms
+ * in BitblastMode::EAGER and therefore add all variables from the
+ * bit-blaster to `termSet`.
+ */
+ if (options::bitblastMode() == options::BitblastMode::EAGER)
+ {
+ d_bitblaster->computeRelevantTerms(termSet);
+ }
+}
+
bool BVSolverBitblast::collectModelValues(TheoryModel* m,
const std::set<Node>& termSet)
{
diff --git a/src/theory/bv/bv_solver_bitblast.h b/src/theory/bv/bv_solver_bitblast.h
index 31d9443c8..c5134c6fc 100644
--- a/src/theory/bv/bv_solver_bitblast.h
+++ b/src/theory/bv/bv_solver_bitblast.h
@@ -64,6 +64,8 @@ class BVSolverBitblast : public BVSolver
EqualityStatus getEqualityStatus(TNode a, TNode b) override;
+ void computeRelevantTerms(std::set<Node>& termSet) override;
+
bool collectModelValues(TheoryModel* m,
const std::set<Node>& termSet) override;
diff --git a/src/theory/bv/int_blaster.cpp b/src/theory/bv/int_blaster.cpp
new file mode 100644
index 000000000..9da9d1c2b
--- /dev/null
+++ b/src/theory/bv/int_blaster.cpp
@@ -0,0 +1,240 @@
+/******************************************************************************
+ * Top contributors (to current version):
+ * Yoni Zohar
+ *
+ * This file is part of the cvc5 project.
+ *
+ * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
+ * in the top-level source directory and their institutional affiliations.
+ * All rights reserved. See the file COPYING in the top-level source
+ * directory for licensing information.
+ * ****************************************************************************
+ *
+ * Int-blasting utility
+ */
+
+#include "theory/bv/int_blaster.h"
+
+#include <cmath>
+#include <string>
+#include <unordered_map>
+#include <vector>
+
+#include "expr/node.h"
+#include "expr/node_traversal.h"
+#include "expr/skolem_manager.h"
+#include "options/option_exception.h"
+#include "options/uf_options.h"
+#include "theory/rewriter.h"
+#include "util/iand.h"
+#include "util/rational.h"
+
+namespace cvc5 {
+using namespace cvc5::theory;
+
+IntBlaster::IntBlaster(context::Context* c,
+ options::SolveBVAsIntMode mode,
+ uint64_t granularity,
+ bool introduceFreshIntVars)
+ : d_binarizeCache(c),
+ d_intblastCache(c),
+ d_rangeAssertions(c),
+ d_bitwiseAssertions(c),
+ d_mode(mode),
+ d_granularity(granularity),
+ d_context(c),
+ d_introduceFreshIntVars(introduceFreshIntVars)
+{
+ d_nm = NodeManager::currentNM();
+ d_zero = d_nm->mkConst<Rational>(0);
+ d_one = d_nm->mkConst<Rational>(1);
+};
+
+void IntBlaster::addRangeConstraint(Node node,
+ uint64_t size,
+ std::vector<Node>& lemmas)
+{
+}
+
+void IntBlaster::addBitwiseConstraint(Node bitwiseConstraint,
+ std::vector<Node>& lemmas)
+{
+}
+
+Node IntBlaster::mkRangeConstraint(Node newVar, uint64_t k) { return Node(); }
+
+Node IntBlaster::maxInt(uint64_t k) { return Node(); }
+
+Node IntBlaster::pow2(uint64_t k) { return Node(); }
+
+Node IntBlaster::modpow2(Node n, uint64_t exponent) { return Node(); }
+
+Node IntBlaster::makeBinary(Node n)
+{
+ if (d_binarizeCache.find(n) != d_binarizeCache.end())
+ {
+ return d_binarizeCache[n];
+ }
+ uint64_t numChildren = n.getNumChildren();
+ kind::Kind_t k = n.getKind();
+ Node result = n;
+ if ((numChildren > 2)
+ && (k == kind::BITVECTOR_ADD || k == kind::BITVECTOR_MULT
+ || k == kind::BITVECTOR_AND || k == kind::BITVECTOR_OR
+ || k == kind::BITVECTOR_XOR || k == kind::BITVECTOR_CONCAT))
+ {
+ result = n[0];
+ for (uint64_t i = 1; i < numChildren; i++)
+ {
+ result = d_nm->mkNode(n.getKind(), result, n[i]);
+ }
+ }
+ d_binarizeCache[n] = result;
+ Trace("int-blaster-debug") << "binarization result: " << result << std::endl;
+ return result;
+}
+
+/**
+ * Translate n to Integers via post-order traversal.
+ */
+Node IntBlaster::intBlast(Node n,
+ std::vector<Node>& lemmas,
+ std::map<Node, Node>& skolems)
+{
+ // make sure the node is re-written
+ n = Rewriter::rewrite(n);
+
+ // helper vector for traversal.
+ std::vector<Node> toVisit;
+ toVisit.push_back(makeBinary(n));
+
+ while (!toVisit.empty())
+ {
+ Node current = toVisit.back();
+ uint64_t currentNumChildren = current.getNumChildren();
+ if (d_intblastCache.find(current) == d_intblastCache.end())
+ {
+ // This is the first time we visit this node and it is not in the cache.
+ // We mark this node as visited but not translated by assiging
+ // a null node to it.
+ d_intblastCache[current] = Node();
+ // all the node's children are added to the stack to be visited
+ // before visiting this node again.
+ for (const Node& child : current)
+ {
+ toVisit.push_back(makeBinary(child));
+ }
+ // If this is a UF applicatinon, we also add the function to
+ // toVisit.
+ if (current.getKind() == kind::APPLY_UF)
+ {
+ toVisit.push_back(current.getOperator());
+ }
+ }
+ else
+ {
+ // We already visited and translated this node
+ if (!d_intblastCache[current].get().isNull())
+ {
+ // We are done computing the translation for current
+ toVisit.pop_back();
+ }
+ else
+ {
+ // We are now visiting current on the way back up.
+ // This is when we do the actual translation.
+ Node translation;
+ if (currentNumChildren == 0)
+ {
+ translation = translateNoChildren(current, lemmas, skolems);
+ }
+ else
+ {
+ /**
+ * The current node has children.
+ * Since we are on the way back up,
+ * these children were already translated.
+ * We save their translation for easy access.
+ * If the node's kind is APPLY_UF,
+ * we also need to include the translated uninterpreted function in
+ * this list.
+ */
+ std::vector<Node> translated_children;
+ if (current.getKind() == kind::APPLY_UF)
+ {
+ translated_children.push_back(
+ d_intblastCache[current.getOperator()]);
+ }
+ for (uint64_t i = 0; i < currentNumChildren; i++)
+ {
+ translated_children.push_back(d_intblastCache[current[i]]);
+ }
+ translation =
+ translateWithChildren(current, translated_children, lemmas);
+ }
+
+ Assert(!translation.isNull());
+ // Map the current node to its translation in the cache.
+ d_intblastCache[current] = translation;
+ // Also map the translation to itself.
+ d_intblastCache[translation] = translation;
+ toVisit.pop_back();
+ }
+ }
+ }
+ return d_intblastCache[n].get();
+}
+
+Node IntBlaster::unsignedToSigned(Node n, uint64_t bw) { return Node(); }
+
+Node IntBlaster::translateWithChildren(
+ Node original,
+ const std::vector<Node>& translated_children,
+ std::vector<Node>& lemmas)
+{
+ Node binarized = makeBinary(original);
+ // continue to process the binarized version
+ return Node();
+}
+
+Node IntBlaster::translateNoChildren(Node original,
+ std::vector<Node>& lemmas,
+ std::map<Node, Node>& skolems)
+{
+ return Node();
+}
+
+Node IntBlaster::defineBVUFAsIntUF(Node bvUF, Node intUF) { return Node(); }
+
+Node IntBlaster::translateFunctionSymbol(Node bvUF,
+ std::map<Node, Node>& skolems)
+{
+ return Node();
+}
+
+bool IntBlaster::childrenTypesChanged(Node n) { return true; }
+
+Node IntBlaster::castToType(Node n, TypeNode tn) { return Node(); }
+
+Node IntBlaster::reconstructNode(Node originalNode,
+ TypeNode resultType,
+ const std::vector<Node>& translated_children)
+{
+ return Node();
+}
+
+Node IntBlaster::createShiftNode(std::vector<Node> children,
+ uint64_t bvsize,
+ bool isLeftShift)
+{
+ return Node();
+}
+
+Node IntBlaster::translateQuantifiedFormula(Node quantifiedNode)
+{
+ return Node();
+}
+
+Node IntBlaster::createBVNotNode(Node n, uint64_t bvsize) { return Node(); }
+
+} // namespace cvc5
diff --git a/src/theory/bv/int_blaster.h b/src/theory/bv/int_blaster.h
index f8717e045..444eb88a7 100644
--- a/src/theory/bv/int_blaster.h
+++ b/src/theory/bv/int_blaster.h
@@ -75,9 +75,10 @@ namespace cvc5 {
** Tr((bvult a b)) = Tr(a) < Tr(b)
** Similar transformations are done for bvule, bvugt, and bvuge.
**
-** Bit-vector operators that are not listed above are either eliminated using
-** the function eliminationPass, or go through the following default
-*translation, that also works for non-bit-vector operators
+** Bit-vector operators that are not listed above are either
+** eliminated using the BV rewriter,
+** or go through the following default
+** translation, that also works for non-bit-vector operators
** with result type BV:
** Tr((op t1 ... tn)) = (bv2nat (op (cast t1) ... (cast tn)))
** where (cast x) is ((_ nat2bv k) x) or just x,
@@ -118,8 +119,7 @@ class IntBlaster
* ff((bv2nat x))), where k is the bit-width of the domain of f, i is the
* bit-width of its range, and ff is a Int->Int function that corresponds to
* f. For functions with other signatures this is similar
- * @return integer node that corresponds to n, or a null node if d_supportNoBV
- * is set to false and n is note purely BV.
+ * @return integer node that corresponds to n
*/
Node intBlast(Node n,
std::vector<Node>& lemmas,
@@ -165,18 +165,15 @@ class IntBlaster
Node mkRangeConstraint(Node newVar, uint64_t k);
/**
- * In the translation to integers, it is convenient to assume that certain
- * bit-vector operators do not occur in the original formula (e.g., repeat).
- * This function eliminates all these operators.
- */
- Node eliminationPass(Node n);
-
- /**
* Some bit-vector operators (e.g., bvadd, bvand) are binary, but allow more
* than two arguments as a syntactic sugar.
* For example, we can have a node for (bvand x y z),
* that represents (bvand (x (bvand y z))).
- * This function makes all such operators strictly binary.
+ * This function locally binarizes these operators.
+ * In the above example, this means that x,y,z
+ * are not handled recursively, but will require a separate
+ * call to the function.
+ *
*/
Node makeBinary(Node n);
@@ -287,7 +284,7 @@ class IntBlaster
* binary representation of n is the same as the
* signed binary representation of m.
*/
- Node unsignedTosigned(Node n, uint64_t bvsize);
+ Node unsignedToSigned(Node n, uint64_t bvsize);
/**
* Performs the actual translation to integers for nodes
@@ -308,8 +305,6 @@ class IntBlaster
/** Caches for the different functions */
CDNodeMap d_binarizeCache;
- CDNodeMap d_eliminationCache;
- CDNodeMap d_rebuildCache;
CDNodeMap d_intblastCache;
/** Node manager that is used throughout the pass */
diff --git a/src/theory/bv/theory_bv.cpp b/src/theory/bv/theory_bv.cpp
index 22b05b026..3d7f11f6d 100644
--- a/src/theory/bv/theory_bv.cpp
+++ b/src/theory/bv/theory_bv.cpp
@@ -175,6 +175,11 @@ bool TheoryBV::needsCheckLastEffort()
return d_internal->needsCheckLastEffort();
}
+void TheoryBV::computeRelevantTerms(std::set<Node>& termSet)
+{
+ return d_internal->computeRelevantTerms(termSet);
+}
+
bool TheoryBV::collectModelValues(TheoryModel* m, const std::set<Node>& termSet)
{
return d_internal->collectModelValues(m, termSet);
diff --git a/src/theory/bv/theory_bv.h b/src/theory/bv/theory_bv.h
index 4b3a1f3b2..e884f621c 100644
--- a/src/theory/bv/theory_bv.h
+++ b/src/theory/bv/theory_bv.h
@@ -83,6 +83,8 @@ class TheoryBV : public Theory
TrustNode explain(TNode n) override;
+ void computeRelevantTerms(std::set<Node>& termSet) override;
+
/** Collect model values in m based on the relevant terms given by termSet */
bool collectModelValues(TheoryModel* m,
const std::set<Node>& termSet) override;
diff --git a/src/theory/datatypes/theory_datatypes.cpp b/src/theory/datatypes/theory_datatypes.cpp
index dc57e4165..53f128286 100644
--- a/src/theory/datatypes/theory_datatypes.cpp
+++ b/src/theory/datatypes/theory_datatypes.cpp
@@ -94,6 +94,9 @@ bool TheoryDatatypes::needsEqualityEngine(EeSetupInfo& esi)
{
esi.d_notify = &d_notify;
esi.d_name = "theory::datatypes::ee";
+ // need notifications on new constructors, merging datatype eqcs
+ esi.d_notifyNewClass = true;
+ esi.d_notifyMerge = true;
return true;
}
diff --git a/src/theory/ee_setup_info.h b/src/theory/ee_setup_info.h
index f6139d109..130241c4a 100644
--- a/src/theory/ee_setup_info.h
+++ b/src/theory/ee_setup_info.h
@@ -39,7 +39,12 @@ class EqualityEngineNotify;
struct EeSetupInfo
{
EeSetupInfo()
- : d_notify(nullptr), d_constantsAreTriggers(true), d_useMaster(false)
+ : d_notify(nullptr),
+ d_constantsAreTriggers(true),
+ d_notifyNewClass(false),
+ d_notifyMerge(false),
+ d_notifyDisequal(false),
+ d_useMaster(false)
{
}
/** The notification class of the theory */
@@ -48,11 +53,25 @@ struct EeSetupInfo
std::string d_name;
/** Constants are triggers */
bool d_constantsAreTriggers;
+ //-------------------------- fine grained notifications
+ /** Whether we need to be notified of new equivalence classes */
+ bool d_notifyNewClass;
+ /** Whether we need to be notified of merged equivalence classes */
+ bool d_notifyMerge;
+ /** Whether we need to be notified of disequal equivalence classes */
+ bool d_notifyDisequal;
+ //-------------------------- end fine grained notifications
/**
* Whether we want our state to use the master equality engine. This should
* be true exclusively for the theory of quantifiers.
*/
bool d_useMaster;
+ /** Does it need notifications when equivalence classes are created? */
+ bool needsNotifyNewClass() const { return d_notifyNewClass; }
+ /** Does it need notifications when equivalence classes are merged? */
+ bool needsNotifyMerge() const { return d_notifyMerge; }
+ /** Does it need notifications when disequalities are generated? */
+ bool needsNotifyDisequal() const { return d_notifyDisequal; }
};
} // namespace theory
diff --git a/src/theory/fp/fp_converter.cpp b/src/theory/fp/fp_converter.cpp
index 0d1b25549..0e196c0e0 100644
--- a/src/theory/fp/fp_converter.cpp
+++ b/src/theory/fp/fp_converter.cpp
@@ -23,7 +23,6 @@
#include "util/floatingpoint.h"
#include "util/floatingpoint_literal_symfpu.h"
-#ifdef CVC5_USE_SYMFPU
#include "symfpu/core/add.h"
#include "symfpu/core/classify.h"
#include "symfpu/core/compare.h"
@@ -38,9 +37,7 @@
#include "symfpu/core/sqrt.h"
#include "symfpu/utils/numberOfRoundingModes.h"
#include "symfpu/utils/properties.h"
-#endif
-#ifdef CVC5_USE_SYMFPU
namespace symfpu {
using namespace ::cvc5::theory::fp::symfpuSymbolic;
@@ -143,11 +140,6 @@ void probabilityAnnotation<traits, traits::prop>(const traits::prop &p,
return;
}
};
-#endif
-
-#ifndef CVC5_USE_SYMFPU
-#define SYMFPU_NUMBER_OF_ROUNDING_MODES 5
-#endif
namespace cvc5 {
namespace theory {
@@ -242,11 +234,7 @@ symbolicProposition symbolicProposition::operator^(
bool symbolicRoundingMode::checkNodeType(const TNode n)
{
-#ifdef CVC5_USE_SYMFPU
return n.getType(false).isBitVector(SYMFPU_NUMBER_OF_ROUNDING_MODES);
-#else
- return false;
-#endif
}
symbolicRoundingMode::symbolicRoundingMode(const Node n) : nodeWrapper(n)
@@ -254,7 +242,6 @@ symbolicRoundingMode::symbolicRoundingMode(const Node n) : nodeWrapper(n)
Assert(checkNodeType(*this));
}
-#ifdef CVC5_USE_SYMFPU
symbolicRoundingMode::symbolicRoundingMode(const unsigned v)
: nodeWrapper(NodeManager::currentNM()->mkConst(
BitVector(SYMFPU_NUMBER_OF_ROUNDING_MODES, v)))
@@ -262,14 +249,6 @@ symbolicRoundingMode::symbolicRoundingMode(const unsigned v)
Assert((v & (v - 1)) == 0 && v != 0); // Exactly one bit set
Assert(checkNodeType(*this));
}
-#else
-symbolicRoundingMode::symbolicRoundingMode(const unsigned v)
- : nodeWrapper(NodeManager::currentNM()->mkConst(
- BitVector(SYMFPU_NUMBER_OF_ROUNDING_MODES, v)))
-{
- Unreachable();
-}
-#endif
symbolicRoundingMode::symbolicRoundingMode(const symbolicRoundingMode &old)
: nodeWrapper(old)
@@ -755,20 +734,17 @@ TypeNode floatingPointTypeInfo::getTypeNode(void) const
FpConverter::FpConverter(context::UserContext* user)
: d_additionalAssertions(user)
-#ifdef CVC5_USE_SYMFPU
,
d_fpMap(user),
d_rmMap(user),
d_boolMap(user),
d_ubvMap(user),
d_sbvMap(user)
-#endif
{
}
FpConverter::~FpConverter() {}
-#ifdef CVC5_USE_SYMFPU
Node FpConverter::ufToNode(const fpt &format, const uf &u) const
{
NodeManager *nm = NodeManager::currentNM();
@@ -843,7 +819,6 @@ FpConverter::uf FpConverter::buildComponents(TNode current)
return tmp;
}
-#endif
// Non-convertible things should only be added to the stack at the very start,
// thus...
@@ -851,7 +826,6 @@ FpConverter::uf FpConverter::buildComponents(TNode current)
Node FpConverter::convert(TNode node)
{
-#ifdef CVC5_USE_SYMFPU
std::vector<TNode> workStack;
TNode result = node;
@@ -1704,9 +1678,6 @@ Node FpConverter::convert(TNode node)
}
return result;
-#else
- Unimplemented() << "Conversion is dependent on SymFPU";
-#endif
}
#undef CVC5_FPCONV_PASSTHROUGH
@@ -1715,7 +1686,6 @@ Node FpConverter::getValue(Valuation &val, TNode var)
{
Assert(Theory::isLeafOf(var, THEORY_FP));
-#ifdef CVC5_USE_SYMFPU
TypeNode t(var.getType());
Assert(t.isRoundingMode() || t.isFloatingPoint())
@@ -1735,9 +1705,6 @@ Node FpConverter::getValue(Valuation &val, TNode var)
Assert(i != d_fpMap.end())
<< "Asking for the value of an unregistered expression";
return ufToNode(fpt(t), (*i).second);
-#else
- Unimplemented() << "Conversion is dependent on SymFPU";
-#endif
}
} // namespace fp
diff --git a/src/theory/fp/fp_converter.h b/src/theory/fp/fp_converter.h
index f1b7c8a83..9900c2987 100644
--- a/src/theory/fp/fp_converter.h
+++ b/src/theory/fp/fp_converter.h
@@ -33,9 +33,7 @@
#include "util/floatingpoint_size.h"
#include "util/hash.h"
-#ifdef CVC5_USE_SYMFPU
#include "symfpu/core/unpackedFloat.h"
-#endif
#ifdef CVC5_SYM_SYMBOLIC_EVAL
// This allows debugging of the cvc5 symbolic back-end.
@@ -120,9 +118,7 @@ class symbolicProposition : public nodeWrapper
protected:
bool checkNodeType(const TNode node);
-#ifdef CVC5_USE_SYMFPU
friend ::symfpu::ite<symbolicProposition, symbolicProposition>; // For ITE
-#endif
public:
symbolicProposition(const Node n);
@@ -141,9 +137,7 @@ class symbolicRoundingMode : public nodeWrapper
protected:
bool checkNodeType(const TNode n);
-#ifdef CVC5_USE_SYMFPU
friend ::symfpu::ite<symbolicProposition, symbolicRoundingMode>; // For ITE
-#endif
public:
symbolicRoundingMode(const Node n);
@@ -183,10 +177,8 @@ class symbolicBitVector : public nodeWrapper
bool checkNodeType(const TNode n);
friend symbolicBitVector<!isSigned>; // To allow conversion between the types
-#ifdef CVC5_USE_SYMFPU
friend ::symfpu::ite<symbolicProposition,
symbolicBitVector<isSigned> >; // For ITE
-#endif
public:
symbolicBitVector(const Node n);
@@ -314,7 +306,6 @@ class FpConverter
context::CDList<Node> d_additionalAssertions;
protected:
-#ifdef CVC5_USE_SYMFPU
typedef symfpuSymbolic::traits traits;
typedef ::symfpu::unpackedFloat<symfpuSymbolic::traits> uf;
typedef symfpuSymbolic::traits::rm rm;
@@ -348,7 +339,6 @@ class FpConverter
/* Creates the relevant components for a variable */
uf buildComponents(TNode current);
-#endif
};
} // namespace fp
diff --git a/src/theory/fp/theory_fp.cpp b/src/theory/fp/theory_fp.cpp
index 3d81a2995..77dba0724 100644
--- a/src/theory/fp/theory_fp.cpp
+++ b/src/theory/fp/theory_fp.cpp
@@ -661,7 +661,7 @@ bool TheoryFp::isRegistered(TNode node) {
void TheoryFp::preRegisterTerm(TNode node)
{
- if (Configuration::isBuiltWithSymFPU() && !options::fpExp())
+ if (!options::fpExp())
{
TypeNode tn = node.getType();
if (tn.isFloatingPoint())
diff --git a/src/theory/fp/theory_fp_rewriter.cpp b/src/theory/fp/theory_fp_rewriter.cpp
index 76f7d55cf..8bc7900de 100644
--- a/src/theory/fp/theory_fp_rewriter.cpp
+++ b/src/theory/fp/theory_fp_rewriter.cpp
@@ -1026,12 +1026,10 @@ RewriteResponse maxTotal(TNode node, bool isPreRewrite)
bool result;
switch (k)
{
-#ifdef CVC5_USE_SYMFPU
case kind::FLOATINGPOINT_COMPONENT_NAN: result = arg0.isNaN(); break;
case kind::FLOATINGPOINT_COMPONENT_INF: result = arg0.isInfinite(); break;
case kind::FLOATINGPOINT_COMPONENT_ZERO: result = arg0.isZero(); break;
case kind::FLOATINGPOINT_COMPONENT_SIGN: result = arg0.getSign(); break;
-#endif
default: Unreachable() << "Unknown kind used in componentFlag"; break;
}
@@ -1050,11 +1048,7 @@ RewriteResponse maxTotal(TNode node, bool isPreRewrite)
// \todo Add a proper interface for this sort of thing to FloatingPoint #1915
return RewriteResponse(
REWRITE_DONE,
-#ifdef CVC5_USE_SYMFPU
NodeManager::currentNM()->mkConst((BitVector)arg0.getExponent())
-#else
- node
-#endif
);
}
@@ -1066,11 +1060,7 @@ RewriteResponse maxTotal(TNode node, bool isPreRewrite)
return RewriteResponse(
REWRITE_DONE,
-#ifdef CVC5_USE_SYMFPU
NodeManager::currentNM()->mkConst((BitVector)arg0.getSignificand())
-#else
- node
-#endif
);
}
@@ -1080,7 +1070,6 @@ RewriteResponse maxTotal(TNode node, bool isPreRewrite)
BitVector value;
-#ifdef CVC5_USE_SYMFPU
/* \todo fix the numbering of rounding modes so this doesn't need
* to call symfpu at all and remove the dependency on fp_converter.h #1915 */
RoundingMode arg0(node[0].getConst<RoundingMode>());
@@ -1110,9 +1099,6 @@ RewriteResponse maxTotal(TNode node, bool isPreRewrite)
Unreachable() << "Unknown rounding mode in roundingModeBitBlast";
break;
}
-#else
- value = BitVector(5U, 0U);
-#endif
return RewriteResponse(REWRITE_DONE,
NodeManager::currentNM()->mkConst(value));
}
diff --git a/src/theory/fp/theory_fp_type_rules.cpp b/src/theory/fp/theory_fp_type_rules.cpp
index b78ef24c7..77c1ef8f0 100644
--- a/src/theory/fp/theory_fp_type_rules.cpp
+++ b/src/theory/fp/theory_fp_type_rules.cpp
@@ -727,7 +727,6 @@ TypeNode FloatingPointComponentExponent::computeType(NodeManager* nodeManager,
}
}
-#ifdef CVC5_USE_SYMFPU
/* Need to create some symfpu objects as the size of bit-vector
* that is needed for this component is dependent on the encoding
* used (i.e. whether subnormals are forcibly normalised or not).
@@ -735,9 +734,6 @@ TypeNode FloatingPointComponentExponent::computeType(NodeManager* nodeManager,
* back-end but it should't make a difference. */
FloatingPointSize fps = operandType.getConst<FloatingPointSize>();
uint32_t bw = FloatingPoint::getUnpackedExponentWidth(fps);
-#else
- uint32_t bw = 2;
-#endif
return nodeManager->mkBitVectorType(bw);
}
@@ -767,13 +763,9 @@ TypeNode FloatingPointComponentSignificand::computeType(
}
}
-#ifdef CVC5_USE_SYMFPU
/* As before we need to use some of sympfu. */
FloatingPointSize fps = operandType.getConst<FloatingPointSize>();
uint32_t bw = FloatingPoint::getUnpackedSignificandWidth(fps);
-#else
- uint32_t bw = 1;
-#endif
return nodeManager->mkBitVectorType(bw);
}
diff --git a/src/theory/inference_id.cpp b/src/theory/inference_id.cpp
index fe4ed4c22..778c842a6 100644
--- a/src/theory/inference_id.cpp
+++ b/src/theory/inference_id.cpp
@@ -75,6 +75,10 @@ const char* toString(InferenceId i)
return "ARITH_NL_IAND_SUM_REFINE";
case InferenceId::ARITH_NL_IAND_BITWISE_REFINE:
return "ARITH_NL_IAND_BITWISE_REFINE";
+ case InferenceId::ARITH_NL_POW2_INIT_REFINE:
+ return "ARITH_NL_POW2_INIT_REFINE";
+ case InferenceId::ARITH_NL_POW2_VALUE_REFINE:
+ return "ARITH_NL_POW2_VALUE_REFINE";
case InferenceId::ARITH_NL_CAD_CONFLICT: return "ARITH_NL_CAD_CONFLICT";
case InferenceId::ARITH_NL_CAD_EXCLUDED_INTERVAL:
return "ARITH_NL_CAD_EXCLUDED_INTERVAL";
diff --git a/src/theory/inference_id.h b/src/theory/inference_id.h
index 169992f41..6a87776d6 100644
--- a/src/theory/inference_id.h
+++ b/src/theory/inference_id.h
@@ -126,6 +126,11 @@ enum class InferenceId
ARITH_NL_IAND_SUM_REFINE,
// bitwise refinements (IAndSolver::checkFullRefine)
ARITH_NL_IAND_BITWISE_REFINE,
+ //-------------------- nonlinear pow2 solver
+ // initial refinements (Pow2Solver::checkInitialRefine)
+ ARITH_NL_POW2_INIT_REFINE,
+ // value refinements (Pow2Solver::checkFullRefine)
+ ARITH_NL_POW2_VALUE_REFINE,
//-------------------- nonlinear cad solver
// conflict / infeasible subset obtained from cad
ARITH_NL_CAD_CONFLICT,
diff --git a/src/theory/logic_info.cpp b/src/theory/logic_info.cpp
index 8ba43aa1a..d53b06151 100644
--- a/src/theory/logic_info.cpp
+++ b/src/theory/logic_info.cpp
@@ -44,10 +44,6 @@ LogicInfo::LogicInfo()
{
for (TheoryId id = THEORY_FIRST; id < THEORY_LAST; ++id)
{
- if (id == THEORY_FP && !Configuration::isBuiltWithSymFPU())
- {
- continue;
- }
enableTheory(id);
}
}
diff --git a/src/theory/quantifiers/fmf/full_model_check.cpp b/src/theory/quantifiers/fmf/full_model_check.cpp
index 808db7aec..c6f38f298 100644
--- a/src/theory/quantifiers/fmf/full_model_check.cpp
+++ b/src/theory/quantifiers/fmf/full_model_check.cpp
@@ -941,8 +941,9 @@ void FullModelChecker::doCheck(FirstOrderModelFmc * fm, Node f, Def & d, Node n
else if( n.getNumChildren()==0 ){
Node r = n;
if( !n.isConst() ){
- if( !fm->hasTerm(n) ){
- r = getSomeDomainElement(fm, n.getType() );
+ TypeNode tn = n.getType();
+ if( !fm->hasTerm(n) && tn.isFirstClass() ){
+ r = getSomeDomainElement(fm, tn );
}
r = fm->getRepresentative( r );
}
diff --git a/src/theory/quantifiers/instantiate.cpp b/src/theory/quantifiers/instantiate.cpp
index 71f4028ec..0f82d8301 100644
--- a/src/theory/quantifiers/instantiate.cpp
+++ b/src/theory/quantifiers/instantiate.cpp
@@ -16,6 +16,7 @@
#include "theory/quantifiers/instantiate.h"
#include "expr/node_algorithm.h"
+#include "options/base_options.h"
#include "options/printer_options.h"
#include "options/quantifiers_options.h"
#include "options/smt_options.h"
diff --git a/src/theory/quantifiers/term_registry.cpp b/src/theory/quantifiers/term_registry.cpp
index 5b7bd1552..31e5240df 100644
--- a/src/theory/quantifiers/term_registry.cpp
+++ b/src/theory/quantifiers/term_registry.cpp
@@ -15,6 +15,7 @@
#include "theory/quantifiers/term_registry.h"
+#include "options/base_options.h"
#include "options/quantifiers_options.h"
#include "options/smt_options.h"
#include "theory/quantifiers/first_order_model.h"
diff --git a/src/theory/sep/theory_sep.cpp b/src/theory/sep/theory_sep.cpp
index 6d1b9955a..efede77ba 100644
--- a/src/theory/sep/theory_sep.cpp
+++ b/src/theory/sep/theory_sep.cpp
@@ -95,6 +95,7 @@ bool TheorySep::needsEqualityEngine(EeSetupInfo& esi)
{
esi.d_notify = &d_notify;
esi.d_name = "theory::sep::ee";
+ esi.d_notifyMerge = true;
return true;
}
diff --git a/src/theory/sets/theory_sets.cpp b/src/theory/sets/theory_sets.cpp
index 4cca76057..439e9443d 100644
--- a/src/theory/sets/theory_sets.cpp
+++ b/src/theory/sets/theory_sets.cpp
@@ -60,6 +60,9 @@ bool TheorySets::needsEqualityEngine(EeSetupInfo& esi)
{
esi.d_notify = &d_notify;
esi.d_name = "theory::sets::ee";
+ esi.d_notifyNewClass = true;
+ esi.d_notifyMerge = true;
+ esi.d_notifyDisequal = true;
return true;
}
diff --git a/src/theory/strings/regexp_entail.cpp b/src/theory/strings/regexp_entail.cpp
index 3d4a2d143..be1646403 100644
--- a/src/theory/strings/regexp_entail.cpp
+++ b/src/theory/strings/regexp_entail.cpp
@@ -364,6 +364,10 @@ bool RegExpEntail::isConstRegExp(TNode t)
}
}
}
+ else if (ck == ITE)
+ {
+ return false;
+ }
else if (cur.isVar())
{
return false;
diff --git a/src/theory/strings/term_registry.cpp b/src/theory/strings/term_registry.cpp
index aac9e9313..8c5805b37 100644
--- a/src/theory/strings/term_registry.cpp
+++ b/src/theory/strings/term_registry.cpp
@@ -249,7 +249,8 @@ void TermRegistry::preRegisterTerm(TNode n)
// Concatenation terms do not need to be considered here because
// their arguments have string type and do not introduce any shared
// terms.
- if (n.hasOperator() && ee->isFunctionKind(k) && k != STRING_CONCAT)
+ if (n.hasOperator() && ee->isFunctionKind(k)
+ && kindToTheoryId(k) == THEORY_STRINGS && k != STRING_CONCAT)
{
d_functionsTerms.push_back(n);
}
diff --git a/src/theory/strings/theory_strings.cpp b/src/theory/strings/theory_strings.cpp
index f4daed85d..f0763e153 100644
--- a/src/theory/strings/theory_strings.cpp
+++ b/src/theory/strings/theory_strings.cpp
@@ -103,6 +103,9 @@ bool TheoryStrings::needsEqualityEngine(EeSetupInfo& esi)
{
esi.d_notify = &d_notify;
esi.d_name = "theory::strings::ee";
+ esi.d_notifyNewClass = true;
+ esi.d_notifyMerge = true;
+ esi.d_notifyDisequal = true;
return true;
}
diff --git a/src/theory/theory.cpp b/src/theory/theory.cpp
index d6ad4cd41..b9dc1ba42 100644
--- a/src/theory/theory.cpp
+++ b/src/theory/theory.cpp
@@ -330,12 +330,18 @@ bool Theory::isLegalElimination(TNode x, TNode val)
{
return false;
}
- if (!options::produceModels())
+ if (!options::produceModels() && !d_logicInfo.isQuantified())
{
- // don't care about the model, we are fine
+ // Don't care about the model and logic is not quantified, we can eliminate.
return true;
}
- // if there is a model object
+ // If models are enabled, then it depends on whether the term contains any
+ // unevaluable operators like FORALL, SINE, etc. Having such operators makes
+ // model construction contain non-constant values for variables, which is
+ // not ideal from a user perspective.
+ // We also insist on this check since the term to eliminate should never
+ // contain quantifiers, or else variable shadowing issues may arise.
+ // there should be a model object
TheoryModel* tm = d_valuation.getModel();
Assert(tm != nullptr);
return tm->isLegalElimination(x, val);
diff --git a/src/theory/theory_model.cpp b/src/theory/theory_model.cpp
index 8eec7f911..3e902463c 100644
--- a/src/theory/theory_model.cpp
+++ b/src/theory/theory_model.cpp
@@ -142,8 +142,22 @@ Node TheoryModel::getValue(TNode n) const
Debug("model-getvalue-debug") << "[model-getvalue] getValue : substitute " << n << " to " << nn << std::endl;
//get value in model
nn = getModelValue(nn);
- if (nn.isNull()) return nn;
- if(options::condenseFunctionValues() || nn.getKind() != kind::LAMBDA) {
+ if (nn.isNull())
+ {
+ return nn;
+ }
+ else if (nn.getKind() == kind::LAMBDA)
+ {
+ if (options::condenseFunctionValues())
+ {
+ // normalize the body. Do not normalize the entire node, which
+ // involves array normalization.
+ NodeManager* nm = NodeManager::currentNM();
+ nn = nm->mkNode(kind::LAMBDA, nn[0], Rewriter::rewrite(nn[1]));
+ }
+ }
+ else
+ {
//normalize
nn = Rewriter::rewrite(nn);
}
diff --git a/src/theory/uf/equality_engine.cpp b/src/theory/uf/equality_engine.cpp
index 8885abe6b..338076e78 100644
--- a/src/theory/uf/equality_engine.cpp
+++ b/src/theory/uf/equality_engine.cpp
@@ -88,10 +88,6 @@ void EqualityEngine::init() {
d_triggerDatabaseAllocatedSize = 100000;
d_triggerDatabase = (char*) malloc(d_triggerDatabaseAllocatedSize);
- //We can't notify during the initialization because it notifies
- // QuantifiersEngine.AddTermToDatabase that try to access to the uf
- // instantiator that currently doesn't exist.
- ScopedBool sb(d_performNotify, false);
addTermInternal(d_true);
addTermInternal(d_false);
@@ -111,7 +107,6 @@ EqualityEngine::EqualityEngine(context::Context* context,
d_masterEqualityEngine(0),
d_context(context),
d_done(context, false),
- d_performNotify(true),
d_notify(s_notifyNone),
d_applicationLookupsCount(context, 0),
d_nodesCount(context, 0),
@@ -141,7 +136,6 @@ EqualityEngine::EqualityEngine(EqualityEngineNotify& notify,
d_masterEqualityEngine(0),
d_context(context),
d_done(context, false),
- d_performNotify(true),
d_notify(notify),
d_applicationLookupsCount(context, 0),
d_nodesCount(context, 0),
@@ -381,10 +375,7 @@ void EqualityEngine::addTermInternal(TNode t, bool isOperator) {
{
// Notify e.g. the theory that owns this equality engine that there is a
// new equivalence class.
- if (d_performNotify)
- {
- d_notify.eqNotifyNewClass(t);
- }
+ d_notify.eqNotifyNewClass(t);
if (d_constantsAreTriggers && d_isConstant[result])
{
// Non-Boolean constants are trigger terms for all tags
@@ -506,9 +497,7 @@ bool EqualityEngine::assertEquality(TNode eq,
}
// notify the theory
- if (d_performNotify) {
- d_notify.eqNotifyDisequal(eq[0], eq[1], reason);
- }
+ d_notify.eqNotifyDisequal(eq[0], eq[1], reason);
Debug("equality::trigger") << d_name << "::eq::addEquality(" << eq << "," << (polarity ? "true" : "false") << ")" << std::endl;
@@ -608,7 +597,7 @@ bool EqualityEngine::merge(EqualityNode& class1, EqualityNode& class2, std::vect
// Determine if we should notify the owner of this class of this merge.
// The second part of this check is needed due to the internal implementation
// of this class. It ensures that we are merging terms and not operators.
- if (d_performNotify && class1Id == cc1.getFind() && class2Id == cc2.getFind())
+ if (class1Id == cc1.getFind() && class2Id == cc2.getFind())
{
doNotify = true;
}
@@ -797,11 +786,11 @@ bool EqualityEngine::merge(EqualityNode& class1, EqualityNode& class2, std::vect
EqualityNodeId tag1id = newSetTriggers[newSetTriggersSize++] =
class1triggers.d_triggers[i1++];
// since they are both tagged notify of merge
- if (d_performNotify) {
- EqualityNodeId tag2id = class2triggers.d_triggers[i2++];
- if (!d_notify.eqNotifyTriggerTermEquality(tag1, d_nodes[tag1id], d_nodes[tag2id], true)) {
- return false;
- }
+ EqualityNodeId tag2id = class2triggers.d_triggers[i2++];
+ if (!d_notify.eqNotifyTriggerTermEquality(
+ tag1, d_nodes[tag1id], d_nodes[tag2id], true))
+ {
+ return false;
}
// Next tags
tag1 = TheoryIdSetUtil::setPop(tags1);
@@ -1934,9 +1923,8 @@ void EqualityEngine::propagate() {
d_assertedEqualities.push_back(Equality(null_id, null_id));
d_assertedEqualitiesCount = d_assertedEqualitiesCount + 1;
// Notify
- if (d_performNotify) {
- d_notify.eqNotifyConstantTermMerge(d_nodes[t1classId], d_nodes[t2classId]);
- }
+ d_notify.eqNotifyConstantTermMerge(d_nodes[t1classId],
+ d_nodes[t2classId]);
// Empty the queue and exit
continue;
}
@@ -1995,7 +1983,8 @@ void EqualityEngine::propagate() {
}
// Notify the triggers
- if (d_performNotify && !d_done) {
+ if (!d_done)
+ {
for (size_t trigger_i = 0, trigger_end = triggers.size(); trigger_i < trigger_end && !d_done; ++ trigger_i) {
const TriggerInfo& triggerInfo = d_equalityTriggersOriginal[triggers[trigger_i]];
if (triggerInfo.d_trigger.getKind() == kind::EQUAL)
@@ -2217,12 +2206,16 @@ void EqualityEngine::addTriggerTerm(TNode t, TheoryId tag)
TriggerTermSetRef triggerSetRef = d_nodeIndividualTrigger[classId];
if (triggerSetRef != +null_set_id && getTriggerTermSet(triggerSetRef).hasTrigger(tag)) {
// If the term already is in the equivalence class that a tagged representative, just notify
- if (d_performNotify) {
- EqualityNodeId triggerId = getTriggerTermSet(triggerSetRef).getTrigger(tag);
- Debug("equality::trigger") << d_name << "::eq::addTriggerTerm(" << t << ", " << tag << "): already have this trigger in class with " << d_nodes[triggerId] << std::endl;
- if (eqNodeId != triggerId && !d_notify.eqNotifyTriggerTermEquality(tag, t, d_nodes[triggerId], true)) {
- d_done = true;
- }
+ EqualityNodeId triggerId = getTriggerTermSet(triggerSetRef).getTrigger(tag);
+ Debug("equality::trigger")
+ << d_name << "::eq::addTriggerTerm(" << t << ", " << tag
+ << "): already have this trigger in class with " << d_nodes[triggerId]
+ << std::endl;
+ if (eqNodeId != triggerId
+ && !d_notify.eqNotifyTriggerTermEquality(
+ tag, t, d_nodes[triggerId], true))
+ {
+ d_done = true;
}
} else {
@@ -2602,10 +2595,10 @@ bool EqualityEngine::propagateTriggerTermDisequalities(
// Store the propagation
storePropagatedDisequality(currentTag, myRep, tagRep);
// Notify
- if (d_performNotify) {
- if (!d_notify.eqNotifyTriggerTermEquality(currentTag, d_nodes[myRep], d_nodes[tagRep], false)) {
- d_done = true;
- }
+ if (!d_notify.eqNotifyTriggerTermEquality(
+ currentTag, d_nodes[myRep], d_nodes[tagRep], false))
+ {
+ d_done = true;
}
}
}
diff --git a/src/theory/uf/equality_engine.h b/src/theory/uf/equality_engine.h
index 024774593..c0e7b3478 100644
--- a/src/theory/uf/equality_engine.h
+++ b/src/theory/uf/equality_engine.h
@@ -120,9 +120,6 @@ private:
/** If we are done, we don't except any new assertions */
context::CDO<bool> d_done;
- /** Whether to notify or not (temporarily disabled on equality checks) */
- bool d_performNotify;
-
/** The class to notify when a representative changes for a term */
EqualityEngineNotify& d_notify;
diff --git a/src/theory/uf/theory_uf.cpp b/src/theory/uf/theory_uf.cpp
index 36b05b145..f1adde143 100644
--- a/src/theory/uf/theory_uf.cpp
+++ b/src/theory/uf/theory_uf.cpp
@@ -73,6 +73,14 @@ bool TheoryUF::needsEqualityEngine(EeSetupInfo& esi)
{
esi.d_notify = &d_notify;
esi.d_name = d_instanceName + "theory::uf::ee";
+ if (options::finiteModelFind()
+ && options::ufssMode() != options::UfssMode::NONE)
+ {
+ // need notifications about sorts
+ esi.d_notifyNewClass = true;
+ esi.d_notifyMerge = true;
+ esi.d_notifyDisequal = true;
+ }
return true;
}
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
index 2938ddcca..71742dfce 100644
--- a/src/util/CMakeLists.txt
+++ b/src/util/CMakeLists.txt
@@ -13,9 +13,6 @@
# The build system configuration.
##
-configure_file(floatingpoint_literal_symfpu.h.in floatingpoint_literal_symfpu.h)
-configure_file(floatingpoint_literal_symfpu_traits.h.in
- floatingpoint_literal_symfpu_traits.h)
configure_file(rational.h.in rational.h)
configure_file(integer.h.in integer.h)
configure_file(real_algebraic_number.h.in real_algebraic_number.h)
diff --git a/src/util/floatingpoint_literal_symfpu.cpp b/src/util/floatingpoint_literal_symfpu.cpp
index c2c3fe77b..dc3dce6b9 100644
--- a/src/util/floatingpoint_literal_symfpu.cpp
+++ b/src/util/floatingpoint_literal_symfpu.cpp
@@ -16,7 +16,6 @@
#include "base/check.h"
-#ifdef CVC5_USE_SYMFPU
#include "symfpu/core/add.h"
#include "symfpu/core/classify.h"
#include "symfpu/core/compare.h"
@@ -31,11 +30,9 @@
#include "symfpu/core/sqrt.h"
#include "symfpu/utils/numberOfRoundingModes.h"
#include "symfpu/utils/properties.h"
-#endif
/* -------------------------------------------------------------------------- */
-#ifdef CVC5_USE_SYMFPU
namespace symfpu {
#define CVC5_LIT_ITE_DFN(T) \
@@ -57,7 +54,6 @@ CVC5_LIT_ITE_DFN(::cvc5::symfpuLiteral::traits::ubv);
#undef CVC5_LIT_ITE_DFN
} // namespace symfpu
-#endif
/* -------------------------------------------------------------------------- */
@@ -65,44 +61,30 @@ namespace cvc5 {
uint32_t FloatingPointLiteral::getUnpackedExponentWidth(FloatingPointSize& size)
{
-#ifdef CVC5_USE_SYMFPU
return SymFPUUnpackedFloatLiteral::exponentWidth(size);
-#else
- unimplemented();
- return 2;
-#endif
}
uint32_t FloatingPointLiteral::getUnpackedSignificandWidth(
FloatingPointSize& size)
{
-#ifdef CVC5_USE_SYMFPU
return SymFPUUnpackedFloatLiteral::significandWidth(size);
-#else
- unimplemented();
- return 2;
-#endif
}
FloatingPointLiteral::FloatingPointLiteral(uint32_t exp_size,
uint32_t sig_size,
const BitVector& bv)
: d_fp_size(exp_size, sig_size)
-#ifdef CVC5_USE_SYMFPU
,
d_symuf(symfpu::unpack<symfpuLiteral::traits>(
symfpuLiteral::Cvc5FPSize(exp_size, sig_size), bv))
-#endif
{
}
FloatingPointLiteral::FloatingPointLiteral(
const FloatingPointSize& size, FloatingPointLiteral::SpecialConstKind kind)
: d_fp_size(size)
-#ifdef CVC5_USE_SYMFPU
,
d_symuf(SymFPUUnpackedFloatLiteral::makeNaN(size))
-#endif
{
Assert(kind == FloatingPointLiteral::SpecialConstKind::FPNAN);
}
@@ -112,12 +94,10 @@ FloatingPointLiteral::FloatingPointLiteral(
FloatingPointLiteral::SpecialConstKind kind,
bool sign)
: d_fp_size(size)
-#ifdef CVC5_USE_SYMFPU
,
d_symuf(kind == FloatingPointLiteral::SpecialConstKind::FPINF
? SymFPUUnpackedFloatLiteral::makeInf(size, sign)
: SymFPUUnpackedFloatLiteral::makeZero(size, sign))
-#endif
{
Assert(kind == FloatingPointLiteral::SpecialConstKind::FPINF
|| kind == FloatingPointLiteral::SpecialConstKind::FPZERO);
@@ -126,10 +106,8 @@ FloatingPointLiteral::FloatingPointLiteral(
FloatingPointLiteral::FloatingPointLiteral(const FloatingPointSize& size,
const BitVector& bv)
: d_fp_size(size)
-#ifdef CVC5_USE_SYMFPU
,
d_symuf(symfpu::unpack<symfpuLiteral::traits>(size, bv))
-#endif
{
}
@@ -138,7 +116,6 @@ FloatingPointLiteral::FloatingPointLiteral(const FloatingPointSize& size,
const BitVector& bv,
bool signedBV)
: d_fp_size(size)
-#ifdef CVC5_USE_SYMFPU
,
d_symuf(signedBV ? symfpu::convertSBVToFloat<symfpuLiteral::traits>(
symfpuLiteral::Cvc5FPSize(size),
@@ -148,97 +125,61 @@ FloatingPointLiteral::FloatingPointLiteral(const FloatingPointSize& size,
symfpuLiteral::Cvc5FPSize(size),
symfpuLiteral::Cvc5RM(rm),
symfpuLiteral::Cvc5UnsignedBitVector(bv)))
-#endif
{
}
BitVector FloatingPointLiteral::pack(void) const
{
-#ifdef CVC5_USE_SYMFPU
BitVector bv(symfpu::pack<symfpuLiteral::traits>(d_fp_size, d_symuf));
-#else
- unimplemented();
- BitVector bv(4u, 0u);
-#endif
return bv;
}
FloatingPointLiteral FloatingPointLiteral::absolute(void) const
{
-#ifdef CVC5_USE_SYMFPU
return FloatingPointLiteral(
d_fp_size, symfpu::absolute<symfpuLiteral::traits>(d_fp_size, d_symuf));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::negate(void) const
{
-#ifdef CVC5_USE_SYMFPU
return FloatingPointLiteral(
d_fp_size, symfpu::negate<symfpuLiteral::traits>(d_fp_size, d_symuf));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::add(
const RoundingMode& rm, const FloatingPointLiteral& arg) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg.d_fp_size);
return FloatingPointLiteral(d_fp_size,
symfpu::add<symfpuLiteral::traits>(
d_fp_size, rm, d_symuf, arg.d_symuf, true));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::sub(
const RoundingMode& rm, const FloatingPointLiteral& arg) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg.d_fp_size);
return FloatingPointLiteral(d_fp_size,
symfpu::add<symfpuLiteral::traits>(
d_fp_size, rm, d_symuf, arg.d_symuf, false));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::mult(
const RoundingMode& rm, const FloatingPointLiteral& arg) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg.d_fp_size);
return FloatingPointLiteral(d_fp_size,
symfpu::multiply<symfpuLiteral::traits>(
d_fp_size, rm, d_symuf, arg.d_symuf));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::div(
const RoundingMode& rm, const FloatingPointLiteral& arg) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg.d_fp_size);
return FloatingPointLiteral(d_fp_size,
symfpu::divide<symfpuLiteral::traits>(
d_fp_size, rm, d_symuf, arg.d_symuf));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::fma(
@@ -246,276 +187,150 @@ FloatingPointLiteral FloatingPointLiteral::fma(
const FloatingPointLiteral& arg1,
const FloatingPointLiteral& arg2) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg1.d_fp_size);
Assert(d_fp_size == arg2.d_fp_size);
return FloatingPointLiteral(
d_fp_size,
symfpu::fma<symfpuLiteral::traits>(
d_fp_size, rm, d_symuf, arg1.d_symuf, arg2.d_symuf));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::sqrt(const RoundingMode& rm) const
{
-#ifdef CVC5_USE_SYMFPU
return FloatingPointLiteral(
d_fp_size, symfpu::sqrt<symfpuLiteral::traits>(d_fp_size, rm, d_symuf));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::rti(const RoundingMode& rm) const
{
-#ifdef CVC5_USE_SYMFPU
return FloatingPointLiteral(
d_fp_size,
symfpu::roundToIntegral<symfpuLiteral::traits>(d_fp_size, rm, d_symuf));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::rem(
const FloatingPointLiteral& arg) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg.d_fp_size);
return FloatingPointLiteral(d_fp_size,
symfpu::remainder<symfpuLiteral::traits>(
d_fp_size, d_symuf, arg.d_symuf));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::maxTotal(
const FloatingPointLiteral& arg, bool zeroCaseLeft) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg.d_fp_size);
return FloatingPointLiteral(
d_fp_size,
symfpu::max<symfpuLiteral::traits>(
d_fp_size, d_symuf, arg.d_symuf, zeroCaseLeft));
-#else
- unimplemented();
- return *this;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::minTotal(
const FloatingPointLiteral& arg, bool zeroCaseLeft) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg.d_fp_size);
return FloatingPointLiteral(
d_fp_size,
symfpu::min<symfpuLiteral::traits>(
d_fp_size, d_symuf, arg.d_symuf, zeroCaseLeft));
-#else
- unimplemented();
- return *this;
-#endif
}
bool FloatingPointLiteral::operator==(const FloatingPointLiteral& fp) const
{
-#ifdef CVC5_USE_SYMFPU
return ((d_fp_size == fp.d_fp_size)
&& symfpu::smtlibEqual<symfpuLiteral::traits>(
d_fp_size, d_symuf, fp.d_symuf));
-#else
- unimplemented();
- return ((d_fp_size == fp.d_fp_size));
-#endif
}
bool FloatingPointLiteral::operator<=(const FloatingPointLiteral& arg) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg.d_fp_size);
return symfpu::lessThanOrEqual<symfpuLiteral::traits>(
d_fp_size, d_symuf, arg.d_symuf);
-#else
- unimplemented();
- return false;
-#endif
}
bool FloatingPointLiteral::operator<(const FloatingPointLiteral& arg) const
{
-#ifdef CVC5_USE_SYMFPU
Assert(d_fp_size == arg.d_fp_size);
return symfpu::lessThan<symfpuLiteral::traits>(
d_fp_size, d_symuf, arg.d_symuf);
-#else
- unimplemented();
- return false;
-#endif
}
BitVector FloatingPointLiteral::getExponent() const
{
-#ifdef CVC5_USE_SYMFPU
return d_symuf.exponent;
-#else
- unimplemented();
- Unreachable() << "no concrete implementation of FloatingPointLiteral";
- return BitVector();
-#endif
}
BitVector FloatingPointLiteral::getSignificand() const
{
-#ifdef CVC5_USE_SYMFPU
return d_symuf.significand;
-#else
- unimplemented();
- Unreachable() << "no concrete implementation of FloatingPointLiteral";
- return BitVector();
-#endif
}
bool FloatingPointLiteral::getSign() const
{
-#ifdef CVC5_USE_SYMFPU
return d_symuf.sign;
-#else
- unimplemented();
- Unreachable() << "no concrete implementation of FloatingPointLiteral";
- return false;
-#endif
}
bool FloatingPointLiteral::isNormal(void) const
{
-#ifdef CVC5_USE_SYMFPU
return symfpu::isNormal<symfpuLiteral::traits>(d_fp_size, d_symuf);
-#else
- unimplemented();
- return false;
-#endif
}
bool FloatingPointLiteral::isSubnormal(void) const
{
-#ifdef CVC5_USE_SYMFPU
return symfpu::isSubnormal<symfpuLiteral::traits>(d_fp_size, d_symuf);
-#else
- unimplemented();
- return false;
-#endif
}
bool FloatingPointLiteral::isZero(void) const
{
-#ifdef CVC5_USE_SYMFPU
return symfpu::isZero<symfpuLiteral::traits>(d_fp_size, d_symuf);
-#else
- unimplemented();
- return false;
-#endif
}
bool FloatingPointLiteral::isInfinite(void) const
{
-#ifdef CVC5_USE_SYMFPU
return symfpu::isInfinite<symfpuLiteral::traits>(d_fp_size, d_symuf);
-#else
- unimplemented();
- return false;
-#endif
}
bool FloatingPointLiteral::isNaN(void) const
{
-#ifdef CVC5_USE_SYMFPU
return symfpu::isNaN<symfpuLiteral::traits>(d_fp_size, d_symuf);
-#else
- unimplemented();
- return false;
-#endif
}
bool FloatingPointLiteral::isNegative(void) const
{
-#ifdef CVC5_USE_SYMFPU
return symfpu::isNegative<symfpuLiteral::traits>(d_fp_size, d_symuf);
-#else
- unimplemented();
- return false;
-#endif
}
bool FloatingPointLiteral::isPositive(void) const
{
-#ifdef CVC5_USE_SYMFPU
return symfpu::isPositive<symfpuLiteral::traits>(d_fp_size, d_symuf);
-#else
- unimplemented();
- return false;
-#endif
}
FloatingPointLiteral FloatingPointLiteral::convert(
const FloatingPointSize& target, const RoundingMode& rm) const
{
-#ifdef CVC5_USE_SYMFPU
return FloatingPointLiteral(
target,
symfpu::convertFloatToFloat<symfpuLiteral::traits>(
d_fp_size, target, rm, d_symuf));
-#else
- unimplemented();
- return *this;
-#endif
}
BitVector FloatingPointLiteral::convertToSBVTotal(BitVectorSize width,
const RoundingMode& rm,
BitVector undefinedCase) const
{
-#ifdef CVC5_USE_SYMFPU
return symfpu::convertFloatToSBV<symfpuLiteral::traits>(
d_fp_size, rm, d_symuf, width, undefinedCase);
-#else
- unimplemented();
- return undefinedCase;
-#endif
}
BitVector FloatingPointLiteral::convertToUBVTotal(BitVectorSize width,
const RoundingMode& rm,
BitVector undefinedCase) const
{
-#ifdef CVC5_USE_SYMFPU
return symfpu::convertFloatToUBV<symfpuLiteral::traits>(
d_fp_size, rm, d_symuf, width, undefinedCase);
-#else
- unimplemented();
- return undefinedCase;
-#endif
}
-#ifndef CVC5_USE_SYMFPU
-void FloatingPointLiteral::unimplemented(void)
-{
- Unimplemented() << "no concrete implementation of FloatingPointLiteral";
-}
-
-size_t FloatingPointLiteral::hash(void) const
-{
- unimplemented();
- return 23;
-}
-#endif
-
} // namespace cvc5
diff --git a/src/util/floatingpoint_literal_symfpu.h.in b/src/util/floatingpoint_literal_symfpu.h
index 54827a308..5b2b0f7c8 100644
--- a/src/util/floatingpoint_literal_symfpu.h.in
+++ b/src/util/floatingpoint_literal_symfpu.h
@@ -20,20 +20,16 @@
#define CVC5__UTIL__FLOATINGPOINT_LITERAL_SYMFPU_H
#include "util/bitvector.h"
-#include "util/floatingpoint_size.h"
#include "util/floatingpoint_literal_symfpu_traits.h"
+#include "util/floatingpoint_size.h"
#include "util/roundingmode.h"
/* -------------------------------------------------------------------------- */
namespace cvc5 {
-// clang-format off
-#if @CVC5_USE_SYMFPU@
-// clang-format on
using SymFPUUnpackedFloatLiteral =
::symfpu::unpackedFloat<symfpuLiteral::traits>;
-#endif
class FloatingPointLiteral
{
@@ -65,13 +61,6 @@ class FloatingPointLiteral
*/
static uint32_t getUnpackedSignificandWidth(FloatingPointSize& size);
-// clang-format off
-#if !@CVC5_USE_SYMFPU@
- // clang-format on
- /** Catch-all for unimplemented functions. */
- static void unimplemented(void);
-#endif
-
/** Constructors. */
/** Create a FP literal from its IEEE bit-vector representation. */
@@ -197,18 +186,10 @@ class FloatingPointLiteral
BitVector convertToUBVTotal(BitVectorSize width,
const RoundingMode& rm,
BitVector undefinedCase) const;
-// clang-format off
-#if @CVC5_USE_SYMFPU@
- // clang-format on
/** Return wrapped floating-point literal. */
const SymFPUUnpackedFloatLiteral& getSymUF() const { return d_symuf; }
-#else
- /** Dummy hash function. */
- size_t hash(void) const;
-#endif
private:
-
/**
* Create a FP literal from unpacked representation.
*
@@ -223,34 +204,19 @@ class FloatingPointLiteral
const bool sign,
const BitVector& exp,
const BitVector& sig)
- : d_fp_size(size)
-// clang-format off
-#if @CVC5_USE_SYMFPU@
- // clang-format on
- ,
- d_symuf(SymFPUUnpackedFloatLiteral(sign, exp, sig))
-#endif
+ : d_fp_size(size), d_symuf(SymFPUUnpackedFloatLiteral(sign, exp, sig))
{
}
-// clang-format off
-#if @CVC5_USE_SYMFPU@
- // clang-format on
-
/** Create a FP literal from a symFPU unpacked float. */
FloatingPointLiteral(const FloatingPointSize& size,
SymFPUUnpackedFloatLiteral symuf)
: d_fp_size(size), d_symuf(symuf){};
-#endif
/** The floating-point size of this floating-point literal. */
FloatingPointSize d_fp_size;
-// clang-format off
-#if @CVC5_USE_SYMFPU@
- // clang-format on
/** The actual floating-point value, a SymFPU unpackedFloat. */
SymFPUUnpackedFloatLiteral d_symuf;
-#endif
};
/* -------------------------------------------------------------------------- */
diff --git a/src/util/floatingpoint_literal_symfpu_traits.cpp b/src/util/floatingpoint_literal_symfpu_traits.cpp
index 071b69912..0f46708b0 100644
--- a/src/util/floatingpoint_literal_symfpu_traits.cpp
+++ b/src/util/floatingpoint_literal_symfpu_traits.cpp
@@ -13,8 +13,6 @@
* SymFPU glue code for floating-point values.
*/
-#if CVC5_USE_SYMFPU
-
#include "util/floatingpoint_literal_symfpu_traits.h"
#include "base/check.h"
@@ -413,4 +411,3 @@ void traits::invariant(const traits::prop& p)
}
} // namespace symfpuLiteral
} // namespace cvc5
-#endif
diff --git a/src/util/floatingpoint_literal_symfpu_traits.h.in b/src/util/floatingpoint_literal_symfpu_traits.h
index 76d2f47e2..bc5caaf88 100644
--- a/src/util/floatingpoint_literal_symfpu_traits.h.in
+++ b/src/util/floatingpoint_literal_symfpu_traits.h
@@ -25,16 +25,12 @@
#ifndef CVC5__UTIL__FLOATINGPOINT_LITERAL_SYMFPU_TRAITS_H
#define CVC5__UTIL__FLOATINGPOINT_LITERAL_SYMFPU_TRAITS_H
-// clang-format off
-#if @CVC5_USE_SYMFPU@
-// clang-format on
+#include <symfpu/core/unpackedFloat.h>
#include "util/bitvector.h"
#include "util/floatingpoint_size.h"
#include "util/roundingmode.h"
-#include <symfpu/core/unpackedFloat.h>
-
/* -------------------------------------------------------------------------- */
namespace cvc5 {
@@ -258,7 +254,6 @@ class wrappedBitVector : public BitVector
Cvc5BitWidth lower) const;
};
} // namespace symfpuLiteral
-}
+} // namespace cvc5
#endif
-#endif
diff --git a/src/util/resource_manager.cpp b/src/util/resource_manager.cpp
index f0cc78789..c4a94dfa2 100644
--- a/src/util/resource_manager.cpp
+++ b/src/util/resource_manager.cpp
@@ -22,9 +22,9 @@
#include "base/check.h"
#include "base/listener.h"
#include "base/output.h"
+#include "options/base_options.h"
#include "options/option_exception.h"
#include "options/options.h"
-#include "options/resource_manager_options.h"
#include "util/statistics_registry.h"
using namespace std;
@@ -164,7 +164,7 @@ ResourceManager::ResourceManager(StatisticsRegistry& stats,
d_infidWeights.fill(1);
d_resourceWeights.fill(1);
- for (const auto& opt : d_options.resman.resourceWeightHolder)
+ for (const auto& opt : d_options.base.resourceWeightHolder)
{
std::string name;
uint64_t weight;
@@ -189,9 +189,9 @@ uint64_t ResourceManager::getTimeUsage() const { return d_cumulativeTimeUsed; }
uint64_t ResourceManager::getResourceRemaining() const
{
- if (d_options.resman.cumulativeResourceLimit <= d_cumulativeResourceUsed)
+ if (d_options.base.cumulativeResourceLimit <= d_cumulativeResourceUsed)
return 0;
- return d_options.resman.cumulativeResourceLimit - d_cumulativeResourceUsed;
+ return d_options.base.cumulativeResourceLimit - d_cumulativeResourceUsed;
}
void ResourceManager::spendResource(uint64_t amount)
@@ -237,21 +237,21 @@ void ResourceManager::spendResource(theory::InferenceId iid)
void ResourceManager::beginCall()
{
- d_perCallTimer.set(d_options.resman.perCallMillisecondLimit);
+ d_perCallTimer.set(d_options.base.perCallMillisecondLimit);
d_thisCallResourceUsed = 0;
- if (d_options.resman.cumulativeResourceLimit > 0)
+ if (d_options.base.cumulativeResourceLimit > 0)
{
// Compute remaining cumulative resource budget
d_thisCallResourceBudget =
- d_options.resman.cumulativeResourceLimit - d_cumulativeResourceUsed;
+ d_options.base.cumulativeResourceLimit - d_cumulativeResourceUsed;
}
- if (d_options.resman.perCallResourceLimit > 0)
+ if (d_options.base.perCallResourceLimit > 0)
{
// Check if per-call resource budget is even smaller
- if (d_options.resman.perCallResourceLimit < d_thisCallResourceBudget)
+ if (d_options.base.perCallResourceLimit < d_thisCallResourceBudget)
{
- d_thisCallResourceBudget = d_options.resman.perCallResourceLimit;
+ d_thisCallResourceBudget = d_options.base.perCallResourceLimit;
}
}
}
@@ -265,25 +265,25 @@ void ResourceManager::endCall()
bool ResourceManager::limitOn() const
{
- return (d_options.resman.cumulativeResourceLimit > 0)
- || (d_options.resman.perCallMillisecondLimit > 0)
- || (d_options.resman.perCallResourceLimit > 0);
+ return (d_options.base.cumulativeResourceLimit > 0)
+ || (d_options.base.perCallMillisecondLimit > 0)
+ || (d_options.base.perCallResourceLimit > 0);
}
bool ResourceManager::outOfResources() const
{
- if (d_options.resman.perCallResourceLimit > 0)
+ if (d_options.base.perCallResourceLimit > 0)
{
// Check if per-call resources are exhausted
- if (d_thisCallResourceUsed >= d_options.resman.perCallResourceLimit)
+ if (d_thisCallResourceUsed >= d_options.base.perCallResourceLimit)
{
return true;
}
}
- if (d_options.resman.cumulativeResourceLimit > 0)
+ if (d_options.base.cumulativeResourceLimit > 0)
{
// Check if cumulative resources are exhausted
- if (d_cumulativeResourceUsed >= d_options.resman.cumulativeResourceLimit)
+ if (d_cumulativeResourceUsed >= d_options.base.cumulativeResourceLimit)
{
return true;
}
@@ -293,7 +293,7 @@ bool ResourceManager::outOfResources() const
bool ResourceManager::outOfTime() const
{
- if (d_options.resman.perCallMillisecondLimit == 0) return false;
+ if (d_options.base.perCallMillisecondLimit == 0) return false;
return d_perCallTimer.expired();
}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback