Python api: Various fixes in docs. (#8480)
[cvc5.git] / src / api / python / cvc5.pxi
1 from collections import defaultdict
2 from fractions import Fraction
3 from functools import wraps
4 import sys
5
6 from cython.operator cimport dereference, preincrement
7
8 from libc.stdint cimport int32_t, int64_t, uint32_t, uint64_t
9 from libc.stddef cimport wchar_t
10
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
16
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 RoundingMode as c_RoundingMode
41 from cvc5types cimport UnknownExplanation as c_UnknownExplanation
42
43 cdef extern from "Python.h":
44 wchar_t* PyUnicode_AsWideCharString(object, Py_ssize_t *)
45 object PyUnicode_FromWideChar(const wchar_t*, Py_ssize_t)
46 void PyMem_Free(void*)
47
48 ################################## DECORATORS #################################
49 def expand_list_arg(num_req_args=0):
50 """
51 Creates a decorator that looks at index num_req_args of the args,
52 if it's a list, it expands it before calling the function.
53 """
54 def decorator(func):
55 @wraps(func)
56 def wrapper(owner, *args):
57 if len(args) == num_req_args + 1 and \
58 isinstance(args[num_req_args], list):
59 args = list(args[:num_req_args]) + args[num_req_args]
60 return func(owner, *args)
61 return wrapper
62 return decorator
63 ###############################################################################
64
65 # Style Guidelines
66 ### Using PEP-8 spacing recommendations
67 ### Limit linewidth to 79 characters
68 ### Break before binary operators
69 ### surround top level functions and classes with two spaces
70 ### separate methods by one space
71 ### use spaces in functions sparingly to separate logical blocks
72 ### can omit spaces between unrelated oneliners
73 ### always use c++ default arguments
74 #### only use default args of None at python level
75
76 # References and pointers
77 # The Solver object holds a pointer to a c_Solver.
78 # This is because the assignment operator is deleted in the C++ API for solvers.
79 # Cython has a limitation where you can't stack allocate objects
80 # that have constructors with arguments:
81 # https://groups.google.com/forum/#!topic/cython-users/fuKd-nQLpBs.
82 # To get around that you can either have a nullary constructor and assignment
83 # or, use a pointer (which is what we chose).
84 # An additional complication of this is that to free up resources, you must
85 # know when to delete the object.
86 # Python will not follow the same scoping rules as in C++, so it must be
87 # able to reference count. To do this correctly, the solver must be a
88 # reference in the Python class for any class that keeps a pointer to
89 # the solver in C++ (to ensure the solver is not deleted before something
90 # that depends on it).
91
92
93 ## Objects for hashing
94 cdef c_hash[c_Op] cophash = c_hash[c_Op]()
95 cdef c_hash[c_Sort] csorthash = c_hash[c_Sort]()
96 cdef c_hash[c_Term] ctermhash = c_hash[c_Term]()
97
98
99 cdef class Datatype:
100 """
101 A cvc5 datatype.
102
103 Wrapper class for the C++ class :cpp:class:`cvc5::Datatype`.
104 """
105 cdef c_Datatype cd
106 cdef Solver solver
107 def __cinit__(self, Solver solver):
108 self.solver = solver
109
110 def __getitem__(self, index):
111 cdef DatatypeConstructor dc = DatatypeConstructor(self.solver)
112 if isinstance(index, int) and index >= 0:
113 dc.cdc = self.cd[(<int?> index)]
114 elif isinstance(index, str):
115 dc.cdc = self.cd[(<const string &> index.encode())]
116 else:
117 raise ValueError("Expecting a non-negative integer or string")
118 return dc
119
120 def getConstructor(self, str name):
121 """
122 :param name: The name of the constructor.
123 :return: A constructor by name.
124 """
125 cdef DatatypeConstructor dc = DatatypeConstructor(self.solver)
126 dc.cdc = self.cd.getConstructor(name.encode())
127 return dc
128
129 def getConstructorTerm(self, str name):
130 """
131 :param name: The name of the constructor.
132 :return: The term representing the datatype constructor with the
133 given name.
134 """
135 cdef Term term = Term(self.solver)
136 term.cterm = self.cd.getConstructorTerm(name.encode())
137 return term
138
139 def getSelector(self, str name):
140 """
141 :param name: The name of the selector..
142 :return: A selector by name.
143 """
144 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
145 ds.cds = self.cd.getSelector(name.encode())
146 return ds
147
148 def getName(self):
149 """
150 :return: The name of the datatype.
151 """
152 return self.cd.getName().decode()
153
154 def getNumConstructors(self):
155 """
156 :return: The number of constructors in this datatype.
157 """
158 return self.cd.getNumConstructors()
159
160 def getParameters(self):
161 """
162 :return: The parameters of this datatype, if it is parametric. An
163 exception is thrown if this datatype is not parametric.
164 """
165 param_sorts = []
166 for s in self.cd.getParameters():
167 sort = Sort(self.solver)
168 sort.csort = s
169 param_sorts.append(sort)
170 return param_sorts
171
172 def isParametric(self):
173 """
174 .. warning:: This method is experimental and may change in future
175 versions.
176 :return: True if this datatype is parametric.
177 """
178 return self.cd.isParametric()
179
180 def isCodatatype(self):
181 """
182 :return: True if this datatype corresponds to a co-datatype.
183 """
184 return self.cd.isCodatatype()
185
186 def isTuple(self):
187 """
188 :return: True if this datatype corresponds to a tuple.
189 """
190 return self.cd.isTuple()
191
192 def isRecord(self):
193 """
194 .. warning:: This method is experimental and may change in future
195 versions.
196 :return: True if this datatype corresponds to a record.
197 """
198 return self.cd.isRecord()
199
200 def isFinite(self):
201 """
202 :return: True if this datatype is finite.
203 """
204 return self.cd.isFinite()
205
206 def isWellFounded(self):
207 """
208 Is this datatype well-founded?
209
210 If this datatype is not a codatatype, this returns false if there
211 are no values of this datatype that are of finite size.
212
213 :return: True if this datatype is well-founded
214 """
215 return self.cd.isWellFounded()
216
217 def isNull(self):
218 """
219 :return: True if this Datatype is a null object.
220 """
221 return self.cd.isNull()
222
223 def __str__(self):
224 return self.cd.toString().decode()
225
226 def __repr__(self):
227 return self.cd.toString().decode()
228
229 def __iter__(self):
230 for ci in self.cd:
231 dc = DatatypeConstructor(self.solver)
232 dc.cdc = ci
233 yield dc
234
235
236 cdef class DatatypeConstructor:
237 """
238 A cvc5 datatype constructor.
239
240 Wrapper class for :cpp:class:`cvc5::DatatypeConstructor`.
241 """
242 cdef c_DatatypeConstructor cdc
243 cdef Solver solver
244 def __cinit__(self, Solver solver):
245 self.cdc = c_DatatypeConstructor()
246 self.solver = solver
247
248 def __getitem__(self, index):
249 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
250 if isinstance(index, int) and index >= 0:
251 ds.cds = self.cdc[(<int?> index)]
252 elif isinstance(index, str):
253 ds.cds = self.cdc[(<const string &> index.encode())]
254 else:
255 raise ValueError("Expecting a non-negative integer or string")
256 return ds
257
258 def getName(self):
259 """
260 :return: The name of the constructor.
261 """
262 return self.cdc.getName().decode()
263
264 def getConstructorTerm(self):
265 """
266 :return: The constructor operator as a term.
267 """
268 cdef Term term = Term(self.solver)
269 term.cterm = self.cdc.getConstructorTerm()
270 return term
271
272 def getInstantiatedConstructorTerm(self, Sort retSort):
273 """
274 Get the constructor operator of this datatype constructor whose
275 return type is retSort. This method is intended to be used on
276 constructors of parametric datatypes and can be seen as returning
277 the constructor term that has been explicitly cast to the given
278 sort.
279
280 This method is required for constructors of parametric datatypes
281 whose return type cannot be determined by type inference. For
282 example, given:
283
284 .. code:: smtlib
285
286 (declare-datatype List
287 (par (T) ((nil) (cons (head T) (tail (List T))))))
288
289 The type of nil terms must be provided by the user. In SMT version
290 2.6, this is done via the syntax for qualified identifiers:
291
292 .. code:: smtlib
293
294 (as nil (List Int))
295
296 This method is equivalent of applying the above, where this
297 DatatypeConstructor is the one corresponding to nil, and retSort is
298 ``(List Int)``.
299
300 .. note::
301
302 The returned constructor term ``t`` is an operator, while
303 ``Solver.mkTerm(APPLY_CONSTRUCTOR, [t])`` is used to construct
304 the above (nullary) application of nil.
305
306 .. warning:: This method is experimental and may change in future
307 versions.
308
309 :param retSort: The desired return sort of the constructor.
310 :return: The constructor operator as a term.
311 """
312 cdef Term term = Term(self.solver)
313 term.cterm = self.cdc.getInstantiatedConstructorTerm(retSort.csort)
314 return term
315
316 def getTesterTerm(self):
317 """
318 :return: The tester operator that is related to this constructor,
319 as a term.
320 """
321 cdef Term term = Term(self.solver)
322 term.cterm = self.cdc.getTesterTerm()
323 return term
324
325 def getNumSelectors(self):
326 """
327 :return: The number of selecters (so far) of this Datatype
328 constructor.
329 """
330 return self.cdc.getNumSelectors()
331
332 def getSelector(self, str name):
333 """
334 :param name: The name of the datatype selector.
335 :return: The first datatype selector with the given name.
336 """
337 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
338 ds.cds = self.cdc.getSelector(name.encode())
339 return ds
340
341 def getSelectorTerm(self, str name):
342 """
343 :param name: The name of the datatype selector.
344 :return: A term representing the firstdatatype selector with the
345 given name.
346 """
347 cdef Term term = Term(self.solver)
348 term.cterm = self.cdc.getSelectorTerm(name.encode())
349 return term
350
351 def isNull(self):
352 """
353 :return: True if this DatatypeConstructor is a null object.
354 """
355 return self.cdc.isNull()
356
357 def __str__(self):
358 return self.cdc.toString().decode()
359
360 def __repr__(self):
361 return self.cdc.toString().decode()
362
363 def __iter__(self):
364 for ci in self.cdc:
365 ds = DatatypeSelector(self.solver)
366 ds.cds = ci
367 yield ds
368
369
370 cdef class DatatypeConstructorDecl:
371 """
372 A cvc5 datatype constructor declaration.
373
374 Wrapper class for :cpp:class:`cvc5::DatatypeConstructorDecl`.
375 """
376 cdef c_DatatypeConstructorDecl cddc
377 cdef Solver solver
378
379 def __cinit__(self, Solver solver):
380 self.solver = solver
381
382 def addSelector(self, str name, Sort sort):
383 """
384 Add datatype selector declaration.
385
386 :param name: The name of the datatype selector declaration to add.
387 :param sort: The codomain sort of the datatype selector declaration
388 to add.
389 """
390 self.cddc.addSelector(name.encode(), sort.csort)
391
392 def addSelectorSelf(self, str name):
393 """
394 Add datatype selector declaration whose codomain sort is the
395 datatype itself.
396
397 :param name: The name of the datatype selector declaration to add.
398 """
399 self.cddc.addSelectorSelf(name.encode())
400
401 def isNull(self):
402 """
403 :return: True if this DatatypeConstructorDecl is a null object.
404 """
405 return self.cddc.isNull()
406
407 def __str__(self):
408 return self.cddc.toString().decode()
409
410 def __repr__(self):
411 return self.cddc.toString().decode()
412
413
414 cdef class DatatypeDecl:
415 """
416 A cvc5 datatype declaration.
417
418 Wrapper class for :cpp:class:`cvc5::DatatypeDecl`.
419 """
420 cdef c_DatatypeDecl cdd
421 cdef Solver solver
422 def __cinit__(self, Solver solver):
423 self.solver = solver
424
425 def addConstructor(self, DatatypeConstructorDecl ctor):
426 """
427 Add a datatype constructor declaration.
428
429 :param ctor: The datatype constructor declaration to add.
430 """
431 self.cdd.addConstructor(ctor.cddc)
432
433 def getNumConstructors(self):
434 """
435 :return: The number of constructors (so far) for this datatype
436 declaration.
437 """
438 return self.cdd.getNumConstructors()
439
440 def isParametric(self):
441 """
442 :return: True if this datatype declaration is parametric.
443 """
444 return self.cdd.isParametric()
445
446 def getName(self):
447 """
448 :return: The name of this datatype declaration.
449 """
450 return self.cdd.getName().decode()
451
452 def isNull(self):
453 """
454 :return: True if this DatatypeDecl is a null object.
455 """
456 return self.cdd.isNull()
457
458 def __str__(self):
459 return self.cdd.toString().decode()
460
461 def __repr__(self):
462 return self.cdd.toString().decode()
463
464
465 cdef class DatatypeSelector:
466 """
467 A cvc5 datatype selector.
468
469 Wrapper class for :cpp:class:`cvc5::DatatypeSelector`.
470 """
471 cdef c_DatatypeSelector cds
472 cdef Solver solver
473 def __cinit__(self, Solver solver):
474 self.cds = c_DatatypeSelector()
475 self.solver = solver
476
477 def getName(self):
478 """
479 :return: The name of this datatype selector.
480 """
481 return self.cds.getName().decode()
482
483 def getSelectorTerm(self):
484 """
485 :return: The selector opeartor of this datatype selector as a term.
486 """
487 cdef Term term = Term(self.solver)
488 term.cterm = self.cds.getSelectorTerm()
489 return term
490
491 def getUpdaterTerm(self):
492 """
493 :return: The updater opeartor of this datatype selector as a term.
494 """
495 cdef Term term = Term(self.solver)
496 term.cterm = self.cds.getUpdaterTerm()
497 return term
498
499 def getCodomainSort(self):
500 """
501 :return: The codomain sort of this selector.
502 """
503 cdef Sort sort = Sort(self.solver)
504 sort.csort = self.cds.getCodomainSort()
505 return sort
506
507 def isNull(self):
508 """
509 :return: True if this DatatypeSelector is a null object.
510 """
511 return self.cds.isNull()
512
513 def __str__(self):
514 return self.cds.toString().decode()
515
516 def __repr__(self):
517 return self.cds.toString().decode()
518
519
520 cdef class Op:
521 """
522 A cvc5 operator.
523
524 An operator is a term that represents certain operators,
525 instantiated with its required parameters, e.g.,
526 a term of kind :py:obj:`BVExtract <cvc5.Kind.BVExtract>`.
527
528 Wrapper class for :cpp:class:`cvc5::Op`.
529 """
530 cdef c_Op cop
531 cdef Solver solver
532 def __cinit__(self, Solver solver):
533 self.cop = c_Op()
534 self.solver = solver
535
536 def __eq__(self, Op other):
537 return self.cop == other.cop
538
539 def __ne__(self, Op other):
540 return self.cop != other.cop
541
542 def __str__(self):
543 return self.cop.toString().decode()
544
545 def __repr__(self):
546 return self.cop.toString().decode()
547
548 def __hash__(self):
549 return cophash(self.cop)
550
551 def getKind(self):
552 """
553 :return: The kind of this operator.
554 """
555 return Kind(<int> self.cop.getKind())
556
557 def isIndexed(self):
558 """
559 :return: True iff this operator is indexed.
560 """
561 return self.cop.isIndexed()
562
563 def isNull(self):
564 """
565 :return: True iff this operator is a null term.
566 """
567 return self.cop.isNull()
568
569 def getNumIndices(self):
570 """
571 :return: The number of indices of this op.
572 """
573 return self.cop.getNumIndices()
574
575 def __getitem__(self, i):
576 """
577 Get the index at position ``i``.
578
579 :param i: The position of the index to return.
580 :return: The index at position ``i``.
581 """
582 cdef Term term = Term(self.solver)
583 term.cterm = self.cop[i]
584 return term
585
586
587 cdef class Grammar:
588 """
589 A Sygus Grammar.
590
591 Wrapper class for :cpp:class:`cvc5::Grammar`.
592 """
593 cdef c_Grammar cgrammar
594 cdef Solver solver
595 def __cinit__(self, Solver solver):
596 self.solver = solver
597 self.cgrammar = c_Grammar()
598
599 def addRule(self, Term ntSymbol, Term rule):
600 """
601 Add ``rule`` to the set of rules corresponding to ``ntSymbol``.
602
603 :param ntSymbol: The non-terminal to which the rule is added.
604 :param rule: The rule to add.
605 """
606 self.cgrammar.addRule(ntSymbol.cterm, rule.cterm)
607
608 def addAnyConstant(self, Term ntSymbol):
609 """
610 Allow ``ntSymbol`` to be an arbitrary constant.
611
612 :param ntSymbol: The non-terminal allowed to be constant.
613 """
614 self.cgrammar.addAnyConstant(ntSymbol.cterm)
615
616 def addAnyVariable(self, Term ntSymbol):
617 """
618 Allow ``ntSymbol`` to be any input variable to corresponding
619 synth-fun/synth-inv with the same sort as ``ntSymbol``.
620
621 :param ntSymbol: The non-terminal allowed to be any input variable.
622 """
623 self.cgrammar.addAnyVariable(ntSymbol.cterm)
624
625 def addRules(self, Term ntSymbol, rules):
626 """
627 Add ``ntSymbol`` to the set of rules corresponding to ``ntSymbol``.
628
629 :param ntSymbol: The non-terminal to which the rules are added.
630 :param rules: The rules to add.
631 """
632 cdef vector[c_Term] crules
633 for r in rules:
634 crules.push_back((<Term?> r).cterm)
635 self.cgrammar.addRules(ntSymbol.cterm, crules)
636
637 cdef class Result:
638 """
639 Encapsulation of a three-valued solver result, with explanations.
640
641 Wrapper class for :cpp:class:`cvc5::Result`.
642 """
643 cdef c_Result cr
644 def __cinit__(self):
645 # gets populated by solver
646 self.cr = c_Result()
647
648 def isNull(self):
649 """
650 :return: True if Result is empty, i.e., a nullary Result, and not
651 an actual result returned from a
652 :py:meth:`Solver.checkSat()` (and friends) query.
653 """
654 return self.cr.isNull()
655
656 def isSat(self):
657 """
658 :return: True if query was a satisfiable
659 :py:meth:`Solver.checkSat()` or
660 :py:meth:`Solver.checkSatAssuming()` query.
661 """
662 return self.cr.isSat()
663
664 def isUnsat(self):
665 """
666 :return: True if query was an usatisfiable
667 :py:meth:`Solver.checkSat()` or
668 :py:meth:`Solver.checkSatAssuming()` query.
669 """
670 return self.cr.isUnsat()
671
672 def isUnknown(self):
673 """
674 :return: True if query was a :py:meth:`Solver.checkSat()` or
675 :py:meth:`Solver.checkSatAssuming()` query and cvc5 was
676 not able to determine (un)satisfiability.
677 """
678 return self.cr.isUnknown()
679
680 def getUnknownExplanation(self):
681 """
682 :return: An explanation for an unknown query result.
683 """
684 return UnknownExplanation(<int> self.cr.getUnknownExplanation())
685
686 def __eq__(self, Result other):
687 return self.cr == other.cr
688
689 def __ne__(self, Result other):
690 return self.cr != other.cr
691
692 def __str__(self):
693 return self.cr.toString().decode()
694
695 def __repr__(self):
696 return self.cr.toString().decode()
697
698 cdef class SynthResult:
699 """
700 Encapsulation of a solver synth result.
701
702 This is the return value of the API methods:
703
704 - :py:meth:`Solver.checkSynth()`
705 - :py:meth:`Solver.checkSynthNext()`
706
707 which we call synthesis queries. This class indicates whether the
708 synthesis query has a solution, has no solution, or is unknown.
709 """
710 cdef c_SynthResult cr
711 def __cinit__(self):
712 # gets populated by solver
713 self.cr = c_SynthResult()
714
715 def isNull(self):
716 """
717 :return: True if SynthResult is null, i.e., not a SynthResult
718 returned from a synthesis query.
719 """
720 return self.cr.isNull()
721
722 def hasSolution(self):
723 """
724 :return: True if the synthesis query has a solution.
725 """
726 return self.cr.hasSolution()
727
728 def hasNoSolution(self):
729 """
730 :return: True if the synthesis query has no solution.
731 In this case, it was determined that there was no solution.
732 """
733 return self.cr.hasNoSolution()
734
735 def isUnknown(self):
736 """
737 :return: True if the result of the synthesis query could not be
738 determined.
739 """
740 return self.cr.isUnknown()
741
742 def __str__(self):
743 return self.cr.toString().decode()
744
745 def __repr__(self):
746 return self.cr.toString().decode()
747
748
749 cdef class Solver:
750 """
751 A cvc5 solver.
752
753 Wrapper class for :cpp:class:`cvc5::Solver`.
754 """
755 cdef c_Solver* csolver
756
757 def __cinit__(self):
758 self.csolver = new c_Solver()
759
760 def __dealloc__(self):
761 del self.csolver
762
763 def getBooleanSort(self):
764 """
765 :return: Sort Boolean.
766 """
767 cdef Sort sort = Sort(self)
768 sort.csort = self.csolver.getBooleanSort()
769 return sort
770
771 def getIntegerSort(self):
772 """
773 :return: Sort Integer.
774 """
775 cdef Sort sort = Sort(self)
776 sort.csort = self.csolver.getIntegerSort()
777 return sort
778
779 def getNullSort(self):
780 """
781 :return: A null sort object.
782 """
783 cdef Sort sort = Sort(self)
784 sort.csort = self.csolver.getNullSort()
785 return sort
786
787 def getRealSort(self):
788 """
789 :return: Sort Real.
790 """
791 cdef Sort sort = Sort(self)
792 sort.csort = self.csolver.getRealSort()
793 return sort
794
795 def getRegExpSort(self):
796 """:return: The sort of regular expressions.
797 """
798 cdef Sort sort = Sort(self)
799 sort.csort = self.csolver.getRegExpSort()
800 return sort
801
802 def getRoundingModeSort(self):
803 """:return: Sort RoundingMode.
804 """
805 cdef Sort sort = Sort(self)
806 sort.csort = self.csolver.getRoundingModeSort()
807 return sort
808
809 def getStringSort(self):
810 """:return: Sort String.
811 """
812 cdef Sort sort = Sort(self)
813 sort.csort = self.csolver.getStringSort()
814 return sort
815
816 def mkArraySort(self, Sort indexSort, Sort elemSort):
817 """
818 Create an array sort.
819
820 :param indexSort: The array index sort.
821 :param elemSort: The array element sort.
822 :return: The array sort.
823 """
824 cdef Sort sort = Sort(self)
825 sort.csort = self.csolver.mkArraySort(indexSort.csort, elemSort.csort)
826 return sort
827
828 def mkBitVectorSort(self, uint32_t size):
829 """
830 Create a bit-vector sort.
831
832 :param size: The bit-width of the bit-vector sort
833 :return: The bit-vector sort
834 """
835 cdef Sort sort = Sort(self)
836 sort.csort = self.csolver.mkBitVectorSort(size)
837 return sort
838
839 def mkFloatingPointSort(self, uint32_t exp, uint32_t sig):
840 """
841 Create a floating-point sort.
842
843 :param exp: The bit-width of the exponent of the floating-point
844 sort.
845 :param sig: The bit-width of the significand of the floating-point
846 sort.
847 """
848 cdef Sort sort = Sort(self)
849 sort.csort = self.csolver.mkFloatingPointSort(exp, sig)
850 return sort
851
852 def mkDatatypeSort(self, DatatypeDecl dtypedecl):
853 """
854 Create a datatype sort.
855
856 :param dtypedecl: The datatype declaration from which the sort is
857 created.
858 :return: The datatype sort.
859 """
860 cdef Sort sort = Sort(self)
861 sort.csort = self.csolver.mkDatatypeSort(dtypedecl.cdd)
862 return sort
863
864 def mkDatatypeSorts(self, list dtypedecls, unresolvedSorts = None):
865 """
866 Create a vector of datatype sorts using unresolved sorts. The names
867 of the datatype declarations in dtypedecls must be distinct.
868
869 This method is called when the DatatypeDecl objects dtypedecls have
870 been built using "unresolved" sorts.
871
872 We associate each sort in unresolvedSorts with exacly one datatype
873 from dtypedecls. In particular, it must have the same name as
874 exactly one datatype declaration in dtypedecls.
875
876 When constructing datatypes, unresolved sorts are replaced by the
877 datatype sort constructed for the datatype declaration it is
878 associated with.
879
880 :param dtypedecls: The datatype declarations from which the sort is
881 created.
882 :param unresolvedSorts: The list of unresolved sorts.
883 :return: The datatype sorts.
884 """
885 if unresolvedSorts == None:
886 unresolvedSorts = set([])
887 else:
888 assert isinstance(unresolvedSorts, set)
889
890 sorts = []
891 cdef vector[c_DatatypeDecl] decls
892 for decl in dtypedecls:
893 decls.push_back((<DatatypeDecl?> decl).cdd)
894
895 cdef c_set[c_Sort] usorts
896 for usort in unresolvedSorts:
897 usorts.insert((<Sort?> usort).csort)
898
899 csorts = self.csolver.mkDatatypeSorts(
900 <const vector[c_DatatypeDecl]&> decls, <const c_set[c_Sort]&> usorts)
901 for csort in csorts:
902 sort = Sort(self)
903 sort.csort = csort
904 sorts.append(sort)
905
906 return sorts
907
908 def mkFunctionSort(self, sorts, Sort codomain):
909 """
910 Create function sort.
911
912 :param sorts: The sort of the function arguments.
913 :param codomain: The sort of the function return value.
914 :return: The function sort.
915 """
916
917 cdef Sort sort = Sort(self)
918 # populate a vector with dereferenced c_Sorts
919 cdef vector[c_Sort] v
920 if isinstance(sorts, Sort):
921 v.push_back((<Sort?>sorts).csort)
922 else:
923 for s in sorts:
924 v.push_back((<Sort?>s).csort)
925
926 sort.csort = self.csolver.mkFunctionSort(<const vector[c_Sort]&> v,
927 codomain.csort)
928 return sort
929
930 def mkParamSort(self, str symbolname = None):
931 """
932 Create a sort parameter.
933
934 .. warning:: This method is experimental and may change in future
935 versions.
936
937 :param symbol: The name of the sort.
938 :return: The sort parameter.
939 """
940 cdef Sort sort = Sort(self)
941 if symbolname is None:
942 sort.csort = self.csolver.mkParamSort()
943 else:
944 sort.csort = self.csolver.mkParamSort(symbolname.encode())
945 return sort
946
947 @expand_list_arg(num_req_args=0)
948 def mkPredicateSort(self, *sorts):
949 """
950 Create a predicate sort.
951
952 :param sorts: The list of sorts of the predicate, as a list or as
953 distinct arguments.
954 :return: The predicate sort.
955 """
956 cdef Sort sort = Sort(self)
957 cdef vector[c_Sort] v
958 for s in sorts:
959 v.push_back((<Sort?> s).csort)
960 sort.csort = self.csolver.mkPredicateSort(<const vector[c_Sort]&> v)
961 return sort
962
963 @expand_list_arg(num_req_args=0)
964 def mkRecordSort(self, *fields):
965 """
966 Create a record sort
967
968 .. warning:: This method is experimental and may change in future
969 versions.
970
971 :param fields: The list of fields of the record, as a list or as
972 distinct arguments.
973 :return: The record sort.
974 """
975 cdef Sort sort = Sort(self)
976 cdef vector[pair[string, c_Sort]] v
977 cdef pair[string, c_Sort] p
978 for f in fields:
979 name, sortarg = f
980 name = name.encode()
981 p = pair[string, c_Sort](<string?> name, (<Sort?> sortarg).csort)
982 v.push_back(p)
983 sort.csort = self.csolver.mkRecordSort(
984 <const vector[pair[string, c_Sort]] &> v)
985 return sort
986
987 def mkSetSort(self, Sort elemSort):
988 """
989 Create a set sort.
990
991 :param elemSort: The sort of the set elements.
992 :return: The set sort.
993 """
994 cdef Sort sort = Sort(self)
995 sort.csort = self.csolver.mkSetSort(elemSort.csort)
996 return sort
997
998 def mkBagSort(self, Sort elemSort):
999 """
1000 Create a bag sort.
1001
1002 :param elemSort: The sort of the bag elements.
1003 :return: The bag sort.
1004 """
1005 cdef Sort sort = Sort(self)
1006 sort.csort = self.csolver.mkBagSort(elemSort.csort)
1007 return sort
1008
1009 def mkSequenceSort(self, Sort elemSort):
1010 """
1011 Create a sequence sort.
1012
1013 :param elemSort: The sort of the sequence elements
1014 :return: The sequence sort.
1015 """
1016 cdef Sort sort = Sort(self)
1017 sort.csort = self.csolver.mkSequenceSort(elemSort.csort)
1018 return sort
1019
1020 def mkUninterpretedSort(self, str name = None):
1021 """
1022 Create an uninterpreted sort.
1023
1024 :param symbol: The name of the sort.
1025 :return: The uninterpreted sort.
1026 """
1027 cdef Sort sort = Sort(self)
1028 if name is None:
1029 sort.csort = self.csolver.mkUninterpretedSort()
1030 else:
1031 sort.csort = self.csolver.mkUninterpretedSort(name.encode())
1032 return sort
1033
1034 def mkUnresolvedSort(self, str name, size_t arity = 0):
1035 """
1036 Create an unresolved sort.
1037
1038 This is for creating yet unresolved sort placeholders for mutually
1039 recursive datatypes.
1040
1041 :param symbol: The name of the sort.
1042 :param arity: The number of sort parameters of the sort.
1043 :return: The unresolved sort.
1044 """
1045 cdef Sort sort = Sort(self)
1046 sort.csort = self.csolver.mkUnresolvedSort(name.encode(), arity)
1047 return sort
1048
1049 def mkUninterpretedSortConstructorSort(self, size_t arity, str symbol = None):
1050 """
1051 Create a sort constructor sort.
1052
1053 An uninterpreted sort constructor is an uninterpreted sort with
1054 arity > 0.
1055
1056 :param symbol: The symbol of the sort.
1057 :param arity: The arity of the sort (must be > 0).
1058 :return: The sort constructor sort.
1059 """
1060 cdef Sort sort = Sort(self)
1061 if symbol is None:
1062 sort.csort = self.csolver.mkUninterpretedSortConstructorSort(arity)
1063 else:
1064 sort.csort = self.csolver.mkUninterpretedSortConstructorSort(
1065 arity, symbol.encode())
1066 return sort
1067
1068 @expand_list_arg(num_req_args=0)
1069 def mkTupleSort(self, *sorts):
1070 """
1071 Create a tuple sort.
1072
1073 :param sorts: Of the elements of the tuple, as a list or as
1074 distinct arguments.
1075 :return: The tuple sort.
1076 """
1077 cdef Sort sort = Sort(self)
1078 cdef vector[c_Sort] v
1079 for s in sorts:
1080 v.push_back((<Sort?> s).csort)
1081 sort.csort = self.csolver.mkTupleSort(v)
1082 return sort
1083
1084 @expand_list_arg(num_req_args=1)
1085 def mkTerm(self, kind_or_op, *args):
1086 """
1087 Create a term.
1088
1089 Supports the following arguments:
1090
1091 - ``Term mkTerm(Kind kind)``
1092 - ``Term mkTerm(Kind kind, List[Term] children)``
1093 - ``Term mkTerm(Op op)``
1094 - ``Term mkTerm(Op op, List[Term] children)``
1095
1096 where ``List[Term]`` can also be comma-separated arguments
1097 """
1098 cdef Term term = Term(self)
1099 cdef vector[c_Term] v
1100
1101 op = kind_or_op
1102 if isinstance(kind_or_op, Kind):
1103 op = self.mkOp(kind_or_op)
1104
1105 if len(args) == 0:
1106 term.cterm = self.csolver.mkTerm((<Op?> op).cop)
1107 else:
1108 for a in args:
1109 v.push_back((<Term?> a).cterm)
1110 term.cterm = self.csolver.mkTerm((<Op?> op).cop, v)
1111 return term
1112
1113 def mkTuple(self, sorts, terms):
1114 """
1115 Create a tuple term. Terms are automatically converted if sorts are
1116 compatible.
1117
1118 :param sorts: The sorts of the elements in the tuple.
1119 :param terms: The elements in the tuple.
1120 :return: The tuple Term.
1121 """
1122 cdef vector[c_Sort] csorts
1123 cdef vector[c_Term] cterms
1124
1125 for s in sorts:
1126 csorts.push_back((<Sort?> s).csort)
1127 for s in terms:
1128 cterms.push_back((<Term?> s).cterm)
1129 cdef Term result = Term(self)
1130 result.cterm = self.csolver.mkTuple(csorts, cterms)
1131 return result
1132
1133 @expand_list_arg(num_req_args=0)
1134 def mkOp(self, k, *args):
1135 """
1136 Create operator.
1137
1138 Supports the following arguments:
1139
1140 - ``Op mkOp(Kind kind)``
1141 - ``Op mkOp(Kind kind, const string& arg)``
1142 - ``Op mkOp(Kind kind, uint32_t arg0, ...)``
1143 """
1144 cdef Op op = Op(self)
1145 cdef vector[uint32_t] v
1146
1147 if len(args) == 0:
1148 op.cop = self.csolver.mkOp(<c_Kind> k.value)
1149 elif len(args) == 1 and isinstance(args[0], str):
1150 op.cop = self.csolver.mkOp(<c_Kind> k.value,
1151 <const string &>
1152 args[0].encode())
1153 else:
1154 for a in args:
1155 if not isinstance(a, int):
1156 raise ValueError(
1157 "Expected uint32_t for argument {}".format(a))
1158 if a < 0 or a >= 2 ** 31:
1159 raise ValueError(
1160 "Argument {} must fit in a uint32_t".format(a))
1161 v.push_back((<uint32_t?> a))
1162 op.cop = self.csolver.mkOp(<c_Kind> k.value, v)
1163 return op
1164
1165 def mkTrue(self):
1166 """
1167 Create a Boolean true constant.
1168
1169 :return: The true constant.
1170 """
1171 cdef Term term = Term(self)
1172 term.cterm = self.csolver.mkTrue()
1173 return term
1174
1175 def mkFalse(self):
1176 """
1177 Create a Boolean false constant.
1178
1179 :return: The false constant.
1180 """
1181 cdef Term term = Term(self)
1182 term.cterm = self.csolver.mkFalse()
1183 return term
1184
1185 def mkBoolean(self, bint val):
1186 """
1187 Create a Boolean constant.
1188
1189 :return: The Boolean constant.
1190 :param val: The value of the constant.
1191 """
1192 cdef Term term = Term(self)
1193 term.cterm = self.csolver.mkBoolean(val)
1194 return term
1195
1196 def mkPi(self):
1197 """
1198 Create a constant representing the number Pi.
1199
1200 :return: A constant representing :py:obj:`Pi <cvc5.Kind.Pi>`.
1201 """
1202 cdef Term term = Term(self)
1203 term.cterm = self.csolver.mkPi()
1204 return term
1205
1206 def mkInteger(self, val):
1207 """
1208 Create an integer constant.
1209
1210 :param val: Representation of the constant: either a string or
1211 integer.
1212 :return: A constant of sort Integer.
1213 """
1214 cdef Term term = Term(self)
1215 if isinstance(val, str):
1216 term.cterm = self.csolver.mkInteger(
1217 <const string &> str(val).encode())
1218 else:
1219 assert(isinstance(val, int))
1220 term.cterm = self.csolver.mkInteger((<int?> val))
1221 return term
1222
1223 def mkReal(self, val, den=None):
1224 """
1225 Create a real constant.
1226
1227 :param val: The value of the term. Can be an integer, float, or
1228 string. It will be formatted as a string before the
1229 term is built.
1230 :param den: If not None, the value is ``val``/``den``.
1231 :return: A real term with literal value.
1232
1233 Can be used in various forms:
1234
1235 - Given a string ``"N/D"`` constructs the corresponding rational.
1236 - Given a string ``"W.D"`` constructs the reduction of
1237 ``(W * P + D)/P``, where ``P`` is the appropriate power of 10.
1238 - Given a float ``f``, constructs the rational matching ``f``'s
1239 string representation. This means that ``mkReal(0.3)`` gives
1240 ``3/10`` and not the IEEE-754 approximation of ``3/10``.
1241 - Given a string ``"W"`` or an integer, constructs that integer.
1242 - Given two strings and/or integers ``N`` and ``D``, constructs
1243 ``N/D``.
1244 """
1245 cdef Term term = Term(self)
1246 if den is None:
1247 term.cterm = self.csolver.mkReal(str(val).encode())
1248 else:
1249 if not isinstance(val, int) or not isinstance(den, int):
1250 raise ValueError("Expecting integers when"
1251 " constructing a rational"
1252 " but got: {}".format((val, den)))
1253 term.cterm = self.csolver.mkReal("{}/{}".format(val, den).encode())
1254 return term
1255
1256 def mkRegexpAll(self):
1257 """
1258 Create a regular expression all (``re.all``) term.
1259
1260 :return: The all term.
1261 """
1262 cdef Term term = Term(self)
1263 term.cterm = self.csolver.mkRegexpAll()
1264 return term
1265
1266 def mkRegexpAllchar(self):
1267 """
1268 Create a regular expression allchar (``re.allchar``) term.
1269
1270 :return: The allchar term.
1271 """
1272 cdef Term term = Term(self)
1273 term.cterm = self.csolver.mkRegexpAllchar()
1274 return term
1275
1276 def mkRegexpNone(self):
1277 """
1278 Create a regular expression none (``re.none``) term.
1279
1280 :return: The none term.
1281 """
1282 cdef Term term = Term(self)
1283 term.cterm = self.csolver.mkRegexpNone()
1284 return term
1285
1286 def mkEmptySet(self, Sort s):
1287 """
1288 Create a constant representing an empty set of the given sort.
1289
1290 :param sort: The sort of the set elements.
1291 :return: The empty set constant.
1292 """
1293 cdef Term term = Term(self)
1294 term.cterm = self.csolver.mkEmptySet(s.csort)
1295 return term
1296
1297 def mkEmptyBag(self, Sort s):
1298 """
1299 Create a constant representing an empty bag of the given sort.
1300
1301 :param sort: The sort of the bag elements.
1302 :return: The empty bag constant.
1303 """
1304 cdef Term term = Term(self)
1305 term.cterm = self.csolver.mkEmptyBag(s.csort)
1306 return term
1307
1308 def mkSepEmp(self):
1309 """
1310 Create a separation logic empty term.
1311
1312 .. warning:: This method is experimental and may change in future
1313 versions.
1314
1315 :return: The separation logic empty term.
1316 """
1317 cdef Term term = Term(self)
1318 term.cterm = self.csolver.mkSepEmp()
1319 return term
1320
1321 def mkSepNil(self, Sort sort):
1322 """
1323 Create a separation logic nil term.
1324
1325 .. warning:: This method is experimental and may change in future
1326 versions.
1327
1328 :param sort: The sort of the nil term.
1329 :return: The separation logic nil term.
1330 """
1331 cdef Term term = Term(self)
1332 term.cterm = self.csolver.mkSepNil(sort.csort)
1333 return term
1334
1335 def mkString(self, str s, useEscSequences = None):
1336 """
1337 Create a String constant from a ``str`` which may contain SMT-LIB
1338 compatible escape sequences like ``\\u1234`` to encode unicode
1339 characters.
1340
1341 :param s: The string this constant represents.
1342 :param useEscSequences: Determines whether escape sequences in `s`
1343 should be converted to the corresponding
1344 unicode character
1345 :return: The String constant.
1346 """
1347 cdef Term term = Term(self)
1348 cdef Py_ssize_t size
1349 cdef wchar_t* tmp = PyUnicode_AsWideCharString(s, &size)
1350 if isinstance(useEscSequences, bool):
1351 term.cterm = self.csolver.mkString(
1352 s.encode(), <bint> useEscSequences)
1353 else:
1354 term.cterm = self.csolver.mkString(c_wstring(tmp, size))
1355 PyMem_Free(tmp)
1356 return term
1357
1358 def mkEmptySequence(self, Sort sort):
1359 """
1360 Create an empty sequence of the given element sort.
1361
1362 :param sort: The element sort of the sequence.
1363 :return: The empty sequence with given element sort.
1364 """
1365 cdef Term term = Term(self)
1366 term.cterm = self.csolver.mkEmptySequence(sort.csort)
1367 return term
1368
1369 def mkUniverseSet(self, Sort sort):
1370 """
1371 Create a universe set of the given sort.
1372
1373 :param sort: The sort of the set elements
1374 :return: The universe set constant
1375 """
1376 cdef Term term = Term(self)
1377 term.cterm = self.csolver.mkUniverseSet(sort.csort)
1378 return term
1379
1380 @expand_list_arg(num_req_args=0)
1381 def mkBitVector(self, *args):
1382 """
1383 Create bit-vector value.
1384
1385 Supports the following arguments:
1386
1387 - ``Term mkBitVector(int size, int val=0)``
1388 - ``Term mkBitVector(int size, string val, int base)``
1389
1390 :return: A Term representing a bit-vector value.
1391 :param size: The bit-width.
1392 :param val: An integer representating the value, in the first form.
1393 In the second form, a string representing the value.
1394 :param base: The base of the string representation (second form
1395 only).
1396 """
1397 cdef Term term = Term(self)
1398 if len(args) == 0:
1399 raise ValueError("Missing arguments to mkBitVector")
1400 size = args[0]
1401 if not isinstance(size, int):
1402 raise ValueError(
1403 "Invalid first argument to mkBitVector '{}', "
1404 "expected bit-vector size".format(size))
1405 if len(args) == 1:
1406 term.cterm = self.csolver.mkBitVector(<uint32_t> size)
1407 elif len(args) == 2:
1408 val = args[1]
1409 if not isinstance(val, int):
1410 raise ValueError(
1411 "Invalid second argument to mkBitVector '{}', "
1412 "expected integer value".format(size))
1413 term.cterm = self.csolver.mkBitVector(
1414 <uint32_t> size, <uint32_t> val)
1415 elif len(args) == 3:
1416 val = args[1]
1417 base = args[2]
1418 if not isinstance(val, str):
1419 raise ValueError(
1420 "Invalid second argument to mkBitVector '{}', "
1421 "expected value string".format(size))
1422 if not isinstance(base, int):
1423 raise ValueError(
1424 "Invalid third argument to mkBitVector '{}', "
1425 "expected base given as integer".format(size))
1426 term.cterm = self.csolver.mkBitVector(
1427 <uint32_t> size,
1428 <const string&> str(val).encode(),
1429 <uint32_t> base)
1430 else:
1431 raise ValueError("Unexpected inputs to mkBitVector")
1432 return term
1433
1434 def mkConstArray(self, Sort sort, Term val):
1435 """
1436 Create a constant array with the provided constant value stored at
1437 every index
1438
1439 :param sort: The sort of the constant array (must be an array sort).
1440 :param val: The constant value to store (must match the sort's
1441 element sort).
1442 :return: The constant array term.
1443 """
1444 cdef Term term = Term(self)
1445 term.cterm = self.csolver.mkConstArray(sort.csort, val.cterm)
1446 return term
1447
1448 def mkFloatingPointPosInf(self, int exp, int sig):
1449 """
1450 Create a positive infinity floating-point constant.
1451
1452 :param exp: Number of bits in the exponent.
1453 :param sig: Number of bits in the significand.
1454 :return: The floating-point constant.
1455 """
1456 cdef Term term = Term(self)
1457 term.cterm = self.csolver.mkFloatingPointPosInf(exp, sig)
1458 return term
1459
1460 def mkFloatingPointNegInf(self, int exp, int sig):
1461 """
1462 Create a negative infinity floating-point constant.
1463
1464 :param exp: Number of bits in the exponent.
1465 :param sig: Number of bits in the significand.
1466 :return: The floating-point constant.
1467 """
1468 cdef Term term = Term(self)
1469 term.cterm = self.csolver.mkFloatingPointNegInf(exp, sig)
1470 return term
1471
1472 def mkFloatingPointNaN(self, int exp, int sig):
1473 """
1474 Create a not-a-number (NaN) floating-point constant.
1475
1476 :param exp: Number of bits in the exponent.
1477 :param sig: Number of bits in the significand.
1478 :return: The floating-point constant.
1479 """
1480 cdef Term term = Term(self)
1481 term.cterm = self.csolver.mkFloatingPointNaN(exp, sig)
1482 return term
1483
1484 def mkFloatingPointPosZero(self, int exp, int sig):
1485 """
1486 Create a positive zero (+0.0) floating-point constant.
1487
1488 :param exp: Number of bits in the exponent.
1489 :param sig: Number of bits in the significand.
1490 :return: The floating-point constant.
1491 """
1492 cdef Term term = Term(self)
1493 term.cterm = self.csolver.mkFloatingPointPosZero(exp, sig)
1494 return term
1495
1496 def mkFloatingPointNegZero(self, int exp, int sig):
1497 """
1498 Create a negative zero (+0.0) floating-point constant.
1499
1500 :param exp: Number of bits in the exponent.
1501 :param sig: Number of bits in the significand.
1502 :return: The floating-point constant.
1503 """
1504 cdef Term term = Term(self)
1505 term.cterm = self.csolver.mkFloatingPointNegZero(exp, sig)
1506 return term
1507
1508 def mkRoundingMode(self, rm):
1509 """
1510 Create a roundingmode constant.
1511
1512 :param rm: The floating point rounding mode this constant
1513 represents.
1514 """
1515 cdef Term term = Term(self)
1516 term.cterm = self.csolver.mkRoundingMode(<c_RoundingMode> rm.value)
1517 return term
1518
1519 def mkFloatingPoint(self, int exp, int sig, Term val):
1520 """
1521 Create a floating-point constant.
1522
1523 :param exp: Size of the exponent.
1524 :param sig: Size of the significand.
1525 :param val: Value of the floating-point constant as a bit-vector
1526 term.
1527 """
1528 cdef Term term = Term(self)
1529 term.cterm = self.csolver.mkFloatingPoint(exp, sig, val.cterm)
1530 return term
1531
1532 def mkCardinalityConstraint(self, Sort sort, int index):
1533 """
1534 Create cardinality constraint.
1535
1536 .. warning:: This method is experimental and may change in future
1537 versions.
1538
1539 :param sort: Sort of the constraint.
1540 :param index: The upper bound for the cardinality of the sort.
1541 """
1542 cdef Term term = Term(self)
1543 term.cterm = self.csolver.mkCardinalityConstraint(sort.csort, index)
1544 return term
1545
1546 def mkConst(self, Sort sort, symbol=None):
1547 """
1548 Create (first-order) constant (0-arity function symbol).
1549
1550 SMT-LIB:
1551
1552 .. code-block:: smtlib
1553
1554 ( declare-const <symbol> <sort> )
1555 ( declare-fun <symbol> ( ) <sort> )
1556
1557 :param sort: The sort of the constant.
1558 :param symbol: The name of the constant. If None, a default symbol
1559 is used.
1560 :return: The first-order constant.
1561 """
1562 cdef Term term = Term(self)
1563 if symbol is None:
1564 term.cterm = self.csolver.mkConst(sort.csort)
1565 else:
1566 term.cterm = self.csolver.mkConst(sort.csort,
1567 (<str?> symbol).encode())
1568 return term
1569
1570 def mkVar(self, Sort sort, symbol=None):
1571 """
1572 Create a bound variable to be used in a binder (i.e. a quantifier,
1573 a lambda, or a witness binder).
1574
1575 :param sort: The sort of the variable.
1576 :param symbol: The name of the variable.
1577 :return: The variable.
1578 """
1579 cdef Term term = Term(self)
1580 if symbol is None:
1581 term.cterm = self.csolver.mkVar(sort.csort)
1582 else:
1583 term.cterm = self.csolver.mkVar(sort.csort,
1584 (<str?> symbol).encode())
1585 return term
1586
1587 def mkDatatypeConstructorDecl(self, str name):
1588 """
1589 Create datatype constructor declaration.
1590
1591 :param name: The name of the constructor.
1592 :return: The datatype constructor declaration.
1593 """
1594 cdef DatatypeConstructorDecl ddc = DatatypeConstructorDecl(self)
1595 ddc.cddc = self.csolver.mkDatatypeConstructorDecl(name.encode())
1596 return ddc
1597
1598 def mkDatatypeDecl(self, str name, sorts_or_bool=None, isCoDatatype=None):
1599 """
1600 Create a datatype declaration.
1601
1602 :param name: The name of the datatype.
1603 :param isCoDatatype: True if a codatatype is to be constructed.
1604 :return: The datatype declaration.
1605 """
1606 cdef DatatypeDecl dd = DatatypeDecl(self)
1607 cdef vector[c_Sort] v
1608
1609 # argument cases
1610 if sorts_or_bool is None and isCoDatatype is None:
1611 dd.cdd = self.csolver.mkDatatypeDecl(name.encode())
1612 elif sorts_or_bool is not None and isCoDatatype is None:
1613 if isinstance(sorts_or_bool, bool):
1614 dd.cdd = self.csolver.mkDatatypeDecl(
1615 <const string &> name.encode(), <bint> sorts_or_bool)
1616 elif isinstance(sorts_or_bool, Sort):
1617 dd.cdd = self.csolver.mkDatatypeDecl(
1618 <const string &> name.encode(),
1619 (<Sort> sorts_or_bool).csort)
1620 elif isinstance(sorts_or_bool, list):
1621 for s in sorts_or_bool:
1622 v.push_back((<Sort?> s).csort)
1623 dd.cdd = self.csolver.mkDatatypeDecl(
1624 <const string &> name.encode(),
1625 <const vector[c_Sort]&> v)
1626 else:
1627 raise ValueError("Unhandled second argument type {}"
1628 .format(type(sorts_or_bool)))
1629 elif sorts_or_bool is not None and isCoDatatype is not None:
1630 if isinstance(sorts_or_bool, Sort):
1631 dd.cdd = self.csolver.mkDatatypeDecl(
1632 <const string &> name.encode(),
1633 (<Sort> sorts_or_bool).csort,
1634 <bint> isCoDatatype)
1635 elif isinstance(sorts_or_bool, list):
1636 for s in sorts_or_bool:
1637 v.push_back((<Sort?> s).csort)
1638 dd.cdd = self.csolver.mkDatatypeDecl(
1639 <const string &> name.encode(),
1640 <const vector[c_Sort]&> v,
1641 <bint> isCoDatatype)
1642 else:
1643 raise ValueError("Unhandled second argument type {}"
1644 .format(type(sorts_or_bool)))
1645 else:
1646 raise ValueError("Can't create DatatypeDecl with {}".format(
1647 [type(a) for a in [name, sorts_or_bool, isCoDatatype]]))
1648
1649 return dd
1650
1651 def simplify(self, Term t):
1652 """
1653 Simplify a formula without doing "much" work. Does not involve the
1654 SAT Engine in the simplification, but uses the current definitions,
1655 assertions, and the current partial model, if one has been
1656 constructed. It also involves theory normalization.
1657
1658 .. warning:: This method is experimental and may change in future
1659 versions.
1660
1661 :param t: The formula to simplify.
1662 :return: The simplified formula.
1663 """
1664 cdef Term term = Term(self)
1665 term.cterm = self.csolver.simplify(t.cterm)
1666 return term
1667
1668 def assertFormula(self, Term term):
1669 """
1670 Assert a formula
1671
1672 SMT-LIB:
1673
1674 .. code-block:: smtlib
1675
1676 ( assert <term> )
1677
1678 :param term: The formula to assert.
1679 """
1680 self.csolver.assertFormula(term.cterm)
1681
1682 def checkSat(self):
1683 """
1684 Check satisfiability.
1685
1686 SMT-LIB:
1687
1688 .. code-block:: smtlib
1689
1690 ( check-sat )
1691
1692 :return: The result of the satisfiability check.
1693 """
1694 cdef Result r = Result()
1695 r.cr = self.csolver.checkSat()
1696 return r
1697
1698 def mkSygusGrammar(self, boundVars, ntSymbols):
1699 """
1700 Create a SyGuS grammar. The first non-terminal is treated as the
1701 starting non-terminal, so the order of non-terminals matters.
1702
1703 :param boundVars: The parameters to corresponding
1704 synth-fun/synth-inv.
1705 :param ntSymbols: The pre-declaration of the non-terminal symbols.
1706 :return: The grammar.
1707 """
1708 cdef Grammar grammar = Grammar(self)
1709 cdef vector[c_Term] bvc
1710 cdef vector[c_Term] ntc
1711 for bv in boundVars:
1712 bvc.push_back((<Term?> bv).cterm)
1713 for nt in ntSymbols:
1714 ntc.push_back((<Term?> nt).cterm)
1715 grammar.cgrammar = self.csolver.mkSygusGrammar(<const vector[c_Term]&> bvc, <const vector[c_Term]&> ntc)
1716 return grammar
1717
1718 def declareSygusVar(self, str symbol, Sort sort):
1719 """
1720 Append symbol to the current list of universal variables.
1721
1722 SyGuS v2:
1723
1724 .. code-block:: smtlib
1725
1726 ( declare-var <symbol> <sort> )
1727
1728 :param sort: The sort of the universal variable.
1729 :param symbol: The name of the universal variable.
1730 :return: The universal variable.
1731 """
1732 cdef Term term = Term(self)
1733 term.cterm = self.csolver.declareSygusVar(symbol.encode(), sort.csort)
1734 return term
1735
1736 def addSygusConstraint(self, Term t):
1737 """
1738 Add a formula to the set of SyGuS constraints.
1739
1740 SyGuS v2:
1741
1742 .. code-block:: smtlib
1743
1744 ( constraint <term> )
1745
1746 :param term: The formula to add as a constraint.
1747 """
1748 self.csolver.addSygusConstraint(t.cterm)
1749
1750 def addSygusAssume(self, Term t):
1751 """
1752 Add a formula to the set of Sygus assumptions.
1753
1754 SyGuS v2:
1755
1756 .. code-block:: smtlib
1757
1758 ( assume <term> )
1759
1760 :param term: The formuula to add as an assumption.
1761 """
1762 self.csolver.addSygusAssume(t.cterm)
1763
1764 def addSygusInvConstraint(self, Term inv_f, Term pre_f, Term trans_f, Term post_f):
1765 """
1766 Add a set of SyGuS constraints to the current state that correspond
1767 to an invariant synthesis problem.
1768
1769 SyGuS v2:
1770
1771 .. code-block:: smtlib
1772
1773 ( inv-constraint <inv> <pre> <trans> <post> )
1774
1775 :param inv: The function-to-synthesize.
1776 :param pre: The pre-condition.
1777 :param trans: The transition relation.
1778 :param post: The post-condition.
1779 """
1780 self.csolver.addSygusInvConstraint(
1781 inv_f.cterm, pre_f.cterm, trans_f.cterm, post_f.cterm)
1782
1783 def synthFun(self, str symbol, bound_vars, Sort sort, Grammar grammar=None):
1784 """
1785 Synthesize n-ary function following specified syntactic constraints.
1786
1787 SyGuS v2:
1788
1789 .. code-block:: smtlib
1790
1791 ( synth-fun <symbol> ( <boundVars>* ) <sort> <g> )
1792
1793 :param symbol: The name of the function.
1794 :param boundVars: The parameters to this function.
1795 :param sort: The sort of the return value of this function.
1796 :param grammar: The syntactic constraints.
1797 :return: The function.
1798 """
1799 cdef Term term = Term(self)
1800 cdef vector[c_Term] v
1801 for bv in bound_vars:
1802 v.push_back((<Term?> bv).cterm)
1803 if grammar is None:
1804 term.cterm = self.csolver.synthFun(symbol.encode(), <const vector[c_Term]&> v, sort.csort)
1805 else:
1806 term.cterm = self.csolver.synthFun(symbol.encode(), <const vector[c_Term]&> v, sort.csort, grammar.cgrammar)
1807 return term
1808
1809 def checkSynth(self):
1810 """
1811 Try to find a solution for the synthesis conjecture corresponding
1812 to the current list of functions-to-synthesize, universal variables
1813 and constraints.
1814
1815 SyGuS v2:
1816
1817 .. code-block:: smtlib
1818
1819 ( check-synth )
1820
1821 :return: The result of the check, which is "solution" if the check
1822 found a solution in which case solutions are available via
1823 getSynthSolutions, "no solution" if it was determined
1824 there is no solution, or "unknown" otherwise.
1825 """
1826 cdef SynthResult r = SynthResult()
1827 r.cr = self.csolver.checkSynth()
1828 return r
1829
1830 def checkSynthNext(self):
1831 """
1832 Try to find a next solution for the synthesis conjecture
1833 corresponding to the current list of functions-to-synthesize,
1834 universal variables and constraints. Must be called immediately
1835 after a successful call to check-synth or check-synth-next.
1836 Requires incremental mode.
1837
1838 SyGuS v2:
1839
1840 .. code-block:: smtlib
1841
1842 ( check-synth )
1843
1844 :return: The result of the check, which is "solution" if the check
1845 found a solution in which case solutions are available via
1846 getSynthSolutions, "no solution" if it was determined
1847 there is no solution, or "unknown" otherwise.
1848 """
1849 cdef SynthResult r = SynthResult()
1850 r.cr = self.csolver.checkSynthNext()
1851 return r
1852
1853 def getSynthSolution(self, Term term):
1854 """
1855 Get the synthesis solution of the given term. This method should be
1856 called immediately after the solver answers unsat for sygus input.
1857
1858 :param term: The term for which the synthesis solution is queried.
1859 :return: The synthesis solution of the given term.
1860 """
1861 cdef Term t = Term(self)
1862 t.cterm = self.csolver.getSynthSolution(term.cterm)
1863 return t
1864
1865 def getSynthSolutions(self, list terms):
1866 """
1867 Get the synthesis solutions of the given terms. This method should
1868 be called immediately after the solver answers unsat for sygus
1869 input.
1870
1871 :param terms: The terms for which the synthesis solutions is
1872 queried.
1873 :return: The synthesis solutions of the given terms.
1874 """
1875 result = []
1876 cdef vector[c_Term] vec
1877 for t in terms:
1878 vec.push_back((<Term?> t).cterm)
1879 cresult = self.csolver.getSynthSolutions(vec)
1880 for s in cresult:
1881 term = Term(self)
1882 term.cterm = s
1883 result.append(term)
1884 return result
1885
1886
1887 def synthInv(self, symbol, bound_vars, Grammar grammar=None):
1888 """
1889 Synthesize invariant.
1890
1891 SyGuS v2:
1892
1893 .. code-block:: smtlib
1894
1895 ( synth-inv <symbol> ( <boundVars>* ) <grammar> )
1896
1897 :param symbol: The name of the invariant.
1898 :param boundVars: The parameters to this invariant.
1899 :param grammar: The syntactic constraints.
1900 :return: The invariant.
1901 """
1902 cdef Term term = Term(self)
1903 cdef vector[c_Term] v
1904 for bv in bound_vars:
1905 v.push_back((<Term?> bv).cterm)
1906 if grammar is None:
1907 term.cterm = self.csolver.synthInv(
1908 symbol.encode(), <const vector[c_Term]&> v)
1909 else:
1910 term.cterm = self.csolver.synthInv(
1911 symbol.encode(),
1912 <const vector[c_Term]&> v,
1913 grammar.cgrammar)
1914 return term
1915
1916 @expand_list_arg(num_req_args=0)
1917 def checkSatAssuming(self, *assumptions):
1918 """
1919 Check satisfiability assuming the given formula.
1920
1921 SMT-LIB:
1922
1923 .. code-block:: smtlib
1924
1925 ( check-sat-assuming ( <prop_literal> ) )
1926
1927 :param assumptions: The formulas to assume, as a list or as
1928 distinct arguments.
1929 :return: The result of the satisfiability check.
1930 """
1931 cdef Result r = Result()
1932 # used if assumptions is a list of terms
1933 cdef vector[c_Term] v
1934 for a in assumptions:
1935 v.push_back((<Term?> a).cterm)
1936 r.cr = self.csolver.checkSatAssuming(<const vector[c_Term]&> v)
1937 return r
1938
1939 @expand_list_arg(num_req_args=1)
1940 def declareDatatype(self, str symbol, *ctors):
1941 """
1942 Create datatype sort.
1943
1944 SMT-LIB:
1945
1946 .. code-block:: smtlib
1947
1948 ( declare-datatype <symbol> <datatype_decl> )
1949
1950 :param symbol: The name of the datatype sort.
1951 :param ctors: The constructor declarations of the datatype sort, as
1952 a list or as distinct arguments.
1953 :return: The datatype sort.
1954 """
1955 cdef Sort sort = Sort(self)
1956 cdef vector[c_DatatypeConstructorDecl] v
1957
1958 for c in ctors:
1959 v.push_back((<DatatypeConstructorDecl?> c).cddc)
1960 sort.csort = self.csolver.declareDatatype(symbol.encode(), v)
1961 return sort
1962
1963 def declareFun(self, str symbol, list sorts, Sort sort):
1964 """
1965 Declare n-ary function symbol.
1966
1967 SMT-LIB:
1968
1969 .. code-block:: smtlib
1970
1971 ( declare-fun <symbol> ( <sort>* ) <sort> )
1972
1973 :param symbol: The name of the function.
1974 :param sorts: The sorts of the parameters to this function.
1975 :param sort: The sort of the return value of this function.
1976 :return: The function.
1977 """
1978 cdef Term term = Term(self)
1979 cdef vector[c_Sort] v
1980 for s in sorts:
1981 v.push_back((<Sort?> s).csort)
1982 term.cterm = self.csolver.declareFun(symbol.encode(),
1983 <const vector[c_Sort]&> v,
1984 sort.csort)
1985 return term
1986
1987 def declareSort(self, str symbol, int arity):
1988 """
1989 Declare uninterpreted sort.
1990
1991 SMT-LIB:
1992
1993 .. code-block:: smtlib
1994
1995 ( declare-sort <symbol> <numeral> )
1996
1997 .. note::
1998
1999 This corresponds to :py:meth:`Solver.mkUninterpretedSort()` if
2000 arity = 0, and to
2001 :py:meth:`Solver.mkUninterpretedSortConstructorSort()` if
2002 arity > 0.
2003
2004 :param symbol: The name of the sort.
2005 :param arity: The arity of the sort.
2006 :return: The sort.
2007 """
2008 cdef Sort sort = Sort(self)
2009 sort.csort = self.csolver.declareSort(symbol.encode(), arity)
2010 return sort
2011
2012 def defineFun(self, str symbol, list bound_vars, Sort sort, Term term, glbl=False):
2013 """
2014 Define n-ary function.
2015
2016 SMT-LIB:
2017
2018 .. code-block:: smtlib
2019
2020 ( define-fun <function_def> )
2021
2022 :param symbol: The name of the function.
2023 :param bound_vars: The parameters to this function.
2024 :param sort: The sort of the return value of this function.
2025 :param term: The function body.
2026 :param glbl: Determines whether this definition is global (i.e.
2027 persists when popping the context).
2028 :return: The function.
2029 """
2030 cdef Term fun = Term(self)
2031 cdef vector[c_Term] v
2032 for bv in bound_vars:
2033 v.push_back((<Term?> bv).cterm)
2034
2035 fun.cterm = self.csolver.defineFun(symbol.encode(),
2036 <const vector[c_Term] &> v,
2037 sort.csort,
2038 term.cterm,
2039 <bint> glbl)
2040 return fun
2041
2042 def defineFunRec(self, sym_or_fun, bound_vars, sort_or_term, t=None, glbl=False):
2043 """
2044 Define recursive functions.
2045
2046 Supports the following arguments:
2047
2048 - ``Term defineFunRec(str symbol, List[Term] bound_vars, Sort sort, Term term, bool glbl)``
2049 - ``Term defineFunRec(Term fun, List[Term] bound_vars, Term term, bool glbl)``
2050
2051 SMT-LIB:
2052
2053 .. code-block:: smtlib
2054
2055 ( define-funs-rec ( <function_decl>^n ) ( <term>^n ) )
2056
2057 Create elements of parameter ``funs`` with :py:meth:`mkConst() <cvc5.Solver.mkConst()>`.
2058
2059 :param funs: The sorted functions.
2060 :param bound_vars: The list of parameters to the functions.
2061 :param terms: The list of function bodies of the functions.
2062 :param global: Determines whether this definition is global (i.e.
2063 persists when popping the context).
2064 :return: The function.
2065 """
2066 cdef Term term = Term(self)
2067 cdef vector[c_Term] v
2068 for bv in bound_vars:
2069 v.push_back((<Term?> bv).cterm)
2070
2071 if t is not None:
2072 term.cterm = self.csolver.defineFunRec((<str?> sym_or_fun).encode(),
2073 <const vector[c_Term] &> v,
2074 (<Sort?> sort_or_term).csort,
2075 (<Term?> t).cterm,
2076 <bint> glbl)
2077 else:
2078 term.cterm = self.csolver.defineFunRec((<Term?> sym_or_fun).cterm,
2079 <const vector[c_Term]&> v,
2080 (<Term?> sort_or_term).cterm,
2081 <bint> glbl)
2082
2083 return term
2084
2085 def defineFunsRec(self, funs, bound_vars, terms):
2086 """
2087 Define recursive functions.
2088
2089 SMT-LIB:
2090
2091 .. code-block:: smtlib
2092
2093 ( define-funs-rec ( <function_decl>^n ) ( <term>^n ) )
2094
2095 Create elements of parameter ``funs`` with :py:meth:`mkConst() <cvc5.Solver.mkConst()>`.
2096
2097 :param funs: The sorted functions.
2098 :param bound_vars: The list of parameters to the functions.
2099 :param terms: The list of function bodies of the functions.
2100 :param global: Determines whether this definition is global (i.e.
2101 persists when popping the context).
2102 :return: The function.
2103 """
2104 cdef vector[c_Term] vf
2105 cdef vector[vector[c_Term]] vbv
2106 cdef vector[c_Term] vt
2107
2108 for f in funs:
2109 vf.push_back((<Term?> f).cterm)
2110
2111 cdef vector[c_Term] temp
2112 for v in bound_vars:
2113 for t in v:
2114 temp.push_back((<Term?> t).cterm)
2115 vbv.push_back(temp)
2116 temp.clear()
2117
2118 for t in terms:
2119 vf.push_back((<Term?> t).cterm)
2120
2121 def getProof(self):
2122 """
2123 Get the refutation proof
2124
2125 SMT-LIB:
2126
2127 .. code-block:: smtlib
2128
2129 (get-proof)
2130
2131 Requires to enable option
2132 :ref:`produce-proofs <lbl-option-produce-proofs>`.
2133
2134 .. warning:: This method is experimental and may change in future
2135 versions.
2136
2137 :return: A string representing the proof, according to the value of
2138 :ref:`proof-format-mode <lbl-option-proof-format-mode>`.
2139 """
2140 return self.csolver.getProof()
2141
2142 def getLearnedLiterals(self):
2143 """
2144 Get a list of literals that are entailed by the current set of assertions
2145
2146 SMT-LIB:
2147
2148 .. code-block:: smtlib
2149
2150 ( get-learned-literals )
2151
2152 .. warning:: This method is experimental and may change in future
2153 versions.
2154
2155 :return: The list of literals.
2156 """
2157 lits = []
2158 for a in self.csolver.getLearnedLiterals():
2159 term = Term(self)
2160 term.cterm = a
2161 lits.append(term)
2162 return lits
2163
2164 def getAssertions(self):
2165 """
2166 Get the list of asserted formulas.
2167
2168 SMT-LIB:
2169
2170 .. code-block:: smtlib
2171
2172 ( get-assertions )
2173
2174 :return: The list of asserted formulas.
2175 """
2176 assertions = []
2177 for a in self.csolver.getAssertions():
2178 term = Term(self)
2179 term.cterm = a
2180 assertions.append(term)
2181 return assertions
2182
2183 def getInfo(self, str flag):
2184 """
2185 Get info from the solver.
2186
2187 SMT-LIB:
2188
2189 .. code-block:: smtlib
2190
2191 ( get-info <info_flag> )
2192
2193 :param flag: The info flag.
2194 :return: The info.
2195 """
2196 return self.csolver.getInfo(flag.encode())
2197
2198 def getOption(self, str option):
2199 """
2200 Get the value of a given option.
2201
2202 SMT-LIB:
2203
2204 .. code-block:: smtlib
2205
2206 ( get-option <keyword> )
2207
2208 :param option: The option for which the value is queried.
2209 :return: A string representation of the option value.
2210 """
2211 return self.csolver.getOption(option.encode()).decode()
2212
2213 def getOptionNames(self):
2214 """
2215 Get all option names that can be used with
2216 :py:meth:`Solver.setOption()`, :py:meth:`Solver.getOption()`
2217 and :py:meth:`Solver.getOptionInfo()`.
2218
2219 :return: All option names.
2220 """
2221 return [s.decode() for s in self.csolver.getOptionNames()]
2222
2223 def getOptionInfo(self, str option):
2224 """
2225 Get some information about the given option.
2226 Returns the information provided by the C++
2227 :cpp:func:`OptionInfo <cvc5::OptionInfo>` as a dictionary.
2228
2229 :return: Information about the given option.
2230 """
2231 # declare all the variables we may need later
2232 cdef c_OptionInfo.ValueInfo[c_bool] vib
2233 cdef c_OptionInfo.ValueInfo[string] vis
2234 cdef c_OptionInfo.NumberInfo[int64_t] nii
2235 cdef c_OptionInfo.NumberInfo[uint64_t] niu
2236 cdef c_OptionInfo.NumberInfo[double] nid
2237 cdef c_OptionInfo.ModeInfo mi
2238
2239 oi = self.csolver.getOptionInfo(option.encode())
2240 # generic information
2241 res = {
2242 'name': oi.name.decode(),
2243 'aliases': [s.decode() for s in oi.aliases],
2244 'setByUser': oi.setByUser,
2245 }
2246
2247 # now check which type is actually in the variant
2248 if c_holds[c_OptionInfo.VoidInfo](oi.valueInfo):
2249 # it's a void
2250 res['type'] = None
2251 elif c_holds[c_OptionInfo.ValueInfo[c_bool]](oi.valueInfo):
2252 # it's a bool
2253 res['type'] = bool
2254 vib = c_getVariant[c_OptionInfo.ValueInfo[c_bool]](oi.valueInfo)
2255 res['current'] = vib.currentValue
2256 res['default'] = vib.defaultValue
2257 elif c_holds[c_OptionInfo.ValueInfo[string]](oi.valueInfo):
2258 # it's a string
2259 res['type'] = str
2260 vis = c_getVariant[c_OptionInfo.ValueInfo[string]](oi.valueInfo)
2261 res['current'] = vis.currentValue.decode()
2262 res['default'] = vis.defaultValue.decode()
2263 elif c_holds[c_OptionInfo.NumberInfo[int64_t]](oi.valueInfo):
2264 # it's an int64_t
2265 res['type'] = int
2266 nii = c_getVariant[c_OptionInfo.NumberInfo[int64_t]](oi.valueInfo)
2267 res['current'] = nii.currentValue
2268 res['default'] = nii.defaultValue
2269 res['minimum'] = nii.minimum.value() \
2270 if nii.minimum.has_value() else None
2271 res['maximum'] = nii.maximum.value() \
2272 if nii.maximum.has_value() else None
2273 elif c_holds[c_OptionInfo.NumberInfo[uint64_t]](oi.valueInfo):
2274 # it's a uint64_t
2275 res['type'] = int
2276 niu = c_getVariant[c_OptionInfo.NumberInfo[uint64_t]](oi.valueInfo)
2277 res['current'] = niu.currentValue
2278 res['default'] = niu.defaultValue
2279 res['minimum'] = niu.minimum.value() \
2280 if niu.minimum.has_value() else None
2281 res['maximum'] = niu.maximum.value() \
2282 if niu.maximum.has_value() else None
2283 elif c_holds[c_OptionInfo.NumberInfo[double]](oi.valueInfo):
2284 # it's a double
2285 res['type'] = float
2286 nid = c_getVariant[c_OptionInfo.NumberInfo[double]](oi.valueInfo)
2287 res['current'] = nid.currentValue
2288 res['default'] = nid.defaultValue
2289 res['minimum'] = nid.minimum.value() \
2290 if nid.minimum.has_value() else None
2291 res['maximum'] = nid.maximum.value() \
2292 if nid.maximum.has_value() else None
2293 elif c_holds[c_OptionInfo.ModeInfo](oi.valueInfo):
2294 # it's a mode
2295 res['type'] = 'mode'
2296 mi = c_getVariant[c_OptionInfo.ModeInfo](oi.valueInfo)
2297 res['current'] = mi.currentValue.decode()
2298 res['default'] = mi.defaultValue.decode()
2299 res['modes'] = [s.decode() for s in mi.modes]
2300 return res
2301
2302 def getOptionNames(self):
2303 """
2304 Get all option names that can be used with
2305 :py:meth:`Solver.setOption()`, :py:meth:`Solver.getOption()` and
2306 :py:meth:`Solver.getOptionInfo()`.
2307 :return: All option names.
2308 """
2309 result = []
2310 for n in self.csolver.getOptionNames():
2311 result += [n.decode()]
2312 return result
2313
2314 def getUnsatAssumptions(self):
2315 """
2316 Get the set of unsat ("failed") assumptions.
2317
2318 SMT-LIB:
2319
2320 .. code-block:: smtlib
2321
2322 ( get-unsat-assumptions )
2323
2324 Requires to enable option :ref:`produce-unsat-assumptions
2325 <lbl-option-produce-unsat-assumptions>`.
2326
2327 :return: The set of unsat assumptions.
2328 """
2329 assumptions = []
2330 for a in self.csolver.getUnsatAssumptions():
2331 term = Term(self)
2332 term.cterm = a
2333 assumptions.append(term)
2334 return assumptions
2335
2336 def getUnsatCore(self):
2337 """
2338 Get the unsatisfiable core.
2339
2340 SMT-LIB:
2341
2342 .. code-block:: smtlib
2343
2344 (get-unsat-core)
2345
2346 Requires to enable option :ref:`produce-unsat-cores
2347 <lbl-option-produce-unsat-cores>`.
2348
2349 .. note::
2350
2351 In contrast to SMT-LIB, the API does not distinguish between
2352 named and unnamed assertions when producing an unsatisfiable
2353 core. Additionally, the API allows this option to be called after
2354 a check with assumptions. A subset of those assumptions may be
2355 included in the unsatisfiable core returned by this method.
2356
2357 :return: A set of terms representing the unsatisfiable core.
2358 """
2359 core = []
2360 for a in self.csolver.getUnsatCore():
2361 term = Term(self)
2362 term.cterm = a
2363 core.append(term)
2364 return core
2365
2366 def getDifficulty(self):
2367 """
2368 Get a difficulty estimate for an asserted formula. This method is
2369 intended to be called immediately after any response to a
2370 :py:meth:`Solver.checkSat()` call.
2371
2372 .. warning:: This method is experimental and may change in future
2373 versions.
2374
2375 :return: A map from (a subset of) the input assertions to a real
2376 value that is an estimate of how difficult each assertion
2377 was to solver. Unmentioned assertions can be assumed to
2378 have zero difficulty.
2379 """
2380 diffi = {}
2381 for p in self.csolver.getDifficulty():
2382 k = p.first
2383 v = p.second
2384
2385 termk = Term(self)
2386 termk.cterm = k
2387
2388 termv = Term(self)
2389 termv.cterm = v
2390
2391 diffi[termk] = termv
2392 return diffi
2393
2394 def getValue(self, Term t):
2395 """
2396 Get the value of the given term in the current model.
2397
2398 SMT-LIB:
2399
2400 .. code-block:: smtlib
2401
2402 ( get-value ( <term> ) )
2403
2404 :param term: The term for which the value is queried.
2405 :return: The value of the given term.
2406 """
2407 cdef Term term = Term(self)
2408 term.cterm = self.csolver.getValue(t.cterm)
2409 return term
2410
2411 def getModelDomainElements(self, Sort s):
2412 """
2413 Get the domain elements of uninterpreted sort s in the current
2414 model. The current model interprets s as the finite sort whose
2415 domain elements are given in the return value of this method.
2416
2417 :param s: The uninterpreted sort in question.
2418 :return: The domain elements of s in the current model.
2419 """
2420 result = []
2421 cresult = self.csolver.getModelDomainElements(s.csort)
2422 for e in cresult:
2423 term = Term(self)
2424 term.cterm = e
2425 result.append(term)
2426 return result
2427
2428 def isModelCoreSymbol(self, Term v):
2429 """
2430 This returns False if the model value of free constant v was not
2431 essential for showing the satisfiability of the last call to
2432 checkSat using the current model. This method will only return
2433 false (for any v) if the model-cores option has been set.
2434
2435 .. warning:: This method is experimental and may change in future
2436 versions.
2437
2438 :param v: The term in question.
2439 :return: True if v is a model core symbol.
2440 """
2441 return self.csolver.isModelCoreSymbol(v.cterm)
2442
2443 def getQuantifierElimination(self, Term term):
2444 """
2445 Do quantifier elimination.
2446
2447 SMT-LIB:
2448
2449 .. code-block:: smtlib
2450
2451 ( get-qe <q> )
2452
2453 Requires a logic that supports quantifier elimination.
2454 Currently, the only logics supported by quantifier elimination
2455 are LRA and LIA.
2456
2457 .. warning:: This method is experimental and may change in future
2458 versions.
2459
2460 :param q: A quantified formula of the form
2461 :math:`Q\\bar{x_1}\\dots Q\\bar{x}_n. P( x_1 \\dots x_i, y_1 \\dots y_j)`
2462 where
2463 :math:`Q\\bar{x}` is a set of quantified variables of the
2464 form :math:`Q x_1...x_k` and
2465 :math:`P( x_1...x_i, y_1...y_j )` is a quantifier-free
2466 formula
2467 :return: A formula :math:`\\phi` such that, given the current set
2468 of formulas :math:`A` asserted to this solver:
2469
2470 - :math:`(A \\wedge q)` :math:`(A \\wedge \\phi)` are
2471 equivalent
2472 - :math:`\\phi` is quantifier-free formula containing only
2473 free variables in :math:`y_1...y_n`.
2474 """
2475 cdef Term result = Term(self)
2476 result.cterm = self.csolver.getQuantifierElimination(term.cterm)
2477 return result
2478
2479 def getQuantifierEliminationDisjunct(self, Term term):
2480 """
2481 Do partial quantifier elimination, which can be used for
2482 incrementally computing the result of a quantifier elimination.
2483
2484 SMT-LIB:
2485
2486 .. code-block:: smtlib
2487
2488 ( get-qe-disjunct <q> )
2489
2490 Requires a logic that supports quantifier elimination.
2491 Currently, the only logics supported by quantifier elimination
2492 are LRA and LIA.
2493
2494 .. warning:: This method is experimental and may change in future
2495 versions.
2496
2497 :param q: A quantified formula of the form
2498 :math:`Q\\bar{x_1} ... Q\\bar{x_n}. P( x_1...x_i, y_1...y_j)`
2499 where :math:`Q\\bar{x}` is a set of quantified variables of
2500 the form :math:`Q x_1...x_k` and
2501 :math:`P( x_1...x_i, y_1...y_j )` is a quantifier-free formula.
2502
2503 :return: A formula :math:`\\phi` such that, given the current set
2504 of formulas :math:`A` asserted to this solver:
2505
2506 - :math:`(A \\wedge q \\implies A \\wedge \\phi)` if :math:`Q`
2507 is :math:`\\forall`, and
2508 :math:`(A \\wedge \\phi \\implies A \\wedge q)` if
2509 :math:`Q` is :math:`\\exists`
2510 - :math:`\\phi` is quantifier-free formula containing only
2511 free variables in :math:`y_1...y_n`
2512 - If :math:`Q` is :math:`\\exists`, let :math:`(A \\wedge Q_n)`
2513 be the formula
2514 :math:`(A \\wedge \\neg (\\phi \wedge Q_1) \\wedge ... \\wedge \\neg (\\phi \\wedge Q_n))`
2515 where for each :math:`i = 1...n`, formula
2516 :math:`(\\phi \\wedge Q_i)` is the result of calling
2517 :py:meth:`getQuantifierEliminationDisjunct()`
2518 for :math:`q` with the set of assertions
2519 :math:`(A \\wedge Q_{i-1})`.
2520 Similarly, if :math:`Q` is :math:`\\forall`, then let
2521 :math:`(A \\wedge Q_n)` be
2522 :math:`(A \\wedge (\\phi \\wedge Q_1) \\wedge ... \\wedge (\\phi \\wedge Q_n))`
2523 where :math:`(\\phi \\wedge Q_i)` is the same as above.
2524 In either case, we have that :math:`(\\phi \\wedge Q_j)`
2525 will eventually be true or false, for some finite :math:`j`.
2526 """
2527 cdef Term result = Term(self)
2528 result.cterm = self.csolver.getQuantifierEliminationDisjunct(term.cterm)
2529 return result
2530
2531 def getModel(self, sorts, consts):
2532 """
2533 Get the model
2534
2535 SMT-LIB:
2536
2537 .. code:: smtlib
2538
2539 (get-model)
2540
2541 Requires to enable option
2542 :ref:`produce-models <lbl-option-produce-models>`.
2543
2544 .. warning:: This method is experimental and may change in future
2545 versions.
2546
2547 :param sorts: The list of uninterpreted sorts that should be
2548 printed in the model.
2549 :param vars: The list of free constants that should be printed in
2550 the model. A subset of these may be printed based on
2551 :py:meth:`Solver.isModelCoreSymbol()`.
2552 :return: A string representing the model.
2553 """
2554
2555 cdef vector[c_Sort] csorts
2556 for sort in sorts:
2557 csorts.push_back((<Sort?> sort).csort)
2558
2559 cdef vector[c_Term] cconsts
2560 for const in consts:
2561 cconsts.push_back((<Term?> const).cterm)
2562
2563 return self.csolver.getModel(csorts, cconsts)
2564
2565 def getValueSepHeap(self):
2566 """
2567 When using separation logic, obtain the term for the heap.
2568
2569 .. warning:: This method is experimental and may change in future
2570 versions.
2571
2572 :return: The term for the heap.
2573 """
2574 cdef Term term = Term(self)
2575 term.cterm = self.csolver.getValueSepHeap()
2576 return term
2577
2578 def getValueSepNil(self):
2579 """
2580 When using separation logic, obtain the term for nil.
2581
2582 .. warning:: This method is experimental and may change in future
2583 versions.
2584
2585 :return: The term for nil.
2586 """
2587 cdef Term term = Term(self)
2588 term.cterm = self.csolver.getValueSepNil()
2589 return term
2590
2591 def declareSepHeap(self, Sort locType, Sort dataType):
2592 """
2593 When using separation logic, this sets the location sort and the
2594 datatype sort to the given ones. This method should be invoked
2595 exactly once, before any separation logic constraints are provided.
2596
2597 .. warning:: This method is experimental and may change in future
2598 versions.
2599
2600 :param locSort: The location sort of the heap.
2601 :param dataSort: The data sort of the heap.
2602 """
2603 self.csolver.declareSepHeap(locType.csort, dataType.csort)
2604
2605 def declarePool(self, str symbol, Sort sort, initValue):
2606 """
2607 Declare a symbolic pool of terms with the given initial value.
2608
2609 SMT-LIB:
2610
2611 .. code-block:: smtlib
2612
2613 ( declare-pool <symbol> <sort> ( <term>* ) )
2614
2615 .. warning:: This method is experimental and may change in future
2616 versions.
2617
2618 :param symbol: The name of the pool.
2619 :param sort: The sort of the elements of the pool.
2620 :param initValue: The initial value of the pool.
2621 """
2622 cdef Term term = Term(self)
2623 cdef vector[c_Term] niv
2624 for v in initValue:
2625 niv.push_back((<Term?> v).cterm)
2626 term.cterm = self.csolver.declarePool(symbol.encode(), sort.csort, niv)
2627 return term
2628
2629 def pop(self, nscopes=1):
2630 """
2631 Pop ``nscopes`` level(s) from the assertion stack.
2632
2633 SMT-LIB:
2634
2635 .. code-block:: smtlib
2636
2637 ( pop <numeral> )
2638
2639 :param nscopes: The number of levels to pop.
2640 """
2641 self.csolver.pop(nscopes)
2642
2643 def push(self, nscopes=1):
2644 """
2645 Push ``nscopes`` level(s) to the assertion stack.
2646
2647 SMT-LIB:
2648
2649 .. code-block:: smtlib
2650
2651 ( push <numeral> )
2652
2653 :param nscopes: The number of levels to push.
2654 """
2655 self.csolver.push(nscopes)
2656
2657 def resetAssertions(self):
2658 """
2659 Remove all assertions.
2660
2661 SMT-LIB:
2662
2663 .. code-block:: smtlib
2664
2665 ( reset-assertions )
2666
2667 """
2668 self.csolver.resetAssertions()
2669
2670 def setInfo(self, str keyword, str value):
2671 """
2672 Set info.
2673
2674 SMT-LIB:
2675
2676 .. code-block:: smtlib
2677
2678 ( set-info <attribute> )
2679
2680 :param keyword: The info flag.
2681 :param value: The value of the info flag.
2682 """
2683 self.csolver.setInfo(keyword.encode(), value.encode())
2684
2685 def setLogic(self, str logic):
2686 """
2687 Set logic.
2688
2689 SMT-LIB:
2690
2691 .. code-block:: smtlib
2692
2693 ( set-logic <symbol> )
2694
2695 :param logic: The logic to set.
2696 """
2697 self.csolver.setLogic(logic.encode())
2698
2699 def setOption(self, str option, str value):
2700 """
2701 Set option.
2702
2703 SMT-LIB:
2704
2705 .. code-block:: smtlib
2706
2707 ( set-option <option> )
2708
2709 :param option: The option name.
2710 :param value: The option value.
2711 """
2712 self.csolver.setOption(option.encode(), value.encode())
2713
2714
2715 def getInterpolant(self, Term conj, *args):
2716 """
2717 Get an interpolant.
2718
2719 SMT-LIB:
2720
2721 .. code-block:: smtlib
2722
2723 ( get-interpolant <conj> )
2724 ( get-interpolant <conj> <grammar> )
2725
2726 Requires option :ref:`produce-interpolants
2727 <lbl-option-produce-interpolants>` to be set to a mode different
2728 from `none`.
2729
2730 Supports the following variants:
2731
2732 - ``Term getInterpolant(Term conj)``
2733 - ``Term getInterpolant(Term conj, Grammar grammar)``
2734
2735 .. warning:: This method is experimental and may change in future
2736 versions.
2737
2738 :param conj: The conjecture term.
2739 :param output: The term where the result will be stored.
2740 :param grammar: A grammar for the inteprolant.
2741 :return: True iff an interpolant was found.
2742 """
2743 cdef Term result = Term(self)
2744 if len(args) == 0:
2745 result.cterm = self.csolver.getInterpolant(conj.cterm)
2746 else:
2747 assert len(args) == 1
2748 assert isinstance(args[0], Grammar)
2749 result.cterm = self.csolver.getInterpolant(
2750 conj.cterm, (<Grammar ?> args[0]).cgrammar)
2751 return result
2752
2753
2754 def getInterpolantNext(self):
2755 """
2756 Get the next interpolant. Can only be called immediately after
2757 a successful call to :py:func:`Solver.getInterpolant()` or
2758 :py:func:`Solver.getInterpolantNext()`.
2759 Is guaranteed to produce a syntactically different interpolant wrt
2760 the last returned interpolant if successful.
2761
2762 SMT-LIB:
2763
2764 .. code-block:: smtlib
2765
2766 ( get-interpolant-next )
2767
2768 Requires to enable incremental mode, and option
2769 :ref:`produce-interpolants <lbl-option-produce-interpolants>` to be
2770 set to a mode different from ``none``.
2771
2772 .. warning:: This method is experimental and may change in future
2773 versions.
2774
2775 :param output: The term where the result will be stored.
2776 :return: True iff an interpolant was found.
2777 """
2778 cdef Term result = Term(self)
2779 result.cterm = self.csolver.getInterpolantNext()
2780 return result
2781
2782 def getAbduct(self, Term conj, *args):
2783 """
2784 Get an abduct.
2785
2786 SMT-LIB:
2787
2788 .. code-block:: smtlib
2789
2790 ( get-abduct <conj> )
2791 ( get-abduct <conj> <grammar> )
2792
2793 Requires to enable option :ref:`produce-abducts
2794 <lbl-option-produce-abducts>`.
2795
2796 Supports the following variants:
2797
2798 - ``Term getAbduct(Term conj)``
2799 - ``Term getAbduct(Term conj, Grammar grammar)``
2800
2801 .. warning:: This method is experimental and may change in future
2802 versions.
2803
2804 :param conj: The conjecture term.
2805 :param output: The term where the result will be stored.
2806 :param grammar: A grammar for the abduct.
2807 :return: True iff an abduct was found.
2808 """
2809 cdef Term result = Term(self)
2810 if len(args) == 0:
2811 result.cterm = self.csolver.getAbduct(conj.cterm)
2812 else:
2813 assert len(args) == 1
2814 assert isinstance(args[0], Grammar)
2815 result.cterm = self.csolver.getAbduct(
2816 conj.cterm, (<Grammar ?> args[0]).cgrammar)
2817 return result
2818
2819 def getAbductNext(self):
2820 """
2821 Get the next abduct. Can only be called immediately after
2822 a succesful call to :py:func:`Solver.getAbduct()` or
2823 :py:func:`Solver.getAbductNext()`.
2824 Is guaranteed to produce a syntactically different abduct wrt the
2825 last returned abduct if successful.
2826
2827 SMT-LIB:
2828
2829 .. code-block:: smtlib
2830
2831 ( get-abduct-next )
2832
2833 Requires to enable incremental mode, and
2834 option :ref:`produce-abducts <lbl-option-produce-abducts>`.
2835
2836 .. warning:: This method is experimental and may change in future
2837 versions.
2838
2839 :param output: The term where the result will be stored.
2840 :return: True iff an abduct was found.
2841 """
2842 cdef Term result = Term(self)
2843 result.cterm = self.csolver.getAbductNext()
2844 return result
2845
2846 def blockModel(self):
2847 """
2848 Block the current model. Can be called only if immediately preceded
2849 by a SAT or INVALID query.
2850
2851 SMT-LIB:
2852
2853 .. code-block:: smtlib
2854
2855 (block-model)
2856
2857 Requires enabling option
2858 :ref:`produce-models <lbl-option-produce-models>`
2859 and setting option
2860 :ref:`block-models <lbl-option-block-models>`
2861 to a mode other than ``none``.
2862
2863 .. warning:: This method is experimental and may change in future
2864 versions.
2865 """
2866 self.csolver.blockModel()
2867
2868 def blockModelValues(self, terms):
2869 """
2870 Block the current model values of (at least) the values in terms.
2871 Can be called only if immediately preceded by a SAT or NOT_ENTAILED
2872 query.
2873
2874 SMT-LIB:
2875
2876 .. code-block:: smtlib
2877
2878 (block-model-values ( <terms>+ ))
2879
2880 Requires enabling option
2881 :ref:`produce-models <lbl-option-produce-models>`.
2882
2883 .. warning:: This method is experimental and may change in future
2884 versions.
2885 """
2886 cdef vector[c_Term] nts
2887 for t in terms:
2888 nts.push_back((<Term?> t).cterm)
2889 self.csolver.blockModelValues(nts)
2890
2891 def getInstantiations(self):
2892 """
2893 Return a string that contains information about all instantiations
2894 made by the quantifiers module.
2895
2896 .. warning:: This method is experimental and may change in future
2897 versions.
2898 """
2899 return self.csolver.getInstantiations()
2900
2901 def getStatistics(self):
2902 """
2903 Returns a snapshot of the current state of the statistic values of
2904 this solver. The returned object is completely decoupled from the
2905 solver and will not change when the solver is used again.
2906 """
2907 res = Statistics()
2908 res.cstats = self.csolver.getStatistics()
2909 return res
2910
2911
2912 cdef class Sort:
2913 """
2914 The sort of a cvc5 term.
2915
2916 Wrapper class for :cpp:class:`cvc5::Sort`.
2917 """
2918 cdef c_Sort csort
2919 cdef Solver solver
2920 def __cinit__(self, Solver solver):
2921 # csort always set by Solver
2922 self.solver = solver
2923
2924 def __eq__(self, Sort other):
2925 return self.csort == other.csort
2926
2927 def __ne__(self, Sort other):
2928 return self.csort != other.csort
2929
2930 def __lt__(self, Sort other):
2931 return self.csort < other.csort
2932
2933 def __gt__(self, Sort other):
2934 return self.csort > other.csort
2935
2936 def __le__(self, Sort other):
2937 return self.csort <= other.csort
2938
2939 def __ge__(self, Sort other):
2940 return self.csort >= other.csort
2941
2942 def __str__(self):
2943 return self.csort.toString().decode()
2944
2945 def __repr__(self):
2946 return self.csort.toString().decode()
2947
2948 def __hash__(self):
2949 return csorthash(self.csort)
2950
2951 def hasSymbol(self):
2952 """
2953 :return: True iff this sort has a symbol.
2954 """
2955 return self.csort.hasSymbol()
2956
2957 def getSymbol(self):
2958 """
2959 Asserts :py:meth:`hasSymbol()`.
2960
2961 :return: The raw symbol of the sort.
2962 """
2963 return self.csort.getSymbol().decode()
2964
2965 def isNull(self):
2966 """
2967 :return: True if this Sort is a null sort.
2968 """
2969 return self.csort.isNull()
2970
2971 def isBoolean(self):
2972 """
2973 Is this a Boolean sort?
2974
2975 :return: True if the sort is the Boolean sort.
2976 """
2977 return self.csort.isBoolean()
2978
2979 def isInteger(self):
2980 """
2981 Is this an integer sort?
2982
2983 :return: True if the sort is the integer sort.
2984 """
2985 return self.csort.isInteger()
2986
2987 def isReal(self):
2988 """
2989 Is this a real sort?
2990
2991 :return: True if the sort is the real sort.
2992 """
2993 return self.csort.isReal()
2994
2995 def isString(self):
2996 """
2997 Is this a string sort?
2998
2999 :return: True if the sort is the string sort.
3000 """
3001 return self.csort.isString()
3002
3003 def isRegExp(self):
3004 """
3005 Is this a regexp sort?
3006
3007 :return: True if the sort is the regexp sort.
3008 """
3009 return self.csort.isRegExp()
3010
3011 def isRoundingMode(self):
3012 """
3013 Is this a rounding mode sort?
3014
3015 :return: True if the sort is the rounding mode sort.
3016 """
3017 return self.csort.isRoundingMode()
3018
3019 def isBitVector(self):
3020 """
3021 Is this a bit-vector sort?
3022
3023 :return: True if the sort is a bit-vector sort.
3024 """
3025 return self.csort.isBitVector()
3026
3027 def isFloatingPoint(self):
3028 """
3029 Is this a floating-point sort?
3030
3031 :return: True if the sort is a bit-vector sort.
3032 """
3033 return self.csort.isFloatingPoint()
3034
3035 def isDatatype(self):
3036 """
3037 Is this a datatype sort?
3038
3039 :return: True if the sort is a datatype sort.
3040 """
3041 return self.csort.isDatatype()
3042
3043 def isDatatypeConstructor(self):
3044 """
3045 Is this a datatype constructor sort?
3046
3047 :return: True if the sort is a datatype constructor sort.
3048 """
3049 return self.csort.isDatatypeConstructor()
3050
3051 def isDatatypeSelector(self):
3052 """
3053 Is this a datatype selector sort?
3054
3055 :return: True if the sort is a datatype selector sort.
3056 """
3057 return self.csort.isDatatypeSelector()
3058
3059 def isDatatypeTester(self):
3060 """
3061 Is this a tester sort?
3062
3063 :return: True if the sort is a selector sort.
3064 """
3065 return self.csort.isDatatypeTester()
3066
3067 def isDatatypeUpdater(self):
3068 """
3069 Is this a datatype updater sort?
3070
3071 :return: True if the sort is a datatype updater sort.
3072 """
3073 return self.csort.isDatatypeUpdater()
3074
3075 def isFunction(self):
3076 """
3077 Is this a function sort?
3078
3079 :return: True if the sort is a function sort.
3080 """
3081 return self.csort.isFunction()
3082
3083 def isPredicate(self):
3084 """
3085 Is this a predicate sort?
3086 That is, is this a function sort mapping to Boolean? All predicate
3087 sorts are also function sorts.
3088
3089 :return: True if the sort is a predicate sort.
3090 """
3091 return self.csort.isPredicate()
3092
3093 def isTuple(self):
3094 """
3095 Is this a tuple sort?
3096
3097 :return: True if the sort is a tuple sort.
3098 """
3099 return self.csort.isTuple()
3100
3101 def isRecord(self):
3102 """
3103 Is this a record sort?
3104
3105 .. warning:: This method is experimental and may change in future
3106 versions.
3107
3108 :return: True if the sort is a record sort.
3109 """
3110 return self.csort.isRecord()
3111
3112 def isArray(self):
3113 """
3114 Is this an array sort?
3115
3116 :return: True if the sort is an array sort.
3117 """
3118 return self.csort.isArray()
3119
3120 def isSet(self):
3121 """
3122 Is this a set sort?
3123
3124 :return: True if the sort is a set sort.
3125 """
3126 return self.csort.isSet()
3127
3128 def isBag(self):
3129 """
3130 Is this a bag sort?
3131
3132 :return: True if the sort is a bag sort.
3133 """
3134 return self.csort.isBag()
3135
3136 def isSequence(self):
3137 """
3138 Is this a sequence sort?
3139
3140 :return: True if the sort is a sequence sort.
3141 """
3142 return self.csort.isSequence()
3143
3144 def isUninterpretedSort(self):
3145 """
3146 Is this a sort uninterpreted?
3147
3148 :return: True if the sort is uninterpreted.
3149 """
3150 return self.csort.isUninterpretedSort()
3151
3152 def isUninterpretedSortConstructor(self):
3153 """
3154 Is this a sort constructor kind?
3155
3156 An uninterpreted sort constructor is an uninterpreted sort with
3157 arity > 0.
3158
3159 :return: True if this a sort constructor kind.
3160 """
3161 return self.csort.isUninterpretedSortConstructor()
3162
3163 def isInstantiated(self):
3164 """
3165 Is this an instantiated (parametric datatype or uninterpreted sort
3166 constructor) sort?
3167
3168 An instantiated sort is a sort that has been constructed from
3169 instantiating a sort parameters with sort arguments
3170 (see :py:meth:`instantiate()`).
3171
3172 :return: True if this is an instantiated sort.
3173 """
3174 return self.csort.isInstantiated()
3175
3176 def getUninterpretedSortConstructor(self):
3177 """
3178 Get the associated uninterpreted sort constructor of an
3179 instantiated uninterpreted sort.
3180
3181 :return: The uninterpreted sort constructor sort
3182 """
3183 cdef Sort sort = Sort(self.solver)
3184 sort.csort = self.csort.getUninterpretedSortConstructor()
3185 return sort
3186
3187 def getDatatype(self):
3188 """
3189 :return: The underlying datatype of a datatype sort
3190 """
3191 cdef Datatype d = Datatype(self.solver)
3192 d.cd = self.csort.getDatatype()
3193 return d
3194
3195 def instantiate(self, params):
3196 """
3197 Instantiate a parameterized datatype sort or uninterpreted sort
3198 constructor sort.
3199
3200 Create sorts parameter with :py:meth:`Solver.mkParamSort()`
3201
3202 .. warning:: This method is experimental and may change in future
3203 versions.
3204
3205 :param params: The list of sort parameters to instantiate with
3206 :return: The instantiated sort
3207 """
3208 cdef Sort sort = Sort(self.solver)
3209 cdef vector[c_Sort] v
3210 for s in params:
3211 v.push_back((<Sort?> s).csort)
3212 sort.csort = self.csort.instantiate(v)
3213 return sort
3214
3215 def getInstantiatedParameters(self):
3216 """
3217 Get the sorts used to instantiate the sort parameters of a
3218 parametric sort (parametric datatype or uninterpreted sort
3219 constructor sort, see :py:meth:`instantiate()`).
3220
3221 :return: The sorts used to instantiate the sort parameters of a
3222 parametric sort
3223 """
3224 instantiated_sorts = []
3225 for s in self.csort.getInstantiatedParameters():
3226 sort = Sort(self.solver)
3227 sort.csort = s
3228 instantiated_sorts.append(sort)
3229 return instantiated_sorts
3230
3231 def substitute(self, sort_or_list_1, sort_or_list_2):
3232 """
3233 Substitution of Sorts.
3234
3235 Note that this replacement is applied during a pre-order traversal
3236 and only once to the sort. It is not run until fix point. In the
3237 case that sort_or_list_1 contains duplicates, the replacement
3238 earliest in the list takes priority.
3239
3240 For example,
3241 ``(Array A B) .substitute([A, C], [(Array C D), (Array A B)])``
3242 will return ``(Array (Array C D) B)``.
3243
3244 .. warning:: This method is experimental and may change in future
3245 versions.
3246
3247 :param sort_or_list_1: The subsort or subsorts to be substituted
3248 within this sort.
3249 :param sort_or_list_2: The sort or list of sorts replacing the
3250 substituted subsort.
3251 """
3252
3253 # The resulting sort after substitution
3254 cdef Sort sort = Sort(self.solver)
3255 # lists for substitutions
3256 cdef vector[c_Sort] ces
3257 cdef vector[c_Sort] creplacements
3258
3259 # normalize the input parameters to be lists
3260 if isinstance(sort_or_list_1, list):
3261 assert isinstance(sort_or_list_2, list)
3262 es = sort_or_list_1
3263 replacements = sort_or_list_2
3264 if len(es) != len(replacements):
3265 raise RuntimeError("Expecting list inputs to substitute to "
3266 "have the same length but got: "
3267 "{} and {}".format(
3268 len(es), len(replacements)))
3269
3270 for e, r in zip(es, replacements):
3271 ces.push_back((<Sort?> e).csort)
3272 creplacements.push_back((<Sort?> r).csort)
3273
3274 else:
3275 # add the single elements to the vectors
3276 ces.push_back((<Sort?> sort_or_list_1).csort)
3277 creplacements.push_back((<Sort?> sort_or_list_2).csort)
3278
3279 # call the API substitute method with lists
3280 sort.csort = self.csort.substitute(ces, creplacements)
3281 return sort
3282
3283
3284 def getDatatypeConstructorArity(self):
3285 """
3286 :return: The arity of a datatype constructor sort.
3287 """
3288 return self.csort.getDatatypeConstructorArity()
3289
3290 def getDatatypeConstructorDomainSorts(self):
3291 """
3292 :return: The domain sorts of a datatype constructor sort.
3293 """
3294 domain_sorts = []
3295 for s in self.csort.getDatatypeConstructorDomainSorts():
3296 sort = Sort(self.solver)
3297 sort.csort = s
3298 domain_sorts.append(sort)
3299 return domain_sorts
3300
3301 def getDatatypeConstructorCodomainSort(self):
3302 """
3303 :return: The codomain sort of a datatype constructor sort.
3304 """
3305 cdef Sort sort = Sort(self.solver)
3306 sort.csort = self.csort.getDatatypeConstructorCodomainSort()
3307 return sort
3308
3309 def getDatatypeSelectorDomainSort(self):
3310 """
3311 :return: The domain sort of a datatype selector sort.
3312 """
3313 cdef Sort sort = Sort(self.solver)
3314 sort.csort = self.csort.getDatatypeSelectorDomainSort()
3315 return sort
3316
3317 def getDatatypeSelectorCodomainSort(self):
3318 """
3319 :return: The codomain sort of a datatype selector sort.
3320 """
3321 cdef Sort sort = Sort(self.solver)
3322 sort.csort = self.csort.getDatatypeSelectorCodomainSort()
3323 return sort
3324
3325 def getDatatypeTesterDomainSort(self):
3326 """
3327 :return: The domain sort of a datatype tester sort.
3328 """
3329 cdef Sort sort = Sort(self.solver)
3330 sort.csort = self.csort.getDatatypeTesterDomainSort()
3331 return sort
3332
3333 def getDatatypeTesterCodomainSort(self):
3334 """
3335 :return: the codomain sort of a datatype tester sort, which is the
3336 Boolean sort
3337 """
3338 cdef Sort sort = Sort(self.solver)
3339 sort.csort = self.csort.getDatatypeTesterCodomainSort()
3340 return sort
3341
3342 def getFunctionArity(self):
3343 """
3344 :return: The arity of a function sort.
3345 """
3346 return self.csort.getFunctionArity()
3347
3348 def getFunctionDomainSorts(self):
3349 """
3350 :return: The domain sorts of a function sort.
3351 """
3352 domain_sorts = []
3353 for s in self.csort.getFunctionDomainSorts():
3354 sort = Sort(self.solver)
3355 sort.csort = s
3356 domain_sorts.append(sort)
3357 return domain_sorts
3358
3359 def getFunctionCodomainSort(self):
3360 """
3361 :return: The codomain sort of a function sort.
3362 """
3363 cdef Sort sort = Sort(self.solver)
3364 sort.csort = self.csort.getFunctionCodomainSort()
3365 return sort
3366
3367 def getArrayIndexSort(self):
3368 """
3369 :return: The array index sort of an array sort.
3370 """
3371 cdef Sort sort = Sort(self.solver)
3372 sort.csort = self.csort.getArrayIndexSort()
3373 return sort
3374
3375 def getArrayElementSort(self):
3376 """
3377 :return: The array element sort of an array sort.
3378 """
3379 cdef Sort sort = Sort(self.solver)
3380 sort.csort = self.csort.getArrayElementSort()
3381 return sort
3382
3383 def getSetElementSort(self):
3384 """
3385 :return: The element sort of a set sort.
3386 """
3387 cdef Sort sort = Sort(self.solver)
3388 sort.csort = self.csort.getSetElementSort()
3389 return sort
3390
3391 def getBagElementSort(self):
3392 """
3393 :return: The element sort of a bag sort.
3394 """
3395 cdef Sort sort = Sort(self.solver)
3396 sort.csort = self.csort.getBagElementSort()
3397 return sort
3398
3399 def getSequenceElementSort(self):
3400 """
3401 :return: The element sort of a sequence sort.
3402 """
3403 cdef Sort sort = Sort(self.solver)
3404 sort.csort = self.csort.getSequenceElementSort()
3405 return sort
3406
3407 def getUninterpretedSortConstructorArity(self):
3408 """
3409 :return: The arity of a sort constructor sort.
3410 """
3411 return self.csort.getUninterpretedSortConstructorArity()
3412
3413 def getBitVectorSize(self):
3414 """
3415 :return: The bit-width of the bit-vector sort.
3416 """
3417 return self.csort.getBitVectorSize()
3418
3419 def getFloatingPointExponentSize(self):
3420 """
3421 :return: The bit-width of the exponent of the floating-point sort.
3422 """
3423 return self.csort.getFloatingPointExponentSize()
3424
3425 def getFloatingPointSignificandSize(self):
3426 """
3427 :return: The width of the significand of the floating-point sort.
3428 """
3429 return self.csort.getFloatingPointSignificandSize()
3430
3431 def getDatatypeArity(self):
3432 """
3433 :return: The arity of a datatype sort.
3434 """
3435 return self.csort.getDatatypeArity()
3436
3437 def getTupleLength(self):
3438 """
3439 :return: The length of a tuple sort.
3440 """
3441 return self.csort.getTupleLength()
3442
3443 def getTupleSorts(self):
3444 """
3445 :return: The element sorts of a tuple sort.
3446 """
3447 tuple_sorts = []
3448 for s in self.csort.getTupleSorts():
3449 sort = Sort(self.solver)
3450 sort.csort = s
3451 tuple_sorts.append(sort)
3452 return tuple_sorts
3453
3454
3455 cdef class Statistics:
3456 """
3457 The cvc5 Statistics.
3458
3459 Wrapper class for :cpp:class:`cvc5::Statistics`.
3460 Obtain a single statistic value using ``stats["name"]`` and a dictionary
3461 with all (visible) statistics using
3462 ``stats.get(internal=False, defaulted=False)``.
3463 """
3464 cdef c_Statistics cstats
3465
3466 cdef __stat_to_dict(self, const c_Stat& s):
3467 res = None
3468 if s.isInt():
3469 res = s.getInt()
3470 elif s.isDouble():
3471 res = s.getDouble()
3472 elif s.isString():
3473 res = s.getString().decode()
3474 elif s.isHistogram():
3475 res = { h.first.decode(): h.second for h in s.getHistogram() }
3476 return {
3477 'defaulted': s.isDefault(),
3478 'internal': s.isInternal(),
3479 'value': res
3480 }
3481
3482 def __getitem__(self, str name):
3483 """
3484 Get the statistics information for the statistic called ``name``.
3485 """
3486 return self.__stat_to_dict(self.cstats.get(name.encode()))
3487
3488 def get(self, bint internal = False, bint defaulted = False):
3489 """
3490 Get all statistics as a dictionary. See :cpp:func:`cvc5::Statistics::begin()`
3491 for more information on which statistics are included based on the parameters.
3492
3493 :return: A dictionary with all available statistics.
3494 """
3495 cdef c_Statistics.iterator it = self.cstats.begin(internal, defaulted)
3496 cdef pair[string,c_Stat]* s
3497 res = {}
3498 while it != self.cstats.end():
3499 s = &dereference(it)
3500 res[s.first.decode()] = self.__stat_to_dict(s.second)
3501 preincrement(it)
3502 return res
3503
3504
3505 cdef class Term:
3506 """
3507 A cvc5 Term.
3508
3509 Wrapper class for :cpp:class:`cvc5::Term`.
3510 """
3511 cdef c_Term cterm
3512 cdef Solver solver
3513 def __cinit__(self, Solver solver):
3514 # cterm always set in the Solver object
3515 self.solver = solver
3516
3517 def __eq__(self, Term other):
3518 return self.cterm == other.cterm
3519
3520 def __ne__(self, Term other):
3521 return self.cterm != other.cterm
3522
3523 def __lt__(self, Term other):
3524 return self.cterm < other.cterm
3525
3526 def __gt__(self, Term other):
3527 return self.cterm > other.cterm
3528
3529 def __le__(self, Term other):
3530 return self.cterm <= other.cterm
3531
3532 def __ge__(self, Term other):
3533 return self.cterm >= other.cterm
3534
3535 def __getitem__(self, int index):
3536 cdef Term term = Term(self.solver)
3537 if index >= 0:
3538 term.cterm = self.cterm[index]
3539 else:
3540 raise ValueError("Expecting a non-negative integer or string")
3541 return term
3542
3543 def __str__(self):
3544 return self.cterm.toString().decode()
3545
3546 def __repr__(self):
3547 return self.cterm.toString().decode()
3548
3549 def __iter__(self):
3550 for ci in self.cterm:
3551 term = Term(self.solver)
3552 term.cterm = ci
3553 yield term
3554
3555 def __hash__(self):
3556 return ctermhash(self.cterm)
3557
3558 def getNumChildren(self):
3559 """
3560 :return: The number of children of this term.
3561 """
3562 return self.cterm.getNumChildren()
3563
3564 def getId(self):
3565 """
3566 :return: The id of this term.
3567 """
3568 return self.cterm.getId()
3569
3570 def getKind(self):
3571 """
3572 :return: The :py:class:`cvc5.Kind` of this term.
3573 """
3574 return Kind(<int> self.cterm.getKind())
3575
3576 def getSort(self):
3577 """
3578 :return: The :py:class:`cvc5.Sort` of this term.
3579 """
3580 cdef Sort sort = Sort(self.solver)
3581 sort.csort = self.cterm.getSort()
3582 return sort
3583
3584 def substitute(self, term_or_list_1, term_or_list_2):
3585 """
3586 :return: The result of simultaneously replacing the term(s) stored
3587 in ``term_or_list_1`` by the term(s) stored in
3588 ``term_or_list_2`` in this term.
3589
3590 .. note::
3591
3592 This replacement is applied during a pre-order traversal and
3593 only once to the term. It is not run until fix point. In the
3594 case that terms contains duplicates, the replacement earliest
3595 in the list takes priority. For example, calling substitute on
3596 ``f(x,y)`` with
3597
3598 .. code:: python
3599
3600 term_or_list_1 = [ x, z ], term_or_list_2 = [ g(z), w ]
3601
3602 results in the term ``f(g(z),y)``.
3603 """
3604 # The resulting term after substitution
3605 cdef Term term = Term(self.solver)
3606 # lists for substitutions
3607 cdef vector[c_Term] ces
3608 cdef vector[c_Term] creplacements
3609
3610 # normalize the input parameters to be lists
3611 if isinstance(term_or_list_1, list):
3612 assert isinstance(term_or_list_2, list)
3613 es = term_or_list_1
3614 replacements = term_or_list_2
3615 if len(es) != len(replacements):
3616 raise RuntimeError("Expecting list inputs to substitute to "
3617 "have the same length but got: "
3618 "{} and {}".format(len(es), len(replacements)))
3619
3620 for e, r in zip(es, replacements):
3621 ces.push_back((<Term?> e).cterm)
3622 creplacements.push_back((<Term?> r).cterm)
3623
3624 else:
3625 # add the single elements to the vectors
3626 ces.push_back((<Term?> term_or_list_1).cterm)
3627 creplacements.push_back((<Term?> term_or_list_2).cterm)
3628
3629 # call the API substitute method with lists
3630 term.cterm = self.cterm.substitute(ces, creplacements)
3631 return term
3632
3633 def hasOp(self):
3634 """
3635 :return: True iff this term has an operator.
3636 """
3637 return self.cterm.hasOp()
3638
3639 def getOp(self):
3640 """
3641 :return: The :py:class:`cvc5.Op` used to create this Term.
3642
3643 .. note::
3644
3645 This is safe to call when :py:meth:`hasOp()` returns True.
3646
3647 """
3648 cdef Op op = Op(self.solver)
3649 op.cop = self.cterm.getOp()
3650 return op
3651
3652 def hasSymbol(self):
3653 """
3654 :return: True iff this term has a symbol.
3655 """
3656 return self.cterm.hasSymbol()
3657
3658 def getSymbol(self):
3659 """
3660 Asserts :py:meth:`hasSymbol()`.
3661
3662 :return: The raw symbol of the term.
3663 """
3664 return self.cterm.getSymbol().decode()
3665
3666 def isNull(self):
3667 """
3668 :return: True iff this term is a null term.
3669 """
3670 return self.cterm.isNull()
3671
3672 def notTerm(self):
3673 """
3674 Boolean negation.
3675
3676 :return: The Boolean negation of this term.
3677 """
3678 cdef Term term = Term(self.solver)
3679 term.cterm = self.cterm.notTerm()
3680 return term
3681
3682 def andTerm(self, Term t):
3683 """
3684 Boolean and.
3685
3686 :param t: A Boolean term.
3687 :return: The conjunction of this term and the given term.
3688 """
3689 cdef Term term = Term(self.solver)
3690 term.cterm = self.cterm.andTerm((<Term> t).cterm)
3691 return term
3692
3693 def orTerm(self, Term t):
3694 """
3695 Boolean or.
3696
3697 :param t: A Boolean term.
3698 :return: The disjunction of this term and the given term.
3699 """
3700 cdef Term term = Term(self.solver)
3701 term.cterm = self.cterm.orTerm(t.cterm)
3702 return term
3703
3704 def xorTerm(self, Term t):
3705 """
3706 Boolean exclusive or.
3707
3708 :param t: A Boolean term.
3709 :return: The exclusive disjunction of this term and the given term.
3710 """
3711 cdef Term term = Term(self.solver)
3712 term.cterm = self.cterm.xorTerm(t.cterm)
3713 return term
3714
3715 def eqTerm(self, Term t):
3716 """
3717 Equality
3718
3719 :param t: A Boolean term.
3720 :return: The Boolean equivalence of this term and the given term.
3721 """
3722 cdef Term term = Term(self.solver)
3723 term.cterm = self.cterm.eqTerm(t.cterm)
3724 return term
3725
3726 def impTerm(self, Term t):
3727 """
3728 Boolean Implication.
3729
3730 :param t: A Boolean term.
3731 :return: The implication of this term and the given term.
3732 """
3733 cdef Term term = Term(self.solver)
3734 term.cterm = self.cterm.impTerm(t.cterm)
3735 return term
3736
3737 def iteTerm(self, Term then_t, Term else_t):
3738 """
3739 If-then-else with this term as the Boolean condition.
3740
3741 :param then_t: The `then` term.
3742 :param else_t: The `else` term.
3743 :return: The if-then-else term with this term as the Boolean
3744 condition.
3745 """
3746 cdef Term term = Term(self.solver)
3747 term.cterm = self.cterm.iteTerm(then_t.cterm, else_t.cterm)
3748 return term
3749
3750 def isConstArray(self):
3751 """
3752 :return: True iff this term is a constant array.
3753 """
3754 return self.cterm.isConstArray()
3755
3756 def getConstArrayBase(self):
3757 """
3758 Asserts :py:meth:`isConstArray()`.
3759
3760 :return: The base (element stored at all indicies) of this constant
3761 array.
3762 """
3763 cdef Term term = Term(self.solver)
3764 term.cterm = self.cterm.getConstArrayBase()
3765 return term
3766
3767 def isBooleanValue(self):
3768 """
3769 :return: True iff this term is a Boolean value.
3770 """
3771 return self.cterm.isBooleanValue()
3772
3773 def getBooleanValue(self):
3774 """
3775 Asserts :py:meth:`isBooleanValue()`
3776
3777 :return: The representation of a Boolean value as a native Boolean
3778 value.
3779 """
3780 return self.cterm.getBooleanValue()
3781
3782 def isStringValue(self):
3783 """
3784 :return: True iff this term is a string value.
3785 """
3786 return self.cterm.isStringValue()
3787
3788 def getStringValue(self):
3789 """
3790 Asserts :py:meth:`isStringValue()`.
3791
3792 .. note::
3793 This method is not to be confused with :py:meth:`__str__()`
3794 which returns the term in some string representation, whatever
3795 data it may hold.
3796
3797 :return: The string term as a native string value.
3798 """
3799 cdef Py_ssize_t size
3800 cdef c_wstring s = self.cterm.getStringValue()
3801 return PyUnicode_FromWideChar(s.data(), s.size())
3802
3803 def getRealOrIntegerValueSign(self):
3804 """
3805 Get integer or real value sign. Must be called on integer or real
3806 values, or otherwise an exception is thrown.
3807
3808 :return: 0 if this term is zero, -1 if this term is a negative real
3809 or integer value, 1 if this term is a positive real or
3810 integer value.
3811 """
3812 return self.cterm.getRealOrIntegerValueSign()
3813
3814 def isIntegerValue(self):
3815 """
3816 :return: True iff this term is an integer value.
3817 """
3818 return self.cterm.isIntegerValue()
3819
3820 def getIntegerValue(self):
3821 """
3822 Asserts :py:meth:`isIntegerValue()`.
3823
3824 :return: The integer term as a native python integer.
3825 """
3826 return int(self.cterm.getIntegerValue().decode())
3827
3828 def isFloatingPointPosZero(self):
3829 """
3830 :return: True iff the term is the floating-point value for positive
3831 zero.
3832 """
3833 return self.cterm.isFloatingPointPosZero()
3834
3835 def isFloatingPointNegZero(self):
3836 """
3837 :return: True iff the term is the floating-point value for negative
3838 zero.
3839 """
3840 return self.cterm.isFloatingPointNegZero()
3841
3842 def isFloatingPointPosInf(self):
3843 """
3844 :return: True iff the term is the floating-point value for positive
3845 infinity.
3846 """
3847 return self.cterm.isFloatingPointPosInf()
3848
3849 def isFloatingPointNegInf(self):
3850 """
3851 :return: True iff the term is the floating-point value for negative
3852 infinity.
3853 """
3854 return self.cterm.isFloatingPointNegInf()
3855
3856 def isFloatingPointNaN(self):
3857 """
3858 :return: True iff the term is the floating-point value for not a
3859 number.
3860 """
3861 return self.cterm.isFloatingPointNaN()
3862
3863 def isFloatingPointValue(self):
3864 """
3865 :return: True iff this term is a floating-point value.
3866 """
3867 return self.cterm.isFloatingPointValue()
3868
3869 def getFloatingPointValue(self):
3870 """
3871 Asserts :py:meth:`isFloatingPointValue()`.
3872
3873 :return: The representation of a floating-point value as a tuple of
3874 the exponent width, the significand width and a bit-vector
3875 value.
3876 """
3877 cdef c_tuple[uint32_t, uint32_t, c_Term] t = \
3878 self.cterm.getFloatingPointValue()
3879 cdef Term term = Term(self.solver)
3880 term.cterm = get2(t)
3881 return (get0(t), get1(t), term)
3882
3883 def isSetValue(self):
3884 """
3885 A term is a set value if it is considered to be a (canonical)
3886 constant set value. A canonical set value is one whose AST is:
3887
3888 .. code:: smtlib
3889
3890 (set.union
3891 (set.singleton c1) ...
3892 (set.union (set.singleton c_{n-1}) (set.singleton c_n))))
3893
3894 where :math:`c_1 \dots c_n` are values ordered by id such that
3895 :math:`c_1 > \cdots > c_n`.
3896
3897 .. note::
3898 A universe set term ``(kind SET_UNIVERSE)`` is not considered
3899 to be a set value.
3900
3901 :return: True if the term is a set value.
3902 """
3903 return self.cterm.isSetValue()
3904
3905 def getSetValue(self):
3906 """
3907 Asserts :py:meth:`isSetValue()`.
3908
3909 :return: The representation of a set value as a set of terms.
3910 """
3911 elems = set()
3912 for e in self.cterm.getSetValue():
3913 term = Term(self.solver)
3914 term.cterm = e
3915 elems.add(term)
3916 return elems
3917
3918 def isSequenceValue(self):
3919 """
3920 :return: True iff this term is a sequence value.
3921 """
3922 return self.cterm.isSequenceValue()
3923
3924 def getSequenceValue(self):
3925 """
3926 Asserts :py:meth:`isSequenceValue()`.
3927
3928 .. note::
3929
3930 It is usually necessary for sequences to call
3931 :py:meth:`Solver.simplify()` to turn a sequence that is
3932 constructed by, e.g., concatenation of unit sequences, into a
3933 sequence value.
3934
3935 :return: The representation of a sequence value as a vector of
3936 terms.
3937 """
3938 elems = []
3939 for e in self.cterm.getSequenceValue():
3940 term = Term(self.solver)
3941 term.cterm = e
3942 elems.append(term)
3943 return elems
3944
3945 def isCardinalityConstraint(self):
3946 """
3947 :return: True if the term is a cardinality constraint.
3948
3949 .. warning:: This method is experimental and may change in future
3950 versions.
3951 """
3952 return self.cterm.isCardinalityConstraint()
3953
3954 def getCardinalityConstraint(self):
3955 """
3956 :return: The sort the cardinality constraint is for and its upper
3957 bound.
3958 .. warning:: This method is experimental and may change in future
3959 versions.
3960 """
3961 cdef pair[c_Sort, uint32_t] p
3962 p = self.cterm.getCardinalityConstraint()
3963 cdef Sort sort = Sort(self.solver)
3964 sort.csort = p.first
3965 return (sort, p.second)
3966
3967
3968 def isUninterpretedSortValue(self):
3969 """
3970 :return: True iff this term is a value from an uninterpreted sort.
3971 """
3972 return self.cterm.isUninterpretedSortValue()
3973
3974 def getUninterpretedSortValue(self):
3975 """
3976 Asserts :py:meth:`isUninterpretedSortValue()`.
3977
3978 :return: The representation of an uninterpreted value as a pair of
3979 its sort and its index.
3980 """
3981 return self.cterm.getUninterpretedSortValue()
3982
3983 def isTupleValue(self):
3984 """
3985 :return: True iff this term is a tuple value.
3986 """
3987 return self.cterm.isTupleValue()
3988
3989 def isRoundingModeValue(self):
3990 """
3991 :return: True if the term is a floating-point rounding mode
3992 value.
3993 """
3994 return self.cterm.isRoundingModeValue()
3995
3996 def getRoundingModeValue(self):
3997 """
3998 Asserts :py:meth:`isRoundingModeValue()`.
3999 :return: The floating-point rounding mode value held by the term.
4000 """
4001 return RoundingMode(<int> self.cterm.getRoundingModeValue())
4002
4003 def getTupleValue(self):
4004 """
4005 Asserts :py:meth:`isTupleValue()`.
4006
4007 :return: The representation of a tuple value as a vector of terms.
4008 """
4009 elems = []
4010 for e in self.cterm.getTupleValue():
4011 term = Term(self.solver)
4012 term.cterm = e
4013 elems.append(term)
4014 return elems
4015
4016 def isRealValue(self):
4017 """
4018 :return: True iff this term is a rational value.
4019
4020 .. note::
4021
4022 A term of kind :py:obj:`Pi <cvc5.Kind.Pi>` is not considered
4023 to be a real value.
4024
4025 """
4026 return self.cterm.isRealValue()
4027
4028 def getRealValue(self):
4029 """
4030 Asserts :py:meth:`isRealValue()`.
4031
4032 :return: The representation of a rational value as a python Fraction.
4033 """
4034 return Fraction(self.cterm.getRealValue().decode())
4035
4036 def isBitVectorValue(self):
4037 """
4038 :return: True iff this term is a bit-vector value.
4039 """
4040 return self.cterm.isBitVectorValue()
4041
4042 def getBitVectorValue(self, base = 2):
4043 """
4044 Asserts :py:meth:`isBitVectorValue()`.
4045 Supported bases are 2 (bit string), 10 (decimal string) or 16
4046 (hexdecimal string).
4047
4048 :return: The representation of a bit-vector value in string
4049 representation.
4050 """
4051 return self.cterm.getBitVectorValue(base).decode()
4052
4053 def toPythonObj(self):
4054 """
4055 Converts a constant value Term to a Python object.
4056
4057 Currently supports:
4058
4059 - **Boolean:** Returns a Python bool
4060 - **Int :** Returns a Python int
4061 - **Real :** Returns a Python Fraction
4062 - **BV :** Returns a Python int (treats BV as unsigned)
4063 - **String :** Returns a Python Unicode string
4064 - **Array :** Returns a Python dict mapping indices to values. The constant base is returned as the default value.
4065
4066 """
4067
4068 if self.isBooleanValue():
4069 return self.getBooleanValue()
4070 elif self.isIntegerValue():
4071 return self.getIntegerValue()
4072 elif self.isRealValue():
4073 return self.getRealValue()
4074 elif self.isBitVectorValue():
4075 return int(self.getBitVectorValue(), 2)
4076 elif self.isStringValue():
4077 return self.getStringValue()
4078 elif self.getSort().isArray():
4079 res = None
4080 keys = []
4081 values = []
4082 base_value = None
4083 to_visit = [self]
4084 # Array models are represented as a series of store operations
4085 # on a constant array
4086 while to_visit:
4087 t = to_visit.pop()
4088 if t.getKind().value == c_Kind.STORE:
4089 # save the mappings
4090 keys.append(t[1].toPythonObj())
4091 values.append(t[2].toPythonObj())
4092 to_visit.append(t[0])
4093 else:
4094 assert t.getKind().value == c_Kind.CONST_ARRAY
4095 base_value = t.getConstArrayBase().toPythonObj()
4096
4097 assert len(keys) == len(values)
4098 assert base_value is not None
4099
4100 # put everything in a dictionary with the constant
4101 # base as the result for any index not included in the stores
4102 res = defaultdict(lambda : base_value)
4103 for k, v in zip(keys, values):
4104 res[k] = v
4105
4106 return res
4107
4108