add_subdirectory(test)
if(BUILD_BINDINGS_PYTHON)
+ set(BUILD_BINDINGS_PYTHON_VERSION ${PYTHON_VERSION_MAJOR})
add_subdirectory(src/api/python)
endif()
@PACKAGE_INIT@
-set(CVC4_BINDINGS_JAVA @BUILD_SWIG_BINDINGS_JAVA@)
-set(CVC4_BINDINGS_PYTHON @BUILD_SWIG_BINDINGS_PYTHON@)
+set(CVC4_BINDINGS_JAVA @BUILD_BINDINGS_JAVA@)
+set(CVC4_BINDINGS_PYTHON @BUILD_BINDINGS_PYTHON@)
+set(CVC4_BINDINGS_PYTHON_VERSION @BUILD_BINDINGS_PYTHON_VERSION@)
if(NOT TARGET CVC4::cvc4)
include(${CMAKE_CURRENT_LIST_DIR}/CVC4Targets.cmake)
set(EXAMPLES_API_PYTHON
+ bitvectors_and_arrays
+ bitvectors
+ combination
+ datatypes
exceptions
+ extract
+ floating_point
+ helloworld
+ linear_arith
sequences
+ sets
+ strings
+ sygus-fun
+ sygus-grammar
+ sygus-inv
)
-find_package(PythonInterp REQUIRED)
+find_package(PythonInterp ${CVC4_BINDINGS_PYTHON_VERSION} REQUIRED)
# Find Python bindings in the corresponding python-*/site-packages directory.
# Lookup Python module directory and store path in PYTHON_MODULE_PATH.
## A simple demonstration of catching CVC4 execptions with the legacy Python
## API.
-import CVC4
+import pycvc4
+from pycvc4 import kinds
import sys
def main():
- em = CVC4.ExprManager()
- smt = CVC4.SmtEngine(em)
+ slv = pycvc4.Solver()
- smt.setOption("produce-models", CVC4.SExpr("true"))
+ slv.setOption("produce-models", "true")
# Setting an invalid option
try:
- smt.setOption("non-existing", CVC4.SExpr("true"))
+ slv.setOption("non-existing", "true")
return 1
- except CVC4.Exception as e:
- print(e.toString())
+ except:
+ pass
# Creating a term with an invalid type
try:
- integer = em.integerType()
- x = em.mkVar("x", integer)
- invalidExpr = em.mkExpr(CVC4.AND, x, x)
- smt.checkSat(invalidExpr)
+ integer = slv.getIntegerSort()
+ x = slv.mkConst("x", integer)
+ invalidTerm = em.mkTerm(AND, x, x)
+ slv.checkSat(invalidTerm)
return 1
- except CVC4.Exception as e:
- print(e.toString())
+ except:
+ pass
# Asking for a model after unsat result
try:
- smt.checkSat(em.mkBoolConst(False))
- smt.getModel()
+ slv.checkSat(slv.mkBoolean(False))
+ slv.getModel()
return 1
- except CVC4.Exception as e:
- print(e.toString())
+ except:
+ pass
return 0
if __name__ == "__main__":
slv = pycvc4.Solver()
+
+ if not slv.supportsFloatingPoint():
+ # CVC4 must be built with SymFPU to support the theory of
+ # floating-point numbers
+ print("CVC4 was not built with floating-point support.")
+ exit()
+
slv.setOption("produce-models", "true")
- slv.setLogic("FP")
+ slv.setLogic("QF_FP")
# single 32-bit precision
fp32 = slv.mkFloatingPointSort(8, 24)
leq = slv.mkTerm(kinds.Leq, start, start)
# create the grammar object
- g = slv.mkSygusGrammar({x, y}, {start, start_bool})
+ g = slv.mkSygusGrammar([x, y], [start, start_bool])
# bind each non-terminal to its rules
g.addRules(start, {zero, one, x, y, plus, minus, ite})
# declare the functions-to-synthesize. Optionally, provide the grammar
# constraints
- max = slv.synthFun("max", {x, y}, integer, g)
- min = slv.synthFun("min", {x, y}, integer)
+ max = slv.synthFun("max", [x, y], integer, g)
+ min = slv.synthFun("min", [x, y], integer)
# declare universal variables.
varX = slv.mkSygusVar(integer, "x")
<< " children (the one under construction has " << nchildren << ")";
}
+/* Solver Configuration */
+/* -------------------------------------------------------------------------- */
+
+bool Solver::supportsFloatingPoint() const
+{
+ return Configuration::isBuiltWithSymFPU();
+}
+
/* Sorts Handling */
/* -------------------------------------------------------------------------- */
CVC4_API_SOLVER_TRY_CATCH_END;
}
-Sort Solver::getRoundingmodeSort(void) const
+Sort Solver::getRoundingModeSort(void) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
+ << "Expected CVC4 to be compiled with SymFPU support";
return Sort(this, d_exprMgr->roundingModeType());
CVC4_API_SOLVER_TRY_CATCH_END;
}
Sort Solver::mkFloatingPointSort(uint32_t exp, uint32_t sig) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
+ << "Expected CVC4 to be compiled with SymFPU support";
CVC4_API_ARG_CHECK_EXPECTED(exp > 0, exp) << "exponent size > 0";
CVC4_API_ARG_CHECK_EXPECTED(sig > 0, sig) << "significand size > 0";
Term Solver::mkRoundingMode(RoundingMode rm) const
{
CVC4_API_SOLVER_TRY_CATCH_BEGIN;
+ CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
+ << "Expected CVC4 to be compiled with SymFPU support";
return mkValHelper<CVC4::RoundingMode>(s_rmodes.at(rm));
CVC4_API_SOLVER_TRY_CATCH_END;
}
{
CVC4_API_CHECK(g->d_ntSyms[0].d_node->getType().toType() == *sort.d_type)
<< "Invalid Start symbol for Grammar g, Expected Start's sort to be "
- << *sort.d_type;
+ << *sort.d_type << " but found " << g->d_ntSyms[0].d_node->getType();
}
Type funType = varTypes.empty()
Solver(const Solver&) = delete;
Solver& operator=(const Solver&) = delete;
+ /* .................................................................... */
+ /* Solver Configuration */
+ /* .................................................................... */
+
+ bool supportsFloatingPoint() const;
+
/* .................................................................... */
/* Sorts Handling */
/* .................................................................... */
/**
* @return sort RoundingMode
*/
- Sort getRoundingmodeSort() const;
+ Sort getRoundingModeSort() const;
/**
* @return sort String
Term mkSygusVar(Sort sort, const std::string& symbol = std::string()) const;
/**
- * Create a Sygus grammar.
+ * Create a Sygus grammar. The first non-terminal is treated as the starting
+ * non-terminal, so the order of non-terminals matters.
+ *
* @param boundVars the parameters to corresponding synth-fun/synth-inv
* @param ntSymbols the pre-declaration of the non-terminal symbols
* @return the grammar
cdef cppclass Solver:
Solver(Options*) except +
+ bint supportsFloatingPoint() except +
Sort getBooleanSort() except +
Sort getIntegerSort() except +
Sort getRealSort() except +
Sort getRegExpSort() except +
- Sort getRoundingmodeSort() except +
+ Sort getRoundingModeSort() except +
Sort getStringSort() except +
Sort mkArraySort(Sort indexSort, Sort elemSort) except +
Sort mkBitVectorSort(uint32_t size) except +
from cvc4 cimport Sort as c_Sort
from cvc4 cimport SortHashFunction as c_SortHashFunction
from cvc4 cimport ROUND_NEAREST_TIES_TO_EVEN, ROUND_TOWARD_POSITIVE
-from cvc4 cimport ROUND_TOWARD_ZERO, ROUND_NEAREST_TIES_TO_AWAY
+from cvc4 cimport ROUND_TOWARD_NEGATIVE, ROUND_TOWARD_ZERO
+from cvc4 cimport ROUND_NEAREST_TIES_TO_AWAY
from cvc4 cimport Term as c_Term
from cvc4 cimport TermHashFunction as c_TermHashFunction
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())]
+ dc.cdc = self.cd[(<const string &> index.encode())]
else:
raise ValueError("Expecting a non-negative integer or string")
return dc
def __dealloc__(self):
del self.csolver
+ def supportsFloatingPoint(self):
+ return self.csolver.supportsFloatingPoint()
+
def getBooleanSort(self):
cdef Sort sort = Sort(self)
sort.csort = self.csolver.getBooleanSort()
sort.csort = self.csolver.getRegExpSort()
return sort
- def getRoundingmodeSort(self):
+ def getRoundingModeSort(self):
cdef Sort sort = Sort(self)
- sort.csort = self.csolver.getRoundingmodeSort()
+ sort.csort = self.csolver.getRoundingModeSort()
return sort
def getStringSort(self):
cdef __rounding_modes = {
<int> ROUND_NEAREST_TIES_TO_EVEN: "RoundNearestTiesToEven",
<int> ROUND_TOWARD_POSITIVE: "RoundTowardPositive",
+ <int> ROUND_TOWARD_NEGATIVE: "RoundTowardNegative",
<int> ROUND_TOWARD_ZERO: "RoundTowardZero",
<int> ROUND_NEAREST_TIES_TO_AWAY: "RoundNearestTiesToAway"
}
}
if (d_logic.isTheoryEnabled(theory::THEORY_FP)) {
- defineType("RoundingMode", d_solver->getRoundingmodeSort());
+ defineType("RoundingMode", d_solver->getRoundingModeSort());
defineType("Float16", d_solver->mkFloatingPointSort(5, 11));
defineType("Float32", d_solver->mkFloatingPointSort(8, 24));
defineType("Float64", d_solver->mkFloatingPointSort(11, 53));
#include <string>
#include "base/check.h"
+#include "base/configuration.h"
#include "expr/kind.h"
using namespace std;
d_higherOrder(true),
d_locked(false)
{
- for(TheoryId id = THEORY_FIRST; id < THEORY_LAST; ++id) {
+ for (TheoryId id = THEORY_FIRST; id < THEORY_LAST; ++id)
+ {
+ if (id == THEORY_FP && !Configuration::isBuiltWithSymFPU())
+ {
+ continue;
+ }
enableTheory(id);
}
}
; EXPECT: unsat
;; produced by cvc4_16.drv ;;
-(set-logic AUFBVFPDTNIRA)
+(set-logic AUFBVDTNIRA)
(set-info :smt-lib-version 2.6)
;;; generated by SMT-LIB2 driver
;;; SMT-LIB2 driver: bit-vectors, common part
;; produced by cvc4_16.drv ;;
(set-info :smt-lib-version 2.6)
-(set-logic AUFBVFPDTNIRA)
+(set-logic AUFBVDTNIRA)
;;; generated by SMT-LIB2 driver
;;; SMT-LIB2 driver: bit-vectors, common part
;;; SMT-LIB2: integer arithmetic
def testGetFPExponentSize():
solver = pycvc4.Solver()
- fpSort = solver.mkFloatingPointSort(4, 8)
- fpSort.getFPExponentSize()
- setSort = solver.mkSetSort(solver.getIntegerSort())
- with pytest.raises(Exception):
- setSort.getFPExponentSize()
+ if solver.supportsFloatingPoint():
+ fpSort = solver.mkFloatingPointSort(4, 8)
+ fpSort.getFPExponentSize()
+ setSort = solver.mkSetSort(solver.getIntegerSort())
+
+ with pytest.raises(Exception):
+ setSort.getFPExponentSize()
+ else:
+ with pytest.raises(Exception):
+ solver.mkFloatingPointSort(4, 8)
def testGetFPSignificandSize():
solver = pycvc4.Solver()
- fpSort = solver.mkFloatingPointSort(4, 8)
- fpSort.getFPSignificandSize()
- setSort = solver.mkSetSort(solver.getIntegerSort())
- with pytest.raises(Exception):
- setSort.getFPSignificandSize()
+ if solver.supportsFloatingPoint():
+ fpSort = solver.mkFloatingPointSort(4, 8)
+ fpSort.getFPSignificandSize()
+ setSort = solver.mkSetSort(solver.getIntegerSort())
+
+ with pytest.raises(Exception):
+ setSort.getFPSignificandSize()
+ else:
+ with pytest.raises(Exception):
+ solver.mkFloatingPointSort(4, 8)
def testGetDatatypeParamSorts():
solver = pycvc4.Solver()
void setUp() override;
void tearDown() override;
+ void testSupportsFloatingPoint();
+
void testGetBooleanSort();
void testGetIntegerSort();
void testGetNullSort();
void testGetRealSort();
void testGetRegExpSort();
- void testGetRoundingmodeSort();
+ void testGetRoundingModeSort();
void testGetStringSort();
void testMkArraySort();
void SolverBlack::tearDown() { d_solver.reset(nullptr); }
+void SolverBlack::testSupportsFloatingPoint()
+{
+ if (d_solver->supportsFloatingPoint())
+ {
+ TS_ASSERT_THROWS_NOTHING(
+ d_solver->mkRoundingMode(ROUND_NEAREST_TIES_TO_EVEN));
+ }
+ else
+ {
+ TS_ASSERT_THROWS(d_solver->mkRoundingMode(ROUND_NEAREST_TIES_TO_EVEN),
+ CVC4ApiException&);
+ }
+}
+
void SolverBlack::testGetBooleanSort()
{
TS_ASSERT_THROWS_NOTHING(d_solver->getBooleanSort());
TS_ASSERT_THROWS_NOTHING(d_solver->getStringSort());
}
-void SolverBlack::testGetRoundingmodeSort()
+void SolverBlack::testGetRoundingModeSort()
{
- TS_ASSERT_THROWS_NOTHING(d_solver->getRoundingmodeSort());
+ if (d_solver->supportsFloatingPoint())
+ {
+ TS_ASSERT_THROWS_NOTHING(d_solver->getRoundingModeSort());
+ }
+ else
+ {
+ TS_ASSERT_THROWS(d_solver->getRoundingModeSort(), CVC4ApiException&);
+ }
}
void SolverBlack::testMkArraySort()
Sort intSort = d_solver->getIntegerSort();
Sort realSort = d_solver->getRealSort();
Sort bvSort = d_solver->mkBitVectorSort(32);
- Sort fpSort = d_solver->mkFloatingPointSort(3, 5);
TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(boolSort, boolSort));
TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(intSort, intSort));
TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(realSort, realSort));
TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(bvSort, bvSort));
- TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(fpSort, fpSort));
TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(boolSort, intSort));
TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(realSort, bvSort));
- TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(bvSort, fpSort));
+
+ if (d_solver->supportsFloatingPoint())
+ {
+ Sort fpSort = d_solver->mkFloatingPointSort(3, 5);
+ TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(fpSort, fpSort));
+ TS_ASSERT_THROWS_NOTHING(d_solver->mkArraySort(bvSort, fpSort));
+ }
+
Solver slv;
TS_ASSERT_THROWS(slv.mkArraySort(boolSort, boolSort), CVC4ApiException&);
}
void SolverBlack::testMkFloatingPointSort()
{
- TS_ASSERT_THROWS_NOTHING(d_solver->mkFloatingPointSort(4, 8));
- TS_ASSERT_THROWS(d_solver->mkFloatingPointSort(0, 8), CVC4ApiException&);
- TS_ASSERT_THROWS(d_solver->mkFloatingPointSort(4, 0), CVC4ApiException&);
+ if (d_solver->supportsFloatingPoint())
+ {
+ TS_ASSERT_THROWS_NOTHING(d_solver->mkFloatingPointSort(4, 8));
+ TS_ASSERT_THROWS(d_solver->mkFloatingPointSort(0, 8), CVC4ApiException&);
+ TS_ASSERT_THROWS(d_solver->mkFloatingPointSort(4, 0), CVC4ApiException&);
+ }
+ else
+ {
+ TS_ASSERT_THROWS(d_solver->mkFloatingPointSort(4, 8), CVC4ApiException&);
+ }
}
void SolverBlack::testMkDatatypeSort()
void SolverBlack::testMkRoundingMode()
{
- TS_ASSERT_THROWS_NOTHING(
- d_solver->mkRoundingMode(RoundingMode::ROUND_TOWARD_ZERO));
+ if (CVC4::Configuration::isBuiltWithSymFPU())
+ {
+ TS_ASSERT_THROWS_NOTHING(
+ d_solver->mkRoundingMode(RoundingMode::ROUND_TOWARD_ZERO));
+ }
+ else
+ {
+ TS_ASSERT_THROWS(d_solver->mkRoundingMode(RoundingMode::ROUND_TOWARD_ZERO),
+ CVC4ApiException&);
+ }
}
void SolverBlack::testMkUninterpretedConst()