summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Reynolds <andrew.j.reynolds@gmail.com>2020-06-30 13:15:49 -0500
committerGitHub <noreply@github.com>2020-06-30 13:15:49 -0500
commit17509acaecf8374b36e2ef27a6aa681cbb847d03 (patch)
tree701e35044aaeba6b0ef021eb28c02e9f26ac43fe
parent8f11851e2ba5c70834faa980cb13790a5a828494 (diff)
parentf9e61ad68d6e5811c7471fa36061b50709ab2fa3 (diff)
Merge branch 'master' into update1.9news
-rwxr-xr-xcontrib/get-gmp-dev4
-rw-r--r--examples/CMakeLists.txt39
-rw-r--r--examples/api/java/CMakeLists.txt29
-rw-r--r--examples/simple_vc_cxx.cpp45
-rw-r--r--examples/simple_vc_quant_cxx.cpp79
-rw-r--r--src/CMakeLists.txt1
-rw-r--r--src/api/cvc4cpp.cpp25
-rw-r--r--src/api/cvc4cpp.h23
-rw-r--r--src/api/python/cvc4.pxd39
-rw-r--r--src/api/python/cvc4.pxi172
-rwxr-xr-xsrc/api/python/genkinds.py4
-rw-r--r--src/bindings/java/CMakeLists.txt1
-rw-r--r--src/cvc4.i2
-rw-r--r--src/expr/expr_manager_template.h9
-rw-r--r--src/expr/proof_rule.cpp7
-rw-r--r--src/expr/proof_rule.h64
-rw-r--r--src/options/smt_options.toml37
-rw-r--r--src/parser/smt2/Smt2.g12
-rw-r--r--src/smt/command.cpp84
-rw-r--r--src/smt/command.h53
-rw-r--r--src/smt/set_defaults.cpp7
-rw-r--r--src/smt/smt_engine.cpp19
-rw-r--r--src/smt/smt_engine.h34
-rw-r--r--src/theory/arith/arith_rewriter.cpp50
-rw-r--r--src/theory/arith/arith_rewriter.h4
-rw-r--r--src/theory/arith/congruence_manager.cpp1
-rw-r--r--src/theory/arith/kinds14
-rw-r--r--src/theory/arith/normal_form.cpp6
-rw-r--r--src/theory/arith/normal_form.h2
-rw-r--r--src/theory/arith/proof_checker.cpp269
-rw-r--r--src/theory/arith/proof_checker.h49
-rw-r--r--src/theory/arith/theory_arith.cpp1
-rw-r--r--src/theory/arith/theory_arith_type_rules.h43
-rw-r--r--src/theory/datatypes/sygus_extension.cpp1
-rw-r--r--src/theory/quantifiers/candidate_rewrite_database.cpp14
-rw-r--r--src/theory/quantifiers/expr_miner.cpp15
-rw-r--r--src/theory/quantifiers/expr_miner.h4
-rw-r--r--src/theory/quantifiers/query_generator.cpp13
-rw-r--r--src/theory/quantifiers/sygus/cegis_core_connective.cpp10
-rw-r--r--src/theory/quantifiers/sygus/sygus_repair_const.cpp76
-rw-r--r--src/theory/quantifiers/sygus/sygus_repair_const.h20
-rw-r--r--src/theory/quantifiers/sygus/synth_engine.cpp5
-rw-r--r--src/theory/quantifiers_engine.cpp7
-rw-r--r--src/theory/smt_engine_subsolver.cpp36
-rw-r--r--src/theory/smt_engine_subsolver.h12
-rw-r--r--src/theory/strings/regexp_entail.cpp64
-rw-r--r--src/theory/strings/sequences_rewriter.cpp6
-rw-r--r--src/util/CMakeLists.txt1
-rw-r--r--src/util/iand.h47
-rw-r--r--src/util/iand.i9
-rw-r--r--test/regress/CMakeLists.txt2
-rw-r--r--test/regress/regress0/strings/issue4662-consume-nterm.smt26
-rw-r--r--test/regress/regress1/quantifiers/eqrange_ex_1.smt2160
-rw-r--r--test/system/CMakeLists.txt2
-rw-r--r--test/system/boilerplate.cpp14
-rw-r--r--test/system/reset_assertions.cpp49
-rw-r--r--test/system/statistics.cpp38
-rw-r--r--test/system/two_solvers.cpp (renamed from test/system/two_smt_engines.cpp)18
-rw-r--r--test/unit/api/python/test_sort.py322
-rw-r--r--test/unit/api/solver_black.h6
-rw-r--r--test/unit/expr/attribute_black.h30
-rw-r--r--test/unit/expr/expr_manager_public.h86
-rw-r--r--test/unit/expr/expr_public.h50
-rw-r--r--test/unit/expr/node_algorithm_black.h17
-rw-r--r--test/unit/expr/symbol_table_black.h14
-rw-r--r--test/unit/expr/type_cardinality_public.h18
-rw-r--r--test/unit/theory/regexp_operation_black.h21
-rw-r--r--test/unit/theory/theory_black.h16
-rw-r--r--test/unit/util/array_store_all_black.h14
-rw-r--r--test/unit/util/datatype_black.h15
70 files changed, 2050 insertions, 416 deletions
diff --git a/contrib/get-gmp-dev b/contrib/get-gmp-dev
index f8a301a89..c844db93c 100755
--- a/contrib/get-gmp-dev
+++ b/contrib/get-gmp-dev
@@ -13,7 +13,7 @@ source "$(dirname "$0")/get-script-header.sh"
[ -z "${BUILD_TYPE}" ] && BUILD_TYPE="--disable-shared --enable-static"
[ -n "$HOST" ] && HOST="--host=$HOST"
-[ -z "$GMPVERSION" ] && GMPVERSION=6.1.2
+[ -z "$GMPVERSION" ] && GMPVERSION=6.2.0
GMP_DIR="$DEPS_DIR/gmp-$GMPVERSION"
@@ -36,7 +36,7 @@ echo "Setting up GMP $GMPVERSION..."
echo
setup_dep "https://gmplib.org/download/gmp/gmp-$GMPVERSION.tar.bz2" "$GMP_DIR"
cd "$GMP_DIR"
-./configure ${HOST} --prefix="$INSTALL_DIR" --enable-cxx ${BUILD_TYPE}
+./configure ${HOST} --prefix="$INSTALL_DIR" --enable-cxx ${BUILD_TYPE} --enable-shared --enable-static
make \
CFLAGS="${MAKE_CFLAGS}" \
CXXFLAGS="${MAKE_CXXFLAGS}" \
diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt
index 6168a8e22..cd74698d7 100644
--- a/examples/CMakeLists.txt
+++ b/examples/CMakeLists.txt
@@ -58,31 +58,34 @@ endmacro()
cvc4_add_example(simple_vc_cxx "" "")
cvc4_add_example(simple_vc_quant_cxx "" "")
-cvc4_add_example(translator "" ""
- # argument to binary (for testing)
- ${CMAKE_CURRENT_SOURCE_DIR}/translator-example-input.smt2)
+# TODO(project issue $206): Port example to new API
+# cvc4_add_example(translator "" ""
+# # argument to binary (for testing)
+# ${CMAKE_CURRENT_SOURCE_DIR}/translator-example-input.smt2)
add_subdirectory(api)
-add_subdirectory(hashsmt)
-add_subdirectory(nra-translate)
-add_subdirectory(sets-translate)
+# TODO(project issue $206): Port example to new API
+# add_subdirectory(hashsmt)
+# add_subdirectory(nra-translate)
+# add_subdirectory(sets-translate)
if(TARGET CVC4::cvc4jar)
find_package(Java REQUIRED)
include(UseJava)
- get_target_property(CVC4_JAR CVC4::cvc4jar JAR_FILE)
-
- add_jar(SimpleVC SimpleVC.java INCLUDE_JARS "${CVC4_JAR}")
-
- add_test(
- NAME java/SimpleVC
- COMMAND
- ${Java_JAVA_EXECUTABLE}
- -cp "${CVC4_JAR}:${CMAKE_BINARY_DIR}/SimpleVC.jar"
- -Djava.library.path=${CVC4_JNI_PATH}
- SimpleVC
- )
+ ## disabled until bindings for the new API are in place (issue #2284)
+ # get_target_property(CVC4_JAR CVC4::cvc4jar JAR_FILE)
+ #
+ # add_jar(SimpleVC SimpleVC.java INCLUDE_JARS "${CVC4_JAR}")
+ #
+ # add_test(
+ # NAME java/SimpleVC
+ # COMMAND
+ # ${Java_JAVA_EXECUTABLE}
+ # -cp "${CVC4_JAR}:${CMAKE_BINARY_DIR}/SimpleVC.jar"
+ # -Djava.library.path=${CVC4_JNI_PATH}
+ # SimpleVC
+ # )
add_subdirectory(api/java)
endif()
diff --git a/examples/api/java/CMakeLists.txt b/examples/api/java/CMakeLists.txt
index 31f62db56..0afcec0e4 100644
--- a/examples/api/java/CMakeLists.txt
+++ b/examples/api/java/CMakeLists.txt
@@ -1,20 +1,19 @@
set(EXAMPLES_API_JAVA
- BitVectors
- BitVectorsAndArrays
## disabled until bindings for the new API are in place (issue #2284)
- #CVC4Streams
- Combination
- Datatypes
- Exceptions
- FloatingPointArith
- HelloWorld
- LinearArith
- ## disabled until bindings for the new API are in place (issue #2284)
- #PipedInput
- Relations
- Statistics
- Strings
- UnsatCores
+ # BitVectors
+ # BitVectorsAndArrays
+ # CVC4Streams
+ # Combination
+ # Datatypes
+ # Exceptions
+ # FloatingPointArith
+ # HelloWorld
+ # LinearArith
+ # PipedInput
+ # Relations
+ # Statistics
+ # Strings
+ # UnsatCores
)
foreach(example ${EXAMPLES_API_JAVA})
diff --git a/examples/simple_vc_cxx.cpp b/examples/simple_vc_cxx.cpp
index 26d785edc..64c2b12c1 100644
--- a/examples/simple_vc_cxx.cpp
+++ b/examples/simple_vc_cxx.cpp
@@ -16,43 +16,42 @@
** identical.
**/
-#include <iostream>
+#include <cvc4/api/cvc4cpp.h>
-#include <cvc4/cvc4.h>
+#include <iostream>
-using namespace std;
-using namespace CVC4;
+using namespace CVC4::api;
int main() {
- ExprManager em;
- SmtEngine smt(&em);
+ Solver slv;
// Prove that for integers x and y:
// x > 0 AND y > 0 => 2x + y >= 3
- Type integer = em.integerType();
+ Sort integer = slv.getIntegerSort();
- Expr x = em.mkVar("x", integer);
- Expr y = em.mkVar("y", integer);
- Expr zero = em.mkConst(Rational(0));
+ Term x = slv.mkConst(integer, "x");
+ Term y = slv.mkConst(integer, "y");
+ Term zero = slv.mkReal(0);
- Expr x_positive = em.mkExpr(kind::GT, x, zero);
- Expr y_positive = em.mkExpr(kind::GT, y, zero);
+ Term x_positive = slv.mkTerm(Kind::GT, x, zero);
+ Term y_positive = slv.mkTerm(Kind::GT, y, zero);
- Expr two = em.mkConst(Rational(2));
- Expr twox = em.mkExpr(kind::MULT, two, x);
- Expr twox_plus_y = em.mkExpr(kind::PLUS, twox, y);
+ Term two = slv.mkReal(2);
+ Term twox = slv.mkTerm(Kind::MULT, two, x);
+ Term twox_plus_y = slv.mkTerm(Kind::PLUS, twox, y);
- Expr three = em.mkConst(Rational(3));
- Expr twox_plus_y_geq_3 = em.mkExpr(kind::GEQ, twox_plus_y, three);
+ Term three = slv.mkReal(3);
+ Term twox_plus_y_geq_3 = slv.mkTerm(Kind::GEQ, twox_plus_y, three);
- Expr formula =
- em.mkExpr(kind::AND, x_positive, y_positive).
- impExpr(twox_plus_y_geq_3);
+ Term formula =
+ slv.mkTerm(Kind::AND, x_positive, y_positive).impTerm(twox_plus_y_geq_3);
- cout << "Checking entailment of formula " << formula << " with CVC4." << endl;
- cout << "CVC4 should report ENTAILED." << endl;
- cout << "Result from CVC4 is: " << smt.checkEntailed(formula) << endl;
+ std::cout << "Checking entailment of formula " << formula << " with CVC4."
+ << std::endl;
+ std::cout << "CVC4 should report ENTAILED." << std::endl;
+ std::cout << "Result from CVC4 is: " << slv.checkEntailed(formula)
+ << std::endl;
return 0;
}
diff --git a/examples/simple_vc_quant_cxx.cpp b/examples/simple_vc_quant_cxx.cpp
index 83d011993..4d5767ebb 100644
--- a/examples/simple_vc_quant_cxx.cpp
+++ b/examples/simple_vc_quant_cxx.cpp
@@ -14,64 +14,63 @@
** A simple demonstration of the C++ interface for quantifiers.
**/
-#include <iostream>
+#include <cvc4/api/cvc4cpp.h>
-#include <cvc4/cvc4.h>
+#include <iostream>
-using namespace std;
-using namespace CVC4;
+using namespace CVC4::api;
int main() {
- ExprManager em;
- SmtEngine smt(&em);
+ Solver slv;
// Prove that the following is unsatisfiable:
// forall x. P( x ) ^ ~P( 5 )
- Type integer = em.integerType();
- Type boolean = em.booleanType();
- Type integerPredicate = em.mkFunctionType(integer, boolean);
-
- Expr p = em.mkVar("P", integerPredicate);
- Expr x = em.mkBoundVar("x", integer);
-
+ Sort integer = slv.getIntegerSort();
+ Sort boolean = slv.getBooleanSort();
+ Sort integerPredicate = slv.mkFunctionSort(integer, boolean);
+
+ Term p = slv.mkConst(integerPredicate, "P");
+ Term x = slv.mkVar(integer, "x");
+
// make forall x. P( x )
- Expr var_list = em.mkExpr(kind::BOUND_VAR_LIST, x);
- Expr px = em.mkExpr(kind::APPLY_UF, p, x);
- Expr quantpospx = em.mkExpr(kind::FORALL, var_list, px);
- cout << "Made expression : " << quantpospx << endl;
-
+ Term var_list = slv.mkTerm(Kind::BOUND_VAR_LIST, x);
+ Term px = slv.mkTerm(Kind::APPLY_UF, p, x);
+ Term quantpospx = slv.mkTerm(Kind::FORALL, var_list, px);
+ std::cout << "Made expression : " << quantpospx << std::endl;
+
//make ~P( 5 )
- Expr five = em.mkConst(Rational(5));
- Expr pfive = em.mkExpr(kind::APPLY_UF, p, five);
- Expr negpfive = em.mkExpr(kind::NOT, pfive);
- cout << "Made expression : " << negpfive << endl;
-
- Expr formula = em.mkExpr(kind::AND, quantpospx, negpfive);
+ Term five = slv.mkReal(5);
+ Term pfive = slv.mkTerm(Kind::APPLY_UF, p, five);
+ Term negpfive = slv.mkTerm(Kind::NOT, pfive);
+ std::cout << "Made expression : " << negpfive << std::endl;
- smt.assertFormula(formula);
+ Term formula = slv.mkTerm(Kind::AND, quantpospx, negpfive);
- cout << "Checking SAT after asserting " << formula << " to CVC4." << endl;
- cout << "CVC4 should report unsat." << endl;
- cout << "Result from CVC4 is: " << smt.checkSat() << endl;
+ slv.assertFormula(formula);
+ std::cout << "Checking SAT after asserting " << formula << " to CVC4."
+ << std::endl;
+ std::cout << "CVC4 should report unsat." << std::endl;
+ std::cout << "Result from CVC4 is: " << slv.checkSat() << std::endl;
- SmtEngine smtp(&em);
-
- // this version has a pattern e.g. in smt2 syntax (forall ((x Int)) (! (P x ) :pattern ((P x))))
- Expr pattern = em.mkExpr(kind::INST_PATTERN, px);
- Expr pattern_list = em.mkExpr(kind::INST_PATTERN_LIST, pattern);
- Expr quantpospx_pattern = em.mkExpr(kind::FORALL, var_list, px, pattern_list);
- cout << "Made expression : " << quantpospx_pattern << endl;
+ slv.resetAssertions();
- Expr formula_pattern = em.mkExpr(kind::AND, quantpospx_pattern, negpfive);
+ // this version has a pattern e.g. in smt2 syntax (forall ((x Int)) (! (P x ) :pattern ((P x))))
+ Term pattern = slv.mkTerm(Kind::INST_PATTERN, px);
+ Term pattern_list = slv.mkTerm(Kind::INST_PATTERN_LIST, pattern);
+ Term quantpospx_pattern =
+ slv.mkTerm(Kind::FORALL, var_list, px, pattern_list);
+ std::cout << "Made expression : " << quantpospx_pattern << std::endl;
- smtp.assertFormula(formula_pattern);
+ Term formula_pattern = slv.mkTerm(Kind::AND, quantpospx_pattern, negpfive);
- cout << "Checking SAT after asserting " << formula_pattern << " to CVC4." << endl;
- cout << "CVC4 should report unsat." << endl;
- cout << "Result from CVC4 is: " << smtp.checkSat() << endl;
+ slv.assertFormula(formula_pattern);
+ std::cout << "Checking SAT after asserting " << formula_pattern << " to CVC4."
+ << std::endl;
+ std::cout << "CVC4 should report unsat." << std::endl;
+ std::cout << "Result from CVC4 is: " << slv.checkSat() << std::endl;
return 0;
}
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6850ef450..0774d60af 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1001,6 +1001,7 @@ install(FILES
util/divisible.h
util/gmp_util.h
util/hash.h
+ util/iand.h
util/integer_cln_imp.h
util/integer_gmp_imp.h
util/maybe.h
diff --git a/src/api/cvc4cpp.cpp b/src/api/cvc4cpp.cpp
index 0c8de5291..1e14e9b3a 100644
--- a/src/api/cvc4cpp.cpp
+++ b/src/api/cvc4cpp.cpp
@@ -4744,6 +4744,31 @@ void Solver::pop(uint32_t nscopes) const
CVC4_API_SOLVER_TRY_CATCH_END;
}
+bool Solver::getInterpolant(Term conj, Term& output) const
+{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ Expr result;
+ bool success = d_smtEngine->getInterpol(*conj.d_expr, result);
+ if (success) {
+ output = Term(output.d_solver, result);
+ }
+ return success;
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
+bool Solver::getInterpolant(Term conj, const Type& gtype, Term& output) const
+{
+ CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ Expr result;
+ bool success = d_smtEngine->getInterpol(*conj.d_expr, gtype, result);
+ if (success)
+ {
+ output = Term(output.d_solver, result);
+ }
+ return success;
+ CVC4_API_SOLVER_TRY_CATCH_END;
+}
+
void Solver::printModel(std::ostream& out) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
diff --git a/src/api/cvc4cpp.h b/src/api/cvc4cpp.h
index 828dc6f65..76306d443 100644
--- a/src/api/cvc4cpp.h
+++ b/src/api/cvc4cpp.h
@@ -3023,6 +3023,29 @@ class CVC4_PUBLIC Solver
void pop(uint32_t nscopes = 1) const;
/**
+ * Get an interpolant
+ * SMT-LIB: ( get-interpol <term> )
+ * Requires to enable option 'produce-interpols'.
+ * @param conj the conjecture term
+ * @param output a Term I such that A->I and I->B are valid, where A is the
+ * current set of assertions and B is given in the input by conj.
+ * @return true if it gets I successfully, false otherwise.
+ */
+ bool getInterpolant(Term conj, Term& output) const;
+
+ /**
+ * Get an interpolant
+ * SMT-LIB: ( get-interpol <term> )
+ * Requires to enable option 'produce-interpols'.
+ * @param conj the conjecture term
+ * @param gtype the grammar for the interpolant I
+ * @param output a Term I such that A->I and I->B are valid, where A is the
+ * current set of assertions and B is given in the input by conj.
+ * @return true if it gets I successfully, false otherwise.
+ */
+ bool getInterpolant(Term conj, const Type& gtype, Term& output) const;
+
+ /**
* Print the model of a satisfiable query to the given output stream.
* Requires to enable option 'produce-models'.
* @param out the output stream
diff --git a/src/api/python/cvc4.pxd b/src/api/python/cvc4.pxd
index ee05709b7..940922052 100644
--- a/src/api/python/cvc4.pxd
+++ b/src/api/python/cvc4.pxd
@@ -21,6 +21,7 @@ cdef extern from "api/cvc4cpp.h" namespace "CVC4":
cdef extern from "api/cvc4cpp.h" namespace "CVC4::api":
cdef cppclass Datatype:
Datatype() except +
+ DatatypeConstructor operator[](size_t idx) except +
DatatypeConstructor operator[](const string& name) except +
DatatypeConstructor getConstructor(const string& name) except +
Term getConstructorTerm(const string& name) except +
@@ -39,7 +40,12 @@ cdef extern from "api/cvc4cpp.h" namespace "CVC4::api":
cdef cppclass DatatypeConstructor:
DatatypeConstructor() except +
+ DatatypeSelector operator[](size_t idx) except +
DatatypeSelector operator[](const string& name) except +
+ string getName() except +
+ Term getConstructorTerm() except +
+ Term getTesterTerm() except +
+ size_t getNumSelectors() except +
DatatypeSelector getSelector(const string& name) except +
Term getSelectorTerm(const string& name) except +
string toString() except +
@@ -61,12 +67,16 @@ cdef extern from "api/cvc4cpp.h" namespace "CVC4::api":
cdef cppclass DatatypeDecl:
void addConstructor(const DatatypeConstructorDecl& ctor) except +
+ size_t getNumConstructors() except +
bint isParametric() except +
string toString() except +
cdef cppclass DatatypeSelector:
DatatypeSelector() except +
+ string getName() except +
+ Term getSelectorTerm() except +
+ Sort getRangeSort() except +
string toString() except +
@@ -213,6 +223,10 @@ cdef extern from "api/cvc4cpp.h" namespace "CVC4::api":
Sort() except +
bint operator==(const Sort&) except +
bint operator!=(const Sort&) except +
+ bint operator<(const Sort&) except +
+ bint operator>(const Sort&) except +
+ bint operator<=(const Sort&) except +
+ bint operator>=(const Sort&) except +
bint isBoolean() except +
bint isInteger() except +
bint isReal() except +
@@ -223,6 +237,9 @@ cdef extern from "api/cvc4cpp.h" namespace "CVC4::api":
bint isFloatingPoint() except +
bint isDatatype() except +
bint isParametricDatatype() except +
+ bint isConstructor() except +
+ bint isSelector() except +
+ bint isTester() except +
bint isFunction() except +
bint isPredicate() except +
bint isTuple() except +
@@ -233,9 +250,31 @@ cdef extern from "api/cvc4cpp.h" namespace "CVC4::api":
bint isSortConstructor() except +
bint isFirstClass() except +
bint isFunctionLike() except +
+ bint isSubsortOf(Sort s) except +
+ bint isComparableTo(Sort s) except +
Datatype getDatatype() except +
Sort instantiate(const vector[Sort]& params) except +
+ size_t getConstructorArity() except +
+ vector[Sort] getConstructorDomainSorts() except +
+ Sort getConstructorCodomainSort() except +
+ size_t getFunctionArity() except +
+ vector[Sort] getFunctionDomainSorts() except +
+ Sort getFunctionCodomainSort() except +
+ Sort getArrayIndexSort() except +
+ Sort getArrayElementSort() except +
+ Sort getSetElementSort() except +
+ string getUninterpretedSortName() except +
bint isUninterpretedSortParameterized() except +
+ vector[Sort] getUninterpretedSortParamSorts() except +
+ string getSortConstructorName() except +
+ size_t getSortConstructorArity() except +
+ uint32_t getBVSize() except +
+ uint32_t getFPExponentSize() except +
+ uint32_t getFPSignificandSize() except +
+ vector[Sort] getDatatypeParamSorts() except +
+ size_t getDatatypeArity() except +
+ size_t getTupleLength() except +
+ vector[Sort] getTupleSorts() except +
string toString() except +
cdef cppclass SortHashFunction:
diff --git a/src/api/python/cvc4.pxi b/src/api/python/cvc4.pxi
index ab174ef0d..01660e206 100644
--- a/src/api/python/cvc4.pxi
+++ b/src/api/python/cvc4.pxi
@@ -65,9 +65,14 @@ cdef class Datatype:
def __cinit__(self):
pass
- def __getitem__(self, str name):
+ def __getitem__(self, index):
cdef DatatypeConstructor dc = DatatypeConstructor()
- dc.cdc = self.cd[name.encode()]
+ if isinstance(index, int) and index >= 0:
+ dc.cdc = self.cd[(<int?> index)]
+ elif isinstance(index, str):
+ dc.cdc = self.cd[(<const string &> name.encode())]
+ else:
+ raise ValueError("Expecting a non-negative integer or string")
return dc
def getConstructor(self, str name):
@@ -104,11 +109,32 @@ cdef class DatatypeConstructor:
def __cinit__(self):
self.cdc = c_DatatypeConstructor()
- def __getitem__(self, str name):
+ def __getitem__(self, index):
cdef DatatypeSelector ds = DatatypeSelector()
- ds.cds = self.cdc[name.encode()]
+ if isinstance(index, int) and index >= 0:
+ ds.cds = self.cdc[(<int?> index)]
+ elif isinstance(index, str):
+ ds.cds = self.cdc[(<const string &> name.encode())]
+ else:
+ raise ValueError("Expecting a non-negative integer or string")
return ds
+ def getName(self):
+ return self.cdc.getName().decode()
+
+ def getConstructorTerm(self):
+ cdef Term term = Term()
+ term.cterm = self.cdc.getConstructorTerm()
+ return term
+
+ def getTesterTerm(self):
+ cdef Term term = Term()
+ term.cterm = self.cdc.getTesterTerm()
+ return term
+
+ def getNumSelectors(self):
+ return self.cdc.getNumSelectors()
+
def getSelector(self, str name):
cdef DatatypeSelector ds = DatatypeSelector()
ds.cds = self.cdc.getSelector(name.encode())
@@ -159,6 +185,9 @@ cdef class DatatypeDecl:
def addConstructor(self, DatatypeConstructorDecl ctor):
self.cdd.addConstructor(ctor.cddc)
+ def getNumConstructors(self):
+ return self.cdd.getNumConstructors()
+
def isParametric(self):
return self.cdd.isParametric()
@@ -174,6 +203,19 @@ cdef class DatatypeSelector:
def __cinit__(self):
self.cds = c_DatatypeSelector()
+ def getName(self):
+ return self.cds.getName().decode()
+
+ def getSelectorTerm(self):
+ cdef Term term = Term()
+ term.cterm = self.cds.getSelectorTerm()
+ return term
+
+ def getRangeSort(self):
+ cdef Sort sort = Sort()
+ sort.csort = self.cds.getRangeSort()
+ return sort
+
def __str__(self):
return self.cds.toString().decode()
@@ -961,6 +1003,18 @@ cdef class Sort:
def __ne__(self, Sort other):
return self.csort != other.csort
+ def __lt__(self, Sort other):
+ return self.csort < other.csort
+
+ def __gt__(self, Sort other):
+ return self.csort > other.csort
+
+ def __le__(self, Sort other):
+ return self.csort <= other.csort
+
+ def __ge__(self, Sort other):
+ return self.csort >= other.csort
+
def __str__(self):
return self.csort.toString().decode()
@@ -1000,6 +1054,15 @@ cdef class Sort:
def isParametricDatatype(self):
return self.csort.isParametricDatatype()
+ def isConstructor(self):
+ return self.csort.isConstructor()
+
+ def isSelector(self):
+ return self.csort.isSelector()
+
+ def isTester(self):
+ return self.csort.isTester()
+
def isFunction(self):
return self.csort.isFunction()
@@ -1030,6 +1093,12 @@ cdef class Sort:
def isFunctionLike(self):
return self.csort.isFunctionLike()
+ def isSubsortOf(self, Sort sort):
+ return self.csort.isSubsortOf(sort.csort)
+
+ def isComparableTo(self, Sort sort):
+ return self.csort.isComparableTo(sort.csort)
+
def getDatatype(self):
cdef Datatype d = Datatype()
d.cd = self.csort.getDatatype()
@@ -1043,9 +1112,104 @@ cdef class Sort:
sort.csort = self.csort.instantiate(v)
return sort
+ def getConstructorArity(self):
+ return self.csort.getConstructorArity()
+
+ def getConstructorDomainSorts(self):
+ domain_sorts = []
+ for s in self.csort.getConstructorDomainSorts():
+ sort = Sort()
+ sort.csort = s
+ domain_sorts.append(sort)
+ return domain_sorts
+
+ def getConstructorCodomainSort(self):
+ cdef Sort sort = Sort()
+ sort.csort = self.csort.getConstructorCodomainSort()
+ return sort
+
+ def getFunctionArity(self):
+ return self.csort.getFunctionArity()
+
+ def getFunctionDomainSorts(self):
+ domain_sorts = []
+ for s in self.csort.getFunctionDomainSorts():
+ sort = Sort()
+ sort.csort = s
+ domain_sorts.append(sort)
+ return domain_sorts
+
+ def getFunctionCodomainSort(self):
+ cdef Sort sort = Sort()
+ sort.csort = self.csort.getFunctionCodomainSort()
+ return sort
+
+ def getArrayIndexSort(self):
+ cdef Sort sort = Sort()
+ sort.csort = self.csort.getArrayIndexSort()
+ return sort
+
+ def getArrayElementSort(self):
+ cdef Sort sort = Sort()
+ sort.csort = self.csort.getArrayElementSort()
+ return sort
+
+ def getSetElementSort(self):
+ cdef Sort sort = Sort()
+ sort.csort = self.csort.getSetElementSort()
+ return sort
+
+ def getUninterpretedSortName(self):
+ return self.csort.getUninterpretedSortName().decode()
+
def isUninterpretedSortParameterized(self):
return self.csort.isUninterpretedSortParameterized()
+ def getUninterpretedSortParamSorts(self):
+ param_sorts = []
+ for s in self.csort.getUninterpretedSortParamSorts():
+ sort = Sort()
+ sort.csort = s
+ param_sorts.append(sort)
+ return param_sorts
+
+ def getSortConstructorName(self):
+ return self.csort.getSortConstructorName().decode()
+
+ def getSortConstructorArity(self):
+ return self.csort.getSortConstructorArity()
+
+ def getBVSize(self):
+ return self.csort.getBVSize()
+
+ def getFPExponentSize(self):
+ return self.csort.getFPExponentSize()
+
+ def getFPSignificandSize(self):
+ return self.csort.getFPSignificandSize()
+
+ def getDatatypeParamSorts(self):
+ param_sorts = []
+ for s in self.csort.getDatatypeParamSorts():
+ sort = Sort()
+ sort.csort = s
+ param_sorts.append(sort)
+ return param_sorts
+
+ def getDatatypeArity(self):
+ return self.csort.getDatatypeArity()
+
+ def getTupleLength(self):
+ return self.csort.getTupleLength()
+
+ def getTupleSorts(self):
+ tuple_sorts = []
+ for s in self.csort.getTupleSorts():
+ sort = Sort()
+ sort.csort = s
+ tuple_sorts.append(sort)
+ return tuple_sorts
+
cdef class Term:
cdef c_Term cterm
diff --git a/src/api/python/genkinds.py b/src/api/python/genkinds.py
index a12c9735c..77b168dea 100755
--- a/src/api/python/genkinds.py
+++ b/src/api/python/genkinds.py
@@ -83,7 +83,7 @@ cdef class kind:
cdef str name
def __cinit__(self, int kindint):
self.k = int2kind[kindint]
- self.name = int2name[kindint].decode()
+ self.name = str(int2name[kindint])
def __eq__(self, kind other):
return (<int> self.k) == (<int> other.k)
@@ -111,7 +111,7 @@ kinds.__file__ = kinds.__name__ + ".py"
KINDS_ATTR_TEMPLATE = \
r"""
int2kind[<int> {kind}] = {kind}
-int2name[<int> {kind}] = "{name}".encode()
+int2name[<int> {kind}] = b"{name}"
cdef kind {name} = kind(<int> {kind})
setattr(kinds, "{name}", {name})
"""
diff --git a/src/bindings/java/CMakeLists.txt b/src/bindings/java/CMakeLists.txt
index 8e919db86..8159b8ee0 100644
--- a/src/bindings/java/CMakeLists.txt
+++ b/src/bindings/java/CMakeLists.txt
@@ -81,6 +81,7 @@ set(gen_java_files
${CMAKE_CURRENT_BINARY_DIR}/FloatingPointType.java
${CMAKE_CURRENT_BINARY_DIR}/FunctionType.java
${CMAKE_CURRENT_BINARY_DIR}/InputLanguage.java
+ ${CMAKE_CURRENT_BINARY_DIR}/IntAnd.java
${CMAKE_CURRENT_BINARY_DIR}/IntToBitVector.java
${CMAKE_CURRENT_BINARY_DIR}/Integer.java
${CMAKE_CURRENT_BINARY_DIR}/IntegerHashFunction.java
diff --git a/src/cvc4.i b/src/cvc4.i
index 4fc0b092a..9fc8ed60e 100644
--- a/src/cvc4.i
+++ b/src/cvc4.i
@@ -40,6 +40,7 @@ using namespace CVC4;
#include "smt/command.h"
#include "util/bitvector.h"
#include "util/floatingpoint.h"
+#include "util/iand.h"
#include "util/integer.h"
#include "util/sexpr.h"
#include "util/unsafe_interrupt_exception.h"
@@ -206,6 +207,7 @@ std::set<JavaInputStreamAdapter*> CVC4::JavaInputStreamAdapter::s_adapters;
%include "util/integer.i"
%include "util/rational.i"
%include "util/bitvector.i"
+%include "util/iand.i"
%include "util/floatingpoint.i"
// Tim: The remainder of util/.
diff --git a/src/expr/expr_manager_template.h b/src/expr/expr_manager_template.h
index 1809eb2d0..3a4498ab7 100644
--- a/src/expr/expr_manager_template.h
+++ b/src/expr/expr_manager_template.h
@@ -36,6 +36,10 @@ ${includes}
namespace CVC4 {
+namespace api {
+class Solver;
+}
+
class Expr;
class SmtEngine;
class NodeManager;
@@ -45,7 +49,8 @@ struct ExprManagerMapCollection;
class ResourceManager;
class CVC4_PUBLIC ExprManager {
-private:
+ private:
+ friend api::Solver;
/** The internal node manager */
NodeManager* d_nodeManager;
@@ -83,7 +88,6 @@ private:
/** A list of datatypes owned by this expr manager. */
std::vector<std::unique_ptr<Datatype> > d_ownedDatatypes;
- public:
/**
* Creates an expression manager with default options.
*/
@@ -97,6 +101,7 @@ private:
*/
explicit ExprManager(const Options& options);
+ public:
/**
* Destroys the expression manager. No will be deallocated at this point, so
* any expression references that used to be managed by this expression
diff --git a/src/expr/proof_rule.cpp b/src/expr/proof_rule.cpp
index f736efed9..d00f1658b 100644
--- a/src/expr/proof_rule.cpp
+++ b/src/expr/proof_rule.cpp
@@ -90,6 +90,13 @@ const char* toString(PfRule id)
case PfRule::EXISTS_INTRO: return "EXISTS_INTRO";
case PfRule::SKOLEMIZE: return "SKOLEMIZE";
case PfRule::INSTANTIATE: return "INSTANTIATE";
+ //================================================= Arith rules
+ case PfRule::ARITH_SCALE_SUM_UPPER_BOUNDS: return "ARITH_SCALE_SUM_UPPER_BOUNDS";
+ case PfRule::ARITH_TRICHOTOMY: return "ARITH_TRICHOTOMY";
+ case PfRule::INT_TIGHT_LB: return "INT_TIGHT_LB";
+ case PfRule::INT_TIGHT_UB: return "INT_TIGHT_UB";
+ case PfRule::INT_TRUST: return "INT_TRUST";
+ case PfRule::ARITH_OP_ELIM_AXIOM: return "ARITH_OP_ELIM_AXIOM";
//================================================= Unknown rule
case PfRule::UNKNOWN: return "UNKNOWN";
default: return "?";
diff --git a/src/expr/proof_rule.h b/src/expr/proof_rule.h
index d6e5b6f4b..ec589a16e 100644
--- a/src/expr/proof_rule.h
+++ b/src/expr/proof_rule.h
@@ -507,6 +507,70 @@ enum class PfRule : uint32_t
// sigma maps x1 ... xn to t1 ... tn.
INSTANTIATE,
+ // ======== Adding Inequalities
+ // Note: an ArithLiteral is a term of the form (>< poly const)
+ // where
+ // >< is >=, >, ==, <, <=, or not(== ...).
+ // poly is a polynomial
+ // const is a rational constant
+
+ // Children: (P1:l1, ..., Pn:ln)
+ // where each li is an ArithLiteral
+ // not(= ...) is dis-allowed!
+ //
+ // Arguments: (k1, ..., kn), non-zero reals
+ // ---------------------
+ // Conclusion: (>< (* k t1) (* k t2))
+ // where >< is the fusion of the combination of the ><i, (flipping each it
+ // its ki is negative). >< is always one of <, <=
+ // NB: this implies that lower bounds must have negative ki,
+ // and upper bounds must have positive ki.
+ // t1 is the sum of the polynomials.
+ // t2 is the sum of the constants.
+ ARITH_SCALE_SUM_UPPER_BOUNDS,
+
+ // ======== Tightening Strict Integer Upper Bounds
+ // Children: (P:(< i c))
+ // where i has integer type.
+ // Arguments: none
+ // ---------------------
+ // Conclusion: (<= i greatestIntLessThan(c)})
+ INT_TIGHT_UB,
+
+ // ======== Tightening Strict Integer Lower Bounds
+ // Children: (P:(> i c))
+ // where i has integer type.
+ // Arguments: none
+ // ---------------------
+ // Conclusion: (>= i leastIntGreaterThan(c)})
+ INT_TIGHT_LB,
+
+ // ======== Trichotomy of the reals
+ // Children: (A B)
+ // Arguments: (C)
+ // ---------------------
+ // Conclusion: (C),
+ // where (not A) (not B) and C
+ // are (> x c) (< x c) and (= x c)
+ // in some order
+ // note that "not" here denotes arithmetic negation, flipping
+ // >= to <, etc.
+ ARITH_TRICHOTOMY,
+
+ // ======== Arithmetic operator elimination
+ // Children: none
+ // Arguments: (t)
+ // ---------------------
+ // Conclusion: arith::OperatorElim::getAxiomFor(t)
+ ARITH_OP_ELIM_AXIOM,
+
+ // ======== Int Trust
+ // Children: (P1 ... Pn)
+ // Arguments: (Q)
+ // ---------------------
+ // Conclusion: (Q)
+ INT_TRUST,
+
//================================================= Unknown rule
UNKNOWN,
};
diff --git a/src/options/smt_options.toml b/src/options/smt_options.toml
index 303448d1b..c104cb3e7 100644
--- a/src/options/smt_options.toml
+++ b/src/options/smt_options.toml
@@ -669,6 +669,34 @@ header = "options/smt_options.h"
help = "attempt to solve a pure real satisfiable problem as an integer problem (for non-linear)"
[[option]]
+ name = "produceInterpols"
+ category = "undocumented"
+ long = "produce-interpols=MODE"
+ type = "ProduceInterpols"
+ default = "NONE"
+ read_only = true
+ help = "support the get-interpol command"
+ help_mode = "Interpolants grammar mode"
+[[option.mode.NONE]]
+ name = "none"
+ help = "don't compute interpolants"
+[[option.mode.DEFAULT]]
+ name = "default"
+ help = "use the default grammar for the theory or the user-defined grammar if given"
+[[option.mode.ASSUMPTIONS]]
+ name = "assumptions"
+ help = "use only operators that occur in the assumptions"
+[[option.mode.CONJECTURE]]
+ name = "conjecture"
+ help = "use only operators that occur in the conjecture"
+[[option.mode.SHARED]]
+ name = "shared"
+ help = "use only operators that occur both in the assumptions and the conjecture"
+[[option.mode.ALL]]
+ name = "all"
+ help = "use only operators that occur either in the assumptions or the conjecture"
+
+[[option]]
name = "produceAbducts"
category = "undocumented"
long = "produce-abducts"
@@ -678,6 +706,15 @@ header = "options/smt_options.h"
help = "support the get-abduct command"
[[option]]
+ name = "checkInterpols"
+ category = "regular"
+ long = "check-interpols"
+ type = "bool"
+ default = "false"
+ read_only = true
+ help = "checks whether produced solutions to get-interpol are correct"
+
+[[option]]
name = "checkAbducts"
category = "regular"
long = "check-abducts"
diff --git a/src/parser/smt2/Smt2.g b/src/parser/smt2/Smt2.g
index 3e8234a86..703696cf5 100644
--- a/src/parser/smt2/Smt2.g
+++ b/src/parser/smt2/Smt2.g
@@ -1136,6 +1136,17 @@ extendedCommand[std::unique_ptr<CVC4::Command>* cmd]
{
cmd->reset(new GetAbductCommand(name,e.getExpr(), t.getType()));
}
+ | GET_INTERPOL_TOK {
+ PARSER_STATE->checkThatLogicIsSet();
+ }
+ symbol[name,CHECK_UNDECLARED,SYM_VARIABLE]
+ term[e,e2]
+ (
+ sygusGrammar[t, terms, name]
+ )?
+ {
+ cmd->reset(new GetInterpolCommand(SOLVER, name, e, t.getType()));
+ }
| DECLARE_HEAP LPAREN_TOK
sortSymbol[t, CHECK_DECLARED]
sortSymbol[t, CHECK_DECLARED]
@@ -2315,6 +2326,7 @@ INCLUDE_TOK : 'include';
GET_QE_TOK : 'get-qe';
GET_QE_DISJUNCT_TOK : 'get-qe-disjunct';
GET_ABDUCT_TOK : 'get-abduct';
+GET_INTERPOL_TOK : 'get-interpol';
DECLARE_HEAP : 'declare-heap';
// SyGuS commands
diff --git a/src/smt/command.cpp b/src/smt/command.cpp
index cbb2076dd..095c59374 100644
--- a/src/smt/command.cpp
+++ b/src/smt/command.cpp
@@ -2091,6 +2091,90 @@ std::string GetSynthSolutionCommand::getCommandName() const
return "get-instantiations";
}
+GetInterpolCommand::GetInterpolCommand(api::Solver* solver,
+ const std::string& name,
+ api::Term conj)
+ : Command(solver), d_name(name), d_conj(conj), d_resultStatus(false)
+{
+}
+GetInterpolCommand::GetInterpolCommand(api::Solver* solver,
+ const std::string& name,
+ api::Term conj,
+ const Type& gtype)
+ : Command(solver),
+ d_name(name),
+ d_conj(conj),
+ d_sygus_grammar_type(gtype),
+ d_resultStatus(false)
+{
+}
+
+api::Term GetInterpolCommand::getConjecture() const { return d_conj; }
+Type GetInterpolCommand::getGrammarType() const { return d_sygus_grammar_type; }
+api::Term GetInterpolCommand::getResult() const { return d_result; }
+
+void GetInterpolCommand::invoke(SmtEngine* smtEngine)
+{
+ try
+ {
+ if (d_sygus_grammar_type.isNull())
+ {
+ d_resultStatus = d_solver->getInterpolant(d_conj, d_result);
+ }
+ else
+ {
+ d_resultStatus =
+ d_solver->getInterpolant(d_conj, d_sygus_grammar_type, d_result);
+ }
+ d_commandStatus = CommandSuccess::instance();
+ }
+ catch (exception& e)
+ {
+ d_commandStatus = new CommandFailure(e.what());
+ }
+}
+
+void GetInterpolCommand::printResult(std::ostream& out,
+ uint32_t verbosity) const
+{
+ if (!ok())
+ {
+ this->Command::printResult(out, verbosity);
+ }
+ else
+ {
+ expr::ExprDag::Scope scope(out, false);
+ if (d_resultStatus)
+ {
+ out << "(define-fun " << d_name << " () Bool " << d_result << ")"
+ << std::endl;
+ }
+ else
+ {
+ out << "none" << std::endl;
+ }
+ }
+}
+
+Command* GetInterpolCommand::exportTo(ExprManager* exprManager,
+ ExprManagerMapCollection& variableMap)
+{
+ Unimplemented();
+}
+
+Command* GetInterpolCommand::clone() const
+{
+ GetInterpolCommand* c = new GetInterpolCommand(d_solver, d_name, d_conj);
+ c->d_result = d_result;
+ c->d_resultStatus = d_resultStatus;
+ return c;
+}
+
+std::string GetInterpolCommand::getCommandName() const
+{
+ return "get-interpol";
+}
+
GetAbductCommand::GetAbductCommand() {}
GetAbductCommand::GetAbductCommand(const std::string& name, Expr conj)
: d_name(name), d_conj(conj), d_resultStatus(false)
diff --git a/src/smt/command.h b/src/smt/command.h
index efb4f2f4a..a6a0faaae 100644
--- a/src/smt/command.h
+++ b/src/smt/command.h
@@ -28,6 +28,7 @@
#include <string>
#include <vector>
+#include "api/cvc4cpp.h"
#include "expr/datatype.h"
#include "expr/expr.h"
#include "expr/type.h"
@@ -1038,6 +1039,58 @@ class CVC4_PUBLIC GetSynthSolutionCommand : public Command
SmtEngine* d_smtEngine;
}; /* class GetSynthSolutionCommand */
+/** The command (get-interpol s B)
+ *
+ * This command asks for an interpolant from the current set of assertions and
+ * conjecture (goal) B.
+ *
+ * The symbol s is the name for the interpolation predicate. If we successfully
+ * find a predicate P, then the output response of this command is: (define-fun
+ * s () Bool P)
+ */
+class CVC4_PUBLIC GetInterpolCommand : public Command
+{
+ public:
+ GetInterpolCommand(api::Solver* solver,
+ const std::string& name,
+ api::Term conj);
+ /** The argument gtype is the grammar of the interpolation query */
+ GetInterpolCommand(api::Solver* solver,
+ const std::string& name,
+ api::Term conj,
+ const Type& gtype);
+
+ /** Get the conjecture of the interpolation query */
+ api::Term getConjecture() const;
+ /** Get the grammar sygus datatype type given for the interpolation query */
+ Type getGrammarType() const;
+ /** Get the result of the query, which is the solution to the interpolation
+ * query. */
+ api::Term getResult() const;
+
+ void invoke(SmtEngine* smtEngine) override;
+ void printResult(std::ostream& out, uint32_t verbosity = 2) const override;
+ Command* exportTo(ExprManager* exprManager,
+ ExprManagerMapCollection& variableMap) override;
+ Command* clone() const override;
+ std::string getCommandName() const override;
+
+ protected:
+ /** The name of the interpolation predicate */
+ std::string d_name;
+ /** The conjecture of the interpolation query */
+ api::Term d_conj;
+ /**
+ * The (optional) grammar of the interpolation query, expressed as a sygus
+ * datatype type.
+ */
+ Type d_sygus_grammar_type;
+ /** the return status of the command */
+ bool d_resultStatus;
+ /** the return expression of the command */
+ api::Term d_result;
+}; /* class GetInterpolCommand */
+
/** The command (get-abduct s B (G)?)
*
* This command asks for an abduct from the current set of assertions and
diff --git a/src/smt/set_defaults.cpp b/src/smt/set_defaults.cpp
index d663352f7..a7e8e6212 100644
--- a/src/smt/set_defaults.cpp
+++ b/src/smt/set_defaults.cpp
@@ -291,8 +291,10 @@ void setDefaults(SmtEngine& smte, LogicInfo& logic)
// sygus inference may require datatypes
if (!smte.isInternalSubsolver())
{
- if (options::produceAbducts() || options::sygusInference()
- || options::sygusRewSynthInput() || options::sygusInst())
+ if (options::produceAbducts()
+ || options::produceInterpols() != options::ProduceInterpols::NONE
+ || options::sygusInference() || options::sygusRewSynthInput()
+ || options::sygusInst())
{
// since we are trying to recast as sygus, we assume the input is sygus
is_sygus = true;
@@ -316,6 +318,7 @@ void setDefaults(SmtEngine& smte, LogicInfo& logic)
if ((options::checkModels() || options::checkSynthSol()
|| options::produceAbducts()
+ || options::produceInterpols() != options::ProduceInterpols::NONE
|| options::modelCoresMode() != options::ModelCoresMode::NONE
|| options::blockModelsMode() != options::BlockModelsMode::NONE)
&& !options::produceAssertions())
diff --git a/src/smt/smt_engine.cpp b/src/smt/smt_engine.cpp
index a6d89aaf5..bb4d82fe0 100644
--- a/src/smt/smt_engine.cpp
+++ b/src/smt/smt_engine.cpp
@@ -2934,6 +2934,12 @@ void SmtEngine::checkSynthSolution()
}
}
+void SmtEngine::checkInterpol(Expr interpol,
+ const std::vector<Expr>& easserts,
+ const Node& conj)
+{
+}
+
void SmtEngine::checkAbduct(Expr a)
{
Assert(a.getType().isBoolean());
@@ -3152,6 +3158,19 @@ Expr SmtEngine::doQuantifierElimination(const Expr& e, bool doFull, bool strict)
}
}
+bool SmtEngine::getInterpol(const Expr& conj,
+ const Type& grammarType,
+ Expr& interpol)
+{
+ return false;
+}
+
+bool SmtEngine::getInterpol(const Expr& conj, Expr& interpol)
+{
+ Type grammarType;
+ return getInterpol(conj, grammarType, interpol);
+}
+
bool SmtEngine::getAbduct(const Expr& conj, const Type& grammarType, Expr& abd)
{
SmtScope smts(this);
diff --git a/src/smt/smt_engine.h b/src/smt/smt_engine.h
index 8a9a60251..afb39b41b 100644
--- a/src/smt/smt_engine.h
+++ b/src/smt/smt_engine.h
@@ -166,7 +166,9 @@ class CVC4_PUBLIC SmtEngine
// immediately after a check-sat returning "unsat"
SMT_MODE_UNSAT,
// immediately after a successful call to get-abduct
- SMT_MODE_ABDUCT
+ SMT_MODE_ABDUCT,
+ // immediately after a successful call to get-interpol
+ SMT_MODE_INTERPOL
};
/** Construct an SmtEngine with the given expression manager. */
@@ -619,6 +621,23 @@ class CVC4_PUBLIC SmtEngine
Expr doQuantifierElimination(const Expr& e, bool doFull, bool strict = true);
/**
+ * This method asks this SMT engine to find an interpolant with respect to
+ * the current assertion stack (call it A) and the conjecture (call it B). If
+ * this method returns true, then interpolant is set to a formula I such that
+ * A ^ ~I and I ^ ~B are both unsatisfiable.
+ *
+ * The argument grammarType is a sygus datatype type that encodes the syntax
+ * restrictions on the shapes of possible solutions.
+ *
+ * This method invokes a separate copy of the SMT engine for solving the
+ * corresponding sygus problem for generating such a solution.
+ */
+ bool getInterpol(const Expr& conj, const Type& grammarType, Expr& interpol);
+
+ /** Same as above, but without user-provided grammar restrictions */
+ bool getInterpol(const Expr& conj, Expr& interpol);
+
+ /**
* This method asks this SMT engine to find an abduct with respect to the
* current assertion stack (call it A) and the conjecture (call it B).
* If this method returns true, then abd is set to a formula C such that
@@ -935,6 +954,18 @@ class CVC4_PUBLIC SmtEngine
* unsatisfiable. If not, then the found solutions are wrong.
*/
void checkSynthSolution();
+
+ /**
+ * Check that a solution to an interpolation problem is indeed a solution.
+ *
+ * The check is made by determining that the assertions imply the solution of
+ * the interpolation problem (interpol), and the solution implies the goal
+ * (conj). If these criteria are not met, an internal error is thrown.
+ */
+ void checkInterpol(Expr interpol,
+ const std::vector<Expr>& easserts,
+ const Node& conj);
+
/**
* Check that a solution to an abduction conjecture is indeed a solution.
*
@@ -1058,6 +1089,7 @@ class CVC4_PUBLIC SmtEngine
void debugCheckFunctionBody(Expr formula,
const std::vector<Expr>& formals,
Expr func);
+
/**
* Get abduct internal.
*
diff --git a/src/theory/arith/arith_rewriter.cpp b/src/theory/arith/arith_rewriter.cpp
index e50b79bbc..188ef47e6 100644
--- a/src/theory/arith/arith_rewriter.cpp
+++ b/src/theory/arith/arith_rewriter.cpp
@@ -25,6 +25,7 @@
#include "theory/arith/arith_utilities.h"
#include "theory/arith/normal_form.h"
#include "theory/theory.h"
+#include "util/iand.h"
namespace CVC4 {
namespace theory {
@@ -101,8 +102,8 @@ RewriteResponse ArithRewriter::preRewriteTerm(TNode t){
case kind::PLUS:
return preRewritePlus(t);
case kind::MULT:
- case kind::NONLINEAR_MULT:
- return preRewriteMult(t);
+ case kind::NONLINEAR_MULT: return preRewriteMult(t);
+ case kind::IAND: return RewriteResponse(REWRITE_DONE, t);
case kind::EXPONENTIAL:
case kind::SINE:
case kind::COSINE:
@@ -165,8 +166,8 @@ RewriteResponse ArithRewriter::postRewriteTerm(TNode t){
case kind::PLUS:
return postRewritePlus(t);
case kind::MULT:
- case kind::NONLINEAR_MULT:
- return postRewriteMult(t);
+ case kind::NONLINEAR_MULT: return postRewriteMult(t);
+ case kind::IAND: return postRewriteIAnd(t);
case kind::EXPONENTIAL:
case kind::SINE:
case kind::COSINE:
@@ -371,6 +372,47 @@ RewriteResponse ArithRewriter::postRewriteMult(TNode t){
return RewriteResponse(REWRITE_DONE, res.getNode());
}
+RewriteResponse ArithRewriter::postRewriteIAnd(TNode t)
+{
+ Assert(t.getKind() == kind::IAND);
+ NodeManager* nm = NodeManager::currentNM();
+ // if constant, we eliminate
+ if (t[0].isConst() && t[1].isConst())
+ {
+ size_t bsize = t.getOperator().getConst<IntAnd>().d_size;
+ Node iToBvop = nm->mkConst(IntToBitVector(bsize));
+ Node arg1 = nm->mkNode(kind::INT_TO_BITVECTOR, iToBvop, t[0]);
+ Node arg2 = nm->mkNode(kind::INT_TO_BITVECTOR, iToBvop, t[1]);
+ Node bvand = nm->mkNode(kind::BITVECTOR_AND, arg1, arg2);
+ Node ret = nm->mkNode(kind::BITVECTOR_TO_NAT, bvand);
+ return RewriteResponse(REWRITE_AGAIN_FULL, ret);
+ }
+ else if (t[0] > t[1])
+ {
+ // ((_ iand k) x y) ---> ((_ iand k) y x) if x > y by node ordering
+ Node ret = nm->mkNode(kind::IAND, t.getOperator(), t[1], t[0]);
+ return RewriteResponse(REWRITE_AGAIN, ret);
+ }
+ else if (t[0] == t[1])
+ {
+ // ((_ iand k) x x) ---> x
+ return RewriteResponse(REWRITE_DONE, t[0]);
+ }
+ // simplifications involving constants
+ for (unsigned i = 0; i < 2; i++)
+ {
+ if (!t[i].isConst())
+ {
+ continue;
+ }
+ if (t[i].getConst<Rational>().sgn() == 0)
+ {
+ // ((_ iand k) 0 y) ---> 0
+ return RewriteResponse(REWRITE_DONE, t[i]);
+ }
+ }
+ return RewriteResponse(REWRITE_DONE, t);
+}
RewriteResponse ArithRewriter::preRewriteTranscendental(TNode t) {
return RewriteResponse(REWRITE_DONE, t);
diff --git a/src/theory/arith/arith_rewriter.h b/src/theory/arith/arith_rewriter.h
index 0563aa1de..1dc756514 100644
--- a/src/theory/arith/arith_rewriter.h
+++ b/src/theory/arith/arith_rewriter.h
@@ -52,7 +52,9 @@ class ArithRewriter : public TheoryRewriter
static RewriteResponse preRewriteMult(TNode t);
static RewriteResponse postRewriteMult(TNode t);
-
+
+ static RewriteResponse postRewriteIAnd(TNode t);
+
static RewriteResponse preRewriteTranscendental(TNode t);
static RewriteResponse postRewriteTranscendental(TNode t);
diff --git a/src/theory/arith/congruence_manager.cpp b/src/theory/arith/congruence_manager.cpp
index 4c35e5d19..858098b70 100644
--- a/src/theory/arith/congruence_manager.cpp
+++ b/src/theory/arith/congruence_manager.cpp
@@ -47,6 +47,7 @@ ArithCongruenceManager::ArithCongruenceManager(
d_ee.addFunctionKind(kind::NONLINEAR_MULT);
d_ee.addFunctionKind(kind::EXPONENTIAL);
d_ee.addFunctionKind(kind::SINE);
+ d_ee.addFunctionKind(kind::IAND);
}
ArithCongruenceManager::~ArithCongruenceManager() {}
diff --git a/src/theory/arith/kinds b/src/theory/arith/kinds
index 409534050..e563d8f66 100644
--- a/src/theory/arith/kinds
+++ b/src/theory/arith/kinds
@@ -133,4 +133,18 @@ nullaryoperator PI "pi"
typerule PI ::CVC4::theory::arith::RealNullaryOperatorTypeRule
+# Integer AND, which is parameterized by a (positive) bitwidth k.
+# ((_ iand k) i1 i2) is equivalent to:
+# (bv2int (bvand ((_ int2bv k) i1) ((_ int2bv k) i2)))
+# for all integers i1, i2.
+constant IAND_OP \
+ ::CVC4::IntAnd \
+ "::CVC4::UnsignedHashFunction< ::CVC4::IntAnd >" \
+ "util/iand.h" \
+ "operator for integer AND; payload is an instance of the CVC4::IntAnd class"
+parameterized IAND IAND_OP 2 "integer version of AND operator; first parameter is an IAND_OP, second and third are integer terms"
+
+typerule IAND_OP ::CVC4::theory::arith::IAndOpTypeRule
+typerule IAND ::CVC4::theory::arith::IAndTypeRule
+
endtheory
diff --git a/src/theory/arith/normal_form.cpp b/src/theory/arith/normal_form.cpp
index c7b4b3625..f964f1628 100644
--- a/src/theory/arith/normal_form.cpp
+++ b/src/theory/arith/normal_form.cpp
@@ -71,6 +71,12 @@ bool Variable::isLeafMember(Node n){
VarList::VarList(Node n) : NodeWrapper(n) { Assert(isSorted(begin(), end())); }
+bool Variable::isIAndMember(Node n)
+{
+ return n.getKind() == kind::IAND && Polynomial::isMember(n[0])
+ && Polynomial::isMember(n[1]);
+}
+
bool Variable::isDivMember(Node n){
switch(n.getKind()){
case kind::DIVISION:
diff --git a/src/theory/arith/normal_form.h b/src/theory/arith/normal_form.h
index 3ab5d907a..484bdbf44 100644
--- a/src/theory/arith/normal_form.h
+++ b/src/theory/arith/normal_form.h
@@ -239,6 +239,7 @@ public:
case kind::INTS_DIVISION_TOTAL:
case kind::INTS_MODULUS_TOTAL:
case kind::DIVISION_TOTAL: return isDivMember(n);
+ case kind::IAND: return isIAndMember(n);
case kind::EXPONENTIAL:
case kind::SINE:
case kind::COSINE:
@@ -264,6 +265,7 @@ public:
}
static bool isLeafMember(Node n);
+ static bool isIAndMember(Node n);
static bool isDivMember(Node n);
bool isDivLike() const{
return isDivMember(getNode());
diff --git a/src/theory/arith/proof_checker.cpp b/src/theory/arith/proof_checker.cpp
new file mode 100644
index 000000000..5b7a3d63a
--- /dev/null
+++ b/src/theory/arith/proof_checker.cpp
@@ -0,0 +1,269 @@
+/********************* */
+/*! \file proof_checker.cpp
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Alex Ozdemir
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2019 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.\endverbatim
+ **
+ ** \brief Implementation of arithmetic proof checker
+ **/
+
+#include "theory/arith/proof_checker.h"
+
+#include <iostream>
+#include <set>
+
+#include "expr/skolem_manager.h"
+#include "theory/arith/arith_utilities.h"
+#include "theory/arith/constraint.h"
+#include "theory/arith/normal_form.h"
+#include "theory/arith/operator_elim.h"
+
+namespace CVC4 {
+namespace theory {
+namespace arith {
+
+void ArithProofRuleChecker::registerTo(ProofChecker* pc)
+{
+ pc->registerChecker(PfRule::ARITH_SCALE_SUM_UPPER_BOUNDS, this);
+ pc->registerChecker(PfRule::ARITH_TRICHOTOMY, this);
+ pc->registerChecker(PfRule::INT_TIGHT_UB, this);
+ pc->registerChecker(PfRule::INT_TIGHT_LB, this);
+ pc->registerChecker(PfRule::INT_TRUST, this);
+ pc->registerChecker(PfRule::ARITH_OP_ELIM_AXIOM, this);
+}
+
+Node ArithProofRuleChecker::checkInternal(PfRule id,
+ const std::vector<Node>& children,
+ const std::vector<Node>& args)
+{
+ if (Debug.isOn("arith::pf::check"))
+ {
+ Debug("arith::pf::check") << "Arith PfRule:" << id << std::endl;
+ Debug("arith::pf::check") << " children: " << std::endl;
+ for (const auto& c : children)
+ {
+ Debug("arith::pf::check") << " * " << c << std::endl;
+ }
+ Debug("arith::pf::check") << " args:" << std::endl;
+ for (const auto& c : args)
+ {
+ Debug("arith::pf::check") << " * " << c << std::endl;
+ }
+ }
+ switch (id)
+ {
+ case PfRule::ARITH_SCALE_SUM_UPPER_BOUNDS:
+ {
+ // Children: (P1:l1, ..., Pn:ln)
+ // where each li is an ArithLiteral
+ // not(= ...) is dis-allowed!
+ //
+ // Arguments: (k1, ..., kn), non-zero reals
+ // ---------------------
+ // Conclusion: (>< (* k t1) (* k t2))
+ // where >< is the fusion of the combination of the ><i, (flipping each
+ // it its ki is negative). >< is always one of <, <= NB: this implies
+ // that lower bounds must have negative ki,
+ // and upper bounds must have positive ki.
+ // t1 is the sum of the polynomials.
+ // t2 is the sum of the constants.
+ Assert(children.size() == args.size());
+ if (children.size() < 2)
+ {
+ return Node::null();
+ }
+
+ // Whether a strict inequality is in the sum.
+ auto nm = NodeManager::currentNM();
+ bool strict = false;
+ NodeBuilder<> leftSum(Kind::PLUS);
+ NodeBuilder<> rightSum(Kind::PLUS);
+ for (size_t i = 0; i < children.size(); ++i)
+ {
+ Rational scalar = args[i].getConst<Rational>();
+ if (scalar == 0)
+ {
+ Debug("arith::pf::check") << "Error: zero scalar" << std::endl;
+ return Node::null();
+ }
+
+ // Adjust strictness
+ switch (children[i].getKind())
+ {
+ case Kind::GT:
+ case Kind::LT:
+ {
+ strict = true;
+ break;
+ }
+ case Kind::GEQ:
+ case Kind::LEQ:
+ case Kind::EQUAL:
+ {
+ break;
+ }
+ default:
+ {
+ Debug("arith::pf::check")
+ << "Bad kind: " << children[i].getKind() << std::endl;
+ }
+ }
+ // Check sign
+ switch (children[i].getKind())
+ {
+ case Kind::GT:
+ case Kind::GEQ:
+ {
+ if (scalar > 0)
+ {
+ Debug("arith::pf::check")
+ << "Positive scalar for lower bound: " << scalar << " for "
+ << children[i] << std::endl;
+ return Node::null();
+ }
+ break;
+ }
+ case Kind::LEQ:
+ case Kind::LT:
+ {
+ if (scalar < 0)
+ {
+ Debug("arith::pf::check")
+ << "Negative scalar for upper bound: " << scalar << " for "
+ << children[i] << std::endl;
+ return Node::null();
+ }
+ break;
+ }
+ case Kind::EQUAL:
+ {
+ break;
+ }
+ default:
+ {
+ Debug("arith::pf::check")
+ << "Bad kind: " << children[i].getKind() << std::endl;
+ }
+ }
+ leftSum << nm->mkNode(
+ Kind::MULT, children[i][0], nm->mkConst<Rational>(scalar));
+ rightSum << nm->mkNode(
+ Kind::MULT, children[i][1], nm->mkConst<Rational>(scalar));
+ }
+ Node r = nm->mkNode(strict ? Kind::LT : Kind::LEQ,
+ leftSum.constructNode(),
+ rightSum.constructNode());
+ return r;
+ }
+ case PfRule::INT_TIGHT_LB:
+ {
+ // Children: (P:(> i c))
+ // where i has integer type.
+ // Arguments: none
+ // ---------------------
+ // Conclusion: (>= i leastIntGreaterThan(c)})
+ if (children.size() != 1
+ || (children[0].getKind() != Kind::GT
+ && children[0].getKind() != Kind::GEQ)
+ || !children[0][0].getType().isInteger()
+ || children[0][1].getKind() != Kind::CONST_RATIONAL)
+ {
+ Debug("arith::pf::check") << "Illformed input: " << children;
+ return Node::null();
+ }
+ else
+ {
+ Rational originalBound = children[0][1].getConst<Rational>();
+ Rational newBound = leastIntGreaterThan(originalBound);
+ auto nm = NodeManager::currentNM();
+ Node rational = nm->mkConst<Rational>(newBound);
+ return nm->mkNode(kind::GEQ, children[0][0], rational);
+ }
+ }
+ case PfRule::INT_TIGHT_UB:
+ {
+ // ======== Tightening Strict Integer Upper Bounds
+ // Children: (P:(< i c))
+ // where i has integer type.
+ // Arguments: none
+ // ---------------------
+ // Conclusion: (<= i greatestIntLessThan(c)})
+ if (children.size() != 1
+ || (children[0].getKind() != Kind::LT
+ && children[0].getKind() != Kind::LEQ)
+ || !children[0][0].getType().isInteger()
+ || children[0][1].getKind() != Kind::CONST_RATIONAL)
+ {
+ Debug("arith::pf::check") << "Illformed input: " << children;
+ return Node::null();
+ }
+ else
+ {
+ Rational originalBound = children[0][1].getConst<Rational>();
+ Rational newBound = greatestIntLessThan(originalBound);
+ auto nm = NodeManager::currentNM();
+ Node rational = nm->mkConst<Rational>(newBound);
+ return nm->mkNode(kind::LEQ, children[0][0], rational);
+ }
+ }
+ case PfRule::ARITH_TRICHOTOMY:
+ {
+ Node a = negateProofLiteral(children[0]);
+ Node b = negateProofLiteral(children[1]);
+ Node c = args[0];
+ if (a[0] == b[0] && b[0] == c[0] && a[1] == b[1] && b[1] == c[1])
+ {
+ std::set<Kind> cmps;
+ cmps.insert(a.getKind());
+ cmps.insert(b.getKind());
+ cmps.insert(c.getKind());
+ if (cmps.count(Kind::EQUAL) == 0)
+ {
+ Debug("arith::pf::check") << "Error: No = " << std::endl;
+ return Node::null();
+ }
+ if (cmps.count(Kind::GT) == 0)
+ {
+ Debug("arith::pf::check") << "Error: No > " << std::endl;
+ return Node::null();
+ }
+ if (cmps.count(Kind::LT) == 0)
+ {
+ Debug("arith::pf::check") << "Error: No < " << std::endl;
+ return Node::null();
+ }
+ return args[0];
+ }
+ else
+ {
+ Debug("arith::pf::check")
+ << "Error: Different polynomials / values" << std::endl;
+ Debug("arith::pf::check") << " a: " << a << std::endl;
+ Debug("arith::pf::check") << " b: " << b << std::endl;
+ Debug("arith::pf::check") << " c: " << c << std::endl;
+ return Node::null();
+ }
+ // Check that all have the same constant:
+ }
+ case PfRule::INT_TRUST:
+ {
+ Assert(args.size() == 1);
+ return args[0];
+ }
+ case PfRule::ARITH_OP_ELIM_AXIOM:
+ {
+ Assert(children.empty());
+ Assert(args.size() == 1);
+ return OperatorElim::getAxiomFor(args[0]);
+ }
+ default: return Node::null();
+ }
+}
+} // namespace arith
+} // namespace theory
+} // namespace CVC4
diff --git a/src/theory/arith/proof_checker.h b/src/theory/arith/proof_checker.h
new file mode 100644
index 000000000..b8a5d0df7
--- /dev/null
+++ b/src/theory/arith/proof_checker.h
@@ -0,0 +1,49 @@
+/********************* */
+/*! \file proof_checker.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Alex Ozdemir
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2019 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.\endverbatim
+ **
+ ** \brief Arithmetic proof checker utility
+ **/
+
+#include "cvc4_private.h"
+
+#ifndef CVC4__THEORY__ARITH__PROOF_CHECKER_H
+#define CVC4__THEORY__ARITH__PROOF_CHECKER_H
+
+#include "expr/node.h"
+#include "expr/proof_checker.h"
+#include "expr/proof_node.h"
+
+namespace CVC4 {
+namespace theory {
+namespace arith {
+
+/** A checker for arithmetic reasoning in proofs */
+class ArithProofRuleChecker : public ProofRuleChecker
+{
+ public:
+ ArithProofRuleChecker() {}
+ ~ArithProofRuleChecker() {}
+
+ /** Register all rules owned by this rule checker into pc. */
+ void registerTo(ProofChecker* pc) override;
+
+ protected:
+ /** Return the conclusion of the given proof step, or null if it is invalid */
+ Node checkInternal(PfRule id,
+ const std::vector<Node>& children,
+ const std::vector<Node>& args) override;
+};
+
+} // namespace arith
+} // namespace theory
+} // namespace CVC4
+
+#endif /* CVC4__THEORY__ARITH__PROOF_CHECKER_H */
diff --git a/src/theory/arith/theory_arith.cpp b/src/theory/arith/theory_arith.cpp
index 30b8ed01d..8b4747927 100644
--- a/src/theory/arith/theory_arith.cpp
+++ b/src/theory/arith/theory_arith.cpp
@@ -48,6 +48,7 @@ TheoryArith::TheoryArith(context::Context* c, context::UserContext* u,
getExtTheory()->addFunctionKind(kind::EXPONENTIAL);
getExtTheory()->addFunctionKind(kind::SINE);
getExtTheory()->addFunctionKind(kind::PI);
+ getExtTheory()->addFunctionKind(kind::IAND);
}
}
diff --git a/src/theory/arith/theory_arith_type_rules.h b/src/theory/arith/theory_arith_type_rules.h
index 2d3d8a28b..77efcfff7 100644
--- a/src/theory/arith/theory_arith_type_rules.h
+++ b/src/theory/arith/theory_arith_type_rules.h
@@ -87,6 +87,49 @@ public:
}
};/* class RealNullaryOperatorTypeRule */
+class IAndOpTypeRule
+{
+ public:
+ inline static TypeNode computeType(NodeManager* nodeManager,
+ TNode n,
+ bool check)
+ {
+ if (n.getKind() != kind::IAND_OP)
+ {
+ InternalError() << "IAND_OP typerule invoked for IAND_OP kind";
+ }
+ TypeNode iType = nodeManager->integerType();
+ std::vector<TypeNode> argTypes;
+ argTypes.push_back(iType);
+ argTypes.push_back(iType);
+ return nodeManager->mkFunctionType(argTypes, iType);
+ }
+}; /* class IAndOpTypeRule */
+
+class IAndTypeRule
+{
+ public:
+ inline static TypeNode computeType(NodeManager* nodeManager,
+ TNode n,
+ bool check)
+ {
+ if (n.getKind() != kind::IAND)
+ {
+ InternalError() << "IAND typerule invoked for IAND kind";
+ }
+ if (check)
+ {
+ TypeNode arg1 = n[0].getType(check);
+ TypeNode arg2 = n[1].getType(check);
+ if (!arg1.isInteger() || !arg2.isInteger())
+ {
+ throw TypeCheckingExceptionPrivate(n, "expecting integer terms");
+ }
+ }
+ return nodeManager->integerType();
+ }
+}; /* class BitVectorConversionTypeRule */
+
}/* CVC4::theory::arith namespace */
}/* CVC4::theory namespace */
}/* CVC4 namespace */
diff --git a/src/theory/datatypes/sygus_extension.cpp b/src/theory/datatypes/sygus_extension.cpp
index 49c7461e6..fda08bb0e 100644
--- a/src/theory/datatypes/sygus_extension.cpp
+++ b/src/theory/datatypes/sygus_extension.cpp
@@ -1673,7 +1673,6 @@ bool SygusExtension::checkValue(Node n,
}
TypeNode tn = n.getType();
const DType& dt = tn.getDType();
- Assert(dt.isSygus());
// ensure that the expected size bound is met
int cindex = utils::indexOf(vn.getOperator());
diff --git a/src/theory/quantifiers/candidate_rewrite_database.cpp b/src/theory/quantifiers/candidate_rewrite_database.cpp
index 0454b6412..fc3474df4 100644
--- a/src/theory/quantifiers/candidate_rewrite_database.cpp
+++ b/src/theory/quantifiers/candidate_rewrite_database.cpp
@@ -14,6 +14,7 @@
#include "theory/quantifiers/candidate_rewrite_database.h"
+#include "api/cvc4cpp.h"
#include "options/base_options.h"
#include "options/quantifiers_options.h"
#include "printer/printer.h"
@@ -137,8 +138,15 @@ bool CandidateRewriteDatabase::addTerm(Node sol,
// options as the SmtEngine we belong to, where we ensure that
// produce-models is set.
bool needExport = false;
- ExprManager em(nm->getOptions());
- std::unique_ptr<SmtEngine> rrChecker;
+
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // This is only temporarily until we have separate options for each
+ // SmtEngine instance. We should reuse the same ExprManager with
+ // a different SmtEngine (and different options) here, eventually.
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ api::Solver slv(&nm->getOptions());
+ ExprManager* em = slv.getExprManager();
+ SmtEngine* rrChecker = slv.getSmtEngine();
ExprManagerMapCollection varMap;
initializeChecker(rrChecker, em, varMap, crr, needExport);
Result r = rrChecker->checkSat();
@@ -175,7 +183,7 @@ bool CandidateRewriteDatabase::addTerm(Node sol,
Assert(!refv.isNull() && refv.getKind() != BOUND_VARIABLE);
if (needExport)
{
- Expr erefv = refv.toExpr().exportTo(&em, varMap);
+ Expr erefv = refv.toExpr().exportTo(em, varMap);
val = Node::fromExpr(rrChecker->getValue(erefv).exportTo(
nm->toExprManager(), varMap));
}
diff --git a/src/theory/quantifiers/expr_miner.cpp b/src/theory/quantifiers/expr_miner.cpp
index 01a46d84a..b209fc6ff 100644
--- a/src/theory/quantifiers/expr_miner.cpp
+++ b/src/theory/quantifiers/expr_miner.cpp
@@ -14,6 +14,7 @@
#include "theory/quantifiers/expr_miner.h"
+#include "api/cvc4cpp.h"
#include "options/quantifiers_options.h"
#include "smt/smt_engine.h"
#include "smt/smt_engine_scope.h"
@@ -68,8 +69,8 @@ Node ExprMiner::convertToSkolem(Node n)
return n.substitute(sfvs.begin(), sfvs.end(), sks.begin(), sks.end());
}
-void ExprMiner::initializeChecker(std::unique_ptr<SmtEngine>& checker,
- ExprManager& em,
+void ExprMiner::initializeChecker(SmtEngine* checker,
+ ExprManager* em,
ExprManagerMapCollection& varMap,
Node query,
bool& needExport)
@@ -110,10 +111,16 @@ Result ExprMiner::doCheck(Node query)
return Result(Result::SAT);
}
}
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // This is only temporarily until we have separate options for each
+ // SmtEngine instance. We should reuse the same ExprManager with
+ // a different SmtEngine (and different options) here, eventually.
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
NodeManager* nm = NodeManager::currentNM();
bool needExport = false;
- ExprManager em(nm->getOptions());
- std::unique_ptr<SmtEngine> smte;
+ api::Solver slv(&nm->getOptions());
+ ExprManager* em = slv.getExprManager();
+ SmtEngine* smte = slv.getSmtEngine();
ExprManagerMapCollection varMap;
initializeChecker(smte, em, varMap, queryr, needExport);
return smte->checkSat();
diff --git a/src/theory/quantifiers/expr_miner.h b/src/theory/quantifiers/expr_miner.h
index d69ef45b4..eebcebf88 100644
--- a/src/theory/quantifiers/expr_miner.h
+++ b/src/theory/quantifiers/expr_miner.h
@@ -89,8 +89,8 @@ class ExprMiner
* (for instance, model values) must be exported to the current expression
* manager.
*/
- void initializeChecker(std::unique_ptr<SmtEngine>& smte,
- ExprManager& em,
+ void initializeChecker(SmtEngine* smte,
+ ExprManager* em,
ExprManagerMapCollection& varMap,
Node query,
bool& needExport);
diff --git a/src/theory/quantifiers/query_generator.cpp b/src/theory/quantifiers/query_generator.cpp
index 9f08ebec7..4cf65b24a 100644
--- a/src/theory/quantifiers/query_generator.cpp
+++ b/src/theory/quantifiers/query_generator.cpp
@@ -16,6 +16,8 @@
#include "theory/quantifiers/query_generator.h"
#include <fstream>
+
+#include "api/cvc4cpp.h"
#include "options/quantifiers_options.h"
#include "smt/smt_engine.h"
#include "smt/smt_engine_scope.h"
@@ -157,9 +159,16 @@ void QueryGenerator::checkQuery(Node qy, unsigned spIndex)
Trace("sygus-qgen-check") << " query: check " << qy << "..." << std::endl;
NodeManager* nm = NodeManager::currentNM();
// make the satisfiability query
+ //
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // This is only temporarily until we have separate options for each
+ // SmtEngine instance. We should reuse the same ExprManager with
+ // a different SmtEngine (and different options) here, eventually.
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
bool needExport = false;
- ExprManager em(nm->getOptions());
- std::unique_ptr<SmtEngine> queryChecker;
+ api::Solver slv(&nm->getOptions());
+ ExprManager* em = slv.getExprManager();
+ SmtEngine* queryChecker = slv.getSmtEngine();
ExprManagerMapCollection varMap;
initializeChecker(queryChecker, em, varMap, qy, needExport);
Result r = queryChecker->checkSat();
diff --git a/src/theory/quantifiers/sygus/cegis_core_connective.cpp b/src/theory/quantifiers/sygus/cegis_core_connective.cpp
index de75af083..5784e42c0 100644
--- a/src/theory/quantifiers/sygus/cegis_core_connective.cpp
+++ b/src/theory/quantifiers/sygus/cegis_core_connective.cpp
@@ -735,8 +735,9 @@ Node CegisCoreConnective::constructSolutionFromPool(Component& ccheck,
{
addSuccess = false;
// try a new core
- std::unique_ptr<SmtEngine> checkSol;
- initializeSubsolver(checkSol);
+ std::unique_ptr<SmtEngine> checkSol(
+ new SmtEngine(NodeManager::currentNM()->toExprManager()));
+ initializeSubsolver(checkSol.get());
Trace("sygus-ccore") << "----- Check candidate " << an << std::endl;
std::vector<Node> rasserts = asserts;
rasserts.push_back(d_sc);
@@ -775,8 +776,9 @@ Node CegisCoreConnective::constructSolutionFromPool(Component& ccheck,
{
// In terms of Variant #2, this is the check "if S ^ U is unsat"
Trace("sygus-ccore") << "----- Check side condition" << std::endl;
- std::unique_ptr<SmtEngine> checkSc;
- initializeSubsolver(checkSc);
+ std::unique_ptr<SmtEngine> checkSc(
+ new SmtEngine(NodeManager::currentNM()->toExprManager()));
+ initializeSubsolver(checkSc.get());
std::vector<Node> scasserts;
scasserts.insert(scasserts.end(), uasserts.begin(), uasserts.end());
scasserts.push_back(d_sc);
diff --git a/src/theory/quantifiers/sygus/sygus_repair_const.cpp b/src/theory/quantifiers/sygus/sygus_repair_const.cpp
index 1c34bd73a..d34903805 100644
--- a/src/theory/quantifiers/sygus/sygus_repair_const.cpp
+++ b/src/theory/quantifiers/sygus/sygus_repair_const.cpp
@@ -14,6 +14,7 @@
#include "theory/quantifiers/sygus/sygus_repair_const.h"
+#include "api/cvc4cpp.h"
#include "options/base_options.h"
#include "options/quantifiers_options.h"
#include "printer/printer.h"
@@ -100,36 +101,6 @@ bool SygusRepairConst::isActive() const
return !d_base_inst.isNull() && d_allow_constant_grammar;
}
-void SygusRepairConst::initializeChecker(std::unique_ptr<SmtEngine>& checker,
- ExprManager& em,
- ExprManagerMapCollection& varMap,
- Node query,
- bool& needExport)
-{
- if (options::sygusRepairConstTimeout.wasSetByUser())
- {
- // To support a separate timeout for the subsolver, we need to create
- // a separate ExprManager with its own options. This requires that
- // the expressions sent to the subsolver can be exported from on
- // ExprManager to another.
- initializeSubsolverWithExport(checker,
- em,
- varMap,
- query.toExpr(),
- true,
- options::sygusRepairConstTimeout());
- // renable options disabled by sygus
- checker->setOption("miniscope-quant", true);
- checker->setOption("miniscope-quant-fv", true);
- checker->setOption("quant-split", true);
- }
- else
- {
- needExport = false;
- initializeSubsolver(checker, query.toExpr());
- }
-}
-
bool SygusRepairConst::repairSolution(const std::vector<Node>& candidates,
const std::vector<Node>& candidate_values,
std::vector<Node>& repair_cv,
@@ -258,11 +229,48 @@ bool SygusRepairConst::repairSolution(Node sygusBody,
Trace("sygus-engine") << "Repairing previous solution..." << std::endl;
// make the satisfiability query
+ //
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // This is only temporarily until we have separate options for each
+ // SmtEngine instance. We should reuse the same ExprManager with
+ // a different SmtEngine (and different options) here, eventually.
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
bool needExport = true;
+ std::unique_ptr<SmtEngine> simpleSmte;
+ std::unique_ptr<api::Solver> slv;
+ ExprManager* em = nullptr;
+ SmtEngine* repcChecker = nullptr;
ExprManagerMapCollection varMap;
- ExprManager em(nm->getOptions());
- std::unique_ptr<SmtEngine> repcChecker;
- initializeChecker(repcChecker, em, varMap, fo_body, needExport);
+
+ if (options::sygusRepairConstTimeout.wasSetByUser())
+ {
+ // To support a separate timeout for the subsolver, we need to create
+ // a separate ExprManager with its own options. This requires that
+ // the expressions sent to the subsolver can be exported from on
+ // ExprManager to another.
+ slv.reset(new api::Solver(&nm->getOptions()));
+ em = slv->getExprManager();
+ repcChecker = slv->getSmtEngine();
+ initializeSubsolverWithExport(repcChecker,
+ em,
+ varMap,
+ fo_body.toExpr(),
+ true,
+ options::sygusRepairConstTimeout());
+ // renable options disabled by sygus
+ repcChecker->setOption("miniscope-quant", true);
+ repcChecker->setOption("miniscope-quant-fv", true);
+ repcChecker->setOption("quant-split", true);
+ }
+ else
+ {
+ needExport = false;
+ em = nm->toExprManager();
+ simpleSmte.reset(new SmtEngine(em));
+ repcChecker = simpleSmte.get();
+ initializeSubsolver(repcChecker, fo_body.toExpr());
+ }
+
Result r = repcChecker->checkSat();
Trace("sygus-repair-const") << "...got : " << r << std::endl;
if (r.asSatisfiabilityResult().isSat() == Result::UNSAT
@@ -279,7 +287,7 @@ bool SygusRepairConst::repairSolution(Node sygusBody,
Node fov_m;
if (needExport)
{
- Expr e_fov = fov.toExpr().exportTo(&em, varMap);
+ Expr e_fov = fov.toExpr().exportTo(em, varMap);
fov_m = Node::fromExpr(
repcChecker->getValue(e_fov).exportTo(nm->toExprManager(), varMap));
}
diff --git a/src/theory/quantifiers/sygus/sygus_repair_const.h b/src/theory/quantifiers/sygus/sygus_repair_const.h
index dc721b42d..e02ca1f3e 100644
--- a/src/theory/quantifiers/sygus/sygus_repair_const.h
+++ b/src/theory/quantifiers/sygus/sygus_repair_const.h
@@ -209,26 +209,6 @@ class SygusRepairConst
* If n is in the given logic, this method returns true.
*/
bool getFitToLogicExcludeVar(LogicInfo& logic, Node n, Node& exvar);
- /** initialize checker
- *
- * This function initializes the smt engine checker to check the
- * satisfiability of the argument "query"
- *
- * The arguments em and varMap are used for supporting cases where we
- * want checker to use a different expression manager instead of the current
- * expression manager. The motivation for this so that different options can
- * be set for the subcall.
- *
- * We update the flag needExport to true if checker is using the expression
- * manager em. In this case, subsequent expressions extracted from smte
- * (for instance, model values) must be exported to the current expression
- * manager.
- */
- void initializeChecker(std::unique_ptr<SmtEngine>& checker,
- ExprManager& em,
- ExprManagerMapCollection& varMap,
- Node query,
- bool& needExport);
};
} /* CVC4::theory::quantifiers namespace */
diff --git a/src/theory/quantifiers/sygus/synth_engine.cpp b/src/theory/quantifiers/sygus/synth_engine.cpp
index f8349c834..590fdaa56 100644
--- a/src/theory/quantifiers/sygus/synth_engine.cpp
+++ b/src/theory/quantifiers/sygus/synth_engine.cpp
@@ -169,8 +169,9 @@ void SynthEngine::assignConjecture(Node q)
if (!sip.isPurelySingleInvocation() && sip.isNonGroundSingleInvocation())
{
// create new smt engine to do quantifier elimination
- std::unique_ptr<SmtEngine> smt_qe;
- initializeSubsolver(smt_qe);
+ std::unique_ptr<SmtEngine> smt_qe(
+ new SmtEngine(NodeManager::currentNM()->toExprManager()));
+ initializeSubsolver(smt_qe.get());
Trace("cegqi-qep") << "Property is non-ground single invocation, run "
"QE to obtain single invocation."
<< std::endl;
diff --git a/src/theory/quantifiers_engine.cpp b/src/theory/quantifiers_engine.cpp
index f38d2fbdb..6dce6ce1e 100644
--- a/src/theory/quantifiers_engine.cpp
+++ b/src/theory/quantifiers_engine.cpp
@@ -1091,13 +1091,6 @@ bool QuantifiersEngine::getInstWhenNeedsCheck( Theory::Effort e ) {
{
performCheck = true;
}
- if( e==Theory::EFFORT_LAST_CALL ){
- //with bounded integers, skip every other last call,
- // since matching loops may occur with infinite quantification
- if( d_ierCounter_lc%2==0 && options::fmfBound() ){
- performCheck = false;
- }
- }
return performCheck;
}
diff --git a/src/theory/smt_engine_subsolver.cpp b/src/theory/smt_engine_subsolver.cpp
index 3386f3691..f529d3fea 100644
--- a/src/theory/smt_engine_subsolver.cpp
+++ b/src/theory/smt_engine_subsolver.cpp
@@ -15,6 +15,7 @@
#include "theory/smt_engine_subsolver.h"
+#include "api/cvc4cpp.h"
#include "smt/smt_engine.h"
#include "smt/smt_engine_scope.h"
#include "theory/rewriter.h"
@@ -40,16 +41,14 @@ Result quickCheck(Node& query)
return Result(Result::SAT_UNKNOWN, Result::REQUIRES_FULL_CHECK);
}
-void initializeSubsolver(std::unique_ptr<SmtEngine>& smte)
+void initializeSubsolver(SmtEngine* smte)
{
- NodeManager* nm = NodeManager::currentNM();
- smte.reset(new SmtEngine(nm->toExprManager()));
smte->setIsInternalSubsolver();
smte->setLogic(smt::currentSmtEngine()->getLogicInfo());
}
-void initializeSubsolverWithExport(std::unique_ptr<SmtEngine>& smte,
- ExprManager& em,
+void initializeSubsolverWithExport(SmtEngine* smte,
+ ExprManager* em,
ExprManagerMapCollection& varMap,
Node query,
bool needsTimeout,
@@ -62,14 +61,13 @@ void initializeSubsolverWithExport(std::unique_ptr<SmtEngine>& smte,
// OptionException.
try
{
- smte.reset(new SmtEngine(&em));
smte->setIsInternalSubsolver();
if (needsTimeout)
{
smte->setTimeLimit(timeout, true);
}
smte->setLogic(smt::currentSmtEngine()->getLogicInfo());
- Expr equery = query.toExpr().exportTo(&em, varMap);
+ Expr equery = query.toExpr().exportTo(em, varMap);
smte->assertFormula(equery);
}
catch (const CVC4::ExportUnsupportedException& e)
@@ -82,13 +80,13 @@ void initializeSubsolverWithExport(std::unique_ptr<SmtEngine>& smte,
}
}
-void initializeSubsolver(std::unique_ptr<SmtEngine>& smte, Node query)
+void initializeSubsolver(SmtEngine* smte, Node query)
{
initializeSubsolver(smte);
smte->assertFormula(query.toExpr());
}
-Result checkWithSubsolver(std::unique_ptr<SmtEngine>& smte, Node query)
+Result checkWithSubsolver(SmtEngine* smte, Node query)
{
Assert(query.getType().isBoolean());
Result r = quickCheck(query);
@@ -130,19 +128,33 @@ Result checkWithSubsolver(Node query,
}
return r;
}
- std::unique_ptr<SmtEngine> smte;
+
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ // This is only temporarily until we have separate options for each
+ // SmtEngine instance. We should reuse the same ExprManager with
+ // a different SmtEngine (and different options) here, eventually.
+ // !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+ std::unique_ptr<SmtEngine> simpleSmte;
+ std::unique_ptr<api::Solver> slv;
+ ExprManager* em = nullptr;
+ SmtEngine* smte = nullptr;
ExprManagerMapCollection varMap;
NodeManager* nm = NodeManager::currentNM();
- ExprManager em(nm->getOptions());
bool needsExport = false;
if (needsTimeout)
{
+ slv.reset(new api::Solver(&nm->getOptions()));
+ em = slv->getExprManager();
+ smte = slv->getSmtEngine();
needsExport = true;
initializeSubsolverWithExport(
smte, em, varMap, query, needsTimeout, timeout);
}
else
{
+ em = nm->toExprManager();
+ simpleSmte.reset(new SmtEngine(em));
+ smte = simpleSmte.get();
initializeSubsolver(smte, query);
}
r = smte->checkSat();
@@ -153,7 +165,7 @@ Result checkWithSubsolver(Node query,
Expr val;
if (needsExport)
{
- Expr ev = v.toExpr().exportTo(&em, varMap);
+ Expr ev = v.toExpr().exportTo(em, varMap);
val = smte->getValue(ev).exportTo(nm->toExprManager(), varMap);
}
else
diff --git a/src/theory/smt_engine_subsolver.h b/src/theory/smt_engine_subsolver.h
index 23308e12e..b606657bb 100644
--- a/src/theory/smt_engine_subsolver.h
+++ b/src/theory/smt_engine_subsolver.h
@@ -34,7 +34,7 @@ namespace theory {
* This function initializes the smt engine smte as a subsolver, e.g. it
* creates a new SMT engine and sets the options of the current SMT engine.
*/
-void initializeSubsolver(std::unique_ptr<SmtEngine>& smte);
+void initializeSubsolver(SmtEngine* smte);
/**
* Initialize Smt subsolver with exporting
@@ -52,14 +52,14 @@ void initializeSubsolver(std::unique_ptr<SmtEngine>& smte);
* manager.
*
* @param smte The smt engine pointer to initialize
- * @param em Reference to the expression manager to use
+ * @param em Reference to the expression manager used by smte
* @param varMap Map used for exporting expressions
* @param query The query to check
* @param needsTimeout Whether we would like to set a timeout
* @param timeout The timeout (in milliseconds)
*/
-void initializeSubsolverWithExport(std::unique_ptr<SmtEngine>& smte,
- ExprManager& em,
+void initializeSubsolverWithExport(SmtEngine* smte,
+ ExprManager* em,
ExprManagerMapCollection& varMap,
Node query,
bool needsTimeout = false,
@@ -73,7 +73,7 @@ void initializeSubsolverWithExport(std::unique_ptr<SmtEngine>& smte,
* exporting since the Options and ExprManager are tied together.
* TODO: eliminate this dependency (cvc4-projects #120).
*/
-void initializeSubsolver(std::unique_ptr<SmtEngine>& smte, Node query);
+void initializeSubsolver(SmtEngine* smte, Node query);
/**
* This returns the result of checking the satisfiability of formula query.
@@ -81,7 +81,7 @@ void initializeSubsolver(std::unique_ptr<SmtEngine>& smte, Node query);
* If necessary, smte is initialized to the SMT engine that checked its
* satisfiability.
*/
-Result checkWithSubsolver(std::unique_ptr<SmtEngine>& smte, Node query);
+Result checkWithSubsolver(SmtEngine* smte, Node query);
/**
* This returns the result of checking the satisfiability of formula query.
diff --git a/src/theory/strings/regexp_entail.cpp b/src/theory/strings/regexp_entail.cpp
index f005b2b42..7e1f42f37 100644
--- a/src/theory/strings/regexp_entail.cpp
+++ b/src/theory/strings/regexp_entail.cpp
@@ -48,6 +48,8 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
do_next = false;
Node xc = mchildren[mchildren.size() - 1];
Node rc = children[children.size() - 1];
+ Trace("regexp-ext-rewrite-debug")
+ << "* " << xc << " in " << rc << std::endl;
Assert(rc.getKind() != REGEXP_CONCAT);
Assert(xc.getKind() != STRING_CONCAT);
if (rc.getKind() == STRING_TO_REGEXP)
@@ -57,7 +59,15 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
children.pop_back();
mchildren.pop_back();
do_next = true;
- Trace("regexp-ext-rewrite-debug") << "...strip equal" << std::endl;
+ Trace("regexp-ext-rewrite-debug") << "- strip equal" << std::endl;
+ }
+ else if (rc[0].isConst() && Word::isEmpty(rc[0]))
+ {
+ Trace("regexp-ext-rewrite-debug")
+ << "- ignore empty RE" << std::endl;
+ // ignore and continue
+ children.pop_back();
+ do_next = true;
}
else if (xc.isConst() && rc[0].isConst())
{
@@ -65,8 +75,8 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
size_t index;
Node s = Word::splitConstant(xc, rc[0], index, t == 0);
Trace("regexp-ext-rewrite-debug")
- << "CRE: Regexp const split : " << xc << " " << rc[0] << " -> "
- << s << " " << index << " " << t << std::endl;
+ << "- CRE: Regexp const split : " << xc << " " << rc[0]
+ << " -> " << s << " " << index << " " << t << std::endl;
if (s.isNull())
{
Trace("regexp-ext-rewrite-debug")
@@ -76,7 +86,7 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
else
{
Trace("regexp-ext-rewrite-debug")
- << "...strip equal const" << std::endl;
+ << "- strip equal const" << std::endl;
children.pop_back();
mchildren.pop_back();
if (index == 0)
@@ -88,6 +98,7 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
children.push_back(nm->mkNode(STRING_TO_REGEXP, s));
}
}
+ Trace("regexp-ext-rewrite-debug") << "- split const" << std::endl;
do_next = true;
}
}
@@ -97,7 +108,7 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
CVC4::String s = xc.getConst<String>();
if (Word::isEmpty(xc))
{
- Trace("regexp-ext-rewrite-debug") << "...ignore empty" << std::endl;
+ Trace("regexp-ext-rewrite-debug") << "- ignore empty" << std::endl;
// ignore and continue
mchildren.pop_back();
do_next = true;
@@ -127,6 +138,8 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
}
else
{
+ Trace("regexp-ext-rewrite-debug")
+ << "...return false" << std::endl;
return nm->mkConst(false);
}
}
@@ -135,19 +148,23 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
// see if any/each child does not work
bool result_valid = true;
Node result;
- Node emp_s = nm->mkConst(::CVC4::String(""));
+ Node emp_s = nm->mkConst(String(""));
for (unsigned i = 0; i < rc.getNumChildren(); i++)
{
std::vector<Node> mchildren_s;
std::vector<Node> children_s;
mchildren_s.push_back(xc);
utils::getConcat(rc[i], children_s);
+ Trace("regexp-ext-rewrite-debug") << push;
Node ret = simpleRegexpConsume(mchildren_s, children_s, t);
+ Trace("regexp-ext-rewrite-debug") << pop;
if (!ret.isNull())
{
// one conjunct cannot be satisfied, return false
if (rc.getKind() == REGEXP_INTER)
{
+ Trace("regexp-ext-rewrite-debug")
+ << "...return " << ret << std::endl;
return ret;
}
}
@@ -182,10 +199,15 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
{
// all disjuncts cannot be satisfied, return false
Assert(rc.getKind() == REGEXP_UNION);
+ Trace("regexp-ext-rewrite-debug")
+ << "...return false" << std::endl;
return nm->mkConst(false);
}
else
{
+ Trace("regexp-ext-rewrite-debug")
+ << "- same result, try again, children now " << children
+ << std::endl;
// all branches led to the same result
children.pop_back();
mchildren.pop_back();
@@ -210,17 +232,19 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
std::vector<Node> children_s;
utils::getConcat(rc[0], children_s);
Trace("regexp-ext-rewrite-debug")
- << "...recursive call on body of star" << std::endl;
+ << "- recursive call on body of star" << std::endl;
+ Trace("regexp-ext-rewrite-debug") << push;
Node ret = simpleRegexpConsume(mchildren_s, children_s, t);
+ Trace("regexp-ext-rewrite-debug") << pop;
if (!ret.isNull())
{
Trace("regexp-ext-rewrite-debug")
- << "CRE : regexp star infeasable " << xc << " " << rc
+ << "- CRE : regexp star infeasable " << xc << " " << rc
<< std::endl;
children.pop_back();
if (!children.empty())
{
- Trace("regexp-ext-rewrite-debug") << "...continue" << std::endl;
+ Trace("regexp-ext-rewrite-debug") << "- continue" << std::endl;
do_next = true;
}
}
@@ -244,16 +268,22 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
std::reverse(mchildren_ss.begin(), mchildren_ss.end());
std::reverse(children_ss.begin(), children_ss.end());
}
- if (simpleRegexpConsume(mchildren_ss, children_ss, t)
- .isNull())
+ Trace("regexp-ext-rewrite-debug")
+ << "- recursive call required repeat star" << std::endl;
+ Trace("regexp-ext-rewrite-debug") << push;
+ Node rets = simpleRegexpConsume(mchildren_ss, children_ss, t);
+ Trace("regexp-ext-rewrite-debug") << pop;
+ if (rets.isNull())
{
can_skip = true;
}
}
if (!can_skip)
{
+ TypeNode stype = nm->stringType();
+ Node prev = utils::mkConcat(mchildren, stype);
Trace("regexp-ext-rewrite-debug")
- << "...can't skip" << std::endl;
+ << "- can't skip" << std::endl;
// take the result of fully consuming once
if (t == 1)
{
@@ -262,12 +292,15 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
mchildren.clear();
mchildren.insert(
mchildren.end(), mchildren_s.begin(), mchildren_s.end());
- do_next = true;
+ Node curr = utils::mkConcat(mchildren, stype);
+ do_next = (prev != curr);
+ Trace("regexp-ext-rewrite-debug")
+ << "- do_next = " << do_next << std::endl;
}
else
{
Trace("regexp-ext-rewrite-debug")
- << "...can skip " << rc << " from " << xc << std::endl;
+ << "- can skip " << rc << " from " << xc << std::endl;
}
}
}
@@ -276,7 +309,7 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
if (!do_next)
{
Trace("regexp-ext-rewrite")
- << "Cannot consume : " << xc << " " << rc << std::endl;
+ << "- cannot consume : " << xc << " " << rc << std::endl;
}
}
}
@@ -286,6 +319,7 @@ Node RegExpEntail::simpleRegexpConsume(std::vector<Node>& mchildren,
std::reverse(mchildren.begin(), mchildren.end());
}
}
+ Trace("regexp-ext-rewrite-debug") << "...finished, return null" << std::endl;
return Node::null();
}
diff --git a/src/theory/strings/sequences_rewriter.cpp b/src/theory/strings/sequences_rewriter.cpp
index 9df03f32c..20b892d0f 100644
--- a/src/theory/strings/sequences_rewriter.cpp
+++ b/src/theory/strings/sequences_rewriter.cpp
@@ -1315,9 +1315,13 @@ Node SequencesRewriter::rewriteMembership(TNode node)
}
else
{
+ Node prev = retNode;
retNode = nm->mkNode(
STRING_IN_REGEXP, utils::mkConcat(mchildren, stype), r);
- success = true;
+ // Iterate again if the node changed. It may not have changed if
+ // nothing was consumed from mchildren (e.g. if the body of the
+ // re.* accepts the empty string.
+ success = (retNode != prev);
}
}
}
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
index eba5fb8c9..028288dbc 100644
--- a/src/util/CMakeLists.txt
+++ b/src/util/CMakeLists.txt
@@ -17,6 +17,7 @@ libcvc4_add_sources(
floatingpoint.cpp
gmp_util.h
hash.h
+ iand.h
index.cpp
index.h
maybe.h
diff --git a/src/util/iand.h b/src/util/iand.h
new file mode 100644
index 000000000..b5bc92960
--- /dev/null
+++ b/src/util/iand.h
@@ -0,0 +1,47 @@
+/********************* */
+/*! \file iand.h
+ ** \verbatim
+ ** Top contributors (to current version):
+ ** Anrew Reynolds
+ ** This file is part of the CVC4 project.
+ ** Copyright (c) 2009-2019 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.\endverbatim
+ **
+ ** \brief The integer AND operator.
+ **/
+
+#include "cvc4_public.h"
+
+#ifndef CVC4__IAND_H
+#define CVC4__IAND_H
+
+#include <cstdint>
+#include <iosfwd>
+
+#include "base/exception.h"
+#include "util/integer.h"
+
+namespace CVC4 {
+
+struct CVC4_PUBLIC IntAnd
+{
+ unsigned d_size;
+ IntAnd(unsigned size) : d_size(size) {}
+ operator unsigned() const { return d_size; }
+}; /* struct IntAnd */
+
+/* -----------------------------------------------------------------------
+ ** Output stream
+ * ----------------------------------------------------------------------- */
+
+inline std::ostream& operator<<(std::ostream& os, const IntAnd& ia) CVC4_PUBLIC;
+inline std::ostream& operator<<(std::ostream& os, const IntAnd& ia)
+{
+ return os << "[" << ia.d_size << "]";
+}
+
+} // namespace CVC4
+
+#endif /* CVC4__IAND_H */
diff --git a/src/util/iand.i b/src/util/iand.i
new file mode 100644
index 000000000..92c5a1223
--- /dev/null
+++ b/src/util/iand.i
@@ -0,0 +1,9 @@
+%{
+#include "util/iand.h"
+%}
+
+%rename(toUnsigned) CVC4::IntAnd::operator unsigned() const;
+
+%ignore CVC4::operator<<(std::ostream&, const IntAnd&);
+
+%include "util/iand.h"
diff --git a/test/regress/CMakeLists.txt b/test/regress/CMakeLists.txt
index 7863c5ec0..9a58457e6 100644
--- a/test/regress/CMakeLists.txt
+++ b/test/regress/CMakeLists.txt
@@ -966,6 +966,7 @@ set(regress_0_tests
regress0/strings/issue3657-evalLeq.smt2
regress0/strings/issue4070.smt2
regress0/strings/issue4376.smt2
+ regress0/strings/issue4662-consume-nterm.smt2
regress0/strings/itos-entail.smt2
regress0/strings/large-model.smt2
regress0/strings/leadingzero001.smt2
@@ -1526,6 +1527,7 @@ set(regress_1_tests
regress1/quantifiers/dump-inst-i.smt2
regress1/quantifiers/dump-inst-proof.smt2
regress1/quantifiers/dump-inst.smt2
+ regress1/quantifiers/eqrange_ex_1.smt2
regress1/quantifiers/ext-ex-deq-trigger.smt2
regress1/quantifiers/extract-nproc.smt2
regress1/quantifiers/f993-loss-easy.smt2
diff --git a/test/regress/regress0/strings/issue4662-consume-nterm.smt2 b/test/regress/regress0/strings/issue4662-consume-nterm.smt2
new file mode 100644
index 000000000..a87279b4c
--- /dev/null
+++ b/test/regress/regress0/strings/issue4662-consume-nterm.smt2
@@ -0,0 +1,6 @@
+(set-logic QF_S)
+(set-info :status unsat)
+(declare-fun a () String)
+(define-fun b () RegLan (str.to_re "A"))
+(assert (str.in_re (str.++ "B" a) (re.+ (re.++ (re.opt b) (re.opt b)))))
+(check-sat)
diff --git a/test/regress/regress1/quantifiers/eqrange_ex_1.smt2 b/test/regress/regress1/quantifiers/eqrange_ex_1.smt2
new file mode 100644
index 000000000..ca53d7cf5
--- /dev/null
+++ b/test/regress/regress1/quantifiers/eqrange_ex_1.smt2
@@ -0,0 +1,160 @@
+(set-logic ALL)
+(set-info :status unsat)
+(set-option :produce-models true)
+(define-fun even_parity ((v (_ BitVec 8))) Bool (= (bvxor ((_ extract 0 0) v) ((_ extract 1 1) v) ((_ extract 2 2) v) ((_ extract 3 3) v) ((_ extract 4 4) v) ((_ extract 5 5) v) ((_ extract 6 6) v) ((_ extract 7 7) v)) #b0))
+(define-fun mem_readbv64 ((m (Array (_ BitVec 64) (_ BitVec 8))) (a (_ BitVec 64))) (_ BitVec 64) (concat (select m (bvadd a (_ bv7 64))) (concat (select m (bvadd a (_ bv6 64))) (concat (select m (bvadd a (_ bv5 64))) (concat (select m (bvadd a (_ bv4 64))) (concat (select m (bvadd a (_ bv3 64))) (concat (select m (bvadd a (_ bv2 64))) (concat (select m (bvadd a (_ bv1 64))) (select m a)))))))))
+(define-fun mem_writebv32 ((m (Array (_ BitVec 64) (_ BitVec 8))) (a (_ BitVec 64)) (v (_ BitVec 32))) (Array (_ BitVec 64) (_ BitVec 8)) (store (store (store (store m a ((_ extract 7 0) v)) (bvadd a (_ bv1 64)) ((_ extract 15 8) v)) (bvadd a (_ bv2 64)) ((_ extract 23 16) v)) (bvadd a (_ bv3 64)) ((_ extract 31 24) v)))
+(define-fun mem_writebv64 ((m (Array (_ BitVec 64) (_ BitVec 8))) (a (_ BitVec 64)) (v (_ BitVec 64))) (Array (_ BitVec 64) (_ BitVec 8)) (store (store (store (store (store (store (store (store m a ((_ extract 7 0) v)) (bvadd a (_ bv1 64)) ((_ extract 15 8) v)) (bvadd a (_ bv2 64)) ((_ extract 23 16) v)) (bvadd a (_ bv3 64)) ((_ extract 31 24) v)) (bvadd a (_ bv4 64)) ((_ extract 39 32) v)) (bvadd a (_ bv5 64)) ((_ extract 47 40) v)) (bvadd a (_ bv6 64)) ((_ extract 55 48) v)) (bvadd a (_ bv7 64)) ((_ extract 63 56) v)))
+(declare-fun fnstart_rcx () (_ BitVec 64))
+(declare-fun fnstart_rdx () (_ BitVec 64))
+(declare-fun fnstart_rbx () (_ BitVec 64))
+(declare-fun fnstart_rsp () (_ BitVec 64))
+(declare-fun fnstart_rbp () (_ BitVec 64))
+(declare-fun fnstart_rsi () (_ BitVec 64))
+(declare-fun fnstart_rdi () (_ BitVec 64))
+(declare-fun fnstart_r8 () (_ BitVec 64))
+(declare-fun fnstart_r9 () (_ BitVec 64))
+(declare-fun fnstart_r12 () (_ BitVec 64))
+(declare-fun fnstart_r13 () (_ BitVec 64))
+(declare-fun fnstart_r14 () (_ BitVec 64))
+(declare-fun fnstart_r15 () (_ BitVec 64))
+(declare-const stack_alloc_min (_ BitVec 64))
+(assert (= (bvand stack_alloc_min #x0000000000000fff) (_ bv0 64)))
+(assert (bvult (_ bv4096 64) stack_alloc_min))
+(define-fun stack_guard_min () (_ BitVec 64) (bvsub stack_alloc_min (_ bv4096 64)))
+(assert (bvult stack_guard_min stack_alloc_min))
+(declare-const stack_max (_ BitVec 64))
+(assert (= (bvand stack_max #x0000000000000fff) (_ bv0 64)))
+(assert (bvult stack_alloc_min stack_max))
+(assert (bvule stack_alloc_min fnstart_rsp))
+(assert (bvule fnstart_rsp (bvsub stack_max (_ bv8 64))))
+(define-fun on_stack ((a (_ BitVec 64)) (sz (_ BitVec 64))) Bool (let ((e (bvadd a sz))) (and (bvule stack_guard_min a) (bvule a e) (bvule e stack_max))))
+(define-fun not_in_stack_range ((a (_ BitVec 64)) (sz (_ BitVec 64))) Bool (let ((e (bvadd a sz))) (and (bvule a e) (or (bvule e stack_alloc_min) (bvule stack_max a)))))
+(assert (bvult fnstart_rsp (bvsub stack_max (_ bv8 64))))
+(assert (= ((_ extract 3 0) fnstart_rsp) (_ bv8 4)))
+(define-fun mc_only_stack_range ((a (_ BitVec 64)) (sz (_ BitVec 64))) Bool (let ((e (bvadd a sz))) (on_stack a sz)))
+(define-fun a201340_rip () (_ BitVec 64) #x0000000000201340)
+(declare-fun a201340_rax () (_ BitVec 64))
+(define-fun a201340_rcx () (_ BitVec 64) fnstart_rcx)
+(define-fun a201340_rdx () (_ BitVec 64) fnstart_rdx)
+(define-fun a201340_rbx () (_ BitVec 64) fnstart_rbx)
+(define-fun a201340_rsp () (_ BitVec 64) fnstart_rsp)
+(define-fun a201340_rbp () (_ BitVec 64) fnstart_rbp)
+(define-fun a201340_rsi () (_ BitVec 64) fnstart_rsi)
+(define-fun a201340_rdi () (_ BitVec 64) fnstart_rdi)
+(define-fun a201340_r8 () (_ BitVec 64) fnstart_r8)
+(define-fun a201340_r9 () (_ BitVec 64) fnstart_r9)
+(declare-fun a201340_r10 () (_ BitVec 64))
+(declare-fun a201340_r11 () (_ BitVec 64))
+(define-fun a201340_r12 () (_ BitVec 64) fnstart_r12)
+(define-fun a201340_r13 () (_ BitVec 64) fnstart_r13)
+(define-fun a201340_r14 () (_ BitVec 64) fnstart_r14)
+(define-fun a201340_r15 () (_ BitVec 64) fnstart_r15)
+(declare-fun a201340_cf () Bool)
+(declare-fun a201340_pf () Bool)
+(declare-fun a201340_af () Bool)
+(declare-fun a201340_zf () Bool)
+(declare-fun a201340_sf () Bool)
+(declare-fun a201340_tf () Bool)
+(declare-fun a201340_if () Bool)
+(define-fun a201340_df () Bool false)
+(declare-fun a201340_of () Bool)
+(declare-fun a201340_ie () Bool)
+(declare-fun a201340_de () Bool)
+(declare-fun a201340_ze () Bool)
+(declare-fun a201340_oe () Bool)
+(declare-fun a201340_ue () Bool)
+(declare-fun a201340_pe () Bool)
+(declare-fun a201340_ef () Bool)
+(declare-fun a201340_es () Bool)
+(declare-fun a201340_c0 () Bool)
+(declare-fun a201340_c1 () Bool)
+(declare-fun a201340_c2 () Bool)
+(declare-fun a201340_RESERVED_STATUS_11 () Bool)
+(declare-fun a201340_RESERVED_STATUS_12 () Bool)
+(declare-fun a201340_RESERVED_STATUS_13 () Bool)
+(declare-fun a201340_c3 () Bool)
+(declare-fun a201340_RESERVED_STATUS_15 () Bool)
+(define-fun a201340_x87top () (_ BitVec 3) (_ bv7 3))
+(declare-fun a201340_tag0 () (_ BitVec 2))
+(declare-fun a201340_tag1 () (_ BitVec 2))
+(declare-fun a201340_tag2 () (_ BitVec 2))
+(declare-fun a201340_tag3 () (_ BitVec 2))
+(declare-fun a201340_tag4 () (_ BitVec 2))
+(declare-fun a201340_tag5 () (_ BitVec 2))
+(declare-fun a201340_tag6 () (_ BitVec 2))
+(declare-fun a201340_tag7 () (_ BitVec 2))
+(declare-fun a201340_mm0 () (_ BitVec 80))
+(declare-fun a201340_mm1 () (_ BitVec 80))
+(declare-fun a201340_mm2 () (_ BitVec 80))
+(declare-fun a201340_mm3 () (_ BitVec 80))
+(declare-fun a201340_mm4 () (_ BitVec 80))
+(declare-fun a201340_mm5 () (_ BitVec 80))
+(declare-fun a201340_mm6 () (_ BitVec 80))
+(declare-fun a201340_mm7 () (_ BitVec 80))
+(declare-fun a201340_zmm0 () (_ BitVec 512))
+(declare-fun a201340_zmm1 () (_ BitVec 512))
+(declare-fun a201340_zmm2 () (_ BitVec 512))
+(declare-fun a201340_zmm3 () (_ BitVec 512))
+(declare-fun a201340_zmm4 () (_ BitVec 512))
+(declare-fun a201340_zmm5 () (_ BitVec 512))
+(declare-fun a201340_zmm6 () (_ BitVec 512))
+(declare-fun a201340_zmm7 () (_ BitVec 512))
+(declare-fun a201340_zmm8 () (_ BitVec 512))
+(declare-fun a201340_zmm9 () (_ BitVec 512))
+(declare-fun a201340_zmm10 () (_ BitVec 512))
+(declare-fun a201340_zmm11 () (_ BitVec 512))
+(declare-fun a201340_zmm12 () (_ BitVec 512))
+(declare-fun a201340_zmm13 () (_ BitVec 512))
+(declare-fun a201340_zmm14 () (_ BitVec 512))
+(declare-fun a201340_zmm15 () (_ BitVec 512))
+(declare-fun a201340_zmm16 () (_ BitVec 512))
+(declare-fun a201340_zmm17 () (_ BitVec 512))
+(declare-fun a201340_zmm18 () (_ BitVec 512))
+(declare-fun a201340_zmm19 () (_ BitVec 512))
+(declare-fun a201340_zmm20 () (_ BitVec 512))
+(declare-fun a201340_zmm21 () (_ BitVec 512))
+(declare-fun a201340_zmm22 () (_ BitVec 512))
+(declare-fun a201340_zmm23 () (_ BitVec 512))
+(declare-fun a201340_zmm24 () (_ BitVec 512))
+(declare-fun a201340_zmm25 () (_ BitVec 512))
+(declare-fun a201340_zmm26 () (_ BitVec 512))
+(declare-fun a201340_zmm27 () (_ BitVec 512))
+(declare-fun a201340_zmm28 () (_ BitVec 512))
+(declare-fun a201340_zmm29 () (_ BitVec 512))
+(declare-fun a201340_zmm30 () (_ BitVec 512))
+(declare-fun a201340_zmm31 () (_ BitVec 512))
+(declare-const x86mem_0 (Array (_ BitVec 64) (_ BitVec 8)))
+(define-fun return_addr () (_ BitVec 64) (mem_readbv64 x86mem_0 fnstart_rsp))
+(assert (= a201340_rbx fnstart_rbx))
+(assert (= a201340_rsp fnstart_rsp))
+(assert (= a201340_rbp fnstart_rbp))
+(assert (= a201340_r12 fnstart_r12))
+(assert (= a201340_r13 fnstart_r13))
+(assert (= a201340_r14 fnstart_r14))
+(assert (= a201340_r15 fnstart_r15))
+; LLVM: %t0 = call i64 (i64) @add(i64 42)
+(define-fun x86local_0 () (_ BitVec 64) (bvsub a201340_rsp (_ bv8 64)))
+(assert (mc_only_stack_range x86local_0 (_ bv8 64)))
+(define-fun x86mem_1 () (Array (_ BitVec 64) (_ BitVec 8)) (mem_writebv64 x86mem_0 x86local_0 a201340_rbp))
+(define-fun x86local_1 () Bool (distinct ((_ extract 64 64) (bvsub (bvsub ((_ sign_extend 1) x86local_0) (bvneg ((_ sign_extend 1) (_ bv16 64)))) (ite false (_ bv1 65) (_ bv0 65)))) ((_ extract 63 63) (bvsub (bvsub ((_ sign_extend 1) x86local_0) (bvneg ((_ sign_extend 1) (_ bv16 64)))) (ite false (_ bv1 65) (_ bv0 65))))))
+(define-fun x86local_2 () Bool (bvult x86local_0 (_ bv16 64)))
+(define-fun x86local_3 () (_ BitVec 64) (bvsub x86local_0 (_ bv16 64)))
+(define-fun x86local_4 () Bool (bvslt x86local_3 (_ bv0 64)))
+(define-fun x86local_5 () Bool (= x86local_3 (_ bv0 64)))
+(define-fun x86local_6 () (_ BitVec 8) ((_ extract 7 0) x86local_3))
+(define-fun x86local_7 () Bool (even_parity x86local_6))
+(define-fun x86local_8 () (_ BitVec 64) (bvadd x86local_0 (_ bv18446744073709551612 64)))
+(assert (mc_only_stack_range x86local_8 (_ bv4 64)))
+(define-fun x86mem_2 () (Array (_ BitVec 64) (_ BitVec 8)) (mem_writebv32 x86mem_1 x86local_8 (_ bv0 32)))
+(define-fun x86local_9 () (_ BitVec 64) (bvsub x86local_3 (_ bv8 64)))
+(assert (mc_only_stack_range x86local_9 (_ bv8 64)))
+(define-fun x86mem_3 () (Array (_ BitVec 64) (_ BitVec 8)) (mem_writebv64 x86mem_2 x86local_9 #x0000000000201359))
+(assert (= #x0000000000201320 #x0000000000201320))
+(assert (= (_ bv42 64) (_ bv42 64)))
+(assert (= (mem_readbv64 x86mem_3 x86local_9) #x0000000000201359))
+(declare-const x86mem_4 (Array (_ BitVec 64) (_ BitVec 8)))
+(assert (eqrange x86mem_4 x86mem_3 (bvadd x86local_9 (_ bv8 64)) (bvadd fnstart_rsp (_ bv7 64))))
+; LLVM: br label %block_0_201359
+(check-sat-assuming ((not (= (mem_readbv64 x86mem_4 (bvsub fnstart_rsp (_ bv8 64))) fnstart_rbp))))
+(exit)
diff --git a/test/system/CMakeLists.txt b/test/system/CMakeLists.txt
index 420ce8e6f..041d14295 100644
--- a/test/system/CMakeLists.txt
+++ b/test/system/CMakeLists.txt
@@ -32,5 +32,5 @@ cvc4_add_system_test(reset_assertions)
cvc4_add_system_test(sep_log_api)
cvc4_add_system_test(smt2_compliance)
cvc4_add_system_test(statistics)
-cvc4_add_system_test(two_smt_engines)
+cvc4_add_system_test(two_solvers)
# TODO: Move CVC4JavaTest.java to test/java and delete run_java_test (after full cmake migration)
diff --git a/test/system/boilerplate.cpp b/test/system/boilerplate.cpp
index 93f5dceb8..315cec7bf 100644
--- a/test/system/boilerplate.cpp
+++ b/test/system/boilerplate.cpp
@@ -19,18 +19,14 @@
#include <iostream>
#include <sstream>
-#include "expr/expr.h"
-#include "smt/smt_engine.h"
+#include "api/cvc4cpp.h"
-using namespace CVC4;
+using namespace CVC4::api;
using namespace std;
int main() {
- ExprManager em;
- Options opts;
- SmtEngine smt(&em);
- Result r = smt.checkEntailed(em.mkConst(true));
-
- return (Result::ENTAILED == r) ? 0 : 1;
+ Solver slv;
+ Result r = slv.checkEntailed(slv.mkBoolean(true));
+ return r.isEntailed() ? 0 : 1;
}
diff --git a/test/system/reset_assertions.cpp b/test/system/reset_assertions.cpp
index 2a94dbd98..dc9bd24f6 100644
--- a/test/system/reset_assertions.cpp
+++ b/test/system/reset_assertions.cpp
@@ -20,34 +20,31 @@
#include <iostream>
#include <sstream>
-#include "expr/expr.h"
-#include "smt/smt_engine.h"
+#include "api/cvc4cpp.h"
-using namespace CVC4;
+using namespace CVC4::api;
int main()
{
- ExprManager em;
- SmtEngine smt(&em);
-
- smt.setOption("incremental", SExpr(true));
-
- Type real = em.realType();
- Expr x = em.mkVar("x", real);
- Expr four = em.mkConst(Rational(4));
- Expr xEqFour = em.mkExpr(Kind::EQUAL, x, four);
- smt.assertFormula(xEqFour);
- std::cout << smt.checkSat() << std::endl;
-
- smt.resetAssertions();
-
- Type elementType = em.integerType();
- Type indexType = em.integerType();
- Type arrayType = em.mkArrayType(indexType, elementType);
- Expr array = em.mkVar("array", arrayType);
- Expr arrayAtFour = em.mkExpr(Kind::SELECT, array, four);
- Expr ten = em.mkConst(Rational(10));
- Expr arrayAtFour_eq_ten = em.mkExpr(Kind::EQUAL, arrayAtFour, ten);
- smt.assertFormula(arrayAtFour_eq_ten);
- std::cout << smt.checkSat() << std::endl;
+ Solver slv;
+ slv.setOption("incremental", "true");
+
+ Sort real = slv.getRealSort();
+ Term x = slv.mkConst(real, "x");
+ Term four = slv.mkReal(4);
+ Term xEqFour = slv.mkTerm(Kind::EQUAL, x, four);
+ slv.assertFormula(xEqFour);
+ std::cout << slv.checkSat() << std::endl;
+
+ slv.resetAssertions();
+
+ Sort elementType = slv.getIntegerSort();
+ Sort indexType = slv.getIntegerSort();
+ Sort arrayType = slv.mkArraySort(indexType, elementType);
+ Term array = slv.mkConst(arrayType, "array");
+ Term arrayAtFour = slv.mkTerm(Kind::SELECT, array, four);
+ Term ten = slv.mkReal(10);
+ Term arrayAtFour_eq_ten = slv.mkTerm(Kind::EQUAL, arrayAtFour, ten);
+ slv.assertFormula(arrayAtFour_eq_ten);
+ std::cout << slv.checkSat() << std::endl;
}
diff --git a/test/system/statistics.cpp b/test/system/statistics.cpp
index 025aaed11..234246112 100644
--- a/test/system/statistics.cpp
+++ b/test/system/statistics.cpp
@@ -15,48 +15,52 @@
** minimally functional.
**/
+#include "util/statistics.h"
+
#include <iostream>
#include <sstream>
+#include "api/cvc4cpp.h"
#include "expr/expr.h"
#include "smt/smt_engine.h"
#include "util/sexpr.h"
-#include "util/statistics.h"
using namespace CVC4;
using namespace std;
int main() {
- ExprManager em;
- Options opts;
- SmtEngine smt(&em);
- smt.setOption("incremental", SExpr("true"));
- Expr x = em.mkVar("x", em.integerType());
- Expr y = em.mkVar("y", em.integerType());
- smt.assertFormula(em.mkExpr(kind::GT, em.mkExpr(kind::PLUS, x, y), em.mkConst(Rational(5))));
- Expr q = em.mkExpr(kind::GT, x, em.mkConst(Rational(0)));
- Result r = smt.checkEntailed(q);
+ api::Solver slv;
+ ExprManager* em = slv.getExprManager();
+ SmtEngine* smt = slv.getSmtEngine();
+ smt->setOption("incremental", SExpr("true"));
+ Expr x = em->mkVar("x", em->integerType());
+ Expr y = em->mkVar("y", em->integerType());
+ smt->assertFormula(em->mkExpr(
+ kind::GT, em->mkExpr(kind::PLUS, x, y), em->mkConst(Rational(5))));
+ Expr q = em->mkExpr(kind::GT, x, em->mkConst(Rational(0)));
+ Result r = smt->checkEntailed(q);
if (r != Result::NOT_ENTAILED)
{
exit(1);
}
- Statistics stats = smt.getStatistics();
+ Statistics stats = smt->getStatistics();
for(Statistics::iterator i = stats.begin(); i != stats.end(); ++i) {
cout << "stat " << (*i).first << " is " << (*i).second << endl;
}
- smt.assertFormula(em.mkExpr(kind::LT, y, em.mkConst(Rational(5))));
- r = smt.checkEntailed(q);
- Statistics stats2 = smt.getStatistics();
+ smt->assertFormula(em->mkExpr(kind::LT, y, em->mkConst(Rational(5))));
+ r = smt->checkEntailed(q);
+ Statistics stats2 = smt->getStatistics();
bool different = false;
for(Statistics::iterator i = stats2.begin(); i != stats2.end(); ++i) {
cout << "stat1 " << (*i).first << " is " << stats.getStatistic((*i).first) << endl;
cout << "stat2 " << (*i).first << " is " << (*i).second << endl;
- if(smt.getStatistic((*i).first) != (*i).second) {
- cout << "SMT engine reports different value for statistic "
- << (*i).first << ": " << smt.getStatistic((*i).first) << endl;
+ if (smt->getStatistic((*i).first) != (*i).second)
+ {
+ cout << "SMT engine reports different value for statistic " << (*i).first
+ << ": " << smt->getStatistic((*i).first) << endl;
exit(1);
}
different = different || stats.getStatistic((*i).first) != (*i).second;
diff --git a/test/system/two_smt_engines.cpp b/test/system/two_solvers.cpp
index 71676482e..c5bea4860 100644
--- a/test/system/two_smt_engines.cpp
+++ b/test/system/two_solvers.cpp
@@ -17,20 +17,16 @@
#include <iostream>
#include <sstream>
-#include "expr/expr.h"
-#include "smt/smt_engine.h"
+#include "api/cvc4cpp.h"
-using namespace CVC4;
+using namespace CVC4::api;
using namespace std;
int main() {
- ExprManager em;
- Options opts;
- SmtEngine smt(&em);
- SmtEngine smt2(&em);
- Result r = smt.checkEntailed(em.mkConst(true));
- Result r2 = smt2.checkEntailed(em.mkConst(true));
-
- return r == Result::ENTAILED && r2 == Result::ENTAILED ? 0 : 1;
+ Solver s1;
+ Solver s2;
+ Result r = s1.checkEntailed(s1.mkBoolean(true));
+ Result r2 = s2.checkEntailed(s2.mkBoolean(true));
+ return r.isEntailed() && r2.isEntailed() ? 0 : 1;
}
diff --git a/test/unit/api/python/test_sort.py b/test/unit/api/python/test_sort.py
new file mode 100644
index 000000000..507aff2ae
--- /dev/null
+++ b/test/unit/api/python/test_sort.py
@@ -0,0 +1,322 @@
+import pytest
+
+import pycvc4
+from pycvc4 import kinds
+
+
+def testGetDatatype():
+ solver = pycvc4.Solver()
+ dtypeSpec = solver.mkDatatypeDecl("list")
+ cons = solver.mkDatatypeConstructorDecl("cons")
+ cons.addSelector("head", solver.getIntegerSort())
+ dtypeSpec.addConstructor(cons)
+ nil = solver.mkDatatypeConstructorDecl("nil")
+ dtypeSpec.addConstructor(nil)
+ dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+
+ # expecting no Error
+ dtypeSort.getDatatype()
+
+ bvSort = solver.mkBitVectorSort(32)
+ with pytest.raises(Exception):
+ # expect an exception
+ bvSort.getDatatype()
+
+
+def testDatatypeSorts():
+ solver = pycvc4.Solver()
+ intSort = solver.getIntegerSort()
+ # create datatype sort to test
+ dtypeSpec = solver.mkDatatypeDecl("list")
+ cons = solver.mkDatatypeConstructorDecl("cons")
+ cons.addSelector("head", intSort)
+ cons.addSelectorSelf("tail")
+ dtypeSpec.addConstructor(cons)
+ nil = solver.mkDatatypeConstructorDecl("nil")
+ dtypeSpec.addConstructor(nil)
+ dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+ dt = dtypeSort.getDatatype()
+ assert not dtypeSort.isConstructor()
+
+ with pytest.raises(Exception):
+ dtypeSort.getConstructorCodomainSort()
+
+ with pytest.raises(Exception):
+ dtypeSort.getConstructorDomainSorts()
+
+ with pytest.raises(Exception):
+ dtypeSort.getConstructorArity()
+
+ # get constructor
+ dcons = dt[0]
+ consTerm = dcons.getConstructorTerm()
+ consSort = consTerm.getSort()
+ assert consSort.isConstructor()
+ assert not consSort.isTester()
+ assert not consSort.isSelector()
+ assert consSort.getConstructorArity() == 2
+ consDomSorts = consSort.getConstructorDomainSorts()
+ assert consDomSorts[0] == intSort
+ assert consDomSorts[1] == dtypeSort
+ assert consSort.getConstructorCodomainSort() == dtypeSort
+
+ # get tester
+ isConsTerm = dcons.getTesterTerm()
+ assert isConsTerm.getSort().isTester()
+
+ # get selector
+ dselTail = dcons[1]
+ tailTerm = dselTail.getSelectorTerm()
+ assert tailTerm.getSort().isSelector()
+
+
+def testInstantiate():
+ solver = pycvc4.Solver()
+ # instantiate parametric datatype, check should not fail
+ sort = solver.mkParamSort("T")
+ paramDtypeSpec = solver.mkDatatypeDecl("paramlist", sort)
+ paramCons = solver.mkDatatypeConstructorDecl("cons")
+ paramNil = solver.mkDatatypeConstructorDecl("nil")
+ paramCons.addSelector("head", sort)
+ paramDtypeSpec.addConstructor(paramCons)
+ paramDtypeSpec.addConstructor(paramNil)
+ paramDtypeSort = solver.mkDatatypeSort(paramDtypeSpec)
+ paramDtypeSort.instantiate([solver.getIntegerSort()])
+
+ # instantiate non-parametric datatype sort, check should fail
+ dtypeSpec = solver.mkDatatypeDecl("list")
+ cons = solver.mkDatatypeConstructorDecl("cons")
+ cons.addSelector("head", solver.getIntegerSort())
+ dtypeSpec.addConstructor(cons)
+ nil = solver.mkDatatypeConstructorDecl("nil")
+ dtypeSpec.addConstructor(nil)
+ dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+
+ with pytest.raises(Exception):
+ dtypeSort.instantiate([solver.getIntegerSort()])
+
+
+def testGetFunctionArity():
+ solver = pycvc4.Solver()
+ funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
+ solver.getIntegerSort())
+ funSort.getFunctionArity()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getFunctionArity()
+
+
+def testGetFunctionDomainSorts():
+ solver = pycvc4.Solver()
+ funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
+ solver.getIntegerSort())
+ funSort.getFunctionDomainSorts()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getFunctionDomainSorts()
+
+
+def testGetFunctionCodomainSort():
+ solver = pycvc4.Solver()
+ funSort = solver.mkFunctionSort(solver.mkUninterpretedSort("u"),
+ solver.getIntegerSort())
+ funSort.getFunctionCodomainSort()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getFunctionCodomainSort()
+
+def testGetArrayIndexSort():
+ solver = pycvc4.Solver()
+ elementSort = solver.mkBitVectorSort(32)
+ indexSort = solver.mkBitVectorSort(32)
+ arraySort = solver.mkArraySort(indexSort, elementSort)
+ arraySort.getArrayIndexSort()
+
+ with pytest.raises(Exception):
+ indexSort.getArrayIndexSort()
+
+def testGetArrayElementSort():
+ solver = pycvc4.Solver()
+ elementSort = solver.mkBitVectorSort(32)
+ indexSort = solver.mkBitVectorSort(32)
+ arraySort = solver.mkArraySort(indexSort, elementSort)
+ arraySort.getArrayElementSort()
+
+ with pytest.raises(Exception):
+ indexSort.getArrayElementSort()
+
+def testGetSetElementSort():
+ solver = pycvc4.Solver()
+ setSort = solver.mkSetSort(solver.getIntegerSort())
+ setSort.getSetElementSort()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getSetElementSort()
+
+def testGetUninterpretedSortName():
+ solver = pycvc4.Solver()
+ uSort = solver.mkUninterpretedSort("u")
+ uSort.getUninterpretedSortName()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getUninterpretedSortName()
+
+def testIsUninterpretedSortParameterized():
+ solver = pycvc4.Solver()
+ uSort = solver.mkUninterpretedSort("u")
+ uSort.isUninterpretedSortParameterized()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.isUninterpretedSortParameterized()
+
+def testGetUninterpretedSortParamSorts():
+ solver = pycvc4.Solver()
+ uSort = solver.mkUninterpretedSort("u")
+ uSort.getUninterpretedSortParamSorts()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getUninterpretedSortParamSorts()
+
+def testGetUninterpretedSortConstructorName():
+ solver = pycvc4.Solver()
+ sSort = solver.mkSortConstructorSort("s", 2)
+ sSort.getSortConstructorName()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getSortConstructorName()
+
+def testGetUninterpretedSortConstructorArity():
+ solver = pycvc4.Solver()
+ sSort = solver.mkSortConstructorSort("s", 2)
+ sSort.getSortConstructorArity()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getSortConstructorArity()
+
+def testGetBVSize():
+ solver = pycvc4.Solver()
+ bvSort = solver.mkBitVectorSort(32)
+ bvSort.getBVSize()
+ setSort = solver.mkSetSort(solver.getIntegerSort())
+
+ with pytest.raises(Exception):
+ setSort.getBVSize()
+
+def testGetFPExponentSize():
+ solver = pycvc4.Solver()
+ fpSort = solver.mkFloatingPointSort(4, 8)
+ fpSort.getFPExponentSize()
+ setSort = solver.mkSetSort(solver.getIntegerSort())
+
+ with pytest.raises(Exception):
+ setSort.getFPExponentSize()
+
+def testGetFPSignificandSize():
+ solver = pycvc4.Solver()
+ fpSort = solver.mkFloatingPointSort(4, 8)
+ fpSort.getFPSignificandSize()
+ setSort = solver.mkSetSort(solver.getIntegerSort())
+
+ with pytest.raises(Exception):
+ setSort.getFPSignificandSize()
+
+def testGetDatatypeParamSorts():
+ solver = pycvc4.Solver()
+ # create parametric datatype, check should not fail
+ sort = solver.mkParamSort("T")
+ paramDtypeSpec = solver.mkDatatypeDecl("paramlist", sort)
+ paramCons = solver.mkDatatypeConstructorDecl("cons")
+ paramNil = solver.mkDatatypeConstructorDecl("nil")
+ paramCons.addSelector("head", sort)
+ paramDtypeSpec.addConstructor(paramCons)
+ paramDtypeSpec.addConstructor(paramNil)
+ paramDtypeSort = solver.mkDatatypeSort(paramDtypeSpec)
+ paramDtypeSort.getDatatypeParamSorts()
+ # create non-parametric datatype sort, check should fail
+ dtypeSpec = solver.mkDatatypeDecl("list")
+ cons = solver.mkDatatypeConstructorDecl("cons")
+ cons.addSelector("head", solver.getIntegerSort())
+ dtypeSpec.addConstructor(cons)
+ nil = solver.mkDatatypeConstructorDecl("nil")
+ dtypeSpec.addConstructor(nil)
+ dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+
+ with pytest.raises(Exception):
+ dtypeSort.getDatatypeParamSorts()
+
+
+def testGetDatatypeArity():
+ solver = pycvc4.Solver()
+ # create datatype sort, check should not fail
+ dtypeSpec = solver.mkDatatypeDecl("list")
+ cons = solver.mkDatatypeConstructorDecl("cons")
+ cons.addSelector("head", solver.getIntegerSort())
+ dtypeSpec.addConstructor(cons)
+ nil = solver.mkDatatypeConstructorDecl("nil")
+ dtypeSpec.addConstructor(nil)
+ dtypeSort = solver.mkDatatypeSort(dtypeSpec)
+ dtypeSort.getDatatypeArity()
+ # create bv sort, check should fail
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getDatatypeArity()
+
+def testGetTupleLength():
+ solver = pycvc4.Solver()
+ tupleSort = solver.mkTupleSort([solver.getIntegerSort(), solver.getIntegerSort()])
+ tupleSort.getTupleLength()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getTupleLength()
+
+def testGetTupleSorts():
+ solver = pycvc4.Solver()
+ tupleSort = solver.mkTupleSort([solver.getIntegerSort(), solver.getIntegerSort()])
+ tupleSort.getTupleSorts()
+ bvSort = solver.mkBitVectorSort(32)
+
+ with pytest.raises(Exception):
+ bvSort.getTupleSorts()
+
+def testSortCompare():
+ solver = pycvc4.Solver()
+ boolSort = solver.getBooleanSort()
+ intSort = solver.getIntegerSort()
+ bvSort = solver.mkBitVectorSort(32)
+ bvSort2 = solver.mkBitVectorSort(32)
+ assert bvSort >= bvSort2
+ assert bvSort <= bvSort2
+ assert (intSort > boolSort) != (intSort < boolSort)
+ assert (intSort > bvSort or intSort == bvSort) == (intSort >= bvSort)
+
+def testSortSubtyping():
+ solver = pycvc4.Solver()
+ intSort = solver.getIntegerSort()
+ realSort = solver.getRealSort()
+ assert intSort.isSubsortOf(realSort)
+ assert not realSort.isSubsortOf(intSort)
+ assert intSort.isComparableTo(realSort)
+ assert realSort.isComparableTo(intSort)
+
+ arraySortII = solver.mkArraySort(intSort, intSort)
+ arraySortIR = solver.mkArraySort(intSort, realSort)
+ assert not arraySortII.isComparableTo(intSort)
+ # we do not support subtyping for arrays
+ assert not arraySortII.isComparableTo(arraySortIR)
+
+ setSortI = solver.mkSetSort(intSort)
+ setSortR = solver.mkSetSort(realSort)
+ # we support subtyping for sets
+ assert setSortI.isSubsortOf(setSortR)
+ assert setSortR.isComparableTo(setSortI)
diff --git a/test/unit/api/solver_black.h b/test/unit/api/solver_black.h
index f080f5348..ddff63352 100644
--- a/test/unit/api/solver_black.h
+++ b/test/unit/api/solver_black.h
@@ -95,6 +95,7 @@ class SolverBlack : public CxxTest::TestSuite
void testUFIteration();
void testGetInfo();
+ void testGetInterpolant();
void testGetOp();
void testGetOption();
void testGetUnsatAssumptions1();
@@ -1309,6 +1310,11 @@ void SolverBlack::testGetInfo()
TS_ASSERT_THROWS(d_solver->getInfo("asdf"), CVC4ApiException&);
}
+void SolverBlack::testGetInterpolant()
+{
+ // TODO
+}
+
void SolverBlack::testGetOp()
{
Sort bv32 = d_solver->mkBitVectorSort(32);
diff --git a/test/unit/expr/attribute_black.h b/test/unit/expr/attribute_black.h
index f07612119..f671fc869 100644
--- a/test/unit/expr/attribute_black.h
+++ b/test/unit/expr/attribute_black.h
@@ -17,15 +17,16 @@
#include <cxxtest/TestSuite.h>
//Used in some of the tests
-#include <vector>
#include <sstream>
+#include <vector>
+#include "api/cvc4cpp.h"
+#include "expr/attribute.h"
#include "expr/expr_manager.h"
-#include "expr/node_value.h"
+#include "expr/node.h"
#include "expr/node_builder.h"
#include "expr/node_manager.h"
-#include "expr/node.h"
-#include "expr/attribute.h"
+#include "expr/node_value.h"
#include "smt/smt_engine.h"
#include "smt/smt_engine_scope.h"
@@ -35,27 +36,20 @@ using namespace CVC4::smt;
using namespace std;
class AttributeBlack : public CxxTest::TestSuite {
-private:
-
- ExprManager* d_exprManager;
- NodeManager* d_nodeManager;
- SmtEngine* d_smtEngine;
- SmtScope* d_scope;
-
public:
void setUp() override
{
- d_exprManager = new ExprManager();
+ d_slv = new api::Solver();
+ d_exprManager = d_slv->getExprManager();
d_nodeManager = NodeManager::fromExprManager(d_exprManager);
- d_smtEngine = new SmtEngine(d_exprManager);
+ d_smtEngine = d_slv->getSmtEngine();
d_scope = new SmtScope(d_smtEngine);
}
void tearDown() override
{
delete d_scope;
- delete d_smtEngine;
- delete d_exprManager;
+ delete d_slv;
}
struct PrimitiveIntAttributeId {};
@@ -135,4 +129,10 @@ private:
delete node;
}
+ private:
+ api::Solver* d_slv;
+ ExprManager* d_exprManager;
+ NodeManager* d_nodeManager;
+ SmtEngine* d_smtEngine;
+ SmtScope* d_scope;
};
diff --git a/test/unit/expr/expr_manager_public.h b/test/unit/expr/expr_manager_public.h
index d28553e08..c632b913e 100644
--- a/test/unit/expr/expr_manager_public.h
+++ b/test/unit/expr/expr_manager_public.h
@@ -19,56 +19,28 @@
#include <sstream>
#include <string>
-#include "expr/expr_manager.h"
-#include "expr/expr.h"
+#include "api/cvc4cpp.h"
#include "base/exception.h"
+#include "expr/expr.h"
+#include "expr/expr_manager.h"
using namespace CVC4;
using namespace CVC4::kind;
using namespace std;
class ExprManagerPublic : public CxxTest::TestSuite {
-private:
-
- ExprManager* d_exprManager;
-
- void checkAssociative(Expr expr, Kind kind, unsigned int numChildren) {
- std::vector<Expr> worklist;
- worklist.push_back(expr);
-
- unsigned int childrenFound = 0;
-
- while( !worklist.empty() ) {
- Expr current = worklist.back();
- worklist.pop_back();
- if( current.getKind() == kind ) {
- for( unsigned int i = 0; i < current.getNumChildren(); ++i ) {
- worklist.push_back( current[i] );
- }
- } else {
- childrenFound++;
- }
- }
-
- TS_ASSERT_EQUALS( childrenFound, numChildren );
- }
-
- std::vector<Expr> mkVars(Type type, unsigned int n) {
- std::vector<Expr> vars;
- for( unsigned int i = 0; i < n; ++i ) {
- vars.push_back( d_exprManager->mkVar(type) );
- }
- return vars;
- }
-
public:
- void setUp() override { d_exprManager = new ExprManager; }
+ void setUp() override
+ {
+ d_slv = new api::Solver();
+ d_exprManager = d_slv->getExprManager();
+ }
void tearDown() override
{
try
{
- delete d_exprManager;
+ delete d_slv;
}
catch (Exception& e)
{
@@ -128,4 +100,44 @@ private:
IllegalArgumentException&);
}
+ private:
+ void checkAssociative(Expr expr, Kind kind, unsigned int numChildren)
+ {
+ std::vector<Expr> worklist;
+ worklist.push_back(expr);
+
+ unsigned int childrenFound = 0;
+
+ while (!worklist.empty())
+ {
+ Expr current = worklist.back();
+ worklist.pop_back();
+ if (current.getKind() == kind)
+ {
+ for (unsigned int i = 0; i < current.getNumChildren(); ++i)
+ {
+ worklist.push_back(current[i]);
+ }
+ }
+ else
+ {
+ childrenFound++;
+ }
+ }
+
+ TS_ASSERT_EQUALS(childrenFound, numChildren);
+ }
+
+ std::vector<Expr> mkVars(Type type, unsigned int n)
+ {
+ std::vector<Expr> vars;
+ for (unsigned int i = 0; i < n; ++i)
+ {
+ vars.push_back(d_exprManager->mkVar(type));
+ }
+ return vars;
+ }
+
+ api::Solver* d_slv;
+ ExprManager* d_exprManager;
};
diff --git a/test/unit/expr/expr_public.h b/test/unit/expr/expr_public.h
index 09452cc7a..86de45fe9 100644
--- a/test/unit/expr/expr_public.h
+++ b/test/unit/expr/expr_public.h
@@ -19,9 +19,10 @@
#include <sstream>
#include <string>
+#include "api/cvc4cpp.h"
#include "base/exception.h"
-#include "expr/expr_manager.h"
#include "expr/expr.h"
+#include "expr/expr_manager.h"
#include "options/options.h"
using namespace CVC4;
@@ -29,27 +30,6 @@ using namespace CVC4::kind;
using namespace std;
class ExprPublic : public CxxTest::TestSuite {
-private:
-
- Options opts;
-
- ExprManager* d_em;
-
- Expr* a_bool;
- Expr* b_bool;
- Expr* c_bool_and;
- Expr* and_op;
- Expr* plus_op;
- Type* fun_type;
- Expr* fun_op;
- Expr* d_apply_fun_bool;
- Expr* null;
-
- Expr* i1;
- Expr* i2;
- Expr* r1;
- Expr* r2;
-
public:
void setUp() override
{
@@ -62,7 +42,8 @@ private:
free(argv[0]);
free(argv[1]);
- d_em = new ExprManager(opts);
+ d_slv = new api::Solver(&opts);
+ d_em = d_slv->getExprManager();
a_bool = new Expr(d_em->mkVar("a", d_em->booleanType()));
b_bool = new Expr(d_em->mkVar("b", d_em->booleanType()));
@@ -105,7 +86,7 @@ private:
delete b_bool;
delete a_bool;
- delete d_em;
+ delete d_slv;
}
catch (Exception& e)
{
@@ -466,4 +447,25 @@ private:
TS_ASSERT(r1->getExprManager() == d_em);
TS_ASSERT(r2->getExprManager() == d_em);
}
+
+ private:
+ Options opts;
+
+ api::Solver* d_slv;
+ ExprManager* d_em;
+
+ Expr* a_bool;
+ Expr* b_bool;
+ Expr* c_bool_and;
+ Expr* and_op;
+ Expr* plus_op;
+ Type* fun_type;
+ Expr* fun_op;
+ Expr* d_apply_fun_bool;
+ Expr* null;
+
+ Expr* i1;
+ Expr* i2;
+ Expr* r1;
+ Expr* r2;
};
diff --git a/test/unit/expr/node_algorithm_black.h b/test/unit/expr/node_algorithm_black.h
index 1f799cd40..7505215e7 100644
--- a/test/unit/expr/node_algorithm_black.h
+++ b/test/unit/expr/node_algorithm_black.h
@@ -32,13 +32,6 @@ using namespace CVC4::kind;
class NodeAlgorithmBlack : public CxxTest::TestSuite
{
- private:
- NodeManager* d_nodeManager;
- NodeManagerScope* d_scope;
- TypeNode* d_intTypeNode;
- TypeNode* d_boolTypeNode;
- TypeNode* d_bvTypeNode;
-
public:
void setUp() override
{
@@ -51,8 +44,9 @@ class NodeAlgorithmBlack : public CxxTest::TestSuite
void tearDown() override
{
- delete d_intTypeNode;
+ delete d_bvTypeNode;
delete d_boolTypeNode;
+ delete d_intTypeNode;
delete d_scope;
delete d_nodeManager;
}
@@ -216,4 +210,11 @@ class NodeAlgorithmBlack : public CxxTest::TestSuite
TS_ASSERT_EQUALS(subs.size(), 1);
TS_ASSERT_EQUALS(subs[x], a);
}
+
+ private:
+ NodeManager* d_nodeManager;
+ NodeManagerScope* d_scope;
+ TypeNode* d_intTypeNode;
+ TypeNode* d_boolTypeNode;
+ TypeNode* d_bvTypeNode;
};
diff --git a/test/unit/expr/symbol_table_black.h b/test/unit/expr/symbol_table_black.h
index 17bab05a4..12a55560d 100644
--- a/test/unit/expr/symbol_table_black.h
+++ b/test/unit/expr/symbol_table_black.h
@@ -19,6 +19,7 @@
#include <sstream>
#include <string>
+#include "api/cvc4cpp.h"
#include "base/check.h"
#include "base/exception.h"
#include "context/context.h"
@@ -33,16 +34,13 @@ using namespace CVC4::context;
using namespace std;
class SymbolTableBlack : public CxxTest::TestSuite {
-private:
-
- ExprManager* d_exprManager;
-
public:
void setUp() override
{
try
{
- d_exprManager = new ExprManager;
+ d_slv = new api::Solver();
+ d_exprManager = d_slv->getExprManager();
}
catch (Exception& e)
{
@@ -54,7 +52,7 @@ private:
void tearDown() override
{
try {
- delete d_exprManager;
+ delete d_slv;
}
catch (Exception& e)
{
@@ -164,4 +162,8 @@ private:
// TODO: What kind of exception gets thrown here?
TS_ASSERT_THROWS(symtab.popScope(), ScopeException&);
}
+
+ private:
+ api::Solver* d_slv;
+ ExprManager* d_exprManager;
};/* class SymbolTableBlack */
diff --git a/test/unit/expr/type_cardinality_public.h b/test/unit/expr/type_cardinality_public.h
index 29d9f5dc2..49d6bd9fd 100644
--- a/test/unit/expr/type_cardinality_public.h
+++ b/test/unit/expr/type_cardinality_public.h
@@ -17,12 +17,13 @@
#include <cxxtest/TestSuite.h>
#include <iostream>
-#include <string>
#include <sstream>
+#include <string>
+#include "api/cvc4cpp.h"
+#include "expr/expr_manager.h"
#include "expr/kind.h"
#include "expr/type.h"
-#include "expr/expr_manager.h"
#include "util/cardinality.h"
using namespace CVC4;
@@ -30,12 +31,14 @@ using namespace CVC4::kind;
using namespace std;
class TypeCardinalityPublic : public CxxTest::TestSuite {
- ExprManager* d_em;
-
public:
- void setUp() override { d_em = new ExprManager(); }
+ void setUp() override
+ {
+ d_slv = new api::Solver();
+ d_em = d_slv->getExprManager();
+ }
- void tearDown() override { delete d_em; }
+ void tearDown() override { delete d_slv; }
void testTheBasics()
{
@@ -226,4 +229,7 @@ class TypeCardinalityPublic : public CxxTest::TestSuite {
}
}
+ private:
+ api::Solver* d_slv;
+ ExprManager* d_em;
};/* TypeCardinalityPublic */
diff --git a/test/unit/theory/regexp_operation_black.h b/test/unit/theory/regexp_operation_black.h
index f42207c49..6e01392ab 100644
--- a/test/unit/theory/regexp_operation_black.h
+++ b/test/unit/theory/regexp_operation_black.h
@@ -14,17 +14,19 @@
** Unit tests for symbolic regular expression operations.
**/
+#include <cxxtest/TestSuite.h>
+
+#include <iostream>
+#include <memory>
+#include <vector>
+
+#include "api/cvc4cpp.h"
#include "expr/node.h"
#include "expr/node_manager.h"
#include "smt/smt_engine.h"
#include "smt/smt_engine_scope.h"
#include "theory/strings/regexp_operation.h"
-#include <cxxtest/TestSuite.h>
-#include <iostream>
-#include <memory>
-#include <vector>
-
using namespace CVC4;
using namespace CVC4::kind;
using namespace CVC4::smt;
@@ -40,8 +42,9 @@ class RegexpOperationBlack : public CxxTest::TestSuite
{
Options opts;
opts.setOutputLanguage(language::output::LANG_SMTLIB_V2);
- d_em = new ExprManager(opts);
- d_smt = new SmtEngine(d_em);
+ d_slv = new api::Solver();
+ d_em = d_slv->getExprManager();
+ d_smt = d_slv->getSmtEngine();
d_scope = new SmtScope(d_smt);
d_regExpOpr = new RegExpOpr();
@@ -56,8 +59,7 @@ class RegexpOperationBlack : public CxxTest::TestSuite
{
delete d_regExpOpr;
delete d_scope;
- delete d_smt;
- delete d_em;
+ delete d_slv;
}
void includes(Node r1, Node r2)
@@ -147,6 +149,7 @@ class RegexpOperationBlack : public CxxTest::TestSuite
}
private:
+ api::Solver* d_slv;
ExprManager* d_em;
SmtEngine* d_smt;
SmtScope* d_scope;
diff --git a/test/unit/theory/theory_black.h b/test/unit/theory/theory_black.h
index 37999b73a..45d13d416 100644
--- a/test/unit/theory/theory_black.h
+++ b/test/unit/theory/theory_black.h
@@ -17,14 +17,15 @@
#include <cxxtest/TestSuite.h>
//Used in some of the tests
-#include <vector>
#include <sstream>
+#include <vector>
+#include "api/cvc4cpp.h"
#include "expr/expr_manager.h"
-#include "expr/node_value.h"
+#include "expr/node.h"
#include "expr/node_builder.h"
#include "expr/node_manager.h"
-#include "expr/node.h"
+#include "expr/node_value.h"
#include "smt/smt_engine.h"
#include "smt/smt_engine_scope.h"
#include "theory/rewriter.h"
@@ -40,8 +41,9 @@ class TheoryBlack : public CxxTest::TestSuite {
public:
void setUp() override
{
- d_em = new ExprManager();
- d_smt = new SmtEngine(d_em);
+ d_slv = new api::Solver();
+ d_em = d_slv->getExprManager();
+ d_smt = d_slv->getSmtEngine();
d_scope = new SmtScope(d_smt);
// Ensure that the SMT engine is fully initialized (required for the
// rewriter)
@@ -53,8 +55,7 @@ class TheoryBlack : public CxxTest::TestSuite {
void tearDown() override
{
delete d_scope;
- delete d_smt;
- delete d_em;
+ delete d_slv;
}
void testArrayConst() {
@@ -149,6 +150,7 @@ class TheoryBlack : public CxxTest::TestSuite {
}
private:
+ api::Solver* d_slv;
ExprManager* d_em;
SmtEngine* d_smt;
NodeManager* d_nm;
diff --git a/test/unit/util/array_store_all_black.h b/test/unit/util/array_store_all_black.h
index 3b00fa192..bf0163317 100644
--- a/test/unit/util/array_store_all_black.h
+++ b/test/unit/util/array_store_all_black.h
@@ -16,6 +16,7 @@
#include <cxxtest/TestSuite.h>
+#include "api/cvc4cpp.h"
#include "expr/array_store_all.h"
#include "expr/expr.h"
#include "expr/expr_manager.h"
@@ -27,18 +28,14 @@ using namespace CVC4;
using namespace std;
class ArrayStoreAllBlack : public CxxTest::TestSuite {
- ExprManager* d_em;
-
public:
void setUp() override
{
- d_em = new ExprManager();
+ d_slv = new api::Solver();
+ d_em = d_slv->getExprManager();
}
- void tearDown() override
- {
- delete d_em;
- }
+ void tearDown() override { delete d_slv; }
void testStoreAll() {
Type usort = d_em->mkSort("U");
@@ -80,4 +77,7 @@ class ArrayStoreAllBlack : public CxxTest::TestSuite {
d_em->mkConst(Rational(0)))));
}
+ private:
+ api::Solver* d_slv;
+ ExprManager* d_em;
}; /* class ArrayStoreAllBlack */
diff --git a/test/unit/util/datatype_black.h b/test/unit/util/datatype_black.h
index f69cc12ea..ac27acfb5 100644
--- a/test/unit/util/datatype_black.h
+++ b/test/unit/util/datatype_black.h
@@ -15,8 +15,10 @@
**/
#include <cxxtest/TestSuite.h>
+
#include <sstream>
+#include "api/cvc4cpp.h"
#include "expr/datatype.h"
#include "expr/expr.h"
#include "expr/expr_manager.h"
@@ -27,14 +29,11 @@ using namespace CVC4;
using namespace std;
class DatatypeBlack : public CxxTest::TestSuite {
-
- ExprManager* d_em;
- ExprManagerScope* d_scope;
-
public:
void setUp() override
{
- d_em = new ExprManager();
+ d_slv = new api::Solver();
+ d_em = d_slv->getExprManager();
d_scope = new ExprManagerScope(*d_em);
Debug.on("datatypes");
Debug.on("groundterms");
@@ -43,7 +42,7 @@ class DatatypeBlack : public CxxTest::TestSuite {
void tearDown() override
{
delete d_scope;
- delete d_em;
+ delete d_slv;
}
void testEnumeration() {
@@ -436,4 +435,8 @@ class DatatypeBlack : public CxxTest::TestSuite {
TS_ASSERT_EQUALS(TypeNode::leastCommonTypeNode(TypeNode::fromType(pairIntInt), TypeNode::fromType(pairIntInt)).toType(), pairIntInt);
}
+ private:
+ api::Solver* d_slv;
+ ExprManager* d_em;
+ ExprManagerScope* d_scope;
};/* class DatatypeBlack */
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback