1 from collections import defaultdict
2 from fractions import Fraction
3 from functools import wraps
6 from cython.operator cimport dereference, preincrement
8 from libc.stdint cimport int32_t, int64_t, uint32_t, uint64_t
9 from libc.stddef cimport wchar_t
11 from libcpp cimport bool as c_bool
12 from libcpp.pair cimport pair
13 from libcpp.set cimport set as c_set
14 from libcpp.string cimport string
15 from libcpp.vector cimport vector
17 from cvc5 cimport cout
18 from cvc5 cimport Datatype as c_Datatype
19 from cvc5 cimport DatatypeConstructor as c_DatatypeConstructor
20 from cvc5 cimport DatatypeConstructorDecl as c_DatatypeConstructorDecl
21 from cvc5 cimport DatatypeDecl as c_DatatypeDecl
22 from cvc5 cimport DatatypeSelector as c_DatatypeSelector
23 from cvc5 cimport Result as c_Result
24 from cvc5 cimport SynthResult as c_SynthResult
25 from cvc5 cimport Op as c_Op
26 from cvc5 cimport OptionInfo as c_OptionInfo
27 from cvc5 cimport holds as c_holds
28 from cvc5 cimport getVariant as c_getVariant
29 from cvc5 cimport Solver as c_Solver
30 from cvc5 cimport Statistics as c_Statistics
31 from cvc5 cimport Stat as c_Stat
32 from cvc5 cimport Grammar as c_Grammar
33 from cvc5 cimport Sort as c_Sort
34 from cvc5 cimport Term as c_Term
35 from cvc5 cimport hash as c_hash
36 from cvc5 cimport wstring as c_wstring
37 from cvc5 cimport tuple as c_tuple
38 from cvc5 cimport get0, get1, get2
39 from cvc5kinds cimport Kind as c_Kind
40 from cvc5types cimport BlockModelsMode as c_BlockModelsMode
41 from cvc5types cimport RoundingMode as c_RoundingMode
42 from cvc5types cimport UnknownExplanation as c_UnknownExplanation
44 cdef extern from "Python.h":
45 wchar_t* PyUnicode_AsWideCharString(object, Py_ssize_t *)
46 object PyUnicode_FromWideChar(const wchar_t*, Py_ssize_t)
47 void PyMem_Free(void*)
50 ### Using PEP-8 spacing recommendations
51 ### Limit linewidth to 79 characters
52 ### Break before binary operators
53 ### surround top level functions and classes with two spaces
54 ### separate methods by one space
55 ### use spaces in functions sparingly to separate logical blocks
56 ### can omit spaces between unrelated oneliners
57 ### always use c++ default arguments
58 #### only use default args of None at python level
60 # References and pointers
61 # The Solver object holds a pointer to a c_Solver.
62 # This is because the assignment operator is deleted in the C++ API for solvers.
63 # Cython has a limitation where you can't stack allocate objects
64 # that have constructors with arguments:
65 # https://groups.google.com/forum/#!topic/cython-users/fuKd-nQLpBs.
66 # To get around that you can either have a nullary constructor and assignment
67 # or, use a pointer (which is what we chose).
68 # An additional complication of this is that to free up resources, you must
69 # know when to delete the object.
70 # Python will not follow the same scoping rules as in C++, so it must be
71 # able to reference count. To do this correctly, the solver must be a
72 # reference in the Python class for any class that keeps a pointer to
73 # the solver in C++ (to ensure the solver is not deleted before something
74 # that depends on it).
77 ## Objects for hashing
78 cdef c_hash[c_Op] cophash = c_hash[c_Op]()
79 cdef c_hash[c_Sort] csorthash = c_hash[c_Sort]()
80 cdef c_hash[c_Term] ctermhash = c_hash[c_Term]()
87 Wrapper class for the C++ class :cpp:class:`cvc5::Datatype`.
91 def __cinit__(self, Solver solver):
94 def __getitem__(self, index):
96 Get the datatype constructor with the given index, where index can
97 be either a numeric id starting with zero, or the name of the
98 constructor. In the latter case, this is a linear search through the
99 constructors, so in case of multiple, similarly-named constructors,
100 the first is returned.
102 :param index: The id or name of the datatype constructor.
103 :return: The matching datatype constructor.
105 cdef DatatypeConstructor dc = DatatypeConstructor(self.solver)
106 if isinstance(index, int) and index >= 0:
107 dc.cdc = self.cd[(<int?> index)]
108 elif isinstance(index, str):
109 dc.cdc = self.cd[(<const string &> index.encode())]
111 raise ValueError("Expecting a non-negative integer or string")
114 def getConstructor(self, str name):
116 :param name: The name of the constructor.
117 :return: A constructor by name.
119 cdef DatatypeConstructor dc = DatatypeConstructor(self.solver)
120 dc.cdc = self.cd.getConstructor(name.encode())
123 def getConstructorTerm(self, str name):
125 :param name: The name of the constructor.
126 :return: The term representing the datatype constructor with the
129 cdef Term term = Term(self.solver)
130 term.cterm = self.cd.getConstructorTerm(name.encode())
133 def getSelector(self, str name):
135 :param name: The name of the selector..
136 :return: A selector by name.
138 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
139 ds.cds = self.cd.getSelector(name.encode())
144 :return: The name of the datatype.
146 return self.cd.getName().decode()
148 def getNumConstructors(self):
150 :return: The number of constructors in this datatype.
152 return self.cd.getNumConstructors()
154 def getParameters(self):
156 :return: The parameters of this datatype, if it is parametric. An
157 exception is thrown if this datatype is not parametric.
160 for s in self.cd.getParameters():
161 sort = Sort(self.solver)
163 param_sorts.append(sort)
166 def isParametric(self):
168 .. warning:: This method is experimental and may change in future
170 :return: True if this datatype is parametric.
172 return self.cd.isParametric()
174 def isCodatatype(self):
176 :return: True if this datatype corresponds to a co-datatype.
178 return self.cd.isCodatatype()
182 :return: True if this datatype corresponds to a tuple.
184 return self.cd.isTuple()
188 .. warning:: This method is experimental and may change in future
190 :return: True if this datatype corresponds to a record.
192 return self.cd.isRecord()
196 :return: True if this datatype is finite.
198 return self.cd.isFinite()
200 def isWellFounded(self):
202 Is this datatype well-founded?
204 If this datatype is not a codatatype, this returns false if there
205 are no values of this datatype that are of finite size.
207 :return: True if this datatype is well-founded
209 return self.cd.isWellFounded()
213 :return: True if this Datatype is a null object.
215 return self.cd.isNull()
218 return self.cd.toString().decode()
221 return self.cd.toString().decode()
224 """Iterate over all constructors."""
226 dc = DatatypeConstructor(self.solver)
231 cdef class DatatypeConstructor:
233 A cvc5 datatype constructor.
235 Wrapper class for :cpp:class:`cvc5::DatatypeConstructor`.
237 cdef c_DatatypeConstructor cdc
239 def __cinit__(self, Solver solver):
240 self.cdc = c_DatatypeConstructor()
243 def __getitem__(self, index):
245 Get the datatype selector with the given index, where index can be
246 either a numeric id starting with zero, or the name of the selector.
247 In the latter case, this is a linear search through the selectors,
248 so in case of multiple, similarly-named selectors, the first is
251 :param index: The id or name of the datatype selector.
252 :return: The matching datatype selector.
254 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
255 if isinstance(index, int) and index >= 0:
256 ds.cds = self.cdc[(<int?> index)]
257 elif isinstance(index, str):
258 ds.cds = self.cdc[(<const string &> index.encode())]
260 raise ValueError("Expecting a non-negative integer or string")
265 :return: The name of the constructor.
267 return self.cdc.getName().decode()
269 def getConstructorTerm(self):
271 :return: The constructor operator as a term.
273 cdef Term term = Term(self.solver)
274 term.cterm = self.cdc.getConstructorTerm()
277 def getInstantiatedConstructorTerm(self, Sort retSort):
279 Get the constructor operator of this datatype constructor whose
280 return type is retSort. This method is intended to be used on
281 constructors of parametric datatypes and can be seen as returning
282 the constructor term that has been explicitly cast to the given
285 This method is required for constructors of parametric datatypes
286 whose return type cannot be determined by type inference. For
291 (declare-datatype List
292 (par (T) ((nil) (cons (head T) (tail (List T))))))
294 The type of nil terms must be provided by the user. In SMT version
295 2.6, this is done via the syntax for qualified identifiers:
301 This method is equivalent of applying the above, where this
302 DatatypeConstructor is the one corresponding to nil, and retSort is
307 The returned constructor term ``t`` is an operator, while
308 ``Solver.mkTerm(APPLY_CONSTRUCTOR, [t])`` is used to construct
309 the above (nullary) application of nil.
311 .. warning:: This method is experimental and may change in future
314 :param retSort: The desired return sort of the constructor.
315 :return: The constructor operator as a term.
317 cdef Term term = Term(self.solver)
318 term.cterm = self.cdc.getInstantiatedConstructorTerm(retSort.csort)
321 def getTesterTerm(self):
323 :return: The tester operator that is related to this constructor,
326 cdef Term term = Term(self.solver)
327 term.cterm = self.cdc.getTesterTerm()
330 def getNumSelectors(self):
332 :return: The number of selecters (so far) of this Datatype
335 return self.cdc.getNumSelectors()
337 def getSelector(self, str name):
339 :param name: The name of the datatype selector.
340 :return: The first datatype selector with the given name.
342 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
343 ds.cds = self.cdc.getSelector(name.encode())
346 def getSelectorTerm(self, str name):
348 :param name: The name of the datatype selector.
349 :return: A term representing the firstdatatype selector with the
352 cdef Term term = Term(self.solver)
353 term.cterm = self.cdc.getSelectorTerm(name.encode())
358 :return: True if this DatatypeConstructor is a null object.
360 return self.cdc.isNull()
363 return self.cdc.toString().decode()
366 return self.cdc.toString().decode()
369 """Iterate over all datatype selectors."""
371 ds = DatatypeSelector(self.solver)
376 cdef class DatatypeConstructorDecl:
378 A cvc5 datatype constructor declaration.
380 Wrapper class for :cpp:class:`cvc5::DatatypeConstructorDecl`.
382 cdef c_DatatypeConstructorDecl cddc
385 def __cinit__(self, Solver solver):
388 def addSelector(self, str name, Sort sort):
390 Add datatype selector declaration.
392 :param name: The name of the datatype selector declaration to add.
393 :param sort: The codomain sort of the datatype selector declaration
396 self.cddc.addSelector(name.encode(), sort.csort)
398 def addSelectorSelf(self, str name):
400 Add datatype selector declaration whose codomain sort is the
403 :param name: The name of the datatype selector declaration to add.
405 self.cddc.addSelectorSelf(name.encode())
409 :return: True if this DatatypeConstructorDecl is a null object.
411 return self.cddc.isNull()
414 return self.cddc.toString().decode()
417 return self.cddc.toString().decode()
420 cdef class DatatypeDecl:
422 A cvc5 datatype declaration.
424 Wrapper class for :cpp:class:`cvc5::DatatypeDecl`.
426 cdef c_DatatypeDecl cdd
428 def __cinit__(self, Solver solver):
431 def addConstructor(self, DatatypeConstructorDecl ctor):
433 Add a datatype constructor declaration.
435 :param ctor: The datatype constructor declaration to add.
437 self.cdd.addConstructor(ctor.cddc)
439 def getNumConstructors(self):
441 :return: The number of constructors (so far) for this datatype
444 return self.cdd.getNumConstructors()
446 def isParametric(self):
448 :return: True if this datatype declaration is parametric.
450 return self.cdd.isParametric()
454 :return: The name of this datatype declaration.
456 return self.cdd.getName().decode()
460 :return: True if this DatatypeDecl is a null object.
462 return self.cdd.isNull()
465 return self.cdd.toString().decode()
468 return self.cdd.toString().decode()
471 cdef class DatatypeSelector:
473 A cvc5 datatype selector.
475 Wrapper class for :cpp:class:`cvc5::DatatypeSelector`.
477 cdef c_DatatypeSelector cds
479 def __cinit__(self, Solver solver):
480 self.cds = c_DatatypeSelector()
485 :return: The name of this datatype selector.
487 return self.cds.getName().decode()
489 def getSelectorTerm(self):
491 :return: The selector opeartor of this datatype selector as a term.
493 cdef Term term = Term(self.solver)
494 term.cterm = self.cds.getSelectorTerm()
497 def getUpdaterTerm(self):
499 :return: The updater opeartor of this datatype selector as a term.
501 cdef Term term = Term(self.solver)
502 term.cterm = self.cds.getUpdaterTerm()
505 def getCodomainSort(self):
507 :return: The codomain sort of this selector.
509 cdef Sort sort = Sort(self.solver)
510 sort.csort = self.cds.getCodomainSort()
515 :return: True if this DatatypeSelector is a null object.
517 return self.cds.isNull()
520 return self.cds.toString().decode()
523 return self.cds.toString().decode()
530 An operator is a term that represents certain operators,
531 instantiated with its required parameters, e.g.,
532 a term of kind :py:obj:`BVExtract <cvc5.Kind.BVExtract>`.
534 Wrapper class for :cpp:class:`cvc5::Op`.
538 def __cinit__(self, Solver solver):
542 def __eq__(self, Op other):
543 return self.cop == other.cop
545 def __ne__(self, Op other):
546 return self.cop != other.cop
549 return self.cop.toString().decode()
552 return self.cop.toString().decode()
555 return cophash(self.cop)
559 :return: The kind of this operator.
561 return Kind(<int> self.cop.getKind())
565 :return: True iff this operator is indexed.
567 return self.cop.isIndexed()
571 :return: True iff this operator is a null term.
573 return self.cop.isNull()
575 def getNumIndices(self):
577 :return: The number of indices of this op.
579 return self.cop.getNumIndices()
581 def __getitem__(self, int i):
583 Get the index at position ``i``.
585 :param i: The position of the index to return.
586 :return: The index at position ``i``.
588 cdef Term term = Term(self.solver)
589 term.cterm = self.cop[i]
597 Wrapper class for :cpp:class:`cvc5::Grammar`.
599 cdef c_Grammar cgrammar
601 def __cinit__(self, Solver solver):
603 self.cgrammar = c_Grammar()
605 def addRule(self, Term ntSymbol, Term rule):
607 Add ``rule`` to the set of rules corresponding to ``ntSymbol``.
609 :param ntSymbol: The non-terminal to which the rule is added.
610 :param rule: The rule to add.
612 self.cgrammar.addRule(ntSymbol.cterm, rule.cterm)
614 def addAnyConstant(self, Term ntSymbol):
616 Allow ``ntSymbol`` to be an arbitrary constant.
618 :param ntSymbol: The non-terminal allowed to be constant.
620 self.cgrammar.addAnyConstant(ntSymbol.cterm)
622 def addAnyVariable(self, Term ntSymbol):
624 Allow ``ntSymbol`` to be any input variable to corresponding
625 synth-fun/synth-inv with the same sort as ``ntSymbol``.
627 :param ntSymbol: The non-terminal allowed to be any input variable.
629 self.cgrammar.addAnyVariable(ntSymbol.cterm)
631 def addRules(self, Term ntSymbol, rules):
633 Add ``ntSymbol`` to the set of rules corresponding to ``ntSymbol``.
635 :param ntSymbol: The non-terminal to which the rules are added.
636 :param rules: The rules to add.
638 cdef vector[c_Term] crules
640 crules.push_back((<Term?> r).cterm)
641 self.cgrammar.addRules(ntSymbol.cterm, crules)
645 Encapsulation of a three-valued solver result, with explanations.
647 Wrapper class for :cpp:class:`cvc5::Result`.
651 # gets populated by solver
656 :return: True if Result is empty, i.e., a nullary Result, and not
657 an actual result returned from a
658 :py:meth:`Solver.checkSat()` (and friends) query.
660 return self.cr.isNull()
664 :return: True if query was a satisfiable
665 :py:meth:`Solver.checkSat()` or
666 :py:meth:`Solver.checkSatAssuming()` query.
668 return self.cr.isSat()
672 :return: True if query was an usatisfiable
673 :py:meth:`Solver.checkSat()` or
674 :py:meth:`Solver.checkSatAssuming()` query.
676 return self.cr.isUnsat()
680 :return: True if query was a :py:meth:`Solver.checkSat()` or
681 :py:meth:`Solver.checkSatAssuming()` query and cvc5 was
682 not able to determine (un)satisfiability.
684 return self.cr.isUnknown()
686 def getUnknownExplanation(self):
688 :return: An explanation for an unknown query result.
690 return UnknownExplanation(<int> self.cr.getUnknownExplanation())
692 def __eq__(self, Result other):
693 return self.cr == other.cr
695 def __ne__(self, Result other):
696 return self.cr != other.cr
699 return self.cr.toString().decode()
702 return self.cr.toString().decode()
704 cdef class SynthResult:
706 Encapsulation of a solver synth result.
708 This is the return value of the API methods:
710 - :py:meth:`Solver.checkSynth()`
711 - :py:meth:`Solver.checkSynthNext()`
713 which we call synthesis queries. This class indicates whether the
714 synthesis query has a solution, has no solution, or is unknown.
716 cdef c_SynthResult cr
718 # gets populated by solver
719 self.cr = c_SynthResult()
723 :return: True if SynthResult is null, i.e., not a SynthResult
724 returned from a synthesis query.
726 return self.cr.isNull()
728 def hasSolution(self):
730 :return: True if the synthesis query has a solution.
732 return self.cr.hasSolution()
734 def hasNoSolution(self):
736 :return: True if the synthesis query has no solution.
737 In this case, it was determined that there was no solution.
739 return self.cr.hasNoSolution()
743 :return: True if the result of the synthesis query could not be
746 return self.cr.isUnknown()
749 return self.cr.toString().decode()
752 return self.cr.toString().decode()
759 Wrapper class for :cpp:class:`cvc5::Solver`.
761 cdef c_Solver* csolver
764 self.csolver = new c_Solver()
766 def __dealloc__(self):
769 def getBooleanSort(self):
771 :return: Sort Boolean.
773 cdef Sort sort = Sort(self)
774 sort.csort = self.csolver.getBooleanSort()
777 def getIntegerSort(self):
779 :return: Sort Integer.
781 cdef Sort sort = Sort(self)
782 sort.csort = self.csolver.getIntegerSort()
785 def getNullSort(self):
787 :return: A null sort object.
789 cdef Sort sort = Sort(self)
790 sort.csort = self.csolver.getNullSort()
793 def getRealSort(self):
797 cdef Sort sort = Sort(self)
798 sort.csort = self.csolver.getRealSort()
801 def getRegExpSort(self):
802 """:return: The sort of regular expressions.
804 cdef Sort sort = Sort(self)
805 sort.csort = self.csolver.getRegExpSort()
808 def getRoundingModeSort(self):
809 """:return: Sort RoundingMode.
811 cdef Sort sort = Sort(self)
812 sort.csort = self.csolver.getRoundingModeSort()
815 def getStringSort(self):
816 """:return: Sort String.
818 cdef Sort sort = Sort(self)
819 sort.csort = self.csolver.getStringSort()
822 def mkArraySort(self, Sort indexSort, Sort elemSort):
824 Create an array sort.
826 :param indexSort: The array index sort.
827 :param elemSort: The array element sort.
828 :return: The array sort.
830 cdef Sort sort = Sort(self)
831 sort.csort = self.csolver.mkArraySort(indexSort.csort, elemSort.csort)
834 def mkBitVectorSort(self, uint32_t size):
836 Create a bit-vector sort.
838 :param size: The bit-width of the bit-vector sort
839 :return: The bit-vector sort
841 cdef Sort sort = Sort(self)
842 sort.csort = self.csolver.mkBitVectorSort(size)
845 def mkFloatingPointSort(self, uint32_t exp, uint32_t sig):
847 Create a floating-point sort.
849 :param exp: The bit-width of the exponent of the floating-point
851 :param sig: The bit-width of the significand of the floating-point
854 cdef Sort sort = Sort(self)
855 sort.csort = self.csolver.mkFloatingPointSort(exp, sig)
858 def mkDatatypeSort(self, DatatypeDecl dtypedecl):
860 Create a datatype sort.
862 :param dtypedecl: The datatype declaration from which the sort is
864 :return: The datatype sort.
866 cdef Sort sort = Sort(self)
867 sort.csort = self.csolver.mkDatatypeSort(dtypedecl.cdd)
870 def mkDatatypeSorts(self, list dtypedecls, unresolvedSorts = None):
872 Create a vector of datatype sorts using unresolved sorts. The names
873 of the datatype declarations in dtypedecls must be distinct.
875 This method is called when the DatatypeDecl objects dtypedecls have
876 been built using "unresolved" sorts.
878 We associate each sort in unresolvedSorts with exacly one datatype
879 from dtypedecls. In particular, it must have the same name as
880 exactly one datatype declaration in dtypedecls.
882 When constructing datatypes, unresolved sorts are replaced by the
883 datatype sort constructed for the datatype declaration it is
886 :param dtypedecls: The datatype declarations from which the sort is
888 :param unresolvedSorts: The list of unresolved sorts.
889 :return: The datatype sorts.
891 if unresolvedSorts == None:
892 unresolvedSorts = set([])
894 assert isinstance(unresolvedSorts, set)
897 cdef vector[c_DatatypeDecl] decls
898 for decl in dtypedecls:
899 decls.push_back((<DatatypeDecl?> decl).cdd)
901 cdef c_set[c_Sort] usorts
902 for usort in unresolvedSorts:
903 usorts.insert((<Sort?> usort).csort)
905 csorts = self.csolver.mkDatatypeSorts(
906 <const vector[c_DatatypeDecl]&> decls, <const c_set[c_Sort]&> usorts)
914 def mkFunctionSort(self, sorts, Sort codomain):
916 Create function sort.
918 :param sorts: The sort of the function arguments.
919 :param codomain: The sort of the function return value.
920 :return: The function sort.
923 cdef Sort sort = Sort(self)
924 # populate a vector with dereferenced c_Sorts
925 cdef vector[c_Sort] v
926 if isinstance(sorts, Sort):
927 v.push_back((<Sort?>sorts).csort)
930 v.push_back((<Sort?>s).csort)
932 sort.csort = self.csolver.mkFunctionSort(<const vector[c_Sort]&> v,
936 def mkParamSort(self, str symbolname = None):
938 Create a sort parameter.
940 .. warning:: This method is experimental and may change in future
943 :param symbol: The name of the sort.
944 :return: The sort parameter.
946 cdef Sort sort = Sort(self)
947 if symbolname is None:
948 sort.csort = self.csolver.mkParamSort()
950 sort.csort = self.csolver.mkParamSort(symbolname.encode())
953 def mkPredicateSort(self, *sorts):
955 Create a predicate sort.
957 :param sorts: The list of sorts of the predicate.
958 :return: The predicate sort.
960 cdef Sort sort = Sort(self)
961 cdef vector[c_Sort] v
963 v.push_back((<Sort?> s).csort)
964 sort.csort = self.csolver.mkPredicateSort(<const vector[c_Sort]&> v)
967 def mkRecordSort(self, *fields):
971 .. warning:: This method is experimental and may change in future
974 :param fields: The list of fields of the record.
975 :return: The record sort.
977 cdef Sort sort = Sort(self)
978 cdef vector[pair[string, c_Sort]] v
979 cdef pair[string, c_Sort] p
983 p = pair[string, c_Sort](<string?> name, (<Sort?> sortarg).csort)
985 sort.csort = self.csolver.mkRecordSort(
986 <const vector[pair[string, c_Sort]] &> v)
989 def mkSetSort(self, Sort elemSort):
993 :param elemSort: The sort of the set elements.
994 :return: The set sort.
996 cdef Sort sort = Sort(self)
997 sort.csort = self.csolver.mkSetSort(elemSort.csort)
1000 def mkBagSort(self, Sort elemSort):
1004 :param elemSort: The sort of the bag elements.
1005 :return: The bag sort.
1007 cdef Sort sort = Sort(self)
1008 sort.csort = self.csolver.mkBagSort(elemSort.csort)
1011 def mkSequenceSort(self, Sort elemSort):
1013 Create a sequence sort.
1015 :param elemSort: The sort of the sequence elements
1016 :return: The sequence sort.
1018 cdef Sort sort = Sort(self)
1019 sort.csort = self.csolver.mkSequenceSort(elemSort.csort)
1022 def mkUninterpretedSort(self, str name = None):
1024 Create an uninterpreted sort.
1026 :param symbol: The name of the sort.
1027 :return: The uninterpreted sort.
1029 cdef Sort sort = Sort(self)
1031 sort.csort = self.csolver.mkUninterpretedSort()
1033 sort.csort = self.csolver.mkUninterpretedSort(name.encode())
1036 def mkUnresolvedSort(self, str name, size_t arity = 0):
1038 Create an unresolved sort.
1040 This is for creating yet unresolved sort placeholders for mutually
1041 recursive datatypes.
1043 :param symbol: The name of the sort.
1044 :param arity: The number of sort parameters of the sort.
1045 :return: The unresolved sort.
1047 cdef Sort sort = Sort(self)
1048 sort.csort = self.csolver.mkUnresolvedSort(name.encode(), arity)
1051 def mkUninterpretedSortConstructorSort(self, size_t arity, str symbol = None):
1053 Create a sort constructor sort.
1055 An uninterpreted sort constructor is an uninterpreted sort with
1058 :param symbol: The symbol of the sort.
1059 :param arity: The arity of the sort (must be > 0).
1060 :return: The sort constructor sort.
1062 cdef Sort sort = Sort(self)
1064 sort.csort = self.csolver.mkUninterpretedSortConstructorSort(arity)
1066 sort.csort = self.csolver.mkUninterpretedSortConstructorSort(
1067 arity, symbol.encode())
1070 def mkTupleSort(self, *sorts):
1072 Create a tuple sort.
1074 :param sorts: Of the elements of the tuple.
1075 :return: The tuple sort.
1077 cdef Sort sort = Sort(self)
1078 cdef vector[c_Sort] v
1080 v.push_back((<Sort?> s).csort)
1081 sort.csort = self.csolver.mkTupleSort(v)
1084 def mkTerm(self, kind_or_op, *args):
1088 Supports the following arguments:
1090 - ``Term mkTerm(Kind kind)``
1091 - ``Term mkTerm(Kind kind, List[Term] children)``
1092 - ``Term mkTerm(Op op)``
1093 - ``Term mkTerm(Op op, List[Term] children)``
1095 where ``List[Term]`` can also be comma-separated arguments
1097 cdef Term term = Term(self)
1098 cdef vector[c_Term] v
1101 if isinstance(kind_or_op, Kind):
1102 op = self.mkOp(kind_or_op)
1105 term.cterm = self.csolver.mkTerm((<Op?> op).cop)
1108 v.push_back((<Term?> a).cterm)
1109 term.cterm = self.csolver.mkTerm((<Op?> op).cop, v)
1112 def mkTuple(self, sorts, terms):
1114 Create a tuple term. Terms are automatically converted if sorts are
1117 :param sorts: The sorts of the elements in the tuple.
1118 :param terms: The elements in the tuple.
1119 :return: The tuple Term.
1121 cdef vector[c_Sort] csorts
1122 cdef vector[c_Term] cterms
1125 csorts.push_back((<Sort?> s).csort)
1127 cterms.push_back((<Term?> s).cterm)
1128 cdef Term result = Term(self)
1129 result.cterm = self.csolver.mkTuple(csorts, cterms)
1132 def mkOp(self, k, *args):
1136 Supports the following arguments:
1138 - ``Op mkOp(Kind kind)``
1139 - ``Op mkOp(Kind kind, const string& arg)``
1140 - ``Op mkOp(Kind kind, uint32_t arg0, ...)``
1142 cdef Op op = Op(self)
1143 cdef vector[uint32_t] v
1146 op.cop = self.csolver.mkOp(<c_Kind> k.value)
1147 elif len(args) == 1 and isinstance(args[0], str):
1148 op.cop = self.csolver.mkOp(<c_Kind> k.value,
1153 if not isinstance(a, int):
1155 "Expected uint32_t for argument {}".format(a))
1156 if a < 0 or a >= 2 ** 31:
1158 "Argument {} must fit in a uint32_t".format(a))
1159 v.push_back((<uint32_t?> a))
1160 op.cop = self.csolver.mkOp(<c_Kind> k.value, v)
1165 Create a Boolean true constant.
1167 :return: The true constant.
1169 cdef Term term = Term(self)
1170 term.cterm = self.csolver.mkTrue()
1175 Create a Boolean false constant.
1177 :return: The false constant.
1179 cdef Term term = Term(self)
1180 term.cterm = self.csolver.mkFalse()
1183 def mkBoolean(self, bint val):
1185 Create a Boolean constant.
1187 :return: The Boolean constant.
1188 :param val: The value of the constant.
1190 cdef Term term = Term(self)
1191 term.cterm = self.csolver.mkBoolean(val)
1196 Create a constant representing the number Pi.
1198 :return: A constant representing :py:obj:`Pi <cvc5.Kind.Pi>`.
1200 cdef Term term = Term(self)
1201 term.cterm = self.csolver.mkPi()
1204 def mkInteger(self, val):
1206 Create an integer constant.
1208 :param val: Representation of the constant: either a string or
1210 :return: A constant of sort Integer.
1212 cdef Term term = Term(self)
1213 if isinstance(val, str):
1214 term.cterm = self.csolver.mkInteger(
1215 <const string &> str(val).encode())
1217 assert(isinstance(val, int))
1218 term.cterm = self.csolver.mkInteger((<int?> val))
1221 def mkReal(self, val, den=None):
1223 Create a real constant.
1225 :param val: The value of the term. Can be an integer, float, or
1226 string. It will be formatted as a string before the
1228 :param den: If not None, the value is ``val``/``den``.
1229 :return: A real term with literal value.
1231 Can be used in various forms:
1233 - Given a string ``"N/D"`` constructs the corresponding rational.
1234 - Given a string ``"W.D"`` constructs the reduction of
1235 ``(W * P + D)/P``, where ``P`` is the appropriate power of 10.
1236 - Given a float ``f``, constructs the rational matching ``f``'s
1237 string representation. This means that ``mkReal(0.3)`` gives
1238 ``3/10`` and not the IEEE-754 approximation of ``3/10``.
1239 - Given a string ``"W"`` or an integer, constructs that integer.
1240 - Given two strings and/or integers ``N`` and ``D``, constructs
1243 cdef Term term = Term(self)
1245 term.cterm = self.csolver.mkReal(str(val).encode())
1247 if not isinstance(val, int) or not isinstance(den, int):
1248 raise ValueError("Expecting integers when"
1249 " constructing a rational"
1250 " but got: {}".format((val, den)))
1251 term.cterm = self.csolver.mkReal("{}/{}".format(val, den).encode())
1254 def mkRegexpAll(self):
1256 Create a regular expression all (``re.all``) term.
1258 :return: The all term.
1260 cdef Term term = Term(self)
1261 term.cterm = self.csolver.mkRegexpAll()
1264 def mkRegexpAllchar(self):
1266 Create a regular expression allchar (``re.allchar``) term.
1268 :return: The allchar term.
1270 cdef Term term = Term(self)
1271 term.cterm = self.csolver.mkRegexpAllchar()
1274 def mkRegexpNone(self):
1276 Create a regular expression none (``re.none``) term.
1278 :return: The none term.
1280 cdef Term term = Term(self)
1281 term.cterm = self.csolver.mkRegexpNone()
1284 def mkEmptySet(self, Sort s):
1286 Create a constant representing an empty set of the given sort.
1288 :param sort: The sort of the set elements.
1289 :return: The empty set constant.
1291 cdef Term term = Term(self)
1292 term.cterm = self.csolver.mkEmptySet(s.csort)
1295 def mkEmptyBag(self, Sort s):
1297 Create a constant representing an empty bag of the given sort.
1299 :param sort: The sort of the bag elements.
1300 :return: The empty bag constant.
1302 cdef Term term = Term(self)
1303 term.cterm = self.csolver.mkEmptyBag(s.csort)
1308 Create a separation logic empty term.
1310 .. warning:: This method is experimental and may change in future
1313 :return: The separation logic empty term.
1315 cdef Term term = Term(self)
1316 term.cterm = self.csolver.mkSepEmp()
1319 def mkSepNil(self, Sort sort):
1321 Create a separation logic nil term.
1323 .. warning:: This method is experimental and may change in future
1326 :param sort: The sort of the nil term.
1327 :return: The separation logic nil term.
1329 cdef Term term = Term(self)
1330 term.cterm = self.csolver.mkSepNil(sort.csort)
1333 def mkString(self, str s, useEscSequences = None):
1335 Create a String constant from a ``str`` which may contain SMT-LIB
1336 compatible escape sequences like ``\\u1234`` to encode unicode
1339 :param s: The string this constant represents.
1340 :param useEscSequences: Determines whether escape sequences in `s`
1341 should be converted to the corresponding
1343 :return: The String constant.
1345 cdef Term term = Term(self)
1346 cdef Py_ssize_t size
1347 cdef wchar_t* tmp = PyUnicode_AsWideCharString(s, &size)
1348 if isinstance(useEscSequences, bool):
1349 term.cterm = self.csolver.mkString(
1350 s.encode(), <bint> useEscSequences)
1352 term.cterm = self.csolver.mkString(c_wstring(tmp, size))
1356 def mkEmptySequence(self, Sort sort):
1358 Create an empty sequence of the given element sort.
1360 :param sort: The element sort of the sequence.
1361 :return: The empty sequence with given element sort.
1363 cdef Term term = Term(self)
1364 term.cterm = self.csolver.mkEmptySequence(sort.csort)
1367 def mkUniverseSet(self, Sort sort):
1369 Create a universe set of the given sort.
1371 :param sort: The sort of the set elements
1372 :return: The universe set constant
1374 cdef Term term = Term(self)
1375 term.cterm = self.csolver.mkUniverseSet(sort.csort)
1378 def mkBitVector(self, *args):
1380 Create bit-vector value.
1382 Supports the following arguments:
1384 - ``Term mkBitVector(int size, int val=0)``
1385 - ``Term mkBitVector(int size, string val, int base)``
1387 :return: A Term representing a bit-vector value.
1388 :param size: The bit-width.
1389 :param val: An integer representating the value, in the first form.
1390 In the second form, a string representing the value.
1391 :param base: The base of the string representation (second form
1394 cdef Term term = Term(self)
1396 raise ValueError("Missing arguments to mkBitVector")
1398 if not isinstance(size, int):
1400 "Invalid first argument to mkBitVector '{}', "
1401 "expected bit-vector size".format(size))
1403 term.cterm = self.csolver.mkBitVector(<uint32_t> size)
1404 elif len(args) == 2:
1406 if not isinstance(val, int):
1408 "Invalid second argument to mkBitVector '{}', "
1409 "expected integer value".format(size))
1410 term.cterm = self.csolver.mkBitVector(
1411 <uint32_t> size, <uint32_t> val)
1412 elif len(args) == 3:
1415 if not isinstance(val, str):
1417 "Invalid second argument to mkBitVector '{}', "
1418 "expected value string".format(size))
1419 if not isinstance(base, int):
1421 "Invalid third argument to mkBitVector '{}', "
1422 "expected base given as integer".format(size))
1423 term.cterm = self.csolver.mkBitVector(
1425 <const string&> str(val).encode(),
1428 raise ValueError("Unexpected inputs to mkBitVector")
1431 def mkConstArray(self, Sort sort, Term val):
1433 Create a constant array with the provided constant value stored at
1436 :param sort: The sort of the constant array (must be an array sort).
1437 :param val: The constant value to store (must match the sort's
1439 :return: The constant array term.
1441 cdef Term term = Term(self)
1442 term.cterm = self.csolver.mkConstArray(sort.csort, val.cterm)
1445 def mkFloatingPointPosInf(self, int exp, int sig):
1447 Create a positive infinity floating-point constant.
1449 :param exp: Number of bits in the exponent.
1450 :param sig: Number of bits in the significand.
1451 :return: The floating-point constant.
1453 cdef Term term = Term(self)
1454 term.cterm = self.csolver.mkFloatingPointPosInf(exp, sig)
1457 def mkFloatingPointNegInf(self, int exp, int sig):
1459 Create a negative infinity floating-point constant.
1461 :param exp: Number of bits in the exponent.
1462 :param sig: Number of bits in the significand.
1463 :return: The floating-point constant.
1465 cdef Term term = Term(self)
1466 term.cterm = self.csolver.mkFloatingPointNegInf(exp, sig)
1469 def mkFloatingPointNaN(self, int exp, int sig):
1471 Create a not-a-number (NaN) floating-point constant.
1473 :param exp: Number of bits in the exponent.
1474 :param sig: Number of bits in the significand.
1475 :return: The floating-point constant.
1477 cdef Term term = Term(self)
1478 term.cterm = self.csolver.mkFloatingPointNaN(exp, sig)
1481 def mkFloatingPointPosZero(self, int exp, int sig):
1483 Create a positive zero (+0.0) floating-point constant.
1485 :param exp: Number of bits in the exponent.
1486 :param sig: Number of bits in the significand.
1487 :return: The floating-point constant.
1489 cdef Term term = Term(self)
1490 term.cterm = self.csolver.mkFloatingPointPosZero(exp, sig)
1493 def mkFloatingPointNegZero(self, int exp, int sig):
1495 Create a negative zero (+0.0) floating-point constant.
1497 :param exp: Number of bits in the exponent.
1498 :param sig: Number of bits in the significand.
1499 :return: The floating-point constant.
1501 cdef Term term = Term(self)
1502 term.cterm = self.csolver.mkFloatingPointNegZero(exp, sig)
1505 def mkRoundingMode(self, rm):
1507 Create a roundingmode constant.
1509 :param rm: The floating point rounding mode this constant
1512 cdef Term term = Term(self)
1513 term.cterm = self.csolver.mkRoundingMode(<c_RoundingMode> rm.value)
1516 def mkFloatingPoint(self, int exp, int sig, Term val):
1518 Create a floating-point constant.
1520 :param exp: Size of the exponent.
1521 :param sig: Size of the significand.
1522 :param val: Value of the floating-point constant as a bit-vector
1525 cdef Term term = Term(self)
1526 term.cterm = self.csolver.mkFloatingPoint(exp, sig, val.cterm)
1529 def mkCardinalityConstraint(self, Sort sort, int index):
1531 Create cardinality constraint.
1533 .. warning:: This method is experimental and may change in future
1536 :param sort: Sort of the constraint.
1537 :param index: The upper bound for the cardinality of the sort.
1539 cdef Term term = Term(self)
1540 term.cterm = self.csolver.mkCardinalityConstraint(sort.csort, index)
1543 def mkConst(self, Sort sort, symbol=None):
1545 Create (first-order) constant (0-arity function symbol).
1549 .. code-block:: smtlib
1551 ( declare-const <symbol> <sort> )
1552 ( declare-fun <symbol> ( ) <sort> )
1554 :param sort: The sort of the constant.
1555 :param symbol: The name of the constant. If None, a default symbol
1557 :return: The first-order constant.
1559 cdef Term term = Term(self)
1561 term.cterm = self.csolver.mkConst(sort.csort)
1563 term.cterm = self.csolver.mkConst(sort.csort,
1564 (<str?> symbol).encode())
1567 def mkVar(self, Sort sort, symbol=None):
1569 Create a bound variable to be used in a binder (i.e. a quantifier,
1570 a lambda, or a witness binder).
1572 :param sort: The sort of the variable.
1573 :param symbol: The name of the variable.
1574 :return: The variable.
1576 cdef Term term = Term(self)
1578 term.cterm = self.csolver.mkVar(sort.csort)
1580 term.cterm = self.csolver.mkVar(sort.csort,
1581 (<str?> symbol).encode())
1584 def mkDatatypeConstructorDecl(self, str name):
1586 Create datatype constructor declaration.
1588 :param name: The name of the constructor.
1589 :return: The datatype constructor declaration.
1591 cdef DatatypeConstructorDecl ddc = DatatypeConstructorDecl(self)
1592 ddc.cddc = self.csolver.mkDatatypeConstructorDecl(name.encode())
1595 def mkDatatypeDecl(self, str name, sorts_or_bool=None, isCoDatatype=None):
1597 Create a datatype declaration.
1599 :param name: The name of the datatype.
1600 :param isCoDatatype: True if a codatatype is to be constructed.
1601 :return: The datatype declaration.
1603 cdef DatatypeDecl dd = DatatypeDecl(self)
1604 cdef vector[c_Sort] v
1607 if sorts_or_bool is None and isCoDatatype is None:
1608 dd.cdd = self.csolver.mkDatatypeDecl(name.encode())
1609 elif sorts_or_bool is not None and isCoDatatype is None:
1610 if isinstance(sorts_or_bool, bool):
1611 dd.cdd = self.csolver.mkDatatypeDecl(
1612 <const string &> name.encode(), <bint> sorts_or_bool)
1613 elif isinstance(sorts_or_bool, Sort):
1614 dd.cdd = self.csolver.mkDatatypeDecl(
1615 <const string &> name.encode(),
1616 (<Sort> sorts_or_bool).csort)
1617 elif isinstance(sorts_or_bool, list):
1618 for s in sorts_or_bool:
1619 v.push_back((<Sort?> s).csort)
1620 dd.cdd = self.csolver.mkDatatypeDecl(
1621 <const string &> name.encode(),
1622 <const vector[c_Sort]&> v)
1624 raise ValueError("Unhandled second argument type {}"
1625 .format(type(sorts_or_bool)))
1626 elif sorts_or_bool is not None and isCoDatatype is not None:
1627 if isinstance(sorts_or_bool, Sort):
1628 dd.cdd = self.csolver.mkDatatypeDecl(
1629 <const string &> name.encode(),
1630 (<Sort> sorts_or_bool).csort,
1631 <bint> isCoDatatype)
1632 elif isinstance(sorts_or_bool, list):
1633 for s in sorts_or_bool:
1634 v.push_back((<Sort?> s).csort)
1635 dd.cdd = self.csolver.mkDatatypeDecl(
1636 <const string &> name.encode(),
1637 <const vector[c_Sort]&> v,
1638 <bint> isCoDatatype)
1640 raise ValueError("Unhandled second argument type {}"
1641 .format(type(sorts_or_bool)))
1643 raise ValueError("Can't create DatatypeDecl with {}".format(
1644 [type(a) for a in [name, sorts_or_bool, isCoDatatype]]))
1648 def simplify(self, Term t):
1650 Simplify a formula without doing "much" work. Does not involve the
1651 SAT Engine in the simplification, but uses the current definitions,
1652 assertions, and the current partial model, if one has been
1653 constructed. It also involves theory normalization.
1655 .. warning:: This method is experimental and may change in future
1658 :param t: The formula to simplify.
1659 :return: The simplified formula.
1661 cdef Term term = Term(self)
1662 term.cterm = self.csolver.simplify(t.cterm)
1665 def assertFormula(self, Term term):
1671 .. code-block:: smtlib
1675 :param term: The formula to assert.
1677 self.csolver.assertFormula(term.cterm)
1681 Check satisfiability.
1685 .. code-block:: smtlib
1689 :return: The result of the satisfiability check.
1691 cdef Result r = Result()
1692 r.cr = self.csolver.checkSat()
1695 def mkSygusGrammar(self, boundVars, ntSymbols):
1697 Create a SyGuS grammar. The first non-terminal is treated as the
1698 starting non-terminal, so the order of non-terminals matters.
1700 :param boundVars: The parameters to corresponding
1701 synth-fun/synth-inv.
1702 :param ntSymbols: The pre-declaration of the non-terminal symbols.
1703 :return: The grammar.
1705 cdef Grammar grammar = Grammar(self)
1706 cdef vector[c_Term] bvc
1707 cdef vector[c_Term] ntc
1708 for bv in boundVars:
1709 bvc.push_back((<Term?> bv).cterm)
1710 for nt in ntSymbols:
1711 ntc.push_back((<Term?> nt).cterm)
1712 grammar.cgrammar = self.csolver.mkSygusGrammar(<const vector[c_Term]&> bvc, <const vector[c_Term]&> ntc)
1715 def declareSygusVar(self, str symbol, Sort sort):
1717 Append symbol to the current list of universal variables.
1721 .. code-block:: smtlib
1723 ( declare-var <symbol> <sort> )
1725 :param sort: The sort of the universal variable.
1726 :param symbol: The name of the universal variable.
1727 :return: The universal variable.
1729 cdef Term term = Term(self)
1730 term.cterm = self.csolver.declareSygusVar(symbol.encode(), sort.csort)
1733 def addSygusConstraint(self, Term t):
1735 Add a formula to the set of SyGuS constraints.
1739 .. code-block:: smtlib
1741 ( constraint <term> )
1743 :param term: The formula to add as a constraint.
1745 self.csolver.addSygusConstraint(t.cterm)
1747 def addSygusAssume(self, Term t):
1749 Add a formula to the set of Sygus assumptions.
1753 .. code-block:: smtlib
1757 :param term: The formuula to add as an assumption.
1759 self.csolver.addSygusAssume(t.cterm)
1761 def addSygusInvConstraint(self, Term inv_f, Term pre_f, Term trans_f, Term post_f):
1763 Add a set of SyGuS constraints to the current state that correspond
1764 to an invariant synthesis problem.
1768 .. code-block:: smtlib
1770 ( inv-constraint <inv> <pre> <trans> <post> )
1772 :param inv: The function-to-synthesize.
1773 :param pre: The pre-condition.
1774 :param trans: The transition relation.
1775 :param post: The post-condition.
1777 self.csolver.addSygusInvConstraint(
1778 inv_f.cterm, pre_f.cterm, trans_f.cterm, post_f.cterm)
1780 def synthFun(self, str symbol, bound_vars, Sort sort, Grammar grammar=None):
1782 Synthesize n-ary function following specified syntactic constraints.
1786 .. code-block:: smtlib
1788 ( synth-fun <symbol> ( <boundVars>* ) <sort> <g> )
1790 :param symbol: The name of the function.
1791 :param boundVars: The parameters to this function.
1792 :param sort: The sort of the return value of this function.
1793 :param grammar: The syntactic constraints.
1794 :return: The function.
1796 cdef Term term = Term(self)
1797 cdef vector[c_Term] v
1798 for bv in bound_vars:
1799 v.push_back((<Term?> bv).cterm)
1801 term.cterm = self.csolver.synthFun(symbol.encode(), <const vector[c_Term]&> v, sort.csort)
1803 term.cterm = self.csolver.synthFun(symbol.encode(), <const vector[c_Term]&> v, sort.csort, grammar.cgrammar)
1806 def checkSynth(self):
1808 Try to find a solution for the synthesis conjecture corresponding
1809 to the current list of functions-to-synthesize, universal variables
1814 .. code-block:: smtlib
1818 :return: The result of the check, which is "solution" if the check
1819 found a solution in which case solutions are available via
1820 getSynthSolutions, "no solution" if it was determined
1821 there is no solution, or "unknown" otherwise.
1823 cdef SynthResult r = SynthResult()
1824 r.cr = self.csolver.checkSynth()
1827 def checkSynthNext(self):
1829 Try to find a next solution for the synthesis conjecture
1830 corresponding to the current list of functions-to-synthesize,
1831 universal variables and constraints. Must be called immediately
1832 after a successful call to check-synth or check-synth-next.
1833 Requires incremental mode.
1837 .. code-block:: smtlib
1841 :return: The result of the check, which is "solution" if the check
1842 found a solution in which case solutions are available via
1843 getSynthSolutions, "no solution" if it was determined
1844 there is no solution, or "unknown" otherwise.
1846 cdef SynthResult r = SynthResult()
1847 r.cr = self.csolver.checkSynthNext()
1850 def getSynthSolution(self, Term term):
1852 Get the synthesis solution of the given term. This method should be
1853 called immediately after the solver answers unsat for sygus input.
1855 :param term: The term for which the synthesis solution is queried.
1856 :return: The synthesis solution of the given term.
1858 cdef Term t = Term(self)
1859 t.cterm = self.csolver.getSynthSolution(term.cterm)
1862 def getSynthSolutions(self, list terms):
1864 Get the synthesis solutions of the given terms. This method should
1865 be called immediately after the solver answers unsat for sygus
1868 :param terms: The terms for which the synthesis solutions is
1870 :return: The synthesis solutions of the given terms.
1873 cdef vector[c_Term] vec
1875 vec.push_back((<Term?> t).cterm)
1876 cresult = self.csolver.getSynthSolutions(vec)
1884 def synthInv(self, symbol, bound_vars, Grammar grammar=None):
1886 Synthesize invariant.
1890 .. code-block:: smtlib
1892 ( synth-inv <symbol> ( <boundVars>* ) <grammar> )
1894 :param symbol: The name of the invariant.
1895 :param boundVars: The parameters to this invariant.
1896 :param grammar: The syntactic constraints.
1897 :return: The invariant.
1899 cdef Term term = Term(self)
1900 cdef vector[c_Term] v
1901 for bv in bound_vars:
1902 v.push_back((<Term?> bv).cterm)
1904 term.cterm = self.csolver.synthInv(
1905 symbol.encode(), <const vector[c_Term]&> v)
1907 term.cterm = self.csolver.synthInv(
1909 <const vector[c_Term]&> v,
1913 def checkSatAssuming(self, *assumptions):
1915 Check satisfiability assuming the given formula.
1919 .. code-block:: smtlib
1921 ( check-sat-assuming ( <prop_literal> ) )
1923 :param assumptions: The formulas to assume.
1924 :return: The result of the satisfiability check.
1926 cdef Result r = Result()
1927 # used if assumptions is a list of terms
1928 cdef vector[c_Term] v
1929 for a in assumptions:
1930 v.push_back((<Term?> a).cterm)
1931 r.cr = self.csolver.checkSatAssuming(<const vector[c_Term]&> v)
1934 def declareDatatype(self, str symbol, *ctors):
1936 Create datatype sort.
1940 .. code-block:: smtlib
1942 ( declare-datatype <symbol> <datatype_decl> )
1944 :param symbol: The name of the datatype sort.
1945 :param ctors: The constructor declarations of the datatype sort.
1946 :return: The datatype sort.
1948 cdef Sort sort = Sort(self)
1949 cdef vector[c_DatatypeConstructorDecl] v
1952 v.push_back((<DatatypeConstructorDecl?> c).cddc)
1953 sort.csort = self.csolver.declareDatatype(symbol.encode(), v)
1956 def declareFun(self, str symbol, list sorts, Sort sort):
1958 Declare n-ary function symbol.
1962 .. code-block:: smtlib
1964 ( declare-fun <symbol> ( <sort>* ) <sort> )
1966 :param symbol: The name of the function.
1967 :param sorts: The sorts of the parameters to this function.
1968 :param sort: The sort of the return value of this function.
1969 :return: The function.
1971 cdef Term term = Term(self)
1972 cdef vector[c_Sort] v
1974 v.push_back((<Sort?> s).csort)
1975 term.cterm = self.csolver.declareFun(symbol.encode(),
1976 <const vector[c_Sort]&> v,
1980 def declareSort(self, str symbol, int arity):
1982 Declare uninterpreted sort.
1986 .. code-block:: smtlib
1988 ( declare-sort <symbol> <numeral> )
1992 This corresponds to :py:meth:`Solver.mkUninterpretedSort()` if
1994 :py:meth:`Solver.mkUninterpretedSortConstructorSort()` if
1997 :param symbol: The name of the sort.
1998 :param arity: The arity of the sort.
2001 cdef Sort sort = Sort(self)
2002 sort.csort = self.csolver.declareSort(symbol.encode(), arity)
2005 def defineFun(self, str symbol, list bound_vars, Sort sort, Term term, glbl=False):
2007 Define n-ary function.
2011 .. code-block:: smtlib
2013 ( define-fun <function_def> )
2015 :param symbol: The name of the function.
2016 :param bound_vars: The parameters to this function.
2017 :param sort: The sort of the return value of this function.
2018 :param term: The function body.
2019 :param glbl: Determines whether this definition is global (i.e.
2020 persists when popping the context).
2021 :return: The function.
2023 cdef Term fun = Term(self)
2024 cdef vector[c_Term] v
2025 for bv in bound_vars:
2026 v.push_back((<Term?> bv).cterm)
2028 fun.cterm = self.csolver.defineFun(symbol.encode(),
2029 <const vector[c_Term] &> v,
2035 def defineFunRec(self, sym_or_fun, bound_vars, sort_or_term, t=None, glbl=False):
2037 Define recursive functions.
2039 Supports the following arguments:
2041 - ``Term defineFunRec(str symbol, List[Term] bound_vars, Sort sort, Term term, bool glbl)``
2042 - ``Term defineFunRec(Term fun, List[Term] bound_vars, Term term, bool glbl)``
2046 .. code-block:: smtlib
2048 ( define-funs-rec ( <function_decl>^n ) ( <term>^n ) )
2050 Create elements of parameter ``funs`` with :py:meth:`mkConst() <cvc5.Solver.mkConst()>`.
2052 :param funs: The sorted functions.
2053 :param bound_vars: The list of parameters to the functions.
2054 :param terms: The list of function bodies of the functions.
2055 :param global: Determines whether this definition is global (i.e.
2056 persists when popping the context).
2057 :return: The function.
2059 cdef Term term = Term(self)
2060 cdef vector[c_Term] v
2061 for bv in bound_vars:
2062 v.push_back((<Term?> bv).cterm)
2065 term.cterm = self.csolver.defineFunRec((<str?> sym_or_fun).encode(),
2066 <const vector[c_Term] &> v,
2067 (<Sort?> sort_or_term).csort,
2071 term.cterm = self.csolver.defineFunRec((<Term?> sym_or_fun).cterm,
2072 <const vector[c_Term]&> v,
2073 (<Term?> sort_or_term).cterm,
2078 def defineFunsRec(self, funs, bound_vars, terms):
2080 Define recursive functions.
2084 .. code-block:: smtlib
2086 ( define-funs-rec ( <function_decl>^n ) ( <term>^n ) )
2088 Create elements of parameter ``funs`` with :py:meth:`mkConst() <cvc5.Solver.mkConst()>`.
2090 :param funs: The sorted functions.
2091 :param bound_vars: The list of parameters to the functions.
2092 :param terms: The list of function bodies of the functions.
2093 :param global: Determines whether this definition is global (i.e.
2094 persists when popping the context).
2095 :return: The function.
2097 cdef vector[c_Term] vf
2098 cdef vector[vector[c_Term]] vbv
2099 cdef vector[c_Term] vt
2102 vf.push_back((<Term?> f).cterm)
2104 cdef vector[c_Term] temp
2105 for v in bound_vars:
2107 temp.push_back((<Term?> t).cterm)
2112 vf.push_back((<Term?> t).cterm)
2116 Get the refutation proof
2120 .. code-block:: smtlib
2124 Requires to enable option
2125 :ref:`produce-proofs <lbl-option-produce-proofs>`.
2127 .. warning:: This method is experimental and may change in future
2130 :return: A string representing the proof, according to the value of
2131 :ref:`proof-format-mode <lbl-option-proof-format-mode>`.
2133 return self.csolver.getProof()
2135 def getLearnedLiterals(self):
2137 Get a list of literals that are entailed by the current set of assertions
2141 .. code-block:: smtlib
2143 ( get-learned-literals )
2145 .. warning:: This method is experimental and may change in future
2148 :return: The list of literals.
2151 for a in self.csolver.getLearnedLiterals():
2157 def getAssertions(self):
2159 Get the list of asserted formulas.
2163 .. code-block:: smtlib
2167 :return: The list of asserted formulas.
2170 for a in self.csolver.getAssertions():
2173 assertions.append(term)
2176 def getInfo(self, str flag):
2178 Get info from the solver.
2182 .. code-block:: smtlib
2184 ( get-info <info_flag> )
2186 :param flag: The info flag.
2189 return self.csolver.getInfo(flag.encode())
2191 def getOption(self, str option):
2193 Get the value of a given option.
2197 .. code-block:: smtlib
2199 ( get-option <keyword> )
2201 :param option: The option for which the value is queried.
2202 :return: A string representation of the option value.
2204 return self.csolver.getOption(option.encode()).decode()
2206 def getOptionNames(self):
2208 Get all option names that can be used with
2209 :py:meth:`Solver.setOption()`, :py:meth:`Solver.getOption()`
2210 and :py:meth:`Solver.getOptionInfo()`.
2212 :return: All option names.
2214 return [s.decode() for s in self.csolver.getOptionNames()]
2216 def getOptionInfo(self, str option):
2218 Get some information about the given option.
2219 Returns the information provided by the C++
2220 :cpp:func:`OptionInfo <cvc5::OptionInfo>` as a dictionary.
2222 :return: Information about the given option.
2224 # declare all the variables we may need later
2225 cdef c_OptionInfo.ValueInfo[c_bool] vib
2226 cdef c_OptionInfo.ValueInfo[string] vis
2227 cdef c_OptionInfo.NumberInfo[int64_t] nii
2228 cdef c_OptionInfo.NumberInfo[uint64_t] niu
2229 cdef c_OptionInfo.NumberInfo[double] nid
2230 cdef c_OptionInfo.ModeInfo mi
2232 oi = self.csolver.getOptionInfo(option.encode())
2233 # generic information
2235 'name': oi.name.decode(),
2236 'aliases': [s.decode() for s in oi.aliases],
2237 'setByUser': oi.setByUser,
2240 # now check which type is actually in the variant
2241 if c_holds[c_OptionInfo.VoidInfo](oi.valueInfo):
2244 elif c_holds[c_OptionInfo.ValueInfo[c_bool]](oi.valueInfo):
2247 vib = c_getVariant[c_OptionInfo.ValueInfo[c_bool]](oi.valueInfo)
2248 res['current'] = vib.currentValue
2249 res['default'] = vib.defaultValue
2250 elif c_holds[c_OptionInfo.ValueInfo[string]](oi.valueInfo):
2253 vis = c_getVariant[c_OptionInfo.ValueInfo[string]](oi.valueInfo)
2254 res['current'] = vis.currentValue.decode()
2255 res['default'] = vis.defaultValue.decode()
2256 elif c_holds[c_OptionInfo.NumberInfo[int64_t]](oi.valueInfo):
2259 nii = c_getVariant[c_OptionInfo.NumberInfo[int64_t]](oi.valueInfo)
2260 res['current'] = nii.currentValue
2261 res['default'] = nii.defaultValue
2262 res['minimum'] = nii.minimum.value() \
2263 if nii.minimum.has_value() else None
2264 res['maximum'] = nii.maximum.value() \
2265 if nii.maximum.has_value() else None
2266 elif c_holds[c_OptionInfo.NumberInfo[uint64_t]](oi.valueInfo):
2269 niu = c_getVariant[c_OptionInfo.NumberInfo[uint64_t]](oi.valueInfo)
2270 res['current'] = niu.currentValue
2271 res['default'] = niu.defaultValue
2272 res['minimum'] = niu.minimum.value() \
2273 if niu.minimum.has_value() else None
2274 res['maximum'] = niu.maximum.value() \
2275 if niu.maximum.has_value() else None
2276 elif c_holds[c_OptionInfo.NumberInfo[double]](oi.valueInfo):
2279 nid = c_getVariant[c_OptionInfo.NumberInfo[double]](oi.valueInfo)
2280 res['current'] = nid.currentValue
2281 res['default'] = nid.defaultValue
2282 res['minimum'] = nid.minimum.value() \
2283 if nid.minimum.has_value() else None
2284 res['maximum'] = nid.maximum.value() \
2285 if nid.maximum.has_value() else None
2286 elif c_holds[c_OptionInfo.ModeInfo](oi.valueInfo):
2288 res['type'] = 'mode'
2289 mi = c_getVariant[c_OptionInfo.ModeInfo](oi.valueInfo)
2290 res['current'] = mi.currentValue.decode()
2291 res['default'] = mi.defaultValue.decode()
2292 res['modes'] = [s.decode() for s in mi.modes]
2295 def getOptionNames(self):
2297 Get all option names that can be used with
2298 :py:meth:`Solver.setOption()`, :py:meth:`Solver.getOption()` and
2299 :py:meth:`Solver.getOptionInfo()`.
2300 :return: All option names.
2303 for n in self.csolver.getOptionNames():
2304 result += [n.decode()]
2307 def getUnsatAssumptions(self):
2309 Get the set of unsat ("failed") assumptions.
2313 .. code-block:: smtlib
2315 ( get-unsat-assumptions )
2317 Requires to enable option :ref:`produce-unsat-assumptions
2318 <lbl-option-produce-unsat-assumptions>`.
2320 :return: The set of unsat assumptions.
2323 for a in self.csolver.getUnsatAssumptions():
2326 assumptions.append(term)
2329 def getUnsatCore(self):
2331 Get the unsatisfiable core.
2335 .. code-block:: smtlib
2339 Requires to enable option :ref:`produce-unsat-cores
2340 <lbl-option-produce-unsat-cores>`.
2344 In contrast to SMT-LIB, the API does not distinguish between
2345 named and unnamed assertions when producing an unsatisfiable
2346 core. Additionally, the API allows this option to be called after
2347 a check with assumptions. A subset of those assumptions may be
2348 included in the unsatisfiable core returned by this method.
2350 :return: A set of terms representing the unsatisfiable core.
2353 for a in self.csolver.getUnsatCore():
2359 def getDifficulty(self):
2361 Get a difficulty estimate for an asserted formula. This method is
2362 intended to be called immediately after any response to a
2363 :py:meth:`Solver.checkSat()` call.
2365 .. warning:: This method is experimental and may change in future
2368 :return: A map from (a subset of) the input assertions to a real
2369 value that is an estimate of how difficult each assertion
2370 was to solver. Unmentioned assertions can be assumed to
2371 have zero difficulty.
2374 for p in self.csolver.getDifficulty():
2384 diffi[termk] = termv
2387 def getValue(self, Term t):
2389 Get the value of the given term in the current model.
2393 .. code-block:: smtlib
2395 ( get-value ( <term> ) )
2397 :param term: The term for which the value is queried.
2398 :return: The value of the given term.
2400 cdef Term term = Term(self)
2401 term.cterm = self.csolver.getValue(t.cterm)
2404 def getModelDomainElements(self, Sort s):
2406 Get the domain elements of uninterpreted sort s in the current
2407 model. The current model interprets s as the finite sort whose
2408 domain elements are given in the return value of this method.
2410 :param s: The uninterpreted sort in question.
2411 :return: The domain elements of s in the current model.
2414 cresult = self.csolver.getModelDomainElements(s.csort)
2421 def isModelCoreSymbol(self, Term v):
2423 This returns False if the model value of free constant v was not
2424 essential for showing the satisfiability of the last call to
2425 checkSat using the current model. This method will only return
2426 false (for any v) if the model-cores option has been set.
2428 .. warning:: This method is experimental and may change in future
2431 :param v: The term in question.
2432 :return: True if v is a model core symbol.
2434 return self.csolver.isModelCoreSymbol(v.cterm)
2436 def getQuantifierElimination(self, Term term):
2438 Do quantifier elimination.
2442 .. code-block:: smtlib
2446 Requires a logic that supports quantifier elimination.
2447 Currently, the only logics supported by quantifier elimination
2450 .. warning:: This method is experimental and may change in future
2453 :param q: A quantified formula of the form
2454 :math:`Q\\bar{x_1}\\dots Q\\bar{x}_n. P( x_1 \\dots x_i, y_1 \\dots y_j)`
2456 :math:`Q\\bar{x}` is a set of quantified variables of the
2457 form :math:`Q x_1...x_k` and
2458 :math:`P( x_1...x_i, y_1...y_j )` is a quantifier-free
2460 :return: A formula :math:`\\phi` such that, given the current set
2461 of formulas :math:`A` asserted to this solver:
2463 - :math:`(A \\wedge q)` :math:`(A \\wedge \\phi)` are
2465 - :math:`\\phi` is quantifier-free formula containing only
2466 free variables in :math:`y_1...y_n`.
2468 cdef Term result = Term(self)
2469 result.cterm = self.csolver.getQuantifierElimination(term.cterm)
2472 def getQuantifierEliminationDisjunct(self, Term term):
2474 Do partial quantifier elimination, which can be used for
2475 incrementally computing the result of a quantifier elimination.
2479 .. code-block:: smtlib
2481 ( get-qe-disjunct <q> )
2483 Requires a logic that supports quantifier elimination.
2484 Currently, the only logics supported by quantifier elimination
2487 .. warning:: This method is experimental and may change in future
2490 :param q: A quantified formula of the form
2491 :math:`Q\\bar{x_1} ... Q\\bar{x_n}. P( x_1...x_i, y_1...y_j)`
2492 where :math:`Q\\bar{x}` is a set of quantified variables of
2493 the form :math:`Q x_1...x_k` and
2494 :math:`P( x_1...x_i, y_1...y_j )` is a quantifier-free formula.
2496 :return: A formula :math:`\\phi` such that, given the current set
2497 of formulas :math:`A` asserted to this solver:
2499 - :math:`(A \\wedge q \\implies A \\wedge \\phi)` if :math:`Q`
2500 is :math:`\\forall`, and
2501 :math:`(A \\wedge \\phi \\implies A \\wedge q)` if
2502 :math:`Q` is :math:`\\exists`
2503 - :math:`\\phi` is quantifier-free formula containing only
2504 free variables in :math:`y_1...y_n`
2505 - If :math:`Q` is :math:`\\exists`, let :math:`(A \\wedge Q_n)`
2507 :math:`(A \\wedge \\neg (\\phi \wedge Q_1) \\wedge ... \\wedge \\neg (\\phi \\wedge Q_n))`
2508 where for each :math:`i = 1...n`, formula
2509 :math:`(\\phi \\wedge Q_i)` is the result of calling
2510 :py:meth:`getQuantifierEliminationDisjunct()`
2511 for :math:`q` with the set of assertions
2512 :math:`(A \\wedge Q_{i-1})`.
2513 Similarly, if :math:`Q` is :math:`\\forall`, then let
2514 :math:`(A \\wedge Q_n)` be
2515 :math:`(A \\wedge (\\phi \\wedge Q_1) \\wedge ... \\wedge (\\phi \\wedge Q_n))`
2516 where :math:`(\\phi \\wedge Q_i)` is the same as above.
2517 In either case, we have that :math:`(\\phi \\wedge Q_j)`
2518 will eventually be true or false, for some finite :math:`j`.
2520 cdef Term result = Term(self)
2521 result.cterm = self.csolver.getQuantifierEliminationDisjunct(term.cterm)
2524 def getModel(self, sorts, consts):
2534 Requires to enable option
2535 :ref:`produce-models <lbl-option-produce-models>`.
2537 .. warning:: This method is experimental and may change in future
2540 :param sorts: The list of uninterpreted sorts that should be
2541 printed in the model.
2542 :param vars: The list of free constants that should be printed in
2543 the model. A subset of these may be printed based on
2544 :py:meth:`Solver.isModelCoreSymbol()`.
2545 :return: A string representing the model.
2548 cdef vector[c_Sort] csorts
2550 csorts.push_back((<Sort?> sort).csort)
2552 cdef vector[c_Term] cconsts
2553 for const in consts:
2554 cconsts.push_back((<Term?> const).cterm)
2556 return self.csolver.getModel(csorts, cconsts)
2558 def getValueSepHeap(self):
2560 When using separation logic, obtain the term for the heap.
2562 .. warning:: This method is experimental and may change in future
2565 :return: The term for the heap.
2567 cdef Term term = Term(self)
2568 term.cterm = self.csolver.getValueSepHeap()
2571 def getValueSepNil(self):
2573 When using separation logic, obtain the term for nil.
2575 .. warning:: This method is experimental and may change in future
2578 :return: The term for nil.
2580 cdef Term term = Term(self)
2581 term.cterm = self.csolver.getValueSepNil()
2584 def declareSepHeap(self, Sort locType, Sort dataType):
2586 When using separation logic, this sets the location sort and the
2587 datatype sort to the given ones. This method should be invoked
2588 exactly once, before any separation logic constraints are provided.
2590 .. warning:: This method is experimental and may change in future
2593 :param locSort: The location sort of the heap.
2594 :param dataSort: The data sort of the heap.
2596 self.csolver.declareSepHeap(locType.csort, dataType.csort)
2598 def declarePool(self, str symbol, Sort sort, initValue):
2600 Declare a symbolic pool of terms with the given initial value.
2604 .. code-block:: smtlib
2606 ( declare-pool <symbol> <sort> ( <term>* ) )
2608 .. warning:: This method is experimental and may change in future
2611 :param symbol: The name of the pool.
2612 :param sort: The sort of the elements of the pool.
2613 :param initValue: The initial value of the pool.
2615 cdef Term term = Term(self)
2616 cdef vector[c_Term] niv
2618 niv.push_back((<Term?> v).cterm)
2619 term.cterm = self.csolver.declarePool(symbol.encode(), sort.csort, niv)
2622 def pop(self, nscopes=1):
2624 Pop ``nscopes`` level(s) from the assertion stack.
2628 .. code-block:: smtlib
2632 :param nscopes: The number of levels to pop.
2634 self.csolver.pop(nscopes)
2636 def push(self, nscopes=1):
2638 Push ``nscopes`` level(s) to the assertion stack.
2642 .. code-block:: smtlib
2646 :param nscopes: The number of levels to push.
2648 self.csolver.push(nscopes)
2650 def resetAssertions(self):
2652 Remove all assertions.
2656 .. code-block:: smtlib
2658 ( reset-assertions )
2661 self.csolver.resetAssertions()
2663 def setInfo(self, str keyword, str value):
2669 .. code-block:: smtlib
2671 ( set-info <attribute> )
2673 :param keyword: The info flag.
2674 :param value: The value of the info flag.
2676 self.csolver.setInfo(keyword.encode(), value.encode())
2678 def setLogic(self, str logic):
2684 .. code-block:: smtlib
2686 ( set-logic <symbol> )
2688 :param logic: The logic to set.
2690 self.csolver.setLogic(logic.encode())
2692 def setOption(self, str option, str value):
2698 .. code-block:: smtlib
2700 ( set-option <option> )
2702 :param option: The option name.
2703 :param value: The option value.
2705 self.csolver.setOption(option.encode(), value.encode())
2708 def getInterpolant(self, Term conj, *args):
2714 .. code-block:: smtlib
2716 ( get-interpolant <conj> )
2717 ( get-interpolant <conj> <grammar> )
2719 Requires option :ref:`produce-interpolants
2720 <lbl-option-produce-interpolants>` to be set to a mode different
2723 Supports the following variants:
2725 - ``Term getInterpolant(Term conj)``
2726 - ``Term getInterpolant(Term conj, Grammar grammar)``
2728 .. warning:: This method is experimental and may change in future
2731 :param conj: The conjecture term.
2732 :param output: The term where the result will be stored.
2733 :param grammar: A grammar for the inteprolant.
2734 :return: True iff an interpolant was found.
2736 cdef Term result = Term(self)
2738 result.cterm = self.csolver.getInterpolant(conj.cterm)
2740 assert len(args) == 1
2741 assert isinstance(args[0], Grammar)
2742 result.cterm = self.csolver.getInterpolant(
2743 conj.cterm, (<Grammar ?> args[0]).cgrammar)
2747 def getInterpolantNext(self):
2749 Get the next interpolant. Can only be called immediately after
2750 a successful call to :py:func:`Solver.getInterpolant()` or
2751 :py:func:`Solver.getInterpolantNext()`.
2752 Is guaranteed to produce a syntactically different interpolant wrt
2753 the last returned interpolant if successful.
2757 .. code-block:: smtlib
2759 ( get-interpolant-next )
2761 Requires to enable incremental mode, and option
2762 :ref:`produce-interpolants <lbl-option-produce-interpolants>` to be
2763 set to a mode different from ``none``.
2765 .. warning:: This method is experimental and may change in future
2768 :param output: The term where the result will be stored.
2769 :return: True iff an interpolant was found.
2771 cdef Term result = Term(self)
2772 result.cterm = self.csolver.getInterpolantNext()
2775 def getAbduct(self, Term conj, *args):
2781 .. code-block:: smtlib
2783 ( get-abduct <conj> )
2784 ( get-abduct <conj> <grammar> )
2786 Requires to enable option :ref:`produce-abducts
2787 <lbl-option-produce-abducts>`.
2789 Supports the following variants:
2791 - ``Term getAbduct(Term conj)``
2792 - ``Term getAbduct(Term conj, Grammar grammar)``
2794 .. warning:: This method is experimental and may change in future
2797 :param conj: The conjecture term.
2798 :param output: The term where the result will be stored.
2799 :param grammar: A grammar for the abduct.
2800 :return: True iff an abduct was found.
2802 cdef Term result = Term(self)
2804 result.cterm = self.csolver.getAbduct(conj.cterm)
2806 assert len(args) == 1
2807 assert isinstance(args[0], Grammar)
2808 result.cterm = self.csolver.getAbduct(
2809 conj.cterm, (<Grammar ?> args[0]).cgrammar)
2812 def getAbductNext(self):
2814 Get the next abduct. Can only be called immediately after
2815 a succesful call to :py:func:`Solver.getAbduct()` or
2816 :py:func:`Solver.getAbductNext()`.
2817 Is guaranteed to produce a syntactically different abduct wrt the
2818 last returned abduct if successful.
2822 .. code-block:: smtlib
2826 Requires to enable incremental mode, and
2827 option :ref:`produce-abducts <lbl-option-produce-abducts>`.
2829 .. warning:: This method is experimental and may change in future
2832 :param output: The term where the result will be stored.
2833 :return: True iff an abduct was found.
2835 cdef Term result = Term(self)
2836 result.cterm = self.csolver.getAbductNext()
2839 def blockModel(self, mode):
2841 Block the current model. Can be called only if immediately preceded
2842 by a SAT or INVALID query.
2846 .. code-block:: smtlib
2850 Requires enabling option
2851 :ref:`produce-models <lbl-option-produce-models>`
2853 :ref:`block-models <lbl-option-block-models>`
2854 to a mode other than ``none``.
2856 .. warning:: This method is experimental and may change in future
2859 :param mode: The mode to use for blocking
2861 self.csolver.blockModel(<c_BlockModelsMode> mode.value)
2863 def blockModelValues(self, terms):
2865 Block the current model values of (at least) the values in terms.
2866 Can be called only if immediately preceded by a SAT or NOT_ENTAILED
2871 .. code-block:: smtlib
2873 (block-model-values ( <terms>+ ))
2875 Requires enabling option
2876 :ref:`produce-models <lbl-option-produce-models>`.
2878 .. warning:: This method is experimental and may change in future
2881 cdef vector[c_Term] nts
2883 nts.push_back((<Term?> t).cterm)
2884 self.csolver.blockModelValues(nts)
2886 def getInstantiations(self):
2888 Return a string that contains information about all instantiations
2889 made by the quantifiers module.
2891 .. warning:: This method is experimental and may change in future
2894 return self.csolver.getInstantiations()
2896 def getStatistics(self):
2898 Returns a snapshot of the current state of the statistic values of
2899 this solver. The returned object is completely decoupled from the
2900 solver and will not change when the solver is used again.
2903 res.cstats = self.csolver.getStatistics()
2909 The sort of a cvc5 term.
2911 Wrapper class for :cpp:class:`cvc5::Sort`.
2915 def __cinit__(self, Solver solver):
2916 # csort always set by Solver
2917 self.solver = solver
2919 def __eq__(self, Sort other):
2920 return self.csort == other.csort
2922 def __ne__(self, Sort other):
2923 return self.csort != other.csort
2925 def __lt__(self, Sort other):
2926 return self.csort < other.csort
2928 def __gt__(self, Sort other):
2929 return self.csort > other.csort
2931 def __le__(self, Sort other):
2932 return self.csort <= other.csort
2934 def __ge__(self, Sort other):
2935 return self.csort >= other.csort
2938 return self.csort.toString().decode()
2941 return self.csort.toString().decode()
2944 return csorthash(self.csort)
2946 def hasSymbol(self):
2948 :return: True iff this sort has a symbol.
2950 return self.csort.hasSymbol()
2952 def getSymbol(self):
2954 Asserts :py:meth:`hasSymbol()`.
2956 :return: The raw symbol of the sort.
2958 return self.csort.getSymbol().decode()
2962 :return: True if this Sort is a null sort.
2964 return self.csort.isNull()
2966 def isBoolean(self):
2968 Is this a Boolean sort?
2970 :return: True if the sort is the Boolean sort.
2972 return self.csort.isBoolean()
2974 def isInteger(self):
2976 Is this an integer sort?
2978 :return: True if the sort is the integer sort.
2980 return self.csort.isInteger()
2984 Is this a real sort?
2986 :return: True if the sort is the real sort.
2988 return self.csort.isReal()
2992 Is this a string sort?
2994 :return: True if the sort is the string sort.
2996 return self.csort.isString()
3000 Is this a regexp sort?
3002 :return: True if the sort is the regexp sort.
3004 return self.csort.isRegExp()
3006 def isRoundingMode(self):
3008 Is this a rounding mode sort?
3010 :return: True if the sort is the rounding mode sort.
3012 return self.csort.isRoundingMode()
3014 def isBitVector(self):
3016 Is this a bit-vector sort?
3018 :return: True if the sort is a bit-vector sort.
3020 return self.csort.isBitVector()
3022 def isFloatingPoint(self):
3024 Is this a floating-point sort?
3026 :return: True if the sort is a bit-vector sort.
3028 return self.csort.isFloatingPoint()
3030 def isDatatype(self):
3032 Is this a datatype sort?
3034 :return: True if the sort is a datatype sort.
3036 return self.csort.isDatatype()
3038 def isDatatypeConstructor(self):
3040 Is this a datatype constructor sort?
3042 :return: True if the sort is a datatype constructor sort.
3044 return self.csort.isDatatypeConstructor()
3046 def isDatatypeSelector(self):
3048 Is this a datatype selector sort?
3050 :return: True if the sort is a datatype selector sort.
3052 return self.csort.isDatatypeSelector()
3054 def isDatatypeTester(self):
3056 Is this a tester sort?
3058 :return: True if the sort is a selector sort.
3060 return self.csort.isDatatypeTester()
3062 def isDatatypeUpdater(self):
3064 Is this a datatype updater sort?
3066 :return: True if the sort is a datatype updater sort.
3068 return self.csort.isDatatypeUpdater()
3070 def isFunction(self):
3072 Is this a function sort?
3074 :return: True if the sort is a function sort.
3076 return self.csort.isFunction()
3078 def isPredicate(self):
3080 Is this a predicate sort?
3081 That is, is this a function sort mapping to Boolean? All predicate
3082 sorts are also function sorts.
3084 :return: True if the sort is a predicate sort.
3086 return self.csort.isPredicate()
3090 Is this a tuple sort?
3092 :return: True if the sort is a tuple sort.
3094 return self.csort.isTuple()
3098 Is this a record sort?
3100 .. warning:: This method is experimental and may change in future
3103 :return: True if the sort is a record sort.
3105 return self.csort.isRecord()
3109 Is this an array sort?
3111 :return: True if the sort is an array sort.
3113 return self.csort.isArray()
3119 :return: True if the sort is a set sort.
3121 return self.csort.isSet()
3127 :return: True if the sort is a bag sort.
3129 return self.csort.isBag()
3131 def isSequence(self):
3133 Is this a sequence sort?
3135 :return: True if the sort is a sequence sort.
3137 return self.csort.isSequence()
3139 def isUninterpretedSort(self):
3141 Is this a sort uninterpreted?
3143 :return: True if the sort is uninterpreted.
3145 return self.csort.isUninterpretedSort()
3147 def isUninterpretedSortConstructor(self):
3149 Is this a sort constructor kind?
3151 An uninterpreted sort constructor is an uninterpreted sort with
3154 :return: True if this a sort constructor kind.
3156 return self.csort.isUninterpretedSortConstructor()
3158 def isInstantiated(self):
3160 Is this an instantiated (parametric datatype or uninterpreted sort
3163 An instantiated sort is a sort that has been constructed from
3164 instantiating a sort parameters with sort arguments
3165 (see :py:meth:`instantiate()`).
3167 :return: True if this is an instantiated sort.
3169 return self.csort.isInstantiated()
3171 def getUninterpretedSortConstructor(self):
3173 Get the associated uninterpreted sort constructor of an
3174 instantiated uninterpreted sort.
3176 :return: The uninterpreted sort constructor sort
3178 cdef Sort sort = Sort(self.solver)
3179 sort.csort = self.csort.getUninterpretedSortConstructor()
3182 def getDatatype(self):
3184 :return: The underlying datatype of a datatype sort
3186 cdef Datatype d = Datatype(self.solver)
3187 d.cd = self.csort.getDatatype()
3190 def instantiate(self, params):
3192 Instantiate a parameterized datatype sort or uninterpreted sort
3195 Create sorts parameter with :py:meth:`Solver.mkParamSort()`
3197 .. warning:: This method is experimental and may change in future
3200 :param params: The list of sort parameters to instantiate with
3201 :return: The instantiated sort
3203 cdef Sort sort = Sort(self.solver)
3204 cdef vector[c_Sort] v
3206 v.push_back((<Sort?> s).csort)
3207 sort.csort = self.csort.instantiate(v)
3210 def getInstantiatedParameters(self):
3212 Get the sorts used to instantiate the sort parameters of a
3213 parametric sort (parametric datatype or uninterpreted sort
3214 constructor sort, see :py:meth:`instantiate()`).
3216 :return: The sorts used to instantiate the sort parameters of a
3219 instantiated_sorts = []
3220 for s in self.csort.getInstantiatedParameters():
3221 sort = Sort(self.solver)
3223 instantiated_sorts.append(sort)
3224 return instantiated_sorts
3226 def substitute(self, sort_or_list_1, sort_or_list_2):
3228 Substitution of Sorts.
3230 Note that this replacement is applied during a pre-order traversal
3231 and only once to the sort. It is not run until fix point. In the
3232 case that sort_or_list_1 contains duplicates, the replacement
3233 earliest in the list takes priority.
3236 ``(Array A B) .substitute([A, C], [(Array C D), (Array A B)])``
3237 will return ``(Array (Array C D) B)``.
3239 .. warning:: This method is experimental and may change in future
3242 :param sort_or_list_1: The subsort or subsorts to be substituted
3244 :param sort_or_list_2: The sort or list of sorts replacing the
3245 substituted subsort.
3248 # The resulting sort after substitution
3249 cdef Sort sort = Sort(self.solver)
3250 # lists for substitutions
3251 cdef vector[c_Sort] ces
3252 cdef vector[c_Sort] creplacements
3254 # normalize the input parameters to be lists
3255 if isinstance(sort_or_list_1, list):
3256 assert isinstance(sort_or_list_2, list)
3258 replacements = sort_or_list_2
3259 if len(es) != len(replacements):
3260 raise RuntimeError("Expecting list inputs to substitute to "
3261 "have the same length but got: "
3263 len(es), len(replacements)))
3265 for e, r in zip(es, replacements):
3266 ces.push_back((<Sort?> e).csort)
3267 creplacements.push_back((<Sort?> r).csort)
3270 # add the single elements to the vectors
3271 ces.push_back((<Sort?> sort_or_list_1).csort)
3272 creplacements.push_back((<Sort?> sort_or_list_2).csort)
3274 # call the API substitute method with lists
3275 sort.csort = self.csort.substitute(ces, creplacements)
3279 def getDatatypeConstructorArity(self):
3281 :return: The arity of a datatype constructor sort.
3283 return self.csort.getDatatypeConstructorArity()
3285 def getDatatypeConstructorDomainSorts(self):
3287 :return: The domain sorts of a datatype constructor sort.
3290 for s in self.csort.getDatatypeConstructorDomainSorts():
3291 sort = Sort(self.solver)
3293 domain_sorts.append(sort)
3296 def getDatatypeConstructorCodomainSort(self):
3298 :return: The codomain sort of a datatype constructor sort.
3300 cdef Sort sort = Sort(self.solver)
3301 sort.csort = self.csort.getDatatypeConstructorCodomainSort()
3304 def getDatatypeSelectorDomainSort(self):
3306 :return: The domain sort of a datatype selector sort.
3308 cdef Sort sort = Sort(self.solver)
3309 sort.csort = self.csort.getDatatypeSelectorDomainSort()
3312 def getDatatypeSelectorCodomainSort(self):
3314 :return: The codomain sort of a datatype selector sort.
3316 cdef Sort sort = Sort(self.solver)
3317 sort.csort = self.csort.getDatatypeSelectorCodomainSort()
3320 def getDatatypeTesterDomainSort(self):
3322 :return: The domain sort of a datatype tester sort.
3324 cdef Sort sort = Sort(self.solver)
3325 sort.csort = self.csort.getDatatypeTesterDomainSort()
3328 def getDatatypeTesterCodomainSort(self):
3330 :return: the codomain sort of a datatype tester sort, which is the
3333 cdef Sort sort = Sort(self.solver)
3334 sort.csort = self.csort.getDatatypeTesterCodomainSort()
3337 def getFunctionArity(self):
3339 :return: The arity of a function sort.
3341 return self.csort.getFunctionArity()
3343 def getFunctionDomainSorts(self):
3345 :return: The domain sorts of a function sort.
3348 for s in self.csort.getFunctionDomainSorts():
3349 sort = Sort(self.solver)
3351 domain_sorts.append(sort)
3354 def getFunctionCodomainSort(self):
3356 :return: The codomain sort of a function sort.
3358 cdef Sort sort = Sort(self.solver)
3359 sort.csort = self.csort.getFunctionCodomainSort()
3362 def getArrayIndexSort(self):
3364 :return: The array index sort of an array sort.
3366 cdef Sort sort = Sort(self.solver)
3367 sort.csort = self.csort.getArrayIndexSort()
3370 def getArrayElementSort(self):
3372 :return: The array element sort of an array sort.
3374 cdef Sort sort = Sort(self.solver)
3375 sort.csort = self.csort.getArrayElementSort()
3378 def getSetElementSort(self):
3380 :return: The element sort of a set sort.
3382 cdef Sort sort = Sort(self.solver)
3383 sort.csort = self.csort.getSetElementSort()
3386 def getBagElementSort(self):
3388 :return: The element sort of a bag sort.
3390 cdef Sort sort = Sort(self.solver)
3391 sort.csort = self.csort.getBagElementSort()
3394 def getSequenceElementSort(self):
3396 :return: The element sort of a sequence sort.
3398 cdef Sort sort = Sort(self.solver)
3399 sort.csort = self.csort.getSequenceElementSort()
3402 def getUninterpretedSortConstructorArity(self):
3404 :return: The arity of a sort constructor sort.
3406 return self.csort.getUninterpretedSortConstructorArity()
3408 def getBitVectorSize(self):
3410 :return: The bit-width of the bit-vector sort.
3412 return self.csort.getBitVectorSize()
3414 def getFloatingPointExponentSize(self):
3416 :return: The bit-width of the exponent of the floating-point sort.
3418 return self.csort.getFloatingPointExponentSize()
3420 def getFloatingPointSignificandSize(self):
3422 :return: The width of the significand of the floating-point sort.
3424 return self.csort.getFloatingPointSignificandSize()
3426 def getDatatypeArity(self):
3428 :return: The arity of a datatype sort.
3430 return self.csort.getDatatypeArity()
3432 def getTupleLength(self):
3434 :return: The length of a tuple sort.
3436 return self.csort.getTupleLength()
3438 def getTupleSorts(self):
3440 :return: The element sorts of a tuple sort.
3443 for s in self.csort.getTupleSorts():
3444 sort = Sort(self.solver)
3446 tuple_sorts.append(sort)
3450 cdef class Statistics:
3452 The cvc5 Statistics.
3454 Wrapper class for :cpp:class:`cvc5::Statistics`.
3455 Obtain a single statistic value using ``stats["name"]`` and a dictionary
3456 with all (visible) statistics using
3457 ``stats.get(internal=False, defaulted=False)``.
3459 cdef c_Statistics cstats
3461 cdef __stat_to_dict(self, const c_Stat& s):
3468 res = s.getString().decode()
3469 elif s.isHistogram():
3470 res = { h.first.decode(): h.second for h in s.getHistogram() }
3472 'defaulted': s.isDefault(),
3473 'internal': s.isInternal(),
3477 def __getitem__(self, str name):
3479 Get the statistics information for the statistic called ``name``.
3481 return self.__stat_to_dict(self.cstats.get(name.encode()))
3483 def get(self, bint internal = False, bint defaulted = False):
3485 Get all statistics as a dictionary. See :cpp:func:`cvc5::Statistics::begin()`
3486 for more information on which statistics are included based on the parameters.
3488 :return: A dictionary with all available statistics.
3490 cdef c_Statistics.iterator it = self.cstats.begin(internal, defaulted)
3491 cdef pair[string,c_Stat]* s
3493 while it != self.cstats.end():
3494 s = &dereference(it)
3495 res[s.first.decode()] = self.__stat_to_dict(s.second)
3504 Wrapper class for :cpp:class:`cvc5::Term`.
3508 def __cinit__(self, Solver solver):
3509 # cterm always set in the Solver object
3510 self.solver = solver
3512 def __eq__(self, Term other):
3513 return self.cterm == other.cterm
3515 def __ne__(self, Term other):
3516 return self.cterm != other.cterm
3518 def __lt__(self, Term other):
3519 return self.cterm < other.cterm
3521 def __gt__(self, Term other):
3522 return self.cterm > other.cterm
3524 def __le__(self, Term other):
3525 return self.cterm <= other.cterm
3527 def __ge__(self, Term other):
3528 return self.cterm >= other.cterm
3530 def __getitem__(self, int index):
3532 Get the child term at a given index.
3534 :param index: The index of the child term to return.
3535 :return: The child term with the given index.
3537 cdef Term term = Term(self.solver)
3539 term.cterm = self.cterm[index]
3541 raise ValueError("Expecting a non-negative integer or string")
3545 return self.cterm.toString().decode()
3548 return self.cterm.toString().decode()
3551 """Iterate over all child terms."""
3552 for ci in self.cterm:
3553 term = Term(self.solver)
3558 return ctermhash(self.cterm)
3560 def getNumChildren(self):
3562 :return: The number of children of this term.
3564 return self.cterm.getNumChildren()
3568 :return: The id of this term.
3570 return self.cterm.getId()
3574 :return: The :py:class:`cvc5.Kind` of this term.
3576 return Kind(<int> self.cterm.getKind())
3580 :return: The :py:class:`cvc5.Sort` of this term.
3582 cdef Sort sort = Sort(self.solver)
3583 sort.csort = self.cterm.getSort()
3586 def substitute(self, term_or_list_1, term_or_list_2):
3588 :return: The result of simultaneously replacing the term(s) stored
3589 in ``term_or_list_1`` by the term(s) stored in
3590 ``term_or_list_2`` in this term.
3594 This replacement is applied during a pre-order traversal and
3595 only once to the term. It is not run until fix point. In the
3596 case that terms contains duplicates, the replacement earliest
3597 in the list takes priority. For example, calling substitute on
3602 term_or_list_1 = [ x, z ], term_or_list_2 = [ g(z), w ]
3604 results in the term ``f(g(z),y)``.
3606 # The resulting term after substitution
3607 cdef Term term = Term(self.solver)
3608 # lists for substitutions
3609 cdef vector[c_Term] ces
3610 cdef vector[c_Term] creplacements
3612 # normalize the input parameters to be lists
3613 if isinstance(term_or_list_1, list):
3614 assert isinstance(term_or_list_2, list)
3616 replacements = term_or_list_2
3617 if len(es) != len(replacements):
3618 raise RuntimeError("Expecting list inputs to substitute to "
3619 "have the same length but got: "
3620 "{} and {}".format(len(es), len(replacements)))
3622 for e, r in zip(es, replacements):
3623 ces.push_back((<Term?> e).cterm)
3624 creplacements.push_back((<Term?> r).cterm)
3627 # add the single elements to the vectors
3628 ces.push_back((<Term?> term_or_list_1).cterm)
3629 creplacements.push_back((<Term?> term_or_list_2).cterm)
3631 # call the API substitute method with lists
3632 term.cterm = self.cterm.substitute(ces, creplacements)
3637 :return: True iff this term has an operator.
3639 return self.cterm.hasOp()
3643 :return: The :py:class:`cvc5.Op` used to create this Term.
3647 This is safe to call when :py:meth:`hasOp()` returns True.
3650 cdef Op op = Op(self.solver)
3651 op.cop = self.cterm.getOp()
3654 def hasSymbol(self):
3656 :return: True iff this term has a symbol.
3658 return self.cterm.hasSymbol()
3660 def getSymbol(self):
3662 Asserts :py:meth:`hasSymbol()`.
3664 :return: The raw symbol of the term.
3666 return self.cterm.getSymbol().decode()
3670 :return: True iff this term is a null term.
3672 return self.cterm.isNull()
3678 :return: The Boolean negation of this term.
3680 cdef Term term = Term(self.solver)
3681 term.cterm = self.cterm.notTerm()
3684 def andTerm(self, Term t):
3688 :param t: A Boolean term.
3689 :return: The conjunction of this term and the given term.
3691 cdef Term term = Term(self.solver)
3692 term.cterm = self.cterm.andTerm((<Term> t).cterm)
3695 def orTerm(self, Term t):
3699 :param t: A Boolean term.
3700 :return: The disjunction of this term and the given term.
3702 cdef Term term = Term(self.solver)
3703 term.cterm = self.cterm.orTerm(t.cterm)
3706 def xorTerm(self, Term t):
3708 Boolean exclusive or.
3710 :param t: A Boolean term.
3711 :return: The exclusive disjunction of this term and the given term.
3713 cdef Term term = Term(self.solver)
3714 term.cterm = self.cterm.xorTerm(t.cterm)
3717 def eqTerm(self, Term t):
3721 :param t: A Boolean term.
3722 :return: The Boolean equivalence of this term and the given term.
3724 cdef Term term = Term(self.solver)
3725 term.cterm = self.cterm.eqTerm(t.cterm)
3728 def impTerm(self, Term t):
3730 Boolean Implication.
3732 :param t: A Boolean term.
3733 :return: The implication of this term and the given term.
3735 cdef Term term = Term(self.solver)
3736 term.cterm = self.cterm.impTerm(t.cterm)
3739 def iteTerm(self, Term then_t, Term else_t):
3741 If-then-else with this term as the Boolean condition.
3743 :param then_t: The `then` term.
3744 :param else_t: The `else` term.
3745 :return: The if-then-else term with this term as the Boolean
3748 cdef Term term = Term(self.solver)
3749 term.cterm = self.cterm.iteTerm(then_t.cterm, else_t.cterm)
3752 def isConstArray(self):
3754 :return: True iff this term is a constant array.
3756 return self.cterm.isConstArray()
3758 def getConstArrayBase(self):
3760 Asserts :py:meth:`isConstArray()`.
3762 :return: The base (element stored at all indicies) of this constant
3765 cdef Term term = Term(self.solver)
3766 term.cterm = self.cterm.getConstArrayBase()
3769 def isBooleanValue(self):
3771 :return: True iff this term is a Boolean value.
3773 return self.cterm.isBooleanValue()
3775 def getBooleanValue(self):
3777 Asserts :py:meth:`isBooleanValue()`
3779 :return: The representation of a Boolean value as a native Boolean
3782 return self.cterm.getBooleanValue()
3784 def isStringValue(self):
3786 :return: True iff this term is a string value.
3788 return self.cterm.isStringValue()
3790 def getStringValue(self):
3792 Asserts :py:meth:`isStringValue()`.
3795 This method is not to be confused with :py:meth:`__str__()`
3796 which returns the term in some string representation, whatever
3799 :return: The string term as a native string value.
3801 cdef Py_ssize_t size
3802 cdef c_wstring s = self.cterm.getStringValue()
3803 return PyUnicode_FromWideChar(s.data(), s.size())
3805 def getRealOrIntegerValueSign(self):
3807 Get integer or real value sign. Must be called on integer or real
3808 values, or otherwise an exception is thrown.
3810 :return: 0 if this term is zero, -1 if this term is a negative real
3811 or integer value, 1 if this term is a positive real or
3814 return self.cterm.getRealOrIntegerValueSign()
3816 def isIntegerValue(self):
3818 :return: True iff this term is an integer value.
3820 return self.cterm.isIntegerValue()
3822 def getIntegerValue(self):
3824 Asserts :py:meth:`isIntegerValue()`.
3826 :return: The integer term as a native python integer.
3828 return int(self.cterm.getIntegerValue().decode())
3830 def isFloatingPointPosZero(self):
3832 :return: True iff the term is the floating-point value for positive
3835 return self.cterm.isFloatingPointPosZero()
3837 def isFloatingPointNegZero(self):
3839 :return: True iff the term is the floating-point value for negative
3842 return self.cterm.isFloatingPointNegZero()
3844 def isFloatingPointPosInf(self):
3846 :return: True iff the term is the floating-point value for positive
3849 return self.cterm.isFloatingPointPosInf()
3851 def isFloatingPointNegInf(self):
3853 :return: True iff the term is the floating-point value for negative
3856 return self.cterm.isFloatingPointNegInf()
3858 def isFloatingPointNaN(self):
3860 :return: True iff the term is the floating-point value for not a
3863 return self.cterm.isFloatingPointNaN()
3865 def isFloatingPointValue(self):
3867 :return: True iff this term is a floating-point value.
3869 return self.cterm.isFloatingPointValue()
3871 def getFloatingPointValue(self):
3873 Asserts :py:meth:`isFloatingPointValue()`.
3875 :return: The representation of a floating-point value as a tuple of
3876 the exponent width, the significand width and a bit-vector
3879 cdef c_tuple[uint32_t, uint32_t, c_Term] t = \
3880 self.cterm.getFloatingPointValue()
3881 cdef Term term = Term(self.solver)
3882 term.cterm = get2(t)
3883 return (get0(t), get1(t), term)
3885 def isSetValue(self):
3887 A term is a set value if it is considered to be a (canonical)
3888 constant set value. A canonical set value is one whose AST is:
3893 (set.singleton c1) ...
3894 (set.union (set.singleton c_{n-1}) (set.singleton c_n))))
3896 where :math:`c_1 \dots c_n` are values ordered by id such that
3897 :math:`c_1 > \cdots > c_n`.
3900 A universe set term ``(kind SET_UNIVERSE)`` is not considered
3903 :return: True if the term is a set value.
3905 return self.cterm.isSetValue()
3907 def getSetValue(self):
3909 Asserts :py:meth:`isSetValue()`.
3911 :return: The representation of a set value as a set of terms.
3914 for e in self.cterm.getSetValue():
3915 term = Term(self.solver)
3920 def isSequenceValue(self):
3922 :return: True iff this term is a sequence value.
3924 return self.cterm.isSequenceValue()
3926 def getSequenceValue(self):
3928 Asserts :py:meth:`isSequenceValue()`.
3932 It is usually necessary for sequences to call
3933 :py:meth:`Solver.simplify()` to turn a sequence that is
3934 constructed by, e.g., concatenation of unit sequences, into a
3937 :return: The representation of a sequence value as a vector of
3941 for e in self.cterm.getSequenceValue():
3942 term = Term(self.solver)
3947 def isCardinalityConstraint(self):
3949 :return: True if the term is a cardinality constraint.
3951 .. warning:: This method is experimental and may change in future
3954 return self.cterm.isCardinalityConstraint()
3956 def getCardinalityConstraint(self):
3958 :return: The sort the cardinality constraint is for and its upper
3960 .. warning:: This method is experimental and may change in future
3963 cdef pair[c_Sort, uint32_t] p
3964 p = self.cterm.getCardinalityConstraint()
3965 cdef Sort sort = Sort(self.solver)
3966 sort.csort = p.first
3967 return (sort, p.second)
3970 def isUninterpretedSortValue(self):
3972 :return: True iff this term is a value from an uninterpreted sort.
3974 return self.cterm.isUninterpretedSortValue()
3976 def getUninterpretedSortValue(self):
3978 Asserts :py:meth:`isUninterpretedSortValue()`.
3980 :return: The representation of an uninterpreted value as a pair of
3981 its sort and its index.
3983 return self.cterm.getUninterpretedSortValue()
3985 def isTupleValue(self):
3987 :return: True iff this term is a tuple value.
3989 return self.cterm.isTupleValue()
3991 def isRoundingModeValue(self):
3993 :return: True if the term is a floating-point rounding mode
3996 return self.cterm.isRoundingModeValue()
3998 def getRoundingModeValue(self):
4000 Asserts :py:meth:`isRoundingModeValue()`.
4001 :return: The floating-point rounding mode value held by the term.
4003 return RoundingMode(<int> self.cterm.getRoundingModeValue())
4005 def getTupleValue(self):
4007 Asserts :py:meth:`isTupleValue()`.
4009 :return: The representation of a tuple value as a vector of terms.
4012 for e in self.cterm.getTupleValue():
4013 term = Term(self.solver)
4018 def isRealValue(self):
4020 :return: True iff this term is a rational value.
4024 A term of kind :py:obj:`Pi <cvc5.Kind.Pi>` is not considered
4028 return self.cterm.isRealValue()
4030 def getRealValue(self):
4032 Asserts :py:meth:`isRealValue()`.
4034 :return: The representation of a rational value as a python Fraction.
4036 return Fraction(self.cterm.getRealValue().decode())
4038 def isBitVectorValue(self):
4040 :return: True iff this term is a bit-vector value.
4042 return self.cterm.isBitVectorValue()
4044 def getBitVectorValue(self, base = 2):
4046 Asserts :py:meth:`isBitVectorValue()`.
4047 Supported bases are 2 (bit string), 10 (decimal string) or 16
4048 (hexdecimal string).
4050 :return: The representation of a bit-vector value in string
4053 return self.cterm.getBitVectorValue(base).decode()
4055 def toPythonObj(self):
4057 Converts a constant value Term to a Python object.
4061 - **Boolean:** Returns a Python bool
4062 - **Int :** Returns a Python int
4063 - **Real :** Returns a Python Fraction
4064 - **BV :** Returns a Python int (treats BV as unsigned)
4065 - **String :** Returns a Python Unicode string
4066 - **Array :** Returns a Python dict mapping indices to values. The constant base is returned as the default value.
4070 if self.isBooleanValue():
4071 return self.getBooleanValue()
4072 elif self.isIntegerValue():
4073 return self.getIntegerValue()
4074 elif self.isRealValue():
4075 return self.getRealValue()
4076 elif self.isBitVectorValue():
4077 return int(self.getBitVectorValue(), 2)
4078 elif self.isStringValue():
4079 return self.getStringValue()
4080 elif self.getSort().isArray():
4086 # Array models are represented as a series of store operations
4087 # on a constant array
4090 if t.getKind().value == c_Kind.STORE:
4092 keys.append(t[1].toPythonObj())
4093 values.append(t[2].toPythonObj())
4094 to_visit.append(t[0])
4096 assert t.getKind().value == c_Kind.CONST_ARRAY
4097 base_value = t.getConstArrayBase().toPythonObj()
4099 assert len(keys) == len(values)
4100 assert base_value is not None
4102 # put everything in a dictionary with the constant
4103 # base as the result for any index not included in the stores
4104 res = defaultdict(lambda : base_value)
4105 for k, v in zip(keys, values):