summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/api/python/cvc5.pxd5
-rw-r--r--src/api/python/cvc5.pxi50
-rw-r--r--test/python/unit/api/test_solver.py306
3 files changed, 342 insertions, 19 deletions
diff --git a/src/api/python/cvc5.pxd b/src/api/python/cvc5.pxd
index 9d980267d..623b2f943 100644
--- a/src/api/python/cvc5.pxd
+++ b/src/api/python/cvc5.pxd
@@ -153,6 +153,7 @@ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api":
Solver(Options*) except +
Sort getBooleanSort() except +
Sort getIntegerSort() except +
+ Sort getNullSort() except +
Sort getRealSort() except +
Sort getRegExpSort() except +
Sort getRoundingModeSort() except +
@@ -178,10 +179,10 @@ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api":
Term mkTerm(Op op, const vector[Term]& children) except +
Term mkTuple(const vector[Sort]& sorts, const vector[Term]& terms) except +
Op mkOp(Kind kind) except +
- Op mkOp(Kind kind, Kind k) except +
Op mkOp(Kind kind, const string& arg) except +
Op mkOp(Kind kind, uint32_t arg) except +
Op mkOp(Kind kind, uint32_t arg1, uint32_t arg2) except +
+ Op mkOp(Kind kind, const vector[uint32_t]& args) except +
# Sygus related functions
Grammar mkSygusGrammar(const vector[Term]& boundVars, const vector[Term]& ntSymbols) except +
Term mkSygusVar(Sort sort, const string& symbol) except +
@@ -207,9 +208,11 @@ cdef extern from "api/cpp/cvc5.h" namespace "cvc5::api":
Term mkRegexpEmpty() except +
Term mkRegexpSigma() except +
Term mkEmptySet(Sort s) except +
+ Term mkEmptyBag(Sort s) except +
Term mkSepNil(Sort sort) except +
Term mkString(const string& s) except +
Term mkString(const wstring& s) except +
+ Term mkString(const string& s, bint useEscSequences) except +
Term mkEmptySequence(Sort sort) except +
Term mkUniverseSet(Sort sort) except +
Term mkBitVector(uint32_t size) except +
diff --git a/src/api/python/cvc5.pxi b/src/api/python/cvc5.pxi
index 874c63c3d..4bb9da3d1 100644
--- a/src/api/python/cvc5.pxi
+++ b/src/api/python/cvc5.pxi
@@ -470,6 +470,11 @@ cdef class Solver:
sort.csort = self.csolver.getIntegerSort()
return sort
+ def getNullSort(self):
+ cdef Sort sort = Sort(self)
+ sort.csort = self.csolver.getNullSort()
+ return sort
+
def getRealSort(self):
cdef Sort sort = Sort(self)
sort.csort = self.csolver.getRealSort()
@@ -672,8 +677,8 @@ cdef class Solver:
result.cterm = self.csolver.mkTuple(csorts, cterms)
return result
-
- def mkOp(self, kind k, arg0=None, arg1 = None):
+ @expand_list_arg(num_req_args=0)
+ def mkOp(self, kind k, *args):
'''
Supports the following uses:
Op mkOp(Kind kind)
@@ -683,28 +688,30 @@ cdef class Solver:
Op mkOp(Kind kind, uint32_t arg0, uint32_t arg1)
'''
cdef Op op = Op(self)
+ cdef vector[int] v
- if arg0 is None:
+ if len(args) == 0:
op.cop = self.csolver.mkOp(k.k)
- elif arg1 is None:
- if isinstance(arg0, kind):
- op.cop = self.csolver.mkOp(k.k, (<kind?> arg0).k)
- elif isinstance(arg0, str):
+ elif len(args) == 1:
+ if isinstance(args[0], str):
op.cop = self.csolver.mkOp(k.k,
<const string &>
- arg0.encode())
- elif isinstance(arg0, int):
- op.cop = self.csolver.mkOp(k.k, <int?> arg0)
+ args[0].encode())
+ elif isinstance(args[0], int):
+ op.cop = self.csolver.mkOp(k.k, <int?> args[0])
+ elif isinstance(args[0], list):
+ for a in args[0]:
+ v.push_back((<int?> a))
+ op.cop = self.csolver.mkOp(k.k, <const vector[uint32_t]&> v)
else:
raise ValueError("Unsupported signature"
- " mkOp: {}".format(" X ".join([str(k), str(arg0)])))
- else:
- if isinstance(arg0, int) and isinstance(arg1, int):
- op.cop = self.csolver.mkOp(k.k, <int> arg0,
- <int> arg1)
+ " mkOp: {}".format(" X ".join([str(k), str(args[0])])))
+ elif len(args) == 2:
+ if isinstance(args[0], int) and isinstance(args[1], int):
+ op.cop = self.csolver.mkOp(k.k, <int> args[0], <int> args[1])
else:
raise ValueError("Unsupported signature"
- " mkOp: {}".format(" X ".join([k, arg0, arg1])))
+ " mkOp: {}".format(" X ".join([k, args[0], args[1]])))
return op
def mkTrue(self):
@@ -778,17 +785,24 @@ cdef class Solver:
term.cterm = self.csolver.mkEmptySet(s.csort)
return term
+ def mkEmptyBag(self, Sort s):
+ cdef Term term = Term(self)
+ term.cterm = self.csolver.mkEmptyBag(s.csort)
+ return term
def mkSepNil(self, Sort sort):
cdef Term term = Term(self)
term.cterm = self.csolver.mkSepNil(sort.csort)
return term
- def mkString(self, str s):
+ def mkString(self, str s, useEscSequences = None):
cdef Term term = Term(self)
cdef Py_ssize_t size
cdef wchar_t* tmp = PyUnicode_AsWideCharString(s, &size)
- term.cterm = self.csolver.mkString(c_wstring(tmp, size))
+ if isinstance(useEscSequences, bool):
+ term.cterm = self.csolver.mkString(s.encode(), <bint> useEscSequences)
+ else:
+ term.cterm = self.csolver.mkString(c_wstring(tmp, size))
PyMem_Free(tmp)
return term
diff --git a/test/python/unit/api/test_solver.py b/test/python/unit/api/test_solver.py
index 1255bf270..8b3ce944e 100644
--- a/test/python/unit/api/test_solver.py
+++ b/test/python/unit/api/test_solver.py
@@ -43,6 +43,10 @@ def test_get_integer_sort(solver):
solver.getIntegerSort()
+def test_get_null_sort(solver):
+ solver.getNullSort()
+
+
def test_get_real_sort(solver):
solver.getRealSort()
@@ -244,6 +248,15 @@ def test_mk_set_sort(solver):
slv.mkSetSort(solver.mkBitVectorSort(4))
+def test_mk_bag_sort(solver):
+ solver.mkBagSort(solver.getBooleanSort())
+ solver.mkBagSort(solver.getIntegerSort())
+ solver.mkBagSort(solver.mkBitVectorSort(4))
+ slv = pycvc5.Solver()
+ with pytest.raises(RuntimeError):
+ slv.mkBagSort(solver.mkBitVectorSort(4))
+
+
def test_mk_sequence_sort(solver):
solver.mkSequenceSort(solver.getBooleanSort())
solver.mkSequenceSort(\
@@ -277,6 +290,42 @@ def test_mk_tuple_sort(solver):
slv.mkTupleSort([solver.getIntegerSort()])
+def test_mk_bit_vector(solver):
+ size0 = 0
+ size1 = 8
+ size2 = 32
+ val1 = 2
+ val2 = 2
+ solver.mkBitVector(size1, val1)
+ solver.mkBitVector(size2, val2)
+ solver.mkBitVector("1010", 2)
+ solver.mkBitVector("1010", 10)
+ solver.mkBitVector("1234", 10)
+ solver.mkBitVector("1010", 16)
+ solver.mkBitVector("a09f", 16)
+ solver.mkBitVector(8, "-127", 10)
+ with pytest.raises(RuntimeError):
+ solver.mkBitVector(size0, val1)
+ with pytest.raises(RuntimeError):
+ solver.mkBitVector(size0, val2)
+ with pytest.raises(RuntimeError):
+ solver.mkBitVector("", 2)
+ with pytest.raises(RuntimeError):
+ solver.mkBitVector("10", 3)
+ with pytest.raises(RuntimeError):
+ solver.mkBitVector("20", 2)
+ with pytest.raises(RuntimeError):
+ solver.mkBitVector(8, "101010101", 2)
+ with pytest.raises(RuntimeError):
+ solver.mkBitVector(8, "-256", 10)
+ assert solver.mkBitVector("1010", 2) == solver.mkBitVector("10", 10)
+ assert solver.mkBitVector("1010", 2) == solver.mkBitVector("a", 16)
+ assert str(solver.mkBitVector(8, "01010101", 2)) == "#b01010101"
+ assert str(solver.mkBitVector(8, "F", 16)) == "#b00001111"
+ assert solver.mkBitVector(8, "-1", 10) ==\
+ solver.mkBitVector(8, "FF", 16)
+
+
def test_mk_var(solver):
boolSort = solver.getBooleanSort()
intSort = solver.getIntegerSort()
@@ -312,6 +361,26 @@ def test_mk_uninterpreted_const(solver):
slv.mkUninterpretedConst(solver.getBooleanSort(), 1)
+def test_mk_abstract_value(solver):
+ solver.mkAbstractValue("1")
+ with pytest.raises(ValueError):
+ solver.mkAbstractValue("0")
+ with pytest.raises(ValueError):
+ solver.mkAbstractValue("-1")
+ with pytest.raises(ValueError):
+ solver.mkAbstractValue("1.2")
+ with pytest.raises(ValueError):
+ solver.mkAbstractValue("1/2")
+ with pytest.raises(ValueError):
+ solver.mkAbstractValue("asdf")
+
+ solver.mkAbstractValue(1)
+ with pytest.raises(ValueError):
+ solver.mkAbstractValue(-1)
+ with pytest.raises(ValueError):
+ solver.mkAbstractValue(0)
+
+
def test_mk_floating_point(solver):
t1 = solver.mkBitVector(8)
t2 = solver.mkBitVector(4)
@@ -345,6 +414,17 @@ def test_mk_empty_set(solver):
slv.mkEmptySet(s)
+def test_mk_empty_bag(solver):
+ slv = pycvc5.Solver()
+ s = solver.mkBagSort(solver.getBooleanSort())
+ solver.mkEmptyBag(pycvc5.Sort(solver))
+ solver.mkEmptyBag(s)
+ with pytest.raises(RuntimeError):
+ solver.mkEmptyBag(solver.getBooleanSort())
+ with pytest.raises(RuntimeError):
+ slv.mkEmptyBag(s)
+
+
def test_mk_empty_sequence(solver):
slv = pycvc5.Solver()
s = solver.mkSequenceSort(solver.getBooleanSort())
@@ -379,6 +459,33 @@ def test_mk_pos_zero(solver):
solver.mkPosZero(3, 5)
+def test_mk_op(solver):
+ # mkOp(Kind kind, Kind k)
+ with pytest.raises(ValueError):
+ solver.mkOp(kinds.BVExtract, kinds.Equal)
+
+ # mkOp(Kind kind, const std::string& arg)
+ solver.mkOp(kinds.Divisible, "2147483648")
+ with pytest.raises(RuntimeError):
+ solver.mkOp(kinds.BVExtract, "asdf")
+
+ # mkOp(Kind kind, uint32_t arg)
+ solver.mkOp(kinds.Divisible, 1)
+ solver.mkOp(kinds.BVRotateLeft, 1)
+ solver.mkOp(kinds.BVRotateRight, 1)
+ with pytest.raises(RuntimeError):
+ solver.mkOp(kinds.BVExtract, 1)
+
+ # mkOp(Kind kind, uint32_t arg1, uint32_t arg2)
+ solver.mkOp(kinds.BVExtract, 1, 1)
+ with pytest.raises(RuntimeError):
+ solver.mkOp(kinds.Divisible, 1, 2)
+
+ # mkOp(Kind kind, std::vector<uint32_t> args)
+ args = [1, 2, 2]
+ solver.mkOp(kinds.TupleProject, args)
+
+
def test_mk_pi(solver):
solver.mkPi()
@@ -526,11 +633,210 @@ def test_mk_sep_nil(solver):
slv.mkSepNil(solver.getIntegerSort())
+def test_mk_string(solver):
+ solver.mkString("")
+ solver.mkString("asdfasdf")
+ str(solver.mkString("asdf\\nasdf")) == "\"asdf\\u{5c}nasdf\""
+ str(solver.mkString("asdf\\u{005c}nasdf", True)) ==\
+ "\"asdf\\u{5c}nasdf\""
+
+
+def test_mk_term(solver):
+ bv32 = solver.mkBitVectorSort(32)
+ a = solver.mkConst(bv32, "a")
+ b = solver.mkConst(bv32, "b")
+ v1 = [a, b]
+ v2 = [a, pycvc5.Term(solver)]
+ v3 = [a, solver.mkTrue()]
+ v4 = [solver.mkInteger(1), solver.mkInteger(2)]
+ v5 = [solver.mkInteger(1), pycvc5.Term(solver)]
+ v6 = []
+ slv = pycvc5.Solver()
+
+ # mkTerm(Kind kind) const
+ solver.mkPi()
+ solver.mkTerm(kinds.RegexpEmpty)
+ solver.mkTerm(kinds.RegexpSigma)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.ConstBV)
+
+ # mkTerm(Kind kind, Term child) const
+ solver.mkTerm(kinds.Not, solver.mkTrue())
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Not, pycvc5.Term(solver))
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Not, a)
+ with pytest.raises(RuntimeError):
+ slv.mkTerm(kinds.Not, solver.mkTrue())
+
+ # mkTerm(Kind kind, Term child1, Term child2) const
+ solver.mkTerm(kinds.Equal, a, b)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Equal, pycvc5.Term(solver), b)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Equal, a, pycvc5.Term(solver))
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Equal, a, solver.mkTrue())
+ with pytest.raises(RuntimeError):
+ slv.mkTerm(kinds.Equal, a, b)
+
+ # mkTerm(Kind kind, Term child1, Term child2, Term child3) const
+ solver.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(), solver.mkTrue())
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Ite, pycvc5.Term(solver), solver.mkTrue(),
+ solver.mkTrue())
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Ite, solver.mkTrue(), pycvc5.Term(solver),
+ solver.mkTrue())
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(),
+ pycvc5.Term(solver))
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(), b)
+ with pytest.raises(RuntimeError):
+ slv.mkTerm(kinds.Ite, solver.mkTrue(), solver.mkTrue(),
+ solver.mkTrue())
+
+ # mkTerm(Kind kind, const std::vector<Term>& children) const
+ solver.mkTerm(kinds.Equal, v1)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Equal, v2)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Equal, v3)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.Distinct, v6)
+
+
+def test_mk_term_from_op(solver):
+ bv32 = solver.mkBitVectorSort(32)
+ a = solver.mkConst(bv32, "a")
+ b = solver.mkConst(bv32, "b")
+ v1 = [solver.mkInteger(1), solver.mkInteger(2)]
+ v2 = [solver.mkInteger(1), pycvc5.Term(solver)]
+ v3 = []
+ v4 = [solver.mkInteger(5)]
+ slv = pycvc5.Solver()
+
+ # simple operator terms
+ opterm1 = solver.mkOp(kinds.BVExtract, 2, 1)
+ opterm2 = solver.mkOp(kinds.Divisible, 1)
+
+ # list datatype
+ sort = solver.mkParamSort("T")
+ listDecl = solver.mkDatatypeDecl("paramlist", sort)
+ cons = solver.mkDatatypeConstructorDecl("cons")
+ nil = solver.mkDatatypeConstructorDecl("nil")
+ cons.addSelector("head", sort)
+ cons.addSelectorSelf("tail")
+ listDecl.addConstructor(cons)
+ listDecl.addConstructor(nil)
+ listSort = solver.mkDatatypeSort(listDecl)
+ intListSort =\
+ listSort.instantiate([solver.getIntegerSort()])
+ c = solver.mkConst(intListSort, "c")
+ lis = listSort.getDatatype()
+
+ # list datatype constructor and selector operator terms
+ consTerm1 = lis.getConstructorTerm("cons")
+ consTerm2 = lis.getConstructor("cons").getConstructorTerm()
+ nilTerm1 = lis.getConstructorTerm("nil")
+ nilTerm2 = lis.getConstructor("nil").getConstructorTerm()
+ headTerm1 = lis["cons"].getSelectorTerm("head")
+ headTerm2 = lis["cons"].getSelector("head").getSelectorTerm()
+ tailTerm1 = lis["cons"].getSelectorTerm("tail")
+ tailTerm2 = lis["cons"]["tail"].getSelectorTerm()
+
+ # mkTerm(Op op, Term term) const
+ solver.mkTerm(kinds.ApplyConstructor, nilTerm1)
+ solver.mkTerm(kinds.ApplyConstructor, nilTerm2)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.ApplySelector, nilTerm1)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.ApplySelector, consTerm1)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.ApplyConstructor, consTerm2)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm1)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.ApplySelector, headTerm1)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm1)
+ with pytest.raises(RuntimeError):
+ slv.mkTerm(kinds.ApplyConstructor, nilTerm1)
+
+ # mkTerm(Op op, Term child) const
+ solver.mkTerm(opterm1, a)
+ solver.mkTerm(opterm2, solver.mkInteger(1))
+ solver.mkTerm(kinds.ApplySelector, headTerm1, c)
+ solver.mkTerm(kinds.ApplySelector, tailTerm2, c)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm2, a)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm1, pycvc5.Term(solver))
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(kinds.ApplyConstructor, consTerm1, solver.mkInteger(0))
+ with pytest.raises(RuntimeError):
+ slv.mkTerm(opterm1, a)
+
+ # mkTerm(Op op, Term child1, Term child2) const
+ solver.mkTerm(kinds.ApplyConstructor, consTerm1, solver.mkInteger(0),
+ solver.mkTerm(kinds.ApplyConstructor, nilTerm1))
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm2, solver.mkInteger(1), solver.mkInteger(2))
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm1, a, b)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm2, solver.mkInteger(1), pycvc5.Term(solver))
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm2, pycvc5.Term(solver), solver.mkInteger(1))
+ with pytest.raises(RuntimeError):
+ slv.mkTerm(kinds.ApplyConstructor,\
+ consTerm1,\
+ solver.mkInteger(0),\
+ solver.mkTerm(kinds.ApplyConstructor, nilTerm1))
+
+ # mkTerm(Op op, Term child1, Term child2, Term child3) const
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm1, a, b, a)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm2, solver.mkInteger(1), solver.mkInteger(1),
+ pycvc5.Term(solver))
+
+ # mkTerm(Op op, const std::vector<Term>& children) const
+ solver.mkTerm(opterm2, v4)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm2, v1)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm2, v2)
+ with pytest.raises(RuntimeError):
+ solver.mkTerm(opterm2, v3)
+ with pytest.raises(RuntimeError):
+ slv.mkTerm(opterm2, v4)
+
+
def test_mk_true(solver):
solver.mkTrue()
solver.mkTrue()
+def test_mk_tuple(solver):
+ solver.mkTuple([solver.mkBitVectorSort(3)], [solver.mkBitVector("101", 2)])
+ solver.mkTuple([solver.getRealSort()], [solver.mkInteger("5")])
+
+ with pytest.raises(RuntimeError):
+ solver.mkTuple([], [solver.mkBitVector("101", 2)])
+ with pytest.raises(RuntimeError):
+ solver.mkTuple([solver.mkBitVectorSort(4)],
+ [solver.mkBitVector("101", 2)])
+ with pytest.raises(RuntimeError):
+ solver.mkTuple([solver.getIntegerSort()], [solver.mkReal("5.3")])
+ slv = pycvc5.Solver()
+ with pytest.raises(RuntimeError):
+ slv.mkTuple([solver.mkBitVectorSort(3)], [slv.mkBitVector("101", 2)])
+ with pytest.raises(RuntimeError):
+ slv.mkTuple([slv.mkBitVectorSort(3)], [solver.mkBitVector("101", 2)])
+
+
def test_mk_universe_set(solver):
solver.mkUniverseSet(solver.getBooleanSort())
with pytest.raises(RuntimeError):
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback