1 from collections import defaultdict
2 from fractions import Fraction
5 from libc.stdint cimport int32_t, int64_t, uint32_t, uint64_t
6 from libc.stddef cimport wchar_t
8 from libcpp.pair cimport pair
9 from libcpp.set cimport set
10 from libcpp.string cimport string
11 from libcpp.vector cimport vector
13 from cvc5 cimport cout
14 from cvc5 cimport Datatype as c_Datatype
15 from cvc5 cimport DatatypeConstructor as c_DatatypeConstructor
16 from cvc5 cimport DatatypeConstructorDecl as c_DatatypeConstructorDecl
17 from cvc5 cimport DatatypeDecl as c_DatatypeDecl
18 from cvc5 cimport DatatypeSelector as c_DatatypeSelector
19 from cvc5 cimport Result as c_Result
20 from cvc5 cimport RoundingMode as c_RoundingMode
21 from cvc5 cimport Op as c_Op
22 from cvc5 cimport Solver as c_Solver
23 from cvc5 cimport Grammar as c_Grammar
24 from cvc5 cimport Sort as c_Sort
25 from cvc5 cimport ROUND_NEAREST_TIES_TO_EVEN, ROUND_TOWARD_POSITIVE
26 from cvc5 cimport ROUND_TOWARD_NEGATIVE, ROUND_TOWARD_ZERO
27 from cvc5 cimport ROUND_NEAREST_TIES_TO_AWAY
28 from cvc5 cimport Term as c_Term
29 from cvc5 cimport hash as c_hash
30 from cvc5 cimport wstring as c_wstring
32 from cvc5kinds cimport Kind as c_Kind
34 cdef extern from "Python.h":
35 wchar_t* PyUnicode_AsWideCharString(object, Py_ssize_t *)
36 object PyUnicode_FromWideChar(const wchar_t*, Py_ssize_t)
37 void PyMem_Free(void*)
39 ################################## DECORATORS #################################
40 def expand_list_arg(num_req_args=0):
42 Creates a decorator that looks at index num_req_args of the args,
43 if it's a list, it expands it before calling the function.
46 def wrapper(owner, *args):
47 if len(args) == num_req_args + 1 and \
48 isinstance(args[num_req_args], list):
49 args = list(args[:num_req_args]) + args[num_req_args]
50 return func(owner, *args)
53 ###############################################################################
56 ### Using PEP-8 spacing recommendations
57 ### Limit linewidth to 79 characters
58 ### Break before binary operators
59 ### surround top level functions and classes with two spaces
60 ### separate methods by one space
61 ### use spaces in functions sparingly to separate logical blocks
62 ### can omit spaces between unrelated oneliners
63 ### always use c++ default arguments
64 #### only use default args of None at python level
66 # References and pointers
67 # The Solver object holds a pointer to a c_Solver.
68 # This is because the assignment operator is deleted in the C++ API for solvers.
69 # Cython has a limitation where you can't stack allocate objects
70 # that have constructors with arguments:
71 # https://groups.google.com/forum/#!topic/cython-users/fuKd-nQLpBs.
72 # To get around that you can either have a nullary constructor and assignment
73 # or, use a pointer (which is what we chose).
74 # An additional complication of this is that to free up resources, you must
75 # know when to delete the object.
76 # Python will not follow the same scoping rules as in C++, so it must be
77 # able to reference count. To do this correctly, the solver must be a
78 # reference in the Python class for any class that keeps a pointer to
79 # the solver in C++ (to ensure the solver is not deleted before something
80 # that depends on it).
83 ## Objects for hashing
84 cdef c_hash[c_Op] cophash = c_hash[c_Op]()
85 cdef c_hash[c_Sort] csorthash = c_hash[c_Sort]()
86 cdef c_hash[c_Term] ctermhash = c_hash[c_Term]()
90 """Wrapper class for :cpp:class:`cvc5::api::Datatype`."""
93 def __cinit__(self, Solver solver):
96 def __getitem__(self, index):
97 """Return a constructor by index or by name."""
98 cdef DatatypeConstructor dc = DatatypeConstructor(self.solver)
99 if isinstance(index, int) and index >= 0:
100 dc.cdc = self.cd[(<int?> index)]
101 elif isinstance(index, str):
102 dc.cdc = self.cd[(<const string &> index.encode())]
104 raise ValueError("Expecting a non-negative integer or string")
107 def getConstructor(self, str name):
108 """Return a constructor by name."""
109 cdef DatatypeConstructor dc = DatatypeConstructor(self.solver)
110 dc.cdc = self.cd.getConstructor(name.encode())
113 def getConstructorTerm(self, str name):
114 """:return: the term representing the datatype constructor with the given name (see :cpp:func:`Datatype::getConstructorTerm() <cvc5::api::Datatype::getConstructorTerm>`)."""
115 cdef Term term = Term(self.solver)
116 term.cterm = self.cd.getConstructorTerm(name.encode())
119 def getSelector(self, str name):
120 """Return a selector by name."""
121 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
122 ds.cds = self.cd.getSelector(name.encode())
125 def getNumConstructors(self):
126 """:return: number of constructors."""
127 return self.cd.getNumConstructors()
129 def isParametric(self):
130 """:return: whether this datatype is parametric."""
131 return self.cd.isParametric()
133 def isCodatatype(self):
134 """:return: whether this datatype corresponds to a co-datatype."""
135 return self.cd.isCodatatype()
138 """:return: whether this datatype corresponds to a tuple."""
139 return self.cd.isTuple()
142 """:return: whether this datatype corresponds to a record."""
143 return self.cd.isRecord()
146 """:return: whether this datatype is finite."""
147 return self.cd.isFinite()
149 def isWellFounded(self):
150 """:return: whether this datatype is well-founded (see :cpp:func:`Datatype::isWellFounded() <cvc5::api::Datatype::isWellFounded>`)."""
151 return self.cd.isWellFounded()
153 def hasNestedRecursion(self):
154 """:return: whether this datatype has nested recursion (see :cpp:func:`Datatype::hasNestedRecursion() <cvc5::api::Datatype::hasNestedRecursion>`)."""
155 return self.cd.hasNestedRecursion()
158 return self.cd.toString().decode()
161 return self.cd.toString().decode()
165 dc = DatatypeConstructor(self.solver)
170 cdef class DatatypeConstructor:
171 cdef c_DatatypeConstructor cdc
173 def __cinit__(self, Solver solver):
174 self.cdc = c_DatatypeConstructor()
177 def __getitem__(self, index):
178 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
179 if isinstance(index, int) and index >= 0:
180 ds.cds = self.cdc[(<int?> index)]
181 elif isinstance(index, str):
182 ds.cds = self.cdc[(<const string &> index.encode())]
184 raise ValueError("Expecting a non-negative integer or string")
188 return self.cdc.getName().decode()
190 def getConstructorTerm(self):
191 cdef Term term = Term(self.solver)
192 term.cterm = self.cdc.getConstructorTerm()
195 def getTesterTerm(self):
196 cdef Term term = Term(self.solver)
197 term.cterm = self.cdc.getTesterTerm()
200 def getNumSelectors(self):
201 return self.cdc.getNumSelectors()
203 def getSelector(self, str name):
204 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
205 ds.cds = self.cdc.getSelector(name.encode())
208 def getSelectorTerm(self, str name):
209 cdef Term term = Term(self.solver)
210 term.cterm = self.cdc.getSelectorTerm(name.encode())
214 return self.cdc.toString().decode()
217 return self.cdc.toString().decode()
221 ds = DatatypeSelector(self.solver)
226 cdef class DatatypeConstructorDecl:
227 cdef c_DatatypeConstructorDecl cddc
230 def __cinit__(self, Solver solver):
233 def addSelector(self, str name, Sort sort):
234 self.cddc.addSelector(name.encode(), sort.csort)
236 def addSelectorSelf(self, str name):
237 self.cddc.addSelectorSelf(name.encode())
240 return self.cddc.toString().decode()
243 return self.cddc.toString().decode()
246 cdef class DatatypeDecl:
247 cdef c_DatatypeDecl cdd
249 def __cinit__(self, Solver solver):
252 def addConstructor(self, DatatypeConstructorDecl ctor):
253 self.cdd.addConstructor(ctor.cddc)
255 def getNumConstructors(self):
256 return self.cdd.getNumConstructors()
258 def isParametric(self):
259 return self.cdd.isParametric()
262 return self.cdd.toString().decode()
265 return self.cdd.toString().decode()
268 cdef class DatatypeSelector:
269 cdef c_DatatypeSelector cds
271 def __cinit__(self, Solver solver):
272 self.cds = c_DatatypeSelector()
276 return self.cds.getName().decode()
278 def getSelectorTerm(self):
279 cdef Term term = Term(self.solver)
280 term.cterm = self.cds.getSelectorTerm()
283 def getUpdaterTerm(self):
284 cdef Term term = Term(self.solver)
285 term.cterm = self.cds.getUpdaterTerm()
288 def getRangeSort(self):
289 cdef Sort sort = Sort(self.solver)
290 sort.csort = self.cds.getRangeSort()
294 return self.cds.toString().decode()
297 return self.cds.toString().decode()
303 def __cinit__(self, Solver solver):
307 def __eq__(self, Op other):
308 return self.cop == other.cop
310 def __ne__(self, Op other):
311 return self.cop != other.cop
314 return self.cop.toString().decode()
317 return self.cop.toString().decode()
320 return cophash(self.cop)
323 return kind(<int> self.cop.getKind())
326 return self.cop.isIndexed()
329 return self.cop.isNull()
331 def getIndices(self):
334 indices = self.cop.getIndices[string]()
339 indices = self.cop.getIndices[uint32_t]()
344 indices = self.cop.getIndices[pair[uint32_t, uint32_t]]()
349 raise RuntimeError("Unable to retrieve indices from {}".format(self))
354 cdef c_Grammar cgrammar
356 def __cinit__(self, Solver solver):
358 self.cgrammar = c_Grammar()
360 def addRule(self, Term ntSymbol, Term rule):
361 self.cgrammar.addRule(ntSymbol.cterm, rule.cterm)
363 def addAnyConstant(self, Term ntSymbol):
364 self.cgrammar.addAnyConstant(ntSymbol.cterm)
366 def addAnyVariable(self, Term ntSymbol):
367 self.cgrammar.addAnyVariable(ntSymbol.cterm)
369 def addRules(self, Term ntSymbol, rules):
370 cdef vector[c_Term] crules
372 crules.push_back((<Term?> r).cterm)
373 self.cgrammar.addRules(ntSymbol.cterm, crules)
378 # gets populated by solver
382 return self.cr.isNull()
385 return self.cr.isSat()
388 return self.cr.isUnsat()
390 def isSatUnknown(self):
391 return self.cr.isSatUnknown()
393 def isEntailed(self):
394 return self.cr.isEntailed()
396 def isNotEntailed(self):
397 return self.cr.isNotEntailed()
399 def isEntailmentUnknown(self):
400 return self.cr.isEntailmentUnknown()
402 def __eq__(self, Result other):
403 return self.cr == other.cr
405 def __ne__(self, Result other):
406 return self.cr != other.cr
408 def getUnknownExplanation(self):
409 return self.cr.getUnknownExplanation().decode()
412 return self.cr.toString().decode()
415 return self.cr.toString().decode()
418 cdef class RoundingMode:
419 cdef c_RoundingMode crm
421 def __cinit__(self, int rm):
422 # crm always assigned externally
423 self.crm = <c_RoundingMode> rm
424 self.name = __rounding_modes[rm]
426 def __eq__(self, RoundingMode other):
427 return (<int> self.crm) == (<int> other.crm)
429 def __ne__(self, RoundingMode other):
430 return not self.__eq__(other)
433 return hash((<int> self.crm, self.name))
443 cdef c_Solver* csolver
446 self.csolver = new c_Solver(NULL)
448 def __dealloc__(self):
451 def supportsFloatingPoint(self):
452 return self.csolver.supportsFloatingPoint()
454 def getBooleanSort(self):
455 cdef Sort sort = Sort(self)
456 sort.csort = self.csolver.getBooleanSort()
459 def getIntegerSort(self):
460 cdef Sort sort = Sort(self)
461 sort.csort = self.csolver.getIntegerSort()
464 def getRealSort(self):
465 cdef Sort sort = Sort(self)
466 sort.csort = self.csolver.getRealSort()
469 def getRegExpSort(self):
470 cdef Sort sort = Sort(self)
471 sort.csort = self.csolver.getRegExpSort()
474 def getRoundingModeSort(self):
475 cdef Sort sort = Sort(self)
476 sort.csort = self.csolver.getRoundingModeSort()
479 def getStringSort(self):
480 cdef Sort sort = Sort(self)
481 sort.csort = self.csolver.getStringSort()
484 def mkArraySort(self, Sort indexSort, Sort elemSort):
485 cdef Sort sort = Sort(self)
486 sort.csort = self.csolver.mkArraySort(indexSort.csort, elemSort.csort)
489 def mkBitVectorSort(self, uint32_t size):
490 cdef Sort sort = Sort(self)
491 sort.csort = self.csolver.mkBitVectorSort(size)
494 def mkFloatingPointSort(self, uint32_t exp, uint32_t sig):
495 cdef Sort sort = Sort(self)
496 sort.csort = self.csolver.mkFloatingPointSort(exp, sig)
499 def mkDatatypeSort(self, DatatypeDecl dtypedecl):
500 cdef Sort sort = Sort(self)
501 sort.csort = self.csolver.mkDatatypeSort(dtypedecl.cdd)
504 def mkDatatypeSorts(self, list dtypedecls, unresolvedSorts):
507 cdef vector[c_DatatypeDecl] decls
508 for decl in dtypedecls:
509 decls.push_back((<DatatypeDecl?> decl).cdd)
511 cdef set[c_Sort] usorts
512 for usort in unresolvedSorts:
513 usorts.insert((<Sort?> usort).csort)
515 csorts = self.csolver.mkDatatypeSorts(
516 <const vector[c_DatatypeDecl]&> decls, <const set[c_Sort]&> usorts)
524 def mkFunctionSort(self, sorts, Sort codomain):
526 cdef Sort sort = Sort(self)
527 # populate a vector with dereferenced c_Sorts
528 cdef vector[c_Sort] v
530 if isinstance(sorts, Sort):
531 sort.csort = self.csolver.mkFunctionSort((<Sort?> sorts).csort,
533 elif isinstance(sorts, list):
535 v.push_back((<Sort?>s).csort)
537 sort.csort = self.csolver.mkFunctionSort(<const vector[c_Sort]&> v,
541 def mkParamSort(self, symbolname):
542 cdef Sort sort = Sort(self)
543 sort.csort = self.csolver.mkParamSort(symbolname.encode())
546 @expand_list_arg(num_req_args=0)
547 def mkPredicateSort(self, *sorts):
549 Supports the following arguments:
550 Sort mkPredicateSort(List[Sort] sorts)
552 where sorts can also be comma-separated arguments of
555 cdef Sort sort = Sort(self)
556 cdef vector[c_Sort] v
558 v.push_back((<Sort?> s).csort)
559 sort.csort = self.csolver.mkPredicateSort(<const vector[c_Sort]&> v)
562 @expand_list_arg(num_req_args=0)
563 def mkRecordSort(self, *fields):
565 Supports the following arguments:
566 Sort mkRecordSort(List[Tuple[str, Sort]] fields)
568 where fields can also be comma-separated arguments of
569 type Tuple[str, Sort]
571 cdef Sort sort = Sort(self)
572 cdef vector[pair[string, c_Sort]] v
573 cdef pair[string, c_Sort] p
577 p = pair[string, c_Sort](<string?> name, (<Sort?> sortarg).csort)
579 sort.csort = self.csolver.mkRecordSort(
580 <const vector[pair[string, c_Sort]] &> v)
583 def mkSetSort(self, Sort elemSort):
584 cdef Sort sort = Sort(self)
585 sort.csort = self.csolver.mkSetSort(elemSort.csort)
588 def mkBagSort(self, Sort elemSort):
589 cdef Sort sort = Sort(self)
590 sort.csort = self.csolver.mkBagSort(elemSort.csort)
593 def mkSequenceSort(self, Sort elemSort):
594 cdef Sort sort = Sort(self)
595 sort.csort = self.csolver.mkSequenceSort(elemSort.csort)
598 def mkUninterpretedSort(self, str name):
599 cdef Sort sort = Sort(self)
600 sort.csort = self.csolver.mkUninterpretedSort(name.encode())
603 def mkSortConstructorSort(self, str symbol, size_t arity):
604 cdef Sort sort = Sort(self)
605 sort.csort =self.csolver.mkSortConstructorSort(symbol.encode(), arity)
608 @expand_list_arg(num_req_args=0)
609 def mkTupleSort(self, *sorts):
611 Supports the following arguments:
612 Sort mkTupleSort(List[Sort] sorts)
614 where sorts can also be comma-separated arguments of
617 cdef Sort sort = Sort(self)
618 cdef vector[c_Sort] v
620 v.push_back((<Sort?> s).csort)
621 sort.csort = self.csolver.mkTupleSort(v)
624 @expand_list_arg(num_req_args=1)
625 def mkTerm(self, kind_or_op, *args):
627 Supports the following arguments:
628 Term mkTerm(Kind kind)
629 Term mkTerm(Kind kind, Op child1, List[Term] children)
630 Term mkTerm(Kind kind, List[Term] children)
632 where List[Term] can also be comma-separated arguments
634 cdef Term term = Term(self)
635 cdef vector[c_Term] v
638 if isinstance(kind_or_op, kind):
639 op = self.mkOp(kind_or_op)
642 term.cterm = self.csolver.mkTerm((<Op?> op).cop)
645 v.push_back((<Term?> a).cterm)
646 term.cterm = self.csolver.mkTerm((<Op?> op).cop, v)
649 def mkOp(self, kind k, arg0=None, arg1 = None):
651 Supports the following uses:
653 Op mkOp(Kind kind, Kind k)
654 Op mkOp(Kind kind, const string& arg)
655 Op mkOp(Kind kind, uint32_t arg)
656 Op mkOp(Kind kind, uint32_t arg0, uint32_t arg1)
658 cdef Op op = Op(self)
661 op.cop = self.csolver.mkOp(k.k)
663 if isinstance(arg0, kind):
664 op.cop = self.csolver.mkOp(k.k, (<kind?> arg0).k)
665 elif isinstance(arg0, str):
666 op.cop = self.csolver.mkOp(k.k,
669 elif isinstance(arg0, int):
670 op.cop = self.csolver.mkOp(k.k, <int?> arg0)
672 raise ValueError("Unsupported signature"
673 " mkOp: {}".format(" X ".join([str(k), str(arg0)])))
675 if isinstance(arg0, int) and isinstance(arg1, int):
676 op.cop = self.csolver.mkOp(k.k, <int> arg0,
679 raise ValueError("Unsupported signature"
680 " mkOp: {}".format(" X ".join([k, arg0, arg1])))
684 cdef Term term = Term(self)
685 term.cterm = self.csolver.mkTrue()
689 cdef Term term = Term(self)
690 term.cterm = self.csolver.mkFalse()
693 def mkBoolean(self, bint val):
694 cdef Term term = Term(self)
695 term.cterm = self.csolver.mkBoolean(val)
699 cdef Term term = Term(self)
700 term.cterm = self.csolver.mkPi()
703 def mkInteger(self, val):
704 cdef Term term = Term(self)
705 if isinstance(val, str):
706 term.cterm = self.csolver.mkInteger(<const string &> str(val).encode())
708 assert(isinstance(val, int))
709 term.cterm = self.csolver.mkInteger((<int?> val))
712 def mkReal(self, val, den=None):
713 cdef Term term = Term(self)
715 term.cterm = self.csolver.mkReal(str(val).encode())
717 if not isinstance(val, int) or not isinstance(den, int):
718 raise ValueError("Expecting integers when"
719 " constructing a rational"
720 " but got: {}".format((val, den)))
721 term.cterm = self.csolver.mkReal("{}/{}".format(val, den).encode())
724 def mkRegexpEmpty(self):
725 cdef Term term = Term(self)
726 term.cterm = self.csolver.mkRegexpEmpty()
729 def mkRegexpSigma(self):
730 cdef Term term = Term(self)
731 term.cterm = self.csolver.mkRegexpSigma()
734 def mkEmptySet(self, Sort s):
735 cdef Term term = Term(self)
736 term.cterm = self.csolver.mkEmptySet(s.csort)
740 def mkSepNil(self, Sort sort):
741 cdef Term term = Term(self)
742 term.cterm = self.csolver.mkSepNil(sort.csort)
745 def mkString(self, str s):
746 cdef Term term = Term(self)
748 cdef wchar_t* tmp = PyUnicode_AsWideCharString(s, &size)
749 term.cterm = self.csolver.mkString(c_wstring(tmp, size))
753 def mkEmptySequence(self, Sort sort):
754 cdef Term term = Term(self)
755 term.cterm = self.csolver.mkEmptySequence(sort.csort)
758 def mkUniverseSet(self, Sort sort):
759 cdef Term term = Term(self)
760 term.cterm = self.csolver.mkUniverseSet(sort.csort)
763 @expand_list_arg(num_req_args=0)
764 def mkBitVector(self, *args):
766 Supports the following arguments:
767 Term mkBitVector(int size, int val=0)
768 Term mkBitVector(string val, int base = 2)
769 Term mkBitVector(int size, string val, int base)
771 cdef Term term = Term(self)
773 size_or_val = args[0]
774 if isinstance(args[0], int):
776 term.cterm = self.csolver.mkBitVector(<uint32_t> size)
778 assert isinstance(args[0], str)
780 term.cterm = self.csolver.mkBitVector(<const string&> str(val).encode())
782 if isinstance(args[0], int):
784 assert isinstance(args[1], int)
786 term.cterm = self.csolver.mkBitVector(<uint32_t> size, <uint32_t> val)
788 assert isinstance(args[0], str)
789 assert isinstance(args[1], int)
792 term.cterm = self.csolver.mkBitVector(<const string&> str(val).encode(), <uint32_t> base)
794 assert isinstance(args[0], int)
795 assert isinstance(args[1], str)
796 assert isinstance(args[2], int)
800 term.cterm = self.csolver.mkBitVector(<uint32_t> size, <const string&> str(val).encode(), <uint32_t> base)
804 def mkBitVector(self, size_or_str, val = None):
805 cdef Term term = Term(self)
806 if isinstance(size_or_str, int):
808 term.cterm = self.csolver.mkBitVector(<uint32_t> size_or_str)
810 term.cterm = self.csolver.mkBitVector(<uint32_t> size_or_str,
811 <const string &> str(val).encode(),
813 elif isinstance(size_or_str, str):
814 # handle default value
816 term.cterm = self.csolver.mkBitVector(
817 <const string &> size_or_str.encode())
819 term.cterm = self.csolver.mkBitVector(
820 <const string &> size_or_str.encode(), <uint32_t> val)
822 raise ValueError("Unexpected inputs {} to"
823 " mkBitVector".format((size_or_str, val)))
826 def mkConstArray(self, Sort sort, Term val):
827 cdef Term term = Term(self)
828 term.cterm = self.csolver.mkConstArray(sort.csort, val.cterm)
831 def mkPosInf(self, int exp, int sig):
832 cdef Term term = Term(self)
833 term.cterm = self.csolver.mkPosInf(exp, sig)
836 def mkNegInf(self, int exp, int sig):
837 cdef Term term = Term(self)
838 term.cterm = self.csolver.mkNegInf(exp, sig)
841 def mkNaN(self, int exp, int sig):
842 cdef Term term = Term(self)
843 term.cterm = self.csolver.mkNaN(exp, sig)
846 def mkPosZero(self, int exp, int sig):
847 cdef Term term = Term(self)
848 term.cterm = self.csolver.mkPosZero(exp, sig)
851 def mkNegZero(self, int exp, int sig):
852 cdef Term term = Term(self)
853 term.cterm = self.csolver.mkNegZero(exp, sig)
856 def mkRoundingMode(self, RoundingMode rm):
857 cdef Term term = Term(self)
858 term.cterm = self.csolver.mkRoundingMode(<c_RoundingMode> rm.crm)
861 def mkUninterpretedConst(self, Sort sort, int index):
862 cdef Term term = Term(self)
863 term.cterm = self.csolver.mkUninterpretedConst(sort.csort, index)
866 def mkAbstractValue(self, index):
867 cdef Term term = Term(self)
869 term.cterm = self.csolver.mkAbstractValue(str(index).encode())
871 raise ValueError("mkAbstractValue expects a str representing a number"
872 " or an int, but got{}".format(index))
875 def mkFloatingPoint(self, int exp, int sig, Term val):
876 cdef Term term = Term(self)
877 term.cterm = self.csolver.mkFloatingPoint(exp, sig, val.cterm)
880 def mkConst(self, Sort sort, symbol=None):
881 cdef Term term = Term(self)
883 term.cterm = self.csolver.mkConst(sort.csort)
885 term.cterm = self.csolver.mkConst(sort.csort,
886 (<str?> symbol).encode())
889 def mkVar(self, Sort sort, symbol=None):
890 cdef Term term = Term(self)
892 term.cterm = self.csolver.mkVar(sort.csort)
894 term.cterm = self.csolver.mkVar(sort.csort,
895 (<str?> symbol).encode())
898 def mkDatatypeConstructorDecl(self, str name):
899 cdef DatatypeConstructorDecl ddc = DatatypeConstructorDecl(self)
900 ddc.cddc = self.csolver.mkDatatypeConstructorDecl(name.encode())
903 def mkDatatypeDecl(self, str name, sorts_or_bool=None, isCoDatatype=None):
904 cdef DatatypeDecl dd = DatatypeDecl(self)
905 cdef vector[c_Sort] v
908 if sorts_or_bool is None and isCoDatatype is None:
909 dd.cdd = self.csolver.mkDatatypeDecl(name.encode())
910 elif sorts_or_bool is not None and isCoDatatype is None:
911 if isinstance(sorts_or_bool, bool):
912 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
913 <bint> sorts_or_bool)
914 elif isinstance(sorts_or_bool, Sort):
915 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
916 (<Sort> sorts_or_bool).csort)
917 elif isinstance(sorts_or_bool, list):
918 for s in sorts_or_bool:
919 v.push_back((<Sort?> s).csort)
920 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
921 <const vector[c_Sort]&> v)
923 raise ValueError("Unhandled second argument type {}"
924 .format(type(sorts_or_bool)))
925 elif sorts_or_bool is not None and isCoDatatype is not None:
926 if isinstance(sorts_or_bool, Sort):
927 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
928 (<Sort> sorts_or_bool).csort,
930 elif isinstance(sorts_or_bool, list):
931 for s in sorts_or_bool:
932 v.push_back((<Sort?> s).csort)
933 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
934 <const vector[c_Sort]&> v,
937 raise ValueError("Unhandled second argument type {}"
938 .format(type(sorts_or_bool)))
940 raise ValueError("Can't create DatatypeDecl with {}".format([type(a)
947 def simplify(self, Term t):
948 cdef Term term = Term(self)
949 term.cterm = self.csolver.simplify(t.cterm)
952 def assertFormula(self, Term term):
953 self.csolver.assertFormula(term.cterm)
956 cdef Result r = Result()
957 r.cr = self.csolver.checkSat()
960 def mkSygusGrammar(self, boundVars, ntSymbols):
961 cdef Grammar grammar = Grammar(self)
962 cdef vector[c_Term] bvc
963 cdef vector[c_Term] ntc
965 bvc.push_back((<Term?> bv).cterm)
967 ntc.push_back((<Term?> nt).cterm)
968 grammar.cgrammar = self.csolver.mkSygusGrammar(<const vector[c_Term]&> bvc, <const vector[c_Term]&> ntc)
971 def mkSygusVar(self, Sort sort, str symbol=""):
972 cdef Term term = Term(self)
973 term.cterm = self.csolver.mkSygusVar(sort.csort, symbol.encode())
976 def addSygusConstraint(self, Term t):
977 self.csolver.addSygusConstraint(t.cterm)
979 def addSygusInvConstraint(self, Term inv_f, Term pre_f, Term trans_f, Term post_f):
980 self.csolver.addSygusInvConstraint(inv_f.cterm, pre_f.cterm, trans_f.cterm, post_f.cterm)
982 def synthFun(self, str symbol, bound_vars, Sort sort, Grammar grammar=None):
983 cdef Term term = Term(self)
984 cdef vector[c_Term] v
985 for bv in bound_vars:
986 v.push_back((<Term?> bv).cterm)
988 term.cterm = self.csolver.synthFun(symbol.encode(), <const vector[c_Term]&> v, sort.csort)
990 term.cterm = self.csolver.synthFun(symbol.encode(), <const vector[c_Term]&> v, sort.csort, grammar.cgrammar)
993 def checkSynth(self):
994 cdef Result r = Result()
995 r.cr = self.csolver.checkSynth()
998 def getSynthSolution(self, Term term):
999 cdef Term t = Term(self)
1000 t.cterm = self.csolver.getSynthSolution(term.cterm)
1003 def getSynthSolutions(self, list terms):
1005 cdef vector[c_Term] vec
1007 vec.push_back((<Term?> t).cterm)
1008 cresult = self.csolver.getSynthSolutions(vec)
1016 def synthInv(self, symbol, bound_vars, Grammar grammar=None):
1017 cdef Term term = Term(self)
1018 cdef vector[c_Term] v
1019 for bv in bound_vars:
1020 v.push_back((<Term?> bv).cterm)
1022 term.cterm = self.csolver.synthInv(symbol.encode(), <const vector[c_Term]&> v)
1024 term.cterm = self.csolver.synthInv(symbol.encode(), <const vector[c_Term]&> v, grammar.cgrammar)
1027 @expand_list_arg(num_req_args=0)
1028 def checkSatAssuming(self, *assumptions):
1030 Supports the following arguments:
1031 Result checkSatAssuming(List[Term] assumptions)
1033 where assumptions can also be comma-separated arguments of
1036 cdef Result r = Result()
1037 # used if assumptions is a list of terms
1038 cdef vector[c_Term] v
1039 for a in assumptions:
1040 v.push_back((<Term?> a).cterm)
1041 r.cr = self.csolver.checkSatAssuming(<const vector[c_Term]&> v)
1044 @expand_list_arg(num_req_args=0)
1045 def checkEntailed(self, *assumptions):
1047 Supports the following arguments:
1048 Result checkEntailed(List[Term] assumptions)
1050 where assumptions can also be comma-separated arguments of
1053 cdef Result r = Result()
1054 # used if assumptions is a list of terms
1055 cdef vector[c_Term] v
1056 for a in assumptions:
1057 v.push_back((<Term?> a).cterm)
1058 r.cr = self.csolver.checkEntailed(<const vector[c_Term]&> v)
1061 @expand_list_arg(num_req_args=1)
1062 def declareDatatype(self, str symbol, *ctors):
1064 Supports the following arguments:
1065 Sort declareDatatype(str symbol, List[Term] ctors)
1067 where ctors can also be comma-separated arguments of
1068 type DatatypeConstructorDecl
1070 cdef Sort sort = Sort(self)
1071 cdef vector[c_DatatypeConstructorDecl] v
1074 v.push_back((<DatatypeConstructorDecl?> c).cddc)
1075 sort.csort = self.csolver.declareDatatype(symbol.encode(), v)
1078 def declareFun(self, str symbol, list sorts, Sort sort):
1079 cdef Term term = Term(self)
1080 cdef vector[c_Sort] v
1082 v.push_back((<Sort?> s).csort)
1083 term.cterm = self.csolver.declareFun(symbol.encode(),
1084 <const vector[c_Sort]&> v,
1088 def declareSort(self, str symbol, int arity):
1089 cdef Sort sort = Sort(self)
1090 sort.csort = self.csolver.declareSort(symbol.encode(), arity)
1093 def defineFun(self, sym_or_fun, bound_vars, sort_or_term, t=None, glbl=False):
1096 Term defineFun(str symbol, List[Term] bound_vars,
1097 Sort sort, Term term, bool glbl)
1098 Term defineFun(Term fun, List[Term] bound_vars,
1099 Term term, bool glbl)
1101 cdef Term term = Term(self)
1102 cdef vector[c_Term] v
1103 for bv in bound_vars:
1104 v.push_back((<Term?> bv).cterm)
1107 term.cterm = self.csolver.defineFun((<str?> sym_or_fun).encode(),
1108 <const vector[c_Term] &> v,
1109 (<Sort?> sort_or_term).csort,
1113 term.cterm = self.csolver.defineFun((<Term?> sym_or_fun).cterm,
1114 <const vector[c_Term]&> v,
1115 (<Term?> sort_or_term).cterm,
1120 def defineFunRec(self, sym_or_fun, bound_vars, sort_or_term, t=None, glbl=False):
1123 Term defineFunRec(str symbol, List[Term] bound_vars,
1124 Sort sort, Term term, bool glbl)
1125 Term defineFunRec(Term fun, List[Term] bound_vars,
1126 Term term, bool glbl)
1128 cdef Term term = Term(self)
1129 cdef vector[c_Term] v
1130 for bv in bound_vars:
1131 v.push_back((<Term?> bv).cterm)
1134 term.cterm = self.csolver.defineFunRec((<str?> sym_or_fun).encode(),
1135 <const vector[c_Term] &> v,
1136 (<Sort?> sort_or_term).csort,
1140 term.cterm = self.csolver.defineFunRec((<Term?> sym_or_fun).cterm,
1141 <const vector[c_Term]&> v,
1142 (<Term?> sort_or_term).cterm,
1147 def defineFunsRec(self, funs, bound_vars, terms):
1148 cdef vector[c_Term] vf
1149 cdef vector[vector[c_Term]] vbv
1150 cdef vector[c_Term] vt
1153 vf.push_back((<Term?> f).cterm)
1155 cdef vector[c_Term] temp
1156 for v in bound_vars:
1158 temp.push_back((<Term?> t).cterm)
1163 vf.push_back((<Term?> t).cterm)
1165 def getAssertions(self):
1167 for a in self.csolver.getAssertions():
1170 assertions.append(term)
1173 def getInfo(self, str flag):
1174 return self.csolver.getInfo(flag.encode())
1176 def getOption(self, str option):
1177 return self.csolver.getOption(option.encode())
1179 def getUnsatAssumptions(self):
1181 for a in self.csolver.getUnsatAssumptions():
1184 assumptions.append(term)
1187 def getUnsatCore(self):
1189 for a in self.csolver.getUnsatCore():
1195 def getValue(self, Term t):
1196 cdef Term term = Term(self)
1197 term.cterm = self.csolver.getValue(t.cterm)
1200 def getSeparationHeap(self):
1201 cdef Term term = Term(self)
1202 term.cterm = self.csolver.getSeparationHeap()
1205 def declareSeparationHeap(self, Sort locType, Sort dataType):
1206 self.csolver.declareSeparationHeap(locType.csort, dataType.csort)
1208 def getSeparationNilTerm(self):
1209 cdef Term term = Term(self)
1210 term.cterm = self.csolver.getSeparationNilTerm()
1213 def declarePool(self, str symbol, Sort sort, initValue):
1214 cdef Term term = Term(self)
1215 cdef vector[c_Term] niv
1217 niv.push_back((<Term?> v).cterm)
1218 term.cterm = self.csolver.declarePool(symbol.encode(), sort.csort, niv)
1221 def pop(self, nscopes=1):
1222 self.csolver.pop(nscopes)
1224 def push(self, nscopes=1):
1225 self.csolver.push(nscopes)
1227 def resetAssertions(self):
1228 self.csolver.resetAssertions()
1230 def setInfo(self, str keyword, str value):
1231 self.csolver.setInfo(keyword.encode(), value.encode())
1233 def setLogic(self, str logic):
1234 self.csolver.setLogic(logic.encode())
1236 def setOption(self, str option, str value):
1237 self.csolver.setOption(option.encode(), value.encode())
1243 def __cinit__(self, Solver solver):
1244 # csort always set by Solver
1245 self.solver = solver
1247 def __eq__(self, Sort other):
1248 return self.csort == other.csort
1250 def __ne__(self, Sort other):
1251 return self.csort != other.csort
1253 def __lt__(self, Sort other):
1254 return self.csort < other.csort
1256 def __gt__(self, Sort other):
1257 return self.csort > other.csort
1259 def __le__(self, Sort other):
1260 return self.csort <= other.csort
1262 def __ge__(self, Sort other):
1263 return self.csort >= other.csort
1266 return self.csort.toString().decode()
1269 return self.csort.toString().decode()
1272 return csorthash(self.csort)
1274 def isBoolean(self):
1275 return self.csort.isBoolean()
1277 def isInteger(self):
1278 return self.csort.isInteger()
1281 return self.csort.isReal()
1284 return self.csort.isString()
1287 return self.csort.isRegExp()
1289 def isRoundingMode(self):
1290 return self.csort.isRoundingMode()
1292 def isBitVector(self):
1293 return self.csort.isBitVector()
1295 def isFloatingPoint(self):
1296 return self.csort.isFloatingPoint()
1298 def isDatatype(self):
1299 return self.csort.isDatatype()
1301 def isParametricDatatype(self):
1302 return self.csort.isParametricDatatype()
1304 def isConstructor(self):
1305 return self.csort.isConstructor()
1307 def isSelector(self):
1308 return self.csort.isSelector()
1311 return self.csort.isTester()
1313 def isFunction(self):
1314 return self.csort.isFunction()
1316 def isPredicate(self):
1317 return self.csort.isPredicate()
1320 return self.csort.isTuple()
1323 return self.csort.isRecord()
1326 return self.csort.isArray()
1329 return self.csort.isSet()
1332 return self.csort.isBag()
1334 def isSequence(self):
1335 return self.csort.isSequence()
1337 def isUninterpretedSort(self):
1338 return self.csort.isUninterpretedSort()
1340 def isSortConstructor(self):
1341 return self.csort.isSortConstructor()
1343 def isFirstClass(self):
1344 return self.csort.isFirstClass()
1346 def isFunctionLike(self):
1347 return self.csort.isFunctionLike()
1349 def isSubsortOf(self, Sort sort):
1350 return self.csort.isSubsortOf(sort.csort)
1352 def isComparableTo(self, Sort sort):
1353 return self.csort.isComparableTo(sort.csort)
1355 def getDatatype(self):
1356 cdef Datatype d = Datatype(self.solver)
1357 d.cd = self.csort.getDatatype()
1360 def instantiate(self, params):
1361 cdef Sort sort = Sort(self.solver)
1362 cdef vector[c_Sort] v
1364 v.push_back((<Sort?> s).csort)
1365 sort.csort = self.csort.instantiate(v)
1368 def getConstructorArity(self):
1369 return self.csort.getConstructorArity()
1371 def getConstructorDomainSorts(self):
1373 for s in self.csort.getConstructorDomainSorts():
1374 sort = Sort(self.solver)
1376 domain_sorts.append(sort)
1379 def getConstructorCodomainSort(self):
1380 cdef Sort sort = Sort(self.solver)
1381 sort.csort = self.csort.getConstructorCodomainSort()
1384 def getSelectorDomainSort(self):
1385 cdef Sort sort = Sort(self.solver)
1386 sort.csort = self.csort.getSelectorDomainSort()
1389 def getSelectorCodomainSort(self):
1390 cdef Sort sort = Sort(self.solver)
1391 sort.csort = self.csort.getSelectorCodomainSort()
1394 def getTesterDomainSort(self):
1395 cdef Sort sort = Sort(self.solver)
1396 sort.csort = self.csort.getTesterDomainSort()
1399 def getTesterCodomainSort(self):
1400 cdef Sort sort = Sort(self.solver)
1401 sort.csort = self.csort.getTesterCodomainSort()
1404 def getFunctionArity(self):
1405 return self.csort.getFunctionArity()
1407 def getFunctionDomainSorts(self):
1409 for s in self.csort.getFunctionDomainSorts():
1410 sort = Sort(self.solver)
1412 domain_sorts.append(sort)
1415 def getFunctionCodomainSort(self):
1416 cdef Sort sort = Sort(self.solver)
1417 sort.csort = self.csort.getFunctionCodomainSort()
1420 def getArrayIndexSort(self):
1421 cdef Sort sort = Sort(self.solver)
1422 sort.csort = self.csort.getArrayIndexSort()
1425 def getArrayElementSort(self):
1426 cdef Sort sort = Sort(self.solver)
1427 sort.csort = self.csort.getArrayElementSort()
1430 def getSetElementSort(self):
1431 cdef Sort sort = Sort(self.solver)
1432 sort.csort = self.csort.getSetElementSort()
1435 def getBagElementSort(self):
1436 cdef Sort sort = Sort(self.solver)
1437 sort.csort = self.csort.getBagElementSort()
1440 def getSequenceElementSort(self):
1441 cdef Sort sort = Sort(self.solver)
1442 sort.csort = self.csort.getSequenceElementSort()
1445 def getUninterpretedSortName(self):
1446 return self.csort.getUninterpretedSortName().decode()
1448 def isUninterpretedSortParameterized(self):
1449 return self.csort.isUninterpretedSortParameterized()
1451 def getUninterpretedSortParamSorts(self):
1453 for s in self.csort.getUninterpretedSortParamSorts():
1454 sort = Sort(self.solver)
1456 param_sorts.append(sort)
1459 def getSortConstructorName(self):
1460 return self.csort.getSortConstructorName().decode()
1462 def getSortConstructorArity(self):
1463 return self.csort.getSortConstructorArity()
1465 def getBVSize(self):
1466 return self.csort.getBVSize()
1468 def getFPExponentSize(self):
1469 return self.csort.getFPExponentSize()
1471 def getFPSignificandSize(self):
1472 return self.csort.getFPSignificandSize()
1474 def getDatatypeParamSorts(self):
1476 for s in self.csort.getDatatypeParamSorts():
1477 sort = Sort(self.solver)
1479 param_sorts.append(sort)
1482 def getDatatypeArity(self):
1483 return self.csort.getDatatypeArity()
1485 def getTupleLength(self):
1486 return self.csort.getTupleLength()
1488 def getTupleSorts(self):
1490 for s in self.csort.getTupleSorts():
1491 sort = Sort(self.solver)
1493 tuple_sorts.append(sort)
1500 def __cinit__(self, Solver solver):
1501 # cterm always set in the Solver object
1502 self.solver = solver
1504 def __eq__(self, Term other):
1505 return self.cterm == other.cterm
1507 def __ne__(self, Term other):
1508 return self.cterm != other.cterm
1510 def __lt__(self, Term other):
1511 return self.cterm < other.cterm
1513 def __gt__(self, Term other):
1514 return self.cterm > other.cterm
1516 def __le__(self, Term other):
1517 return self.cterm <= other.cterm
1519 def __ge__(self, Term other):
1520 return self.cterm >= other.cterm
1522 def __getitem__(self, int index):
1523 cdef Term term = Term(self.solver)
1525 term.cterm = self.cterm[index]
1527 raise ValueError("Expecting a non-negative integer or string")
1531 return self.cterm.toString().decode()
1534 return self.cterm.toString().decode()
1537 for ci in self.cterm:
1538 term = Term(self.solver)
1543 return ctermhash(self.cterm)
1545 def getNumChildren(self):
1546 return self.cterm.getNumChildren()
1549 return self.cterm.getId()
1552 return kind(<int> self.cterm.getKind())
1555 cdef Sort sort = Sort(self.solver)
1556 sort.csort = self.cterm.getSort()
1559 def substitute(self, term_or_list_1, term_or_list_2):
1560 # The resulting term after substitution
1561 cdef Term term = Term(self.solver)
1562 # lists for substitutions
1563 cdef vector[c_Term] ces
1564 cdef vector[c_Term] creplacements
1566 # normalize the input parameters to be lists
1567 if isinstance(term_or_list_1, list):
1568 assert isinstance(term_or_list_2, list)
1570 replacements = term_or_list_2
1571 if len(es) != len(replacements):
1572 raise RuntimeError("Expecting list inputs to substitute to "
1573 "have the same length but got: "
1574 "{} and {}".format(len(es), len(replacements)))
1576 for e, r in zip(es, replacements):
1577 ces.push_back((<Term?> e).cterm)
1578 creplacements.push_back((<Term?> r).cterm)
1581 # add the single elements to the vectors
1582 ces.push_back((<Term?> term_or_list_1).cterm)
1583 creplacements.push_back((<Term?> term_or_list_2).cterm)
1585 # call the API substitute method with lists
1586 term.cterm = self.cterm.substitute(ces, creplacements)
1590 return self.cterm.hasOp()
1593 cdef Op op = Op(self.solver)
1594 op.cop = self.cterm.getOp()
1598 return self.cterm.isNull()
1600 def getConstArrayBase(self):
1601 cdef Term term = Term(self.solver)
1602 term.cterm = self.cterm.getConstArrayBase()
1605 def getSequenceValue(self):
1607 for e in self.cterm.getSequenceValue():
1608 term = Term(self.solver)
1614 cdef Term term = Term(self.solver)
1615 term.cterm = self.cterm.notTerm()
1618 def andTerm(self, Term t):
1619 cdef Term term = Term(self.solver)
1620 term.cterm = self.cterm.andTerm((<Term> t).cterm)
1623 def orTerm(self, Term t):
1624 cdef Term term = Term(self.solver)
1625 term.cterm = self.cterm.orTerm(t.cterm)
1628 def xorTerm(self, Term t):
1629 cdef Term term = Term(self.solver)
1630 term.cterm = self.cterm.xorTerm(t.cterm)
1633 def eqTerm(self, Term t):
1634 cdef Term term = Term(self.solver)
1635 term.cterm = self.cterm.eqTerm(t.cterm)
1638 def impTerm(self, Term t):
1639 cdef Term term = Term(self.solver)
1640 term.cterm = self.cterm.impTerm(t.cterm)
1643 def iteTerm(self, Term then_t, Term else_t):
1644 cdef Term term = Term(self.solver)
1645 term.cterm = self.cterm.iteTerm(then_t.cterm, else_t.cterm)
1648 def isBooleanValue(self):
1649 return self.cterm.isBooleanValue()
1651 def getBooleanValue(self):
1652 return self.cterm.getBooleanValue()
1654 def isStringValue(self):
1655 return self.cterm.isStringValue()
1657 def getStringValue(self):
1658 cdef Py_ssize_t size
1659 cdef c_wstring s = self.cterm.getStringValue()
1660 return PyUnicode_FromWideChar(s.data(), s.size())
1662 def isIntegerValue(self):
1663 return self.cterm.isIntegerValue()
1665 def getIntegerValue(self):
1666 return int(self.cterm.getIntegerValue().decode())
1668 def isRealValue(self):
1669 return self.cterm.isRealValue()
1671 def getRealValue(self):
1672 return float(Fraction(self.cterm.getRealValue().decode()))
1674 def isBitVectorValue(self):
1675 return self.cterm.isBitVectorValue()
1677 def getBitVectorValue(self, base = 2):
1678 return self.cterm.getBitVectorValue(base).decode()
1680 def toPythonObj(self):
1682 Converts a constant value Term to a Python object.
1685 Boolean -- returns a Python bool
1686 Int -- returns a Python int
1687 Real -- returns a Python Fraction
1688 BV -- returns a Python int (treats BV as unsigned)
1689 String -- returns a Python Unicode string
1690 Array -- returns a Python dict mapping indices to values
1691 -- the constant base is returned as the default value
1694 if self.isBooleanValue():
1695 return self.getBooleanValue()
1696 elif self.isIntegerValue():
1697 return self.getIntegerValue()
1698 elif self.isRealValue():
1699 return self.getRealValue()
1700 elif self.isBitVectorValue():
1701 return int(self.getBitVectorValue(), 2)
1702 elif self.isStringValue():
1703 return self.getStringValue()
1704 elif self.getSort().isArray():
1710 # Array models are represented as a series of store operations
1711 # on a constant array
1714 if t.getKind() == kinds.Store:
1716 keys.append(t[1].toPythonObj())
1717 values.append(t[2].toPythonObj())
1718 to_visit.append(t[0])
1720 assert t.getKind() == kinds.ConstArray
1721 base_value = t.getConstArrayBase().toPythonObj()
1723 assert len(keys) == len(values)
1724 assert base_value is not None
1726 # put everything in a dictionary with the constant
1727 # base as the result for any index not included in the stores
1728 res = defaultdict(lambda : base_value)
1729 for k, v in zip(keys, values):
1735 # Generate rounding modes
1736 cdef __rounding_modes = {
1737 <int> ROUND_NEAREST_TIES_TO_EVEN: "RoundNearestTiesToEven",
1738 <int> ROUND_TOWARD_POSITIVE: "RoundTowardPositive",
1739 <int> ROUND_TOWARD_NEGATIVE: "RoundTowardNegative",
1740 <int> ROUND_TOWARD_ZERO: "RoundTowardZero",
1741 <int> ROUND_NEAREST_TIES_TO_AWAY: "RoundNearestTiesToAway"
1744 mod_ref = sys.modules[__name__]
1745 for rm_int, name in __rounding_modes.items():
1746 r = RoundingMode(rm_int)
1748 if name in dir(mod_ref):
1749 raise RuntimeError("Redefinition of Python RoundingMode %s."%name)
1751 setattr(mod_ref, name, r)