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