summaryrefslogtreecommitdiff
path: root/src/api/python/cvc4.pxi
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/python/cvc4.pxi')
-rw-r--r--src/api/python/cvc4.pxi155
1 files changed, 89 insertions, 66 deletions
diff --git a/src/api/python/cvc4.pxi b/src/api/python/cvc4.pxi
index 1489b34a6..827c53ef4 100644
--- a/src/api/python/cvc4.pxi
+++ b/src/api/python/cvc4.pxi
@@ -15,11 +15,14 @@ from cvc4 cimport DatatypeSelector as c_DatatypeSelector
from cvc4 cimport Result as c_Result
from cvc4 cimport RoundingMode as c_RoundingMode
from cvc4 cimport Op as c_Op
+from cvc4 cimport OpHashFunction as c_OpHashFunction
from cvc4 cimport Solver as c_Solver
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 Term as c_Term
+from cvc4 cimport TermHashFunction as c_TermHashFunction
from cvc4kinds cimport Kind as c_Kind
@@ -49,7 +52,12 @@ def expand_list_arg(num_req_args=0):
### can omit spaces between unrelated oneliners
### always use c++ default arguments
#### only use default args of None at python level
-#### Result class can have default because it's pure python
+
+
+## Objects for hashing
+cdef c_OpHashFunction cophash = c_OpHashFunction()
+cdef c_SortHashFunction csorthash = c_SortHashFunction()
+cdef c_TermHashFunction ctermhash = c_TermHashFunction()
cdef class Datatype:
@@ -125,12 +133,14 @@ cdef class DatatypeConstructor:
cdef class DatatypeConstructorDecl:
- cdef c_DatatypeConstructorDecl* cddc
- def __cinit__(self, str name):
- self.cddc = new c_DatatypeConstructorDecl(name.encode())
+ cdef c_DatatypeConstructorDecl cddc
+
+ def __cinit__(self):
+ pass
def addSelector(self, str name, Sort sort):
self.cddc.addSelector(name.encode(), sort.csort)
+
def addSelectorSelf(self, str name):
self.cddc.addSelectorSelf(name.encode())
@@ -147,7 +157,7 @@ cdef class DatatypeDecl:
pass
def addConstructor(self, DatatypeConstructorDecl ctor):
- self.cdd.addConstructor(ctor.cddc[0])
+ self.cdd.addConstructor(ctor.cddc)
def isParametric(self):
return self.cdd.isParametric()
@@ -188,6 +198,9 @@ cdef class Op:
def __repr__(self):
return self.cop.toString().decode()
+ def __hash__(self):
+ return cophash(self.cop)
+
def getKind(self):
return kind(<int> self.cop.getKind())
@@ -217,54 +230,47 @@ cdef class Op:
return indices
-class Result:
- def __init__(self, name, explanation=""):
- name = name.lower()
- incomplete = False
- if "(incomplete)" in name:
- incomplete = True
- name = name.replace("(incomplete)", "").strip()
- assert name in {"sat", "unsat", "valid", "invalid", "unknown"}, \
- "can't interpret result = {}".format(name)
-
- self._name = name
- self._explanation = explanation
- self._incomplete = incomplete
-
- def __bool__(self):
- if self._name in {"sat", "valid"}:
- return True
- elif self._name in {"unsat", "invalid"}:
- return False
- elif self._name == "unknown":
- raise RuntimeError("Cannot interpret 'unknown' result as a Boolean")
- else:
- assert False, "Unhandled result=%s"%self._name
+cdef class Result:
+ cdef c_Result cr
+ def __cinit__(self):
+ # gets populated by solver
+ self.cr = c_Result()
- def __eq__(self, other):
- if not isinstance(other, Result):
- return False
+ def isNull(self):
+ return self.cr.isNull()
- return self._name == other._name
+ def isSat(self):
+ return self.cr.isSat()
- def __ne__(self, other):
- return not self.__eq__(other)
+ def isUnsat(self):
+ return self.cr.isUnsat()
- def __str__(self):
- return self._name
+ def isSatUnknown(self):
+ return self.cr.isSatUnknown()
- def __repr__(self):
- return self._name
+ def isEntailed(self):
+ return self.cr.isEntailed()
+
+ def isNotEntailed(self):
+ return self.cr.isNotEntailed()
+
+ def isEntailmentUnknown(self):
+ return self.cr.isEntailmentUnknown()
- def isUnknown(self):
- return self._name == "unknown"
+ def __eq__(self, Result other):
+ return self.cr == other.cr
- def isIncomplete(self):
- return self._incomplete
+ def __ne__(self, Result other):
+ return self.cr != other.cr
- @property
- def explanation(self):
- return self._explanation
+ def getUnknownExplanation(self):
+ return self.cr.getUnknownExplanation().decode()
+
+ def __str__(self):
+ return self.cr.toString().decode()
+
+ def __repr__(self):
+ return self.cr.toString().decode()
cdef class RoundingMode:
@@ -663,6 +669,11 @@ cdef class Solver:
(<str?> symbol).encode())
return term
+ def mkDatatypeConstructorDecl(self, str name):
+ cdef DatatypeConstructorDecl ddc = DatatypeConstructorDecl()
+ ddc.cddc = self.csolver.mkDatatypeConstructorDecl(name.encode())
+ return ddc
+
def mkDatatypeDecl(self, str name, sorts_or_bool=None, isCoDatatype=None):
cdef DatatypeDecl dd = DatatypeDecl()
cdef vector[c_Sort] v
@@ -716,12 +727,9 @@ cdef class Solver:
self.csolver.assertFormula(term.cterm)
def checkSat(self):
- cdef c_Result r = self.csolver.checkSat()
- name = r.toString().decode()
- explanation = ""
- if r.isSatUnknown():
- explanation = r.getUnknownExplanation().decode()
- return Result(name, explanation)
+ cdef Result r = Result()
+ r.cr = self.csolver.checkSat()
+ return r
@expand_list_arg(num_req_args=0)
def checkSatAssuming(self, *assumptions):
@@ -732,17 +740,13 @@ cdef class Solver:
where assumptions can also be comma-separated arguments of
type (boolean) Term
'''
- cdef c_Result r
+ cdef Result r = Result()
# used if assumptions is a list of terms
cdef vector[c_Term] v
for a in assumptions:
v.push_back((<Term?> a).cterm)
- r = self.csolver.checkSatAssuming(<const vector[c_Term]&> v)
- name = r.toString().decode()
- explanation = ""
- if r.isSatUnknown():
- explanation = r.getUnknownExplanation().decode()
- return Result(name, explanation)
+ r.cr = self.csolver.checkSatAssuming(<const vector[c_Term]&> v)
+ return r
@expand_list_arg(num_req_args=0)
def checkEntailed(self, *assumptions):
@@ -753,17 +757,13 @@ cdef class Solver:
where assumptions can also be comma-separated arguments of
type (boolean) Term
'''
- cdef c_Result r
+ cdef Result r = Result()
# used if assumptions is a list of terms
cdef vector[c_Term] v
for a in assumptions:
v.push_back((<Term?> a).cterm)
- r = self.csolver.checkEntailed(<const vector[c_Term]&> v)
- name = r.toString().decode()
- explanation = ""
- if r.isEntailmentUnknown():
- explanation = r.getUnknownExplanation().decode()
- return Result(name, explanation)
+ r.cr = self.csolver.checkEntailed(<const vector[c_Term]&> v)
+ return r
@expand_list_arg(num_req_args=1)
def declareDatatype(self, str symbol, *ctors):
@@ -778,7 +778,7 @@ cdef class Solver:
cdef vector[c_DatatypeConstructorDecl] v
for c in ctors:
- v.push_back((<DatatypeConstructorDecl?> c).cddc[0])
+ v.push_back((<DatatypeConstructorDecl?> c).cddc)
sort.csort = self.csolver.declareDatatype(symbol.encode(), v)
return sort
@@ -953,6 +953,9 @@ cdef class Sort:
def __repr__(self):
return self.csort.toString().decode()
+ def __hash__(self):
+ return csorthash(self.csort)
+
def isBoolean(self):
return self.csort.isBoolean()
@@ -1054,6 +1057,9 @@ cdef class Term:
term.cterm = ci
yield term
+ def __hash__(self):
+ return ctermhash(self.cterm)
+
def getKind(self):
return kind(<int> self.cterm.getKind())
@@ -1062,6 +1068,23 @@ cdef class Term:
sort.csort = self.cterm.getSort()
return sort
+ def substitute(self, list es, list replacements):
+ cdef vector[c_Term] ces
+ cdef vector[c_Term] creplacements
+ cdef Term term = Term()
+
+ if len(es) != len(replacements):
+ raise RuntimeError("Expecting list inputs to substitute to "
+ "have the same length but got: "
+ "{} and {}".format(len(es), len(replacements)))
+
+ for e, r in zip(es, replacements):
+ ces.push_back((<Term?> e).cterm)
+ creplacements.push_back((<Term?> r).cterm)
+
+ term.cterm = self.cterm.substitute(ces, creplacements)
+ return term
+
def hasOp(self):
return self.cterm.hasOp()
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback