Remove separate cpp docs for UnknownExplanation (#7516)
[cvc5.git] / src / api / python / cvc5.pxi
1 from collections import defaultdict, Set
2 from fractions import Fraction
3 from functools import wraps
4 import sys
5
6 from libc.stdint cimport int32_t, int64_t, uint32_t, uint64_t
7 from libc.stddef cimport wchar_t
8
9 from libcpp.pair cimport pair
10 from libcpp.set cimport set as c_set
11 from libcpp.string cimport string
12 from libcpp.vector cimport vector
13
14 from cvc5 cimport cout
15 from cvc5 cimport Datatype as c_Datatype
16 from cvc5 cimport DatatypeConstructor as c_DatatypeConstructor
17 from cvc5 cimport DatatypeConstructorDecl as c_DatatypeConstructorDecl
18 from cvc5 cimport DatatypeDecl as c_DatatypeDecl
19 from cvc5 cimport DatatypeSelector as c_DatatypeSelector
20 from cvc5 cimport Result as c_Result
21 from cvc5 cimport RoundingMode as c_RoundingMode
22 from cvc5 cimport UnknownExplanation as c_UnknownExplanation
23 from cvc5 cimport Op as c_Op
24 from cvc5 cimport Solver as c_Solver
25 from cvc5 cimport Grammar as c_Grammar
26 from cvc5 cimport Sort as c_Sort
27 from cvc5 cimport ROUND_NEAREST_TIES_TO_EVEN, ROUND_TOWARD_POSITIVE
28 from cvc5 cimport ROUND_TOWARD_NEGATIVE, ROUND_TOWARD_ZERO
29 from cvc5 cimport ROUND_NEAREST_TIES_TO_AWAY
30 from cvc5 cimport REQUIRES_FULL_CHECK, INCOMPLETE, TIMEOUT
31 from cvc5 cimport RESOURCEOUT, MEMOUT, INTERRUPTED
32 from cvc5 cimport NO_STATUS, UNSUPPORTED, UNKNOWN_REASON
33 from cvc5 cimport OTHER
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
41 cdef extern from "Python.h":
42 wchar_t* PyUnicode_AsWideCharString(object, Py_ssize_t *)
43 object PyUnicode_FromWideChar(const wchar_t*, Py_ssize_t)
44 void PyMem_Free(void*)
45
46 ################################## DECORATORS #################################
47 def expand_list_arg(num_req_args=0):
48 """
49 Creates a decorator that looks at index num_req_args of the args,
50 if it's a list, it expands it before calling the function.
51 """
52 def decorator(func):
53 @wraps(func)
54 def wrapper(owner, *args):
55 if len(args) == num_req_args + 1 and \
56 isinstance(args[num_req_args], list):
57 args = list(args[:num_req_args]) + args[num_req_args]
58 return func(owner, *args)
59 return wrapper
60 return decorator
61 ###############################################################################
62
63 # Style Guidelines
64 ### Using PEP-8 spacing recommendations
65 ### Limit linewidth to 79 characters
66 ### Break before binary operators
67 ### surround top level functions and classes with two spaces
68 ### separate methods by one space
69 ### use spaces in functions sparingly to separate logical blocks
70 ### can omit spaces between unrelated oneliners
71 ### always use c++ default arguments
72 #### only use default args of None at python level
73
74 # References and pointers
75 # The Solver object holds a pointer to a c_Solver.
76 # This is because the assignment operator is deleted in the C++ API for solvers.
77 # Cython has a limitation where you can't stack allocate objects
78 # that have constructors with arguments:
79 # https://groups.google.com/forum/#!topic/cython-users/fuKd-nQLpBs.
80 # To get around that you can either have a nullary constructor and assignment
81 # or, use a pointer (which is what we chose).
82 # An additional complication of this is that to free up resources, you must
83 # know when to delete the object.
84 # Python will not follow the same scoping rules as in C++, so it must be
85 # able to reference count. To do this correctly, the solver must be a
86 # reference in the Python class for any class that keeps a pointer to
87 # the solver in C++ (to ensure the solver is not deleted before something
88 # that depends on it).
89
90
91 ## Objects for hashing
92 cdef c_hash[c_Op] cophash = c_hash[c_Op]()
93 cdef c_hash[c_Sort] csorthash = c_hash[c_Sort]()
94 cdef c_hash[c_Term] ctermhash = c_hash[c_Term]()
95
96
97 cdef class Datatype:
98 """
99 A cvc5 datatype.
100 Wrapper class for :cpp:class:`cvc5::api::Datatype`.
101 """
102 cdef c_Datatype cd
103 cdef Solver solver
104 def __cinit__(self, Solver solver):
105 self.solver = solver
106
107 def __getitem__(self, index):
108 cdef DatatypeConstructor dc = DatatypeConstructor(self.solver)
109 if isinstance(index, int) and index >= 0:
110 dc.cdc = self.cd[(<int?> index)]
111 elif isinstance(index, str):
112 dc.cdc = self.cd[(<const string &> index.encode())]
113 else:
114 raise ValueError("Expecting a non-negative integer or string")
115 return dc
116
117 def getConstructor(self, str name):
118 """
119 :param name: the name of the constructor.
120 :return: a constructor by name.
121 """
122 cdef DatatypeConstructor dc = DatatypeConstructor(self.solver)
123 dc.cdc = self.cd.getConstructor(name.encode())
124 return dc
125
126 def getConstructorTerm(self, str name):
127 """
128 :param name: the name of the constructor.
129 :return: the term representing the datatype constructor with the given name (see :cpp:func:`Datatype::getConstructorTerm() <cvc5::api::Datatype::getConstructorTerm>`).
130 """
131 cdef Term term = Term(self.solver)
132 term.cterm = self.cd.getConstructorTerm(name.encode())
133 return term
134
135 def getSelector(self, str name):
136 """
137 :param name: the name of the selector..
138 :return: a selector by name.
139 """
140 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
141 ds.cds = self.cd.getSelector(name.encode())
142 return ds
143
144 def getName(self):
145 """
146 :return: the name of the datatype.
147 """
148 return self.cd.getName().decode()
149
150 def getNumConstructors(self):
151 """
152 :return: number of constructors in this datatype.
153 """
154 return self.cd.getNumConstructors()
155
156 def isParametric(self):
157 """:return: True if this datatype is parametric."""
158 return self.cd.isParametric()
159
160 def isCodatatype(self):
161 """:return: True if this datatype corresponds to a co-datatype."""
162 return self.cd.isCodatatype()
163
164 def isTuple(self):
165 """:return: True if this datatype corresponds to a tuple."""
166 return self.cd.isTuple()
167
168 def isRecord(self):
169 """:return: True if this datatype corresponds to a record."""
170 return self.cd.isRecord()
171
172 def isFinite(self):
173 """:return: True if this datatype is finite."""
174 return self.cd.isFinite()
175
176 def isWellFounded(self):
177 """:return: True if this datatype is well-founded (see :cpp:func:`Datatype::isWellFounded() <cvc5::api::Datatype::isWellFounded>`)."""
178 return self.cd.isWellFounded()
179
180 def hasNestedRecursion(self):
181 """:return: True if this datatype has nested recursion (see :cpp:func:`Datatype::hasNestedRecursion() <cvc5::api::Datatype::hasNestedRecursion>`)."""
182 return self.cd.hasNestedRecursion()
183
184 def isNull(self):
185 """:return: True if this Datatype is a null object."""
186 return self.cd.isNull()
187
188 def __str__(self):
189 return self.cd.toString().decode()
190
191 def __repr__(self):
192 return self.cd.toString().decode()
193
194 def __iter__(self):
195 for ci in self.cd:
196 dc = DatatypeConstructor(self.solver)
197 dc.cdc = ci
198 yield dc
199
200
201 cdef class DatatypeConstructor:
202 """
203 A cvc5 datatype constructor.
204 Wrapper class for :cpp:class:`cvc5::api::DatatypeConstructor`.
205 """
206 cdef c_DatatypeConstructor cdc
207 cdef Solver solver
208 def __cinit__(self, Solver solver):
209 self.cdc = c_DatatypeConstructor()
210 self.solver = solver
211
212 def __getitem__(self, index):
213 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
214 if isinstance(index, int) and index >= 0:
215 ds.cds = self.cdc[(<int?> index)]
216 elif isinstance(index, str):
217 ds.cds = self.cdc[(<const string &> index.encode())]
218 else:
219 raise ValueError("Expecting a non-negative integer or string")
220 return ds
221
222 def getName(self):
223 """
224 :return: the name of the constructor.
225 """
226 return self.cdc.getName().decode()
227
228 def getConstructorTerm(self):
229 """
230 :return: the constructor operator as a term.
231 """
232 cdef Term term = Term(self.solver)
233 term.cterm = self.cdc.getConstructorTerm()
234 return term
235
236 def getSpecializedConstructorTerm(self, Sort retSort):
237 """
238 Specialized method for parametric datatypes (see :cpp:func:`DatatypeConstructor::getSpecializedConstructorTerm() <cvc5::api::DatatypeConstructor::getSpecializedConstructorTerm>`).
239
240 :param retSort: the desired return sort of the constructor
241 :return: the constructor operator as a term.
242 """
243 cdef Term term = Term(self.solver)
244 term.cterm = self.cdc.getSpecializedConstructorTerm(retSort.csort)
245 return term
246
247 def getTesterTerm(self):
248 """
249 :return: the tester operator that is related to this constructor, as a term.
250 """
251 cdef Term term = Term(self.solver)
252 term.cterm = self.cdc.getTesterTerm()
253 return term
254
255 def getNumSelectors(self):
256 """
257 :return: the number of selecters (so far) of this Datatype constructor.
258 """
259 return self.cdc.getNumSelectors()
260
261 def getSelector(self, str name):
262 """
263 :param name: the name of the datatype selector.
264 :return: the first datatype selector with the given name
265 """
266 cdef DatatypeSelector ds = DatatypeSelector(self.solver)
267 ds.cds = self.cdc.getSelector(name.encode())
268 return ds
269
270 def getSelectorTerm(self, str name):
271 """
272 :param name: the name of the datatype selector.
273 :return: a term representing the firstdatatype selector with the given name.
274 """
275 cdef Term term = Term(self.solver)
276 term.cterm = self.cdc.getSelectorTerm(name.encode())
277 return term
278
279 def isNull(self):
280 """:return: True if this DatatypeConstructor is a null object."""
281 return self.cdc.isNull()
282
283 def __str__(self):
284 return self.cdc.toString().decode()
285
286 def __repr__(self):
287 return self.cdc.toString().decode()
288
289 def __iter__(self):
290 for ci in self.cdc:
291 ds = DatatypeSelector(self.solver)
292 ds.cds = ci
293 yield ds
294
295
296 cdef class DatatypeConstructorDecl:
297 """
298 A cvc5 datatype constructor declaration.
299 Wrapper class for :cpp:class:`cvc5::api::DatatypeConstructorDecl`.
300 """
301 cdef c_DatatypeConstructorDecl cddc
302 cdef Solver solver
303
304 def __cinit__(self, Solver solver):
305 self.solver = solver
306
307 def addSelector(self, str name, Sort sort):
308 """
309 Add datatype selector declaration.
310
311 :param name: the name of the datatype selector declaration to add.
312 :param sort: the range sort of the datatype selector declaration to add.
313 """
314 self.cddc.addSelector(name.encode(), sort.csort)
315
316 def addSelectorSelf(self, str name):
317 """
318 Add datatype selector declaration whose range sort is the datatype itself.
319
320 :param name: the name of the datatype selector declaration to add.
321 """
322 self.cddc.addSelectorSelf(name.encode())
323
324 def isNull(self):
325 """:return: True if this DatatypeConstructorDecl is a null object."""
326 return self.cddc.isNull()
327
328 def __str__(self):
329 return self.cddc.toString().decode()
330
331 def __repr__(self):
332 return self.cddc.toString().decode()
333
334
335 cdef class DatatypeDecl:
336 """
337 A cvc5 datatype declaration.
338 Wrapper class for :cpp:class:`cvc5::api::DatatypeDecl`.
339 """
340 cdef c_DatatypeDecl cdd
341 cdef Solver solver
342 def __cinit__(self, Solver solver):
343 self.solver = solver
344
345 def addConstructor(self, DatatypeConstructorDecl ctor):
346 """
347 Add a datatype constructor declaration.
348
349 :param ctor: the datatype constructor declaration to add.
350 """
351 self.cdd.addConstructor(ctor.cddc)
352
353 def getNumConstructors(self):
354 """
355 :return: number of constructors (so far) for this datatype declaration.
356 """
357 return self.cdd.getNumConstructors()
358
359 def isParametric(self):
360 """
361 :return: is this datatype declaration parametric?
362 """
363 return self.cdd.isParametric()
364
365 def getName(self):
366 """
367 :return: the name of this datatype declaration.
368 """
369 return self.cdd.getName().decode()
370
371 def isNull(self):
372 """:return: True if this DatatypeDecl is a null object."""
373 return self.cdd.isNull()
374
375 def __str__(self):
376 return self.cdd.toString().decode()
377
378 def __repr__(self):
379 return self.cdd.toString().decode()
380
381
382 cdef class DatatypeSelector:
383 """
384 A cvc5 datatype selector.
385 Wrapper class for :cpp:class:`cvc5::api::DatatypeSelector`.
386 """
387 cdef c_DatatypeSelector cds
388 cdef Solver solver
389 def __cinit__(self, Solver solver):
390 self.cds = c_DatatypeSelector()
391 self.solver = solver
392
393 def getName(self):
394 """
395 :return: the name of this datatype selector.
396 """
397 return self.cds.getName().decode()
398
399 def getSelectorTerm(self):
400 """
401 :return: the selector opeartor of this datatype selector as a term.
402 """
403 cdef Term term = Term(self.solver)
404 term.cterm = self.cds.getSelectorTerm()
405 return term
406
407 def getUpdaterTerm(self):
408 """
409 :return: the updater opeartor of this datatype selector as a term.
410 """
411 cdef Term term = Term(self.solver)
412 term.cterm = self.cds.getUpdaterTerm()
413 return term
414
415 def getRangeSort(self):
416 """
417 :return: the range sort of this selector.
418 """
419 cdef Sort sort = Sort(self.solver)
420 sort.csort = self.cds.getRangeSort()
421 return sort
422
423 def isNull(self):
424 """:return: True if this DatatypeSelector is a null object."""
425 return self.cds.isNull()
426
427 def __str__(self):
428 return self.cds.toString().decode()
429
430 def __repr__(self):
431 return self.cds.toString().decode()
432
433
434 cdef class Op:
435 """
436 A cvc5 operator.
437 An operator is a term that represents certain operators,
438 instantiated with its required parameters, e.g.,
439 a term of kind :cpp:enumerator:`BITVECTOR_EXTRACT`.
440 Wrapper class for :cpp:class:`cvc5::api::Op`.
441 """
442 cdef c_Op cop
443 cdef Solver solver
444 def __cinit__(self, Solver solver):
445 self.cop = c_Op()
446 self.solver = solver
447
448 def __eq__(self, Op other):
449 return self.cop == other.cop
450
451 def __ne__(self, Op other):
452 return self.cop != other.cop
453
454 def __str__(self):
455 return self.cop.toString().decode()
456
457 def __repr__(self):
458 return self.cop.toString().decode()
459
460 def __hash__(self):
461 return cophash(self.cop)
462
463 def getKind(self):
464 """
465 :return: the kind of this operator.
466 """
467 return kind(<int> self.cop.getKind())
468
469 def isIndexed(self):
470 """
471 :return: True iff this operator is indexed.
472 """
473 return self.cop.isIndexed()
474
475 def isNull(self):
476 """
477 :return: True iff this operator is a null term.
478 """
479 return self.cop.isNull()
480
481 def getNumIndices(self):
482 """
483 :return: number of indices of this op.
484 """
485 return self.cop.getNumIndices()
486
487 def getIndices(self):
488 """
489 :return: the indices used to create this Op (see :cpp:func:`Op::getIndices() <cvc5::api::Op::getIndices>`).
490 """
491 indices = None
492 try:
493 indices = self.cop.getIndices[string]().decode()
494 except:
495 pass
496
497 try:
498 indices = self.cop.getIndices[uint32_t]()
499 except:
500 pass
501
502 try:
503 indices = self.cop.getIndices[pair[uint32_t, uint32_t]]()
504 except:
505 pass
506
507 if indices is None:
508 raise RuntimeError("Unable to retrieve indices from {}".format(self))
509
510 return indices
511
512 cdef class Grammar:
513 """
514 A Sygus Grammar.
515 Wrapper class for :cpp:class:`cvc5::api::Grammar`.
516 """
517 cdef c_Grammar cgrammar
518 cdef Solver solver
519 def __cinit__(self, Solver solver):
520 self.solver = solver
521 self.cgrammar = c_Grammar()
522
523 def addRule(self, Term ntSymbol, Term rule):
524 """
525 Add ``rule`` to the set of rules corresponding to ``ntSymbol``.
526
527 :param ntSymbol: the non-terminal to which the rule is added.
528 :param rule: the rule to add.
529 """
530 self.cgrammar.addRule(ntSymbol.cterm, rule.cterm)
531
532 def addAnyConstant(self, Term ntSymbol):
533 """
534 Allow ``ntSymbol`` to be an arbitrary constant.
535
536 :param ntSymbol: the non-terminal allowed to be constant.
537 """
538 self.cgrammar.addAnyConstant(ntSymbol.cterm)
539
540 def addAnyVariable(self, Term ntSymbol):
541 """
542 Allow ``ntSymbol`` to be any input variable to corresponding synth-fun/synth-inv with the same sort as ``ntSymbol``.
543
544 :param ntSymbol: the non-terminal allowed to be any input variable.
545 """
546 self.cgrammar.addAnyVariable(ntSymbol.cterm)
547
548 def addRules(self, Term ntSymbol, rules):
549 """
550 Add ``ntSymbol`` to the set of rules corresponding to ``ntSymbol``.
551
552 :param ntSymbol: the non-terminal to which the rules are added.
553 :param rules: the rules to add.
554 """
555 cdef vector[c_Term] crules
556 for r in rules:
557 crules.push_back((<Term?> r).cterm)
558 self.cgrammar.addRules(ntSymbol.cterm, crules)
559
560 cdef class Result:
561 """
562 Encapsulation of a three-valued solver result, with explanations.
563 Wrapper class for :cpp:class:`cvc5::api::Result`.
564 """
565 cdef c_Result cr
566 def __cinit__(self):
567 # gets populated by solver
568 self.cr = c_Result()
569
570 def isNull(self):
571 """
572 :return: True if Result is empty, i.e., a nullary Result, and not an actual result returned from a
573 :cpp:func:`Solver::checkSat() <cvc5::api::Solver::checkSat>` (and friends) query.
574 """
575 return self.cr.isNull()
576
577 def isSat(self):
578 """
579 :return: True if query was a satisfiable :cpp:func:`Solver::checkSat() <cvc5::api::Solver::checkSat>` or :cpp:func:`Solver::checkSatAssuming() <cvc5::api::Solver::checkSatAssuming>` query.
580 """
581 return self.cr.isSat()
582
583 def isUnsat(self):
584 """
585 :return: True if query was an usatisfiable :cpp:func:`Solver::checkSat() <cvc5::api::Solver::checkSat>` or :cpp:func:`Solver::checkSatAssuming() <cvc5::api::Solver::checkSatAssuming>` query.
586 """
587 return self.cr.isUnsat()
588
589 def isSatUnknown(self):
590 """
591 :return: True if query was a :cpp:func:`Solver::checkSat() <cvc5::api::Solver::checkSat>` or :cpp:func:`Solver::checkSatAssuming() <cvc5::api::Solver::checkSatAssuming>` query and cvc5 was not able to determine (un)satisfiability.
592 """
593 return self.cr.isSatUnknown()
594
595 def isEntailed(self):
596 """
597 :return: True if corresponding query was an entailed :cpp:func:`Solver::checkEntailed() <cvc5::api::Solver::checkEntailed>` query.
598 """
599 return self.cr.isEntailed()
600
601 def isNotEntailed(self):
602 """
603 :return: True if corresponding query was a :cpp:func:`Solver::checkEntailed() <cvc5::api::Solver::checkEntailed>` query that is not entailed.
604 """
605 return self.cr.isNotEntailed()
606
607 def isEntailmentUnknown(self):
608 """
609 :return: True if query was a :cpp:func:`Solver::checkEntailed() <cvc5::api::Solver::checkEntailed>` query query and cvc5 was not able to determine if it is entailed.
610 """
611 return self.cr.isEntailmentUnknown()
612
613 def getUnknownExplanation(self):
614 """
615 :return: an explanation for an unknown query result.
616 """
617 return UnknownExplanation(<int> self.cr.getUnknownExplanation())
618
619 def __eq__(self, Result other):
620 return self.cr == other.cr
621
622 def __ne__(self, Result other):
623 return self.cr != other.cr
624
625 def __str__(self):
626 return self.cr.toString().decode()
627
628 def __repr__(self):
629 return self.cr.toString().decode()
630
631
632 cdef class RoundingMode:
633 """
634 Rounding modes for floating-point numbers.
635
636 For many floating-point operations, infinitely precise results may not be
637 representable with the number of available bits. Thus, the results are
638 rounded in a certain way to one of the representable floating-point numbers.
639
640 These rounding modes directly follow the SMT-LIB theory for floating-point
641 arithmetic, which in turn is based on IEEE Standard 754 :cite:`IEEE754`.
642 The rounding modes are specified in Sections 4.3.1 and 4.3.2 of the IEEE
643 Standard 754.
644
645 Wrapper class for :cpp:enum:`cvc5::api::RoundingMode`.
646 """
647 cdef c_RoundingMode crm
648 cdef str name
649 def __cinit__(self, int rm):
650 # crm always assigned externally
651 self.crm = <c_RoundingMode> rm
652 self.name = __rounding_modes[rm]
653
654 def __eq__(self, RoundingMode other):
655 return (<int> self.crm) == (<int> other.crm)
656
657 def __ne__(self, RoundingMode other):
658 return not self.__eq__(other)
659
660 def __hash__(self):
661 return hash((<int> self.crm, self.name))
662
663 def __str__(self):
664 return self.name
665
666 def __repr__(self):
667 return self.name
668
669
670 cdef class UnknownExplanation:
671 """
672 Wrapper class for :cpp:enum:`cvc5::api::Result::UnknownExplanation`.
673 """
674 cdef c_UnknownExplanation cue
675 cdef str name
676 def __cinit__(self, int ue):
677 # crm always assigned externally
678 self.cue = <c_UnknownExplanation> ue
679 self.name = __unknown_explanations[ue]
680
681 def __eq__(self, UnknownExplanation other):
682 return (<int> self.cue) == (<int> other.cue)
683
684 def __ne__(self, UnknownExplanation other):
685 return not self.__eq__(other)
686
687 def __hash__(self):
688 return hash((<int> self.crm, self.name))
689
690 def __str__(self):
691 return self.name
692
693 def __repr__(self):
694 return self.name
695
696
697 cdef class Solver:
698 """Wrapper class for :cpp:class:`cvc5::api::Solver`."""
699 cdef c_Solver* csolver
700
701 def __cinit__(self):
702 self.csolver = new c_Solver()
703
704 def __dealloc__(self):
705 del self.csolver
706
707 def getBooleanSort(self):
708 """:return: sort Boolean
709 """
710 cdef Sort sort = Sort(self)
711 sort.csort = self.csolver.getBooleanSort()
712 return sort
713
714 def getIntegerSort(self):
715 """:return: sort Integer
716 """
717 cdef Sort sort = Sort(self)
718 sort.csort = self.csolver.getIntegerSort()
719 return sort
720
721 def getNullSort(self):
722 """:return: sort null
723 """
724 cdef Sort sort = Sort(self)
725 sort.csort = self.csolver.getNullSort()
726 return sort
727
728 def getRealSort(self):
729 """:return: sort Real
730 """
731 cdef Sort sort = Sort(self)
732 sort.csort = self.csolver.getRealSort()
733 return sort
734
735 def getRegExpSort(self):
736 """:return: sort of RegExp
737 """
738 cdef Sort sort = Sort(self)
739 sort.csort = self.csolver.getRegExpSort()
740 return sort
741
742 def getRoundingModeSort(self):
743 """:return: sort RoundingMode
744 """
745 cdef Sort sort = Sort(self)
746 sort.csort = self.csolver.getRoundingModeSort()
747 return sort
748
749 def getStringSort(self):
750 """:return: sort String
751 """
752 cdef Sort sort = Sort(self)
753 sort.csort = self.csolver.getStringSort()
754 return sort
755
756 def mkArraySort(self, Sort indexSort, Sort elemSort):
757 """Create an array sort.
758
759 :param indexSort: the array index sort
760 :param elemSort: the array element sort
761 :return: the array sort
762 """
763 cdef Sort sort = Sort(self)
764 sort.csort = self.csolver.mkArraySort(indexSort.csort, elemSort.csort)
765 return sort
766
767 def mkBitVectorSort(self, uint32_t size):
768 """Create a bit-vector sort.
769
770 :param size: the bit-width of the bit-vector sort
771 :return: the bit-vector sort
772 """
773 cdef Sort sort = Sort(self)
774 sort.csort = self.csolver.mkBitVectorSort(size)
775 return sort
776
777 def mkFloatingPointSort(self, uint32_t exp, uint32_t sig):
778 """Create a floating-point sort.
779
780 :param exp: the bit-width of the exponent of the floating-point sort.
781 :param sig: the bit-width of the significand of the floating-point sort.
782 """
783 cdef Sort sort = Sort(self)
784 sort.csort = self.csolver.mkFloatingPointSort(exp, sig)
785 return sort
786
787 def mkDatatypeSort(self, DatatypeDecl dtypedecl):
788 """Create a datatype sort.
789
790 :param dtypedecl: the datatype declaration from which the sort is created
791 :return: the datatype sort
792 """
793 cdef Sort sort = Sort(self)
794 sort.csort = self.csolver.mkDatatypeSort(dtypedecl.cdd)
795 return sort
796
797 def mkDatatypeSorts(self, list dtypedecls, unresolvedSorts = None):
798 """
799 Create a vector of datatype sorts using unresolved sorts. The names of
800 the datatype declarations in dtypedecls must be distinct.
801
802 This method is called when the DatatypeDecl objects dtypedecls have been
803 built using "unresolved" sorts.
804
805 We associate each sort in unresolvedSorts with exacly one datatype from
806 dtypedecls. In particular, it must have the same name as exactly one
807 datatype declaration in dtypedecls.
808
809 When constructing datatypes, unresolved sorts are replaced by the datatype
810 sort constructed for the datatype declaration it is associated with.
811
812 :param dtypedecls: the datatype declarations from which the sort is created
813 :param unresolvedSorts: the list of unresolved sorts
814 :return: the datatype sorts
815 """
816 if unresolvedSorts == None:
817 unresolvedSorts = set([])
818 else:
819 assert isinstance(unresolvedSorts, Set)
820
821 sorts = []
822 cdef vector[c_DatatypeDecl] decls
823 for decl in dtypedecls:
824 decls.push_back((<DatatypeDecl?> decl).cdd)
825
826 cdef c_set[c_Sort] usorts
827 for usort in unresolvedSorts:
828 usorts.insert((<Sort?> usort).csort)
829
830 csorts = self.csolver.mkDatatypeSorts(
831 <const vector[c_DatatypeDecl]&> decls, <const c_set[c_Sort]&> usorts)
832 for csort in csorts:
833 sort = Sort(self)
834 sort.csort = csort
835 sorts.append(sort)
836
837 return sorts
838
839 def mkFunctionSort(self, sorts, Sort codomain):
840 """ Create function sort.
841
842 :param sorts: the sort of the function arguments
843 :param codomain: the sort of the function return value
844 :return: the function sort
845 """
846
847 cdef Sort sort = Sort(self)
848 # populate a vector with dereferenced c_Sorts
849 cdef vector[c_Sort] v
850
851 if isinstance(sorts, Sort):
852 sort.csort = self.csolver.mkFunctionSort((<Sort?> sorts).csort,
853 codomain.csort)
854 elif isinstance(sorts, list):
855 for s in sorts:
856 v.push_back((<Sort?>s).csort)
857
858 sort.csort = self.csolver.mkFunctionSort(<const vector[c_Sort]&> v,
859 codomain.csort)
860 return sort
861
862 def mkParamSort(self, symbolname):
863 """ Create a sort parameter.
864
865 :param symbol: the name of the sort
866 :return: the sort parameter
867 """
868 cdef Sort sort = Sort(self)
869 sort.csort = self.csolver.mkParamSort(symbolname.encode())
870 return sort
871
872 @expand_list_arg(num_req_args=0)
873 def mkPredicateSort(self, *sorts):
874 """Create a predicate sort.
875
876 :param sorts: the list of sorts of the predicate, as a list or as distinct arguments.
877 :return: the predicate sort
878 """
879 cdef Sort sort = Sort(self)
880 cdef vector[c_Sort] v
881 for s in sorts:
882 v.push_back((<Sort?> s).csort)
883 sort.csort = self.csolver.mkPredicateSort(<const vector[c_Sort]&> v)
884 return sort
885
886 @expand_list_arg(num_req_args=0)
887 def mkRecordSort(self, *fields):
888 """Create a record sort
889
890 :param fields: the list of fields of the record, as a list or as distinct arguments
891 :return: the record sort
892 """
893 cdef Sort sort = Sort(self)
894 cdef vector[pair[string, c_Sort]] v
895 cdef pair[string, c_Sort] p
896 for f in fields:
897 name, sortarg = f
898 name = name.encode()
899 p = pair[string, c_Sort](<string?> name, (<Sort?> sortarg).csort)
900 v.push_back(p)
901 sort.csort = self.csolver.mkRecordSort(
902 <const vector[pair[string, c_Sort]] &> v)
903 return sort
904
905 def mkSetSort(self, Sort elemSort):
906 """Create a set sort.
907
908 :param elemSort: the sort of the set elements
909 :return: the set sort
910 """
911 cdef Sort sort = Sort(self)
912 sort.csort = self.csolver.mkSetSort(elemSort.csort)
913 return sort
914
915 def mkBagSort(self, Sort elemSort):
916 """Create a bag sort.
917
918 :param elemSort: the sort of the bag elements
919 :return: the bag sort
920 """
921 cdef Sort sort = Sort(self)
922 sort.csort = self.csolver.mkBagSort(elemSort.csort)
923 return sort
924
925 def mkSequenceSort(self, Sort elemSort):
926 """Create a sequence sort.
927
928 :param elemSort: the sort of the sequence elements
929 :return: the sequence sort
930 """
931 cdef Sort sort = Sort(self)
932 sort.csort = self.csolver.mkSequenceSort(elemSort.csort)
933 return sort
934
935 def mkUninterpretedSort(self, str name):
936 """Create an uninterpreted sort.
937
938 :param symbol: the name of the sort
939 :return: the uninterpreted sort
940 """
941 cdef Sort sort = Sort(self)
942 sort.csort = self.csolver.mkUninterpretedSort(name.encode())
943 return sort
944
945 def mkSortConstructorSort(self, str symbol, size_t arity):
946 """Create a sort constructor sort.
947
948 :param symbol: the symbol of the sort
949 :param arity: the arity of the sort
950 :return: the sort constructor sort
951 """
952 cdef Sort sort = Sort(self)
953 sort.csort =self.csolver.mkSortConstructorSort(symbol.encode(), arity)
954 return sort
955
956 @expand_list_arg(num_req_args=0)
957 def mkTupleSort(self, *sorts):
958 """Create a tuple sort.
959
960 :param sorts: of the elements of the tuple, as a list or as distinct arguments
961 :return: the tuple sort
962 """
963 cdef Sort sort = Sort(self)
964 cdef vector[c_Sort] v
965 for s in sorts:
966 v.push_back((<Sort?> s).csort)
967 sort.csort = self.csolver.mkTupleSort(v)
968 return sort
969
970 @expand_list_arg(num_req_args=1)
971 def mkTerm(self, kind_or_op, *args):
972 """
973 Supports the following arguments:
974
975 - ``Term mkTerm(Kind kind)``
976 - ``Term mkTerm(Kind kind, Op child1, List[Term] children)``
977 - ``Term mkTerm(Kind kind, List[Term] children)``
978
979 where ``List[Term]`` can also be comma-separated arguments
980 """
981 cdef Term term = Term(self)
982 cdef vector[c_Term] v
983
984 op = kind_or_op
985 if isinstance(kind_or_op, kind):
986 op = self.mkOp(kind_or_op)
987
988 if len(args) == 0:
989 term.cterm = self.csolver.mkTerm((<Op?> op).cop)
990 else:
991 for a in args:
992 v.push_back((<Term?> a).cterm)
993 term.cterm = self.csolver.mkTerm((<Op?> op).cop, v)
994 return term
995
996 def mkTuple(self, sorts, terms):
997 """Create a tuple term. Terms are automatically converted if sorts are compatible.
998
999 :param sorts: The sorts of the elements in the tuple
1000 :param terms: The elements in the tuple
1001 :return: the tuple Term
1002 """
1003 cdef vector[c_Sort] csorts
1004 cdef vector[c_Term] cterms
1005
1006 for s in sorts:
1007 csorts.push_back((<Sort?> s).csort)
1008 for s in terms:
1009 cterms.push_back((<Term?> s).cterm)
1010 cdef Term result = Term(self)
1011 result.cterm = self.csolver.mkTuple(csorts, cterms)
1012 return result
1013
1014 @expand_list_arg(num_req_args=0)
1015 def mkOp(self, kind k, *args):
1016 """
1017 Supports the following uses:
1018
1019 - ``Op mkOp(Kind kind)``
1020 - ``Op mkOp(Kind kind, Kind k)``
1021 - ``Op mkOp(Kind kind, const string& arg)``
1022 - ``Op mkOp(Kind kind, uint32_t arg)``
1023 - ``Op mkOp(Kind kind, uint32_t arg0, uint32_t arg1)``
1024 - ``Op mkOp(Kind kind, [uint32_t arg0, ...])`` (used for the TupleProject kind)
1025 """
1026 cdef Op op = Op(self)
1027 cdef vector[uint32_t] v
1028
1029 if len(args) == 0:
1030 op.cop = self.csolver.mkOp(k.k)
1031 elif len(args) == 1:
1032 if isinstance(args[0], str):
1033 op.cop = self.csolver.mkOp(k.k,
1034 <const string &>
1035 args[0].encode())
1036 elif isinstance(args[0], int):
1037 op.cop = self.csolver.mkOp(k.k, <int?> args[0])
1038 elif isinstance(args[0], list):
1039 for a in args[0]:
1040 if a < 0 or a >= 2 ** 31:
1041 raise ValueError("Argument {} must fit in a uint32_t".format(a))
1042
1043 v.push_back((<uint32_t?> a))
1044 op.cop = self.csolver.mkOp(k.k, <const vector[uint32_t]&> v)
1045 else:
1046 raise ValueError("Unsupported signature"
1047 " mkOp: {}".format(" X ".join([str(k), str(args[0])])))
1048 elif len(args) == 2:
1049 if isinstance(args[0], int) and isinstance(args[1], int):
1050 op.cop = self.csolver.mkOp(k.k, <int> args[0], <int> args[1])
1051 else:
1052 raise ValueError("Unsupported signature"
1053 " mkOp: {}".format(" X ".join([k, args[0], args[1]])))
1054 return op
1055
1056 def mkTrue(self):
1057 """Create a Boolean true constant.
1058
1059 :return: the true constant
1060 """
1061 cdef Term term = Term(self)
1062 term.cterm = self.csolver.mkTrue()
1063 return term
1064
1065 def mkFalse(self):
1066 """Create a Boolean false constant.
1067
1068 :return: the false constant
1069 """
1070 cdef Term term = Term(self)
1071 term.cterm = self.csolver.mkFalse()
1072 return term
1073
1074 def mkBoolean(self, bint val):
1075 """Create a Boolean constant.
1076
1077 :return: the Boolean constant
1078 :param val: the value of the constant
1079 """
1080 cdef Term term = Term(self)
1081 term.cterm = self.csolver.mkBoolean(val)
1082 return term
1083
1084 def mkPi(self):
1085 """Create a constant representing the number Pi.
1086
1087 :return: a constant representing Pi
1088 """
1089 cdef Term term = Term(self)
1090 term.cterm = self.csolver.mkPi()
1091 return term
1092
1093 def mkInteger(self, val):
1094 """Create an integer constant.
1095
1096 :param val: representation of the constant: either a string or integer
1097 :return: a constant of sort Integer
1098 """
1099 cdef Term term = Term(self)
1100 if isinstance(val, str):
1101 term.cterm = self.csolver.mkInteger(<const string &> str(val).encode())
1102 else:
1103 assert(isinstance(val, int))
1104 term.cterm = self.csolver.mkInteger((<int?> val))
1105 return term
1106
1107 def mkReal(self, val, den=None):
1108 """Create a real constant.
1109
1110 :param: `val` the value of the term. Can be an integer, float, or string. It will be formatted as a string before the term is built.
1111 :param: `den` if not None, the value is `val`/`den`
1112 :return: a real term with literal value
1113
1114 Can be used in various forms:
1115
1116 - Given a string ``"N/D"`` constructs the corresponding rational.
1117 - Given a string ``"W.D"`` constructs the reduction of ``(W * P + D)/P``, where ``P`` is the appropriate power of 10.
1118 - Given a float ``f``, constructs the rational matching ``f``'s string representation. This means that ``mkReal(0.3)`` gives ``3/10`` and not the IEEE-754 approximation of ``3/10``.
1119 - Given a string ``"W"`` or an integer, constructs that integer.
1120 - Given two strings and/or integers ``N`` and ``D``, constructs ``N/D``.
1121 """
1122 cdef Term term = Term(self)
1123 if den is None:
1124 term.cterm = self.csolver.mkReal(str(val).encode())
1125 else:
1126 if not isinstance(val, int) or not isinstance(den, int):
1127 raise ValueError("Expecting integers when"
1128 " constructing a rational"
1129 " but got: {}".format((val, den)))
1130 term.cterm = self.csolver.mkReal("{}/{}".format(val, den).encode())
1131 return term
1132
1133 def mkRegexpEmpty(self):
1134 """Create a regular expression empty term.
1135
1136 :return: the empty term
1137 """
1138 cdef Term term = Term(self)
1139 term.cterm = self.csolver.mkRegexpEmpty()
1140 return term
1141
1142 def mkRegexpSigma(self):
1143 """Create a regular expression sigma term.
1144
1145 :return: the sigma term
1146 """
1147 cdef Term term = Term(self)
1148 term.cterm = self.csolver.mkRegexpSigma()
1149 return term
1150
1151 def mkEmptySet(self, Sort s):
1152 """Create a constant representing an empty set of the given sort.
1153
1154 :param sort: the sort of the set elements.
1155 :return: the empty set constant
1156 """
1157 cdef Term term = Term(self)
1158 term.cterm = self.csolver.mkEmptySet(s.csort)
1159 return term
1160
1161 def mkEmptyBag(self, Sort s):
1162 """Create a constant representing an empty bag of the given sort.
1163
1164 :param sort: the sort of the bag elements.
1165 :return: the empty bag constant
1166 """
1167 cdef Term term = Term(self)
1168 term.cterm = self.csolver.mkEmptyBag(s.csort)
1169 return term
1170
1171 def mkSepEmp(self):
1172 """Create a separation logic empty term.
1173
1174 :return: the separation logic empty term
1175 """
1176 cdef Term term = Term(self)
1177 term.cterm = self.csolver.mkSepEmp()
1178 return term
1179
1180 def mkSepNil(self, Sort sort):
1181 """Create a separation logic nil term.
1182
1183 :param sort: the sort of the nil term
1184 :return: the separation logic nil term
1185 """
1186 cdef Term term = Term(self)
1187 term.cterm = self.csolver.mkSepNil(sort.csort)
1188 return term
1189
1190 def mkString(self, str s, useEscSequences = None):
1191 """
1192 Create a String constant from a `str` which may contain SMT-LIB
1193 compatible escape sequences like ``\\u1234`` to encode unicode characters.
1194
1195 :param s: the string this constant represents
1196 :param useEscSequences: determines whether escape sequences in `s` should be converted to the corresponding unicode character
1197 :return: the String constant
1198 """
1199 cdef Term term = Term(self)
1200 cdef Py_ssize_t size
1201 cdef wchar_t* tmp = PyUnicode_AsWideCharString(s, &size)
1202 if isinstance(useEscSequences, bool):
1203 term.cterm = self.csolver.mkString(
1204 s.encode(), <bint> useEscSequences)
1205 else:
1206 term.cterm = self.csolver.mkString(c_wstring(tmp, size))
1207 PyMem_Free(tmp)
1208 return term
1209
1210 def mkEmptySequence(self, Sort sort):
1211 """Create an empty sequence of the given element sort.
1212
1213 :param sort: The element sort of the sequence.
1214 :return: the empty sequence with given element sort.
1215 """
1216 cdef Term term = Term(self)
1217 term.cterm = self.csolver.mkEmptySequence(sort.csort)
1218 return term
1219
1220 def mkUniverseSet(self, Sort sort):
1221 """Create a universe set of the given sort.
1222
1223 :param sort: the sort of the set elements
1224 :return: the universe set constant
1225 """
1226 cdef Term term = Term(self)
1227 term.cterm = self.csolver.mkUniverseSet(sort.csort)
1228 return term
1229
1230 @expand_list_arg(num_req_args=0)
1231 def mkBitVector(self, *args):
1232 """
1233 Supports the following arguments:
1234
1235 - ``Term mkBitVector(int size, int val=0)``
1236 - ``Term mkBitVector(int size, string val, int base)``
1237
1238 :return: a bit-vector literal term
1239 :param: `size` an integer size.
1240 :param: `val` an integer representating the value, in the first form. In the second form, a string representing the value.
1241 :param: `base` the base of the string representation (second form only)
1242 """
1243 cdef Term term = Term(self)
1244 if len(args) == 0:
1245 raise ValueError("Missing arguments to mkBitVector")
1246 size = args[0]
1247 if not isinstance(size, int):
1248 raise ValueError(
1249 "Invalid first argument to mkBitVector '{}', "
1250 "expected bit-vector size".format(size))
1251 if len(args) == 1:
1252 term.cterm = self.csolver.mkBitVector(<uint32_t> size)
1253 elif len(args) == 2:
1254 val = args[1]
1255 if not isinstance(val, int):
1256 raise ValueError(
1257 "Invalid second argument to mkBitVector '{}', "
1258 "expected integer value".format(size))
1259 term.cterm = self.csolver.mkBitVector(
1260 <uint32_t> size, <uint32_t> val)
1261 elif len(args) == 3:
1262 val = args[1]
1263 base = args[2]
1264 if not isinstance(val, str):
1265 raise ValueError(
1266 "Invalid second argument to mkBitVector '{}', "
1267 "expected value string".format(size))
1268 if not isinstance(base, int):
1269 raise ValueError(
1270 "Invalid third argument to mkBitVector '{}', "
1271 "expected base given as integer".format(size))
1272 term.cterm = self.csolver.mkBitVector(
1273 <uint32_t> size,
1274 <const string&> str(val).encode(),
1275 <uint32_t> base)
1276 else:
1277 raise ValueError("Unexpected inputs to mkBitVector")
1278 return term
1279
1280 def mkConstArray(self, Sort sort, Term val):
1281 """
1282 Create a constant array with the provided constant value stored at every
1283 index
1284
1285 :param sort: the sort of the constant array (must be an array sort)
1286 :param val: the constant value to store (must match the sort's element sort)
1287 :return: the constant array term
1288 """
1289 cdef Term term = Term(self)
1290 term.cterm = self.csolver.mkConstArray(sort.csort, val.cterm)
1291 return term
1292
1293 def mkPosInf(self, int exp, int sig):
1294 """Create a positive infinity floating-point constant.
1295
1296 :param exp: Number of bits in the exponent
1297 :param sig: Number of bits in the significand
1298 :return: the floating-point constant
1299 """
1300 cdef Term term = Term(self)
1301 term.cterm = self.csolver.mkPosInf(exp, sig)
1302 return term
1303
1304 def mkNegInf(self, int exp, int sig):
1305 """Create a negative infinity floating-point constant.
1306
1307 :param exp: Number of bits in the exponent
1308 :param sig: Number of bits in the significand
1309 :return: the floating-point constant
1310 """
1311 cdef Term term = Term(self)
1312 term.cterm = self.csolver.mkNegInf(exp, sig)
1313 return term
1314
1315 def mkNaN(self, int exp, int sig):
1316 """Create a not-a-number (NaN) floating-point constant.
1317
1318 :param exp: Number of bits in the exponent
1319 :param sig: Number of bits in the significand
1320 :return: the floating-point constant
1321 """
1322 cdef Term term = Term(self)
1323 term.cterm = self.csolver.mkNaN(exp, sig)
1324 return term
1325
1326 def mkPosZero(self, int exp, int sig):
1327 """Create a positive zero (+0.0) floating-point constant.
1328
1329 :param exp: Number of bits in the exponent
1330 :param sig: Number of bits in the significand
1331 :return: the floating-point constant
1332 """
1333 cdef Term term = Term(self)
1334 term.cterm = self.csolver.mkPosZero(exp, sig)
1335 return term
1336
1337 def mkNegZero(self, int exp, int sig):
1338 """Create a negative zero (+0.0) floating-point constant.
1339
1340 :param exp: Number of bits in the exponent
1341 :param sig: Number of bits in the significand
1342 :return: the floating-point constant
1343 """
1344 cdef Term term = Term(self)
1345 term.cterm = self.csolver.mkNegZero(exp, sig)
1346 return term
1347
1348 def mkRoundingMode(self, RoundingMode rm):
1349 """Create a roundingmode constant.
1350
1351 :param rm: the floating point rounding mode this constant represents
1352 """
1353 cdef Term term = Term(self)
1354 term.cterm = self.csolver.mkRoundingMode(<c_RoundingMode> rm.crm)
1355 return term
1356
1357 def mkUninterpretedConst(self, Sort sort, int index):
1358 """Create uninterpreted constant.
1359
1360 :param sort: Sort of the constant
1361 :param index: Index of the constant
1362 """
1363 cdef Term term = Term(self)
1364 term.cterm = self.csolver.mkUninterpretedConst(sort.csort, index)
1365 return term
1366
1367 def mkAbstractValue(self, index):
1368 """
1369 Create an abstract value constant.
1370 The given index needs to be positive.
1371
1372 :param index: Index of the abstract value
1373 """
1374 cdef Term term = Term(self)
1375 try:
1376 term.cterm = self.csolver.mkAbstractValue(str(index).encode())
1377 except:
1378 raise ValueError(
1379 "mkAbstractValue expects a str representing a number"
1380 " or an int, but got{}".format(index))
1381 return term
1382
1383 def mkFloatingPoint(self, int exp, int sig, Term val):
1384 """Create a floating-point constant.
1385
1386 :param exp: Size of the exponent
1387 :param sig: Size of the significand
1388 :param val: Value of the floating-point constant as a bit-vector term
1389 """
1390 cdef Term term = Term(self)
1391 term.cterm = self.csolver.mkFloatingPoint(exp, sig, val.cterm)
1392 return term
1393
1394 def mkCardinalityConstraint(self, Sort sort, int index):
1395 """Create cardinality constraint.
1396
1397 :param sort: Sort of the constraint
1398 :param index: The upper bound for the cardinality of the sort
1399 """
1400 cdef Term term = Term(self)
1401 term.cterm = self.csolver.mkCardinalityConstraint(sort.csort, index)
1402 return term
1403
1404 def mkConst(self, Sort sort, symbol=None):
1405 """
1406 Create (first-order) constant (0-arity function symbol).
1407
1408 SMT-LIB:
1409
1410 .. code-block:: smtlib
1411
1412 ( declare-const <symbol> <sort> )
1413 ( declare-fun <symbol> ( ) <sort> )
1414
1415 :param sort: the sort of the constant
1416 :param symbol: the name of the constant. If None, a default symbol is used.
1417 :return: the first-order constant
1418 """
1419 cdef Term term = Term(self)
1420 if symbol is None:
1421 term.cterm = self.csolver.mkConst(sort.csort)
1422 else:
1423 term.cterm = self.csolver.mkConst(sort.csort,
1424 (<str?> symbol).encode())
1425 return term
1426
1427 def mkVar(self, Sort sort, symbol=None):
1428 """
1429 Create a bound variable to be used in a binder (i.e. a quantifier, a
1430 lambda, or a witness binder).
1431
1432 :param sort: the sort of the variable
1433 :param symbol: the name of the variable
1434 :return: the variable
1435 """
1436 cdef Term term = Term(self)
1437 if symbol is None:
1438 term.cterm = self.csolver.mkVar(sort.csort)
1439 else:
1440 term.cterm = self.csolver.mkVar(sort.csort,
1441 (<str?> symbol).encode())
1442 return term
1443
1444 def mkDatatypeConstructorDecl(self, str name):
1445 """
1446 :return: a datatype constructor declaration
1447 :param: `name` the constructor's name
1448 """
1449 cdef DatatypeConstructorDecl ddc = DatatypeConstructorDecl(self)
1450 ddc.cddc = self.csolver.mkDatatypeConstructorDecl(name.encode())
1451 return ddc
1452
1453 def mkDatatypeDecl(self, str name, sorts_or_bool=None, isCoDatatype=None):
1454 """Create a datatype declaration.
1455
1456 :param name: the name of the datatype
1457 :param isCoDatatype: true if a codatatype is to be constructed
1458 :return: the DatatypeDecl
1459 """
1460 cdef DatatypeDecl dd = DatatypeDecl(self)
1461 cdef vector[c_Sort] v
1462
1463 # argument cases
1464 if sorts_or_bool is None and isCoDatatype is None:
1465 dd.cdd = self.csolver.mkDatatypeDecl(name.encode())
1466 elif sorts_or_bool is not None and isCoDatatype is None:
1467 if isinstance(sorts_or_bool, bool):
1468 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
1469 <bint> sorts_or_bool)
1470 elif isinstance(sorts_or_bool, Sort):
1471 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
1472 (<Sort> sorts_or_bool).csort)
1473 elif isinstance(sorts_or_bool, list):
1474 for s in sorts_or_bool:
1475 v.push_back((<Sort?> s).csort)
1476 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
1477 <const vector[c_Sort]&> v)
1478 else:
1479 raise ValueError("Unhandled second argument type {}"
1480 .format(type(sorts_or_bool)))
1481 elif sorts_or_bool is not None and isCoDatatype is not None:
1482 if isinstance(sorts_or_bool, Sort):
1483 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
1484 (<Sort> sorts_or_bool).csort,
1485 <bint> isCoDatatype)
1486 elif isinstance(sorts_or_bool, list):
1487 for s in sorts_or_bool:
1488 v.push_back((<Sort?> s).csort)
1489 dd.cdd = self.csolver.mkDatatypeDecl(<const string &> name.encode(),
1490 <const vector[c_Sort]&> v,
1491 <bint> isCoDatatype)
1492 else:
1493 raise ValueError("Unhandled second argument type {}"
1494 .format(type(sorts_or_bool)))
1495 else:
1496 raise ValueError("Can't create DatatypeDecl with {}".format([type(a)
1497 for a in [name,
1498 sorts_or_bool,
1499 isCoDatatype]]))
1500
1501 return dd
1502
1503 def simplify(self, Term t):
1504 """
1505 Simplify a formula without doing "much" work. Does not involve the
1506 SAT Engine in the simplification, but uses the current definitions,
1507 assertions, and the current partial model, if one has been constructed.
1508 It also involves theory normalization.
1509
1510 :param t: the formula to simplify
1511 :return: the simplified formula
1512 """
1513 cdef Term term = Term(self)
1514 term.cterm = self.csolver.simplify(t.cterm)
1515 return term
1516
1517 def assertFormula(self, Term term):
1518 """ Assert a formula
1519
1520 SMT-LIB:
1521
1522 .. code-block:: smtlib
1523
1524 ( assert <term> )
1525
1526 :param term: the formula to assert
1527 """
1528 self.csolver.assertFormula(term.cterm)
1529
1530 def checkSat(self):
1531 """
1532 Check satisfiability.
1533
1534 SMT-LIB:
1535
1536 .. code-block:: smtlib
1537
1538 ( check-sat )
1539
1540 :return: the result of the satisfiability check.
1541 """
1542 cdef Result r = Result()
1543 r.cr = self.csolver.checkSat()
1544 return r
1545
1546 def mkSygusGrammar(self, boundVars, ntSymbols):
1547 """
1548 Create a SyGuS grammar. The first non-terminal is treated as the
1549 starting non-terminal, so the order of non-terminals matters.
1550
1551 :param boundVars: the parameters to corresponding synth-fun/synth-inv
1552 :param ntSymbols: the pre-declaration of the non-terminal symbols
1553 :return: the grammar
1554 """
1555 cdef Grammar grammar = Grammar(self)
1556 cdef vector[c_Term] bvc
1557 cdef vector[c_Term] ntc
1558 for bv in boundVars:
1559 bvc.push_back((<Term?> bv).cterm)
1560 for nt in ntSymbols:
1561 ntc.push_back((<Term?> nt).cterm)
1562 grammar.cgrammar = self.csolver.mkSygusGrammar(<const vector[c_Term]&> bvc, <const vector[c_Term]&> ntc)
1563 return grammar
1564
1565 def mkSygusVar(self, Sort sort, str symbol=""):
1566 """Append symbol to the current list of universal variables.
1567
1568 SyGuS v2:
1569
1570 .. code-block:: smtlib
1571
1572 ( declare-var <symbol> <sort> )
1573
1574 :param sort: the sort of the universal variable
1575 :param symbol: the name of the universal variable
1576 :return: the universal variable
1577 """
1578 cdef Term term = Term(self)
1579 term.cterm = self.csolver.mkSygusVar(sort.csort, symbol.encode())
1580 return term
1581
1582 def addSygusConstraint(self, Term t):
1583 """
1584 Add a formula to the set of SyGuS constraints.
1585
1586 SyGuS v2:
1587
1588 .. code-block:: smtlib
1589
1590 ( constraint <term> )
1591
1592 :param term: the formula to add as a constraint
1593 """
1594 self.csolver.addSygusConstraint(t.cterm)
1595
1596 def addSygusInvConstraint(self, Term inv_f, Term pre_f, Term trans_f, Term post_f):
1597 """
1598 Add a set of SyGuS constraints to the current state that correspond to an
1599 invariant synthesis problem.
1600
1601 SyGuS v2:
1602
1603 .. code-block:: smtlib
1604
1605 ( inv-constraint <inv> <pre> <trans> <post> )
1606
1607 :param inv: the function-to-synthesize
1608 :param pre: the pre-condition
1609 :param trans: the transition relation
1610 :param post: the post-condition
1611 """
1612 self.csolver.addSygusInvConstraint(inv_f.cterm, pre_f.cterm, trans_f.cterm, post_f.cterm)
1613
1614 def synthFun(self, str symbol, bound_vars, Sort sort, Grammar grammar=None):
1615 """
1616 Synthesize n-ary function following specified syntactic constraints.
1617
1618 SyGuS v2:
1619
1620 .. code-block:: smtlib
1621
1622 ( synth-fun <symbol> ( <boundVars>* ) <sort> <g> )
1623
1624 :param symbol: the name of the function
1625 :param boundVars: the parameters to this function
1626 :param sort: the sort of the return value of this function
1627 :param grammar: the syntactic constraints
1628 :return: the function
1629 """
1630 cdef Term term = Term(self)
1631 cdef vector[c_Term] v
1632 for bv in bound_vars:
1633 v.push_back((<Term?> bv).cterm)
1634 if grammar is None:
1635 term.cterm = self.csolver.synthFun(symbol.encode(), <const vector[c_Term]&> v, sort.csort)
1636 else:
1637 term.cterm = self.csolver.synthFun(symbol.encode(), <const vector[c_Term]&> v, sort.csort, grammar.cgrammar)
1638 return term
1639
1640 def checkSynth(self):
1641 """
1642 Try to find a solution for the synthesis conjecture corresponding to the
1643 current list of functions-to-synthesize, universal variables and
1644 constraints.
1645
1646 SyGuS v2:
1647
1648 .. code-block:: smtlib
1649
1650 ( check-synth )
1651
1652 :return: the result of the synthesis conjecture.
1653 """
1654 cdef Result r = Result()
1655 r.cr = self.csolver.checkSynth()
1656 return r
1657
1658 def getSynthSolution(self, Term term):
1659 """
1660 Get the synthesis solution of the given term. This method should be
1661 called immediately after the solver answers unsat for sygus input.
1662
1663 :param term: the term for which the synthesis solution is queried
1664 :return: the synthesis solution of the given term
1665 """
1666 cdef Term t = Term(self)
1667 t.cterm = self.csolver.getSynthSolution(term.cterm)
1668 return t
1669
1670 def getSynthSolutions(self, list terms):
1671 """
1672 Get the synthesis solutions of the given terms. This method should be
1673 called immediately after the solver answers unsat for sygus input.
1674
1675 :param terms: the terms for which the synthesis solutions is queried
1676 :return: the synthesis solutions of the given terms
1677 """
1678 result = []
1679 cdef vector[c_Term] vec
1680 for t in terms:
1681 vec.push_back((<Term?> t).cterm)
1682 cresult = self.csolver.getSynthSolutions(vec)
1683 for s in cresult:
1684 term = Term(self)
1685 term.cterm = s
1686 result.append(term)
1687 return result
1688
1689
1690 def synthInv(self, symbol, bound_vars, Grammar grammar=None):
1691 """
1692 Synthesize invariant.
1693
1694 SyGuS v2:
1695
1696 .. code-block:: smtlib
1697
1698 ( synth-inv <symbol> ( <boundVars>* ) <grammar> )
1699
1700 :param symbol: the name of the invariant
1701 :param boundVars: the parameters to this invariant
1702 :param grammar: the syntactic constraints
1703 :return: the invariant
1704 """
1705 cdef Term term = Term(self)
1706 cdef vector[c_Term] v
1707 for bv in bound_vars:
1708 v.push_back((<Term?> bv).cterm)
1709 if grammar is None:
1710 term.cterm = self.csolver.synthInv(symbol.encode(), <const vector[c_Term]&> v)
1711 else:
1712 term.cterm = self.csolver.synthInv(symbol.encode(), <const vector[c_Term]&> v, grammar.cgrammar)
1713 return term
1714
1715 @expand_list_arg(num_req_args=0)
1716 def checkSatAssuming(self, *assumptions):
1717 """ Check satisfiability assuming the given formula.
1718
1719 SMT-LIB:
1720
1721 .. code-block:: smtlib
1722
1723 ( check-sat-assuming ( <prop_literal> ) )
1724
1725 :param assumptions: the formulas to assume, as a list or as distinct arguments
1726 :return: the result of the satisfiability check.
1727 """
1728 cdef Result r = Result()
1729 # used if assumptions is a list of terms
1730 cdef vector[c_Term] v
1731 for a in assumptions:
1732 v.push_back((<Term?> a).cterm)
1733 r.cr = self.csolver.checkSatAssuming(<const vector[c_Term]&> v)
1734 return r
1735
1736 @expand_list_arg(num_req_args=0)
1737 def checkEntailed(self, *assumptions):
1738 """Check entailment of the given formula w.r.t. the current set of assertions.
1739
1740 :param terms: the formulas to check entailment for, as a list or as distinct arguments
1741 :return: the result of the entailment check.
1742 """
1743 cdef Result r = Result()
1744 # used if assumptions is a list of terms
1745 cdef vector[c_Term] v
1746 for a in assumptions:
1747 v.push_back((<Term?> a).cterm)
1748 r.cr = self.csolver.checkEntailed(<const vector[c_Term]&> v)
1749 return r
1750
1751 @expand_list_arg(num_req_args=1)
1752 def declareDatatype(self, str symbol, *ctors):
1753 """
1754 Create datatype sort.
1755
1756 SMT-LIB:
1757
1758 .. code-block:: smtlib
1759
1760 ( declare-datatype <symbol> <datatype_decl> )
1761
1762 :param symbol: the name of the datatype sort
1763 :param ctors: the constructor declarations of the datatype sort, as a list or as distinct arguments
1764 :return: the datatype sort
1765 """
1766 cdef Sort sort = Sort(self)
1767 cdef vector[c_DatatypeConstructorDecl] v
1768
1769 for c in ctors:
1770 v.push_back((<DatatypeConstructorDecl?> c).cddc)
1771 sort.csort = self.csolver.declareDatatype(symbol.encode(), v)
1772 return sort
1773
1774 def declareFun(self, str symbol, list sorts, Sort sort):
1775 """Declare n-ary function symbol.
1776
1777 SMT-LIB:
1778
1779 .. code-block:: smtlib
1780
1781 ( declare-fun <symbol> ( <sort>* ) <sort> )
1782
1783 :param symbol: the name of the function
1784 :param sorts: the sorts of the parameters to this function
1785 :param sort: the sort of the return value of this function
1786 :return: the function
1787 """
1788 cdef Term term = Term(self)
1789 cdef vector[c_Sort] v
1790 for s in sorts:
1791 v.push_back((<Sort?> s).csort)
1792 term.cterm = self.csolver.declareFun(symbol.encode(),
1793 <const vector[c_Sort]&> v,
1794 sort.csort)
1795 return term
1796
1797 def declareSort(self, str symbol, int arity):
1798 """Declare uninterpreted sort.
1799
1800 SMT-LIB:
1801
1802 .. code-block:: smtlib
1803
1804 ( declare-sort <symbol> <numeral> )
1805
1806 :param symbol: the name of the sort
1807 :param arity: the arity of the sort
1808 :return: the sort
1809 """
1810 cdef Sort sort = Sort(self)
1811 sort.csort = self.csolver.declareSort(symbol.encode(), arity)
1812 return sort
1813
1814 def defineFun(self, sym_or_fun, bound_vars, sort_or_term, t=None, glbl=False):
1815 """
1816 Define n-ary function.
1817 Supports two uses:
1818
1819 - ``Term defineFun(str symbol, List[Term] bound_vars, Sort sort, Term term, bool glbl)``
1820 - ``Term defineFun(Term fun, List[Term] bound_vars, Term term, bool glbl)``
1821
1822
1823 SMT-LIB:
1824
1825 .. code-block:: smtlib
1826
1827 ( define-fun <function_def> )
1828
1829 :param symbol: the name of the function
1830 :param bound_vars: the parameters to this function
1831 :param sort: the sort of the return value of this function
1832 :param term: the function body
1833 :param global: determines whether this definition is global (i.e. persists when popping the context)
1834 :return: the function
1835 """
1836 cdef Term term = Term(self)
1837 cdef vector[c_Term] v
1838 for bv in bound_vars:
1839 v.push_back((<Term?> bv).cterm)
1840
1841 if t is not None:
1842 term.cterm = self.csolver.defineFun((<str?> sym_or_fun).encode(),
1843 <const vector[c_Term] &> v,
1844 (<Sort?> sort_or_term).csort,
1845 (<Term?> t).cterm,
1846 <bint> glbl)
1847 else:
1848 term.cterm = self.csolver.defineFun((<Term?> sym_or_fun).cterm,
1849 <const vector[c_Term]&> v,
1850 (<Term?> sort_or_term).cterm,
1851 <bint> glbl)
1852
1853 return term
1854
1855 def defineFunRec(self, sym_or_fun, bound_vars, sort_or_term, t=None, glbl=False):
1856 """Define recursive functions.
1857
1858 Supports two uses:
1859
1860 - ``Term defineFunRec(str symbol, List[Term] bound_vars, Sort sort, Term term, bool glbl)``
1861 - ``Term defineFunRec(Term fun, List[Term] bound_vars, Term term, bool glbl)``
1862
1863
1864 SMT-LIB:
1865
1866 .. code-block:: smtlib
1867
1868 ( define-funs-rec ( <function_decl>^n ) ( <term>^n ) )
1869
1870 Create elements of parameter ``funs`` with mkConst().
1871
1872 :param funs: the sorted functions
1873 :param bound_vars: the list of parameters to the functions
1874 :param terms: the list of function bodies of the functions
1875 :param global: determines whether this definition is global (i.e. persists when popping the context)
1876 :return: the function
1877 """
1878 cdef Term term = Term(self)
1879 cdef vector[c_Term] v
1880 for bv in bound_vars:
1881 v.push_back((<Term?> bv).cterm)
1882
1883 if t is not None:
1884 term.cterm = self.csolver.defineFunRec((<str?> sym_or_fun).encode(),
1885 <const vector[c_Term] &> v,
1886 (<Sort?> sort_or_term).csort,
1887 (<Term?> t).cterm,
1888 <bint> glbl)
1889 else:
1890 term.cterm = self.csolver.defineFunRec((<Term?> sym_or_fun).cterm,
1891 <const vector[c_Term]&> v,
1892 (<Term?> sort_or_term).cterm,
1893 <bint> glbl)
1894
1895 return term
1896
1897 def defineFunsRec(self, funs, bound_vars, terms):
1898 """Define recursive functions.
1899
1900 SMT-LIB:
1901
1902 .. code-block:: smtlib
1903
1904 ( define-funs-rec ( <function_decl>^n ) ( <term>^n ) )
1905
1906 Create elements of parameter ``funs`` with mkConst().
1907
1908 :param funs: the sorted functions
1909 :param bound_vars: the list of parameters to the functions
1910 :param terms: the list of function bodies of the functions
1911 :param global: determines whether this definition is global (i.e. persists when popping the context)
1912 :return: the function
1913 """
1914 cdef vector[c_Term] vf
1915 cdef vector[vector[c_Term]] vbv
1916 cdef vector[c_Term] vt
1917
1918 for f in funs:
1919 vf.push_back((<Term?> f).cterm)
1920
1921 cdef vector[c_Term] temp
1922 for v in bound_vars:
1923 for t in v:
1924 temp.push_back((<Term?> t).cterm)
1925 vbv.push_back(temp)
1926 temp.clear()
1927
1928 for t in terms:
1929 vf.push_back((<Term?> t).cterm)
1930
1931 def getAssertions(self):
1932 """Get the list of asserted formulas.
1933
1934 SMT-LIB:
1935
1936 .. code-block:: smtlib
1937
1938 ( get-assertions )
1939
1940 :return: the list of asserted formulas
1941 """
1942 assertions = []
1943 for a in self.csolver.getAssertions():
1944 term = Term(self)
1945 term.cterm = a
1946 assertions.append(term)
1947 return assertions
1948
1949 def getInfo(self, str flag):
1950 """Get info from the solver.
1951
1952 SMT-LIB:
1953
1954 .. code-block:: smtlib
1955
1956 ( get-info <info_flag> )
1957
1958 :param flag: the info flag
1959 :return: the info
1960 """
1961 return self.csolver.getInfo(flag.encode())
1962
1963 def getOption(self, str option):
1964 """Get the value of a given option.
1965
1966 SMT-LIB:
1967
1968 .. code-block:: smtlib
1969
1970 ( get-option <keyword> )
1971
1972 :param option: the option for which the value is queried
1973 :return: a string representation of the option value
1974 """
1975 return self.csolver.getOption(option.encode())
1976
1977 def getUnsatAssumptions(self):
1978 """
1979 Get the set of unsat ("failed") assumptions.
1980
1981 SMT-LIB:
1982
1983 .. code-block:: smtlib
1984
1985 ( get-unsat-assumptions )
1986
1987 Requires to enable option :ref:`produce-unsat-assumptions <lbl-option-produce-unsat-assumptions>`.
1988
1989 :return: the set of unsat assumptions.
1990 """
1991 assumptions = []
1992 for a in self.csolver.getUnsatAssumptions():
1993 term = Term(self)
1994 term.cterm = a
1995 assumptions.append(term)
1996 return assumptions
1997
1998 def getUnsatCore(self):
1999 """Get the unsatisfiable core.
2000
2001 SMT-LIB:
2002
2003 .. code-block:: smtlib
2004
2005 ( get-unsat-core )
2006
2007 Requires to enable option :ref:`produce-unsat-cores <lbl-option-produce-unsat-cores>`.
2008
2009 :return: a set of terms representing the unsatisfiable core
2010 """
2011 core = []
2012 for a in self.csolver.getUnsatCore():
2013 term = Term(self)
2014 term.cterm = a
2015 core.append(term)
2016 return core
2017
2018 def getValue(self, Term t):
2019 """Get the value of the given term in the current model.
2020
2021 SMT-LIB:
2022
2023 .. code-block:: smtlib
2024
2025 ( get-value ( <term> ) )
2026
2027 :param term: the term for which the value is queried
2028 :return: the value of the given term
2029 """
2030 cdef Term term = Term(self)
2031 term.cterm = self.csolver.getValue(t.cterm)
2032 return term
2033
2034 def getModelDomainElements(self, Sort s):
2035 """
2036 Get the domain elements of uninterpreted sort s in the current model. The
2037 current model interprets s as the finite sort whose domain elements are
2038 given in the return value of this method.
2039
2040 :param s: The uninterpreted sort in question
2041 :return: the domain elements of s in the current model
2042 """
2043 result = []
2044 cresult = self.csolver.getModelDomainElements(s.csort)
2045 for e in cresult:
2046 term = Term(self)
2047 term.cterm = e
2048 result.append(term)
2049 return result
2050
2051 def isModelCoreSymbol(self, Term v):
2052 """
2053 This returns false if the model value of free constant v was not
2054 essential for showing the satisfiability of the last call to checkSat
2055 using the current model. This method will only return false (for any v)
2056 if the model-cores option has been set.
2057
2058 :param v: The term in question
2059 :return: true if v is a model core symbol
2060 """
2061 return self.csolver.isModelCoreSymbol(v.cterm)
2062
2063 def getSeparationHeap(self):
2064 """When using separation logic, obtain the term for the heap.
2065
2066 :return: The term for the heap
2067 """
2068 cdef Term term = Term(self)
2069 term.cterm = self.csolver.getSeparationHeap()
2070 return term
2071
2072 def getSeparationNilTerm(self):
2073 """When using separation logic, obtain the term for nil.
2074
2075 :return: The term for nil
2076 """
2077 cdef Term term = Term(self)
2078 term.cterm = self.csolver.getSeparationNilTerm()
2079 return term
2080
2081 def declareSeparationHeap(self, Sort locType, Sort dataType):
2082 """
2083 When using separation logic, this sets the location sort and the
2084 datatype sort to the given ones. This method should be invoked exactly
2085 once, before any separation logic constraints are provided.
2086
2087 :param locSort: The location sort of the heap
2088 :param dataSort: The data sort of the heap
2089 """
2090 self.csolver.declareSeparationHeap(locType.csort, dataType.csort)
2091
2092 def declarePool(self, str symbol, Sort sort, initValue):
2093 """Declare a symbolic pool of terms with the given initial value.
2094
2095 SMT-LIB:
2096
2097 .. code-block:: smtlib
2098
2099 ( declare-pool <symbol> <sort> ( <term>* ) )
2100
2101 :param symbol: The name of the pool
2102 :param sort: The sort of the elements of the pool.
2103 :param initValue: The initial value of the pool
2104 """
2105 cdef Term term = Term(self)
2106 cdef vector[c_Term] niv
2107 for v in initValue:
2108 niv.push_back((<Term?> v).cterm)
2109 term.cterm = self.csolver.declarePool(symbol.encode(), sort.csort, niv)
2110 return term
2111
2112 def pop(self, nscopes=1):
2113 """Pop ``nscopes`` level(s) from the assertion stack.
2114
2115 SMT-LIB:
2116
2117 .. code-block:: smtlib
2118
2119 ( pop <numeral> )
2120
2121 :param nscopes: the number of levels to pop
2122 """
2123 self.csolver.pop(nscopes)
2124
2125 def push(self, nscopes=1):
2126 """ Push ``nscopes`` level(s) to the assertion stack.
2127
2128 SMT-LIB:
2129
2130 .. code-block:: smtlib
2131
2132 ( push <numeral> )
2133
2134 :param nscopes: the number of levels to push
2135 """
2136 self.csolver.push(nscopes)
2137
2138 def resetAssertions(self):
2139 """
2140 Remove all assertions.
2141
2142 SMT-LIB:
2143
2144 .. code-block:: smtlib
2145
2146 ( reset-assertions )
2147
2148 """
2149 self.csolver.resetAssertions()
2150
2151 def setInfo(self, str keyword, str value):
2152 """Set info.
2153
2154 SMT-LIB:
2155
2156 .. code-block:: smtlib
2157
2158 ( set-info <attribute> )
2159
2160 :param keyword: the info flag
2161 :param value: the value of the info flag
2162 """
2163 self.csolver.setInfo(keyword.encode(), value.encode())
2164
2165 def setLogic(self, str logic):
2166 """Set logic.
2167
2168 SMT-LIB:
2169
2170 .. code-block:: smtlib
2171
2172 ( set-logic <symbol> )
2173
2174 :param logic: the logic to set
2175 """
2176 self.csolver.setLogic(logic.encode())
2177
2178 def setOption(self, str option, str value):
2179 """Set option.
2180
2181 SMT-LIB:
2182
2183 .. code-block:: smtlib
2184
2185 ( set-option <option> )
2186
2187 :param option: the option name
2188 :param value: the option value
2189 """
2190 self.csolver.setOption(option.encode(), value.encode())
2191
2192
2193 cdef class Sort:
2194 """
2195 The sort of a cvc5 term.
2196 """
2197 cdef c_Sort csort
2198 cdef Solver solver
2199 def __cinit__(self, Solver solver):
2200 # csort always set by Solver
2201 self.solver = solver
2202
2203 def __eq__(self, Sort other):
2204 return self.csort == other.csort
2205
2206 def __ne__(self, Sort other):
2207 return self.csort != other.csort
2208
2209 def __lt__(self, Sort other):
2210 return self.csort < other.csort
2211
2212 def __gt__(self, Sort other):
2213 return self.csort > other.csort
2214
2215 def __le__(self, Sort other):
2216 return self.csort <= other.csort
2217
2218 def __ge__(self, Sort other):
2219 return self.csort >= other.csort
2220
2221 def __str__(self):
2222 return self.csort.toString().decode()
2223
2224 def __repr__(self):
2225 return self.csort.toString().decode()
2226
2227 def __hash__(self):
2228 return csorthash(self.csort)
2229
2230 def isNull(self):
2231 """:return: True if this Sort is a null sort."""
2232 return self.csort.isNull()
2233
2234 def isBoolean(self):
2235 """
2236 Is this a Boolean sort?
2237
2238 :return: True if the sort is the Boolean sort.
2239 """
2240 return self.csort.isBoolean()
2241
2242 def isInteger(self):
2243 """
2244 Is this an integer sort?
2245
2246 :return: True if the sort is the integer sort.
2247 """
2248 return self.csort.isInteger()
2249
2250 def isReal(self):
2251 """
2252 Is this a real sort?
2253
2254 :return: True if the sort is the real sort.
2255 """
2256 return self.csort.isReal()
2257
2258 def isString(self):
2259 """
2260 Is this a string sort?
2261
2262 :return: True if the sort is the string sort.
2263 """
2264 return self.csort.isString()
2265
2266 def isRegExp(self):
2267 """
2268 Is this a regexp sort?
2269
2270 :return: True if the sort is the regexp sort.
2271 """
2272 return self.csort.isRegExp()
2273
2274 def isRoundingMode(self):
2275 """
2276 Is this a rounding mode sort?
2277
2278 :return: True if the sort is the rounding mode sort.
2279 """
2280 return self.csort.isRoundingMode()
2281
2282 def isBitVector(self):
2283 """
2284 Is this a bit-vector sort?
2285
2286 :return: True if the sort is a bit-vector sort.
2287 """
2288 return self.csort.isBitVector()
2289
2290 def isFloatingPoint(self):
2291 """
2292 Is this a floating-point sort?
2293
2294 :return: True if the sort is a bit-vector sort.
2295 """
2296 return self.csort.isFloatingPoint()
2297
2298 def isDatatype(self):
2299 """
2300 Is this a datatype sort?
2301
2302 :return: True if the sort is a datatype sort.
2303 """
2304 return self.csort.isDatatype()
2305
2306 def isParametricDatatype(self):
2307 """
2308 Is this a parametric datatype sort?
2309
2310 :return: True if the sort is a parametric datatype sort.
2311 """
2312 return self.csort.isParametricDatatype()
2313
2314 def isConstructor(self):
2315 """
2316 Is this a constructor sort?
2317
2318 :return: True if the sort is a constructor sort.
2319 """
2320 return self.csort.isConstructor()
2321
2322 def isSelector(self):
2323 """
2324 Is this a selector sort?
2325
2326 :return: True if the sort is a selector sort.
2327 """
2328 return self.csort.isSelector()
2329
2330 def isTester(self):
2331 """
2332 Is this a tester sort?
2333
2334 :return: True if the sort is a selector sort.
2335 """
2336 return self.csort.isTester()
2337
2338 def isUpdater(self):
2339 """
2340 Is this a datatype updater sort?
2341
2342 :return: True if the sort is a datatype updater sort.
2343 """
2344 return self.csort.isUpdater()
2345
2346 def isFunction(self):
2347 """
2348 Is this a function sort?
2349
2350 :return: True if the sort is a function sort.
2351 """
2352 return self.csort.isFunction()
2353
2354 def isPredicate(self):
2355 """
2356 Is this a predicate sort?
2357 That is, is this a function sort mapping to Boolean? All predicate
2358 sorts are also function sorts.
2359
2360 :return: True if the sort is a predicate sort.
2361 """
2362 return self.csort.isPredicate()
2363
2364 def isTuple(self):
2365 """
2366 Is this a tuple sort?
2367
2368 :return: True if the sort is a tuple sort.
2369 """
2370 return self.csort.isTuple()
2371
2372 def isRecord(self):
2373 """
2374 Is this a record sort?
2375
2376 :return: True if the sort is a record sort.
2377 """
2378 return self.csort.isRecord()
2379
2380 def isArray(self):
2381 """
2382 Is this an array sort?
2383
2384 :return: True if the sort is an array sort.
2385 """
2386 return self.csort.isArray()
2387
2388 def isSet(self):
2389 """
2390 Is this a set sort?
2391
2392 :return: True if the sort is a set sort.
2393 """
2394 return self.csort.isSet()
2395
2396 def isBag(self):
2397 """
2398 Is this a bag sort?
2399
2400 :return: True if the sort is a bag sort.
2401 """
2402 return self.csort.isBag()
2403
2404 def isSequence(self):
2405 """
2406 Is this a sequence sort?
2407
2408 :return: True if the sort is a sequence sort.
2409 """
2410 return self.csort.isSequence()
2411
2412 def isUninterpretedSort(self):
2413 """
2414 Is this a sort uninterpreted?
2415
2416 :return: True if the sort is uninterpreted.
2417 """
2418 return self.csort.isUninterpretedSort()
2419
2420 def isSortConstructor(self):
2421 """
2422 Is this a sort constructor kind?
2423
2424 :return: True if this a sort constructor kind.
2425 """
2426 return self.csort.isSortConstructor()
2427
2428 def isFirstClass(self):
2429 """
2430 Is this a first-class sort?
2431 First-class sorts are sorts for which:
2432
2433 1. we handle equalities between terms of that type, and
2434 2. they are allowed to be parameters of parametric sorts
2435 (e.g. index or element sorts of arrays).
2436
2437 Examples of sorts that are not first-class include sort constructor
2438 sorts and regular expression sorts.
2439
2440 :return: True if the sort is a first-class sort.
2441 """
2442 return self.csort.isFirstClass()
2443
2444 def isFunctionLike(self):
2445 """
2446 Is this a function-LIKE sort?
2447
2448 Anything function-like except arrays (e.g., datatype selectors) is
2449 considered a function here. Function-like terms can not be the argument
2450 or return value for any term that is function-like.
2451 This is mainly to avoid higher order.
2452
2453 Note that arrays are explicitly not considered function-like here.
2454
2455 :return: True if this is a function-like sort
2456 """
2457 return self.csort.isFunctionLike()
2458
2459 def isSubsortOf(self, Sort sort):
2460 """
2461 Is this sort a subsort of the given sort?
2462
2463 :return: True if this sort is a subsort of s
2464 """
2465 return self.csort.isSubsortOf(sort.csort)
2466
2467 def isComparableTo(self, Sort sort):
2468 """
2469 Is this sort comparable to the given sort
2470 (i.e., do they share a common ancestor in the subsort tree)?
2471
2472 :return: True if this sort is comparable to s
2473 """
2474 return self.csort.isComparableTo(sort.csort)
2475
2476 def getDatatype(self):
2477 """
2478 :return: the underlying datatype of a datatype sort
2479 """
2480 cdef Datatype d = Datatype(self.solver)
2481 d.cd = self.csort.getDatatype()
2482 return d
2483
2484 def instantiate(self, params):
2485 """
2486 Instantiate a parameterized datatype/sort sort.
2487 Create sorts parameter with :py:meth:`Solver.mkParamSort()`
2488
2489 :param params: the list of sort parameters to instantiate with
2490 """
2491 cdef Sort sort = Sort(self.solver)
2492 cdef vector[c_Sort] v
2493 for s in params:
2494 v.push_back((<Sort?> s).csort)
2495 sort.csort = self.csort.instantiate(v)
2496 return sort
2497
2498 def substitute(self, sort_or_list_1, sort_or_list_2):
2499 """
2500 Substitution of Sorts.
2501
2502 :param sort_or_list_1: the subsort or subsorts to be substituted within this sort.
2503 :param sort_or_list_2: the sort or list of sorts replacing the substituted subsort.
2504 """
2505
2506 # The resulting sort after substitution
2507 cdef Sort sort = Sort(self.solver)
2508 # lists for substitutions
2509 cdef vector[c_Sort] ces
2510 cdef vector[c_Sort] creplacements
2511
2512 # normalize the input parameters to be lists
2513 if isinstance(sort_or_list_1, list):
2514 assert isinstance(sort_or_list_2, list)
2515 es = sort_or_list_1
2516 replacements = sort_or_list_2
2517 if len(es) != len(replacements):
2518 raise RuntimeError("Expecting list inputs to substitute to "
2519 "have the same length but got: "
2520 "{} and {}".format(len(es), len(replacements)))
2521
2522 for e, r in zip(es, replacements):
2523 ces.push_back((<Sort?> e).csort)
2524 creplacements.push_back((<Sort?> r).csort)
2525
2526 else:
2527 # add the single elements to the vectors
2528 ces.push_back((<Sort?> sort_or_list_1).csort)
2529 creplacements.push_back((<Sort?> sort_or_list_2).csort)
2530
2531 # call the API substitute method with lists
2532 sort.csort = self.csort.substitute(ces, creplacements)
2533 return sort
2534
2535
2536 def getConstructorArity(self):
2537 """
2538 :return: the arity of a constructor sort.
2539 """
2540 return self.csort.getConstructorArity()
2541
2542 def getConstructorDomainSorts(self):
2543 """
2544 :return: the domain sorts of a constructor sort
2545 """
2546 domain_sorts = []
2547 for s in self.csort.getConstructorDomainSorts():
2548 sort = Sort(self.solver)
2549 sort.csort = s
2550 domain_sorts.append(sort)
2551 return domain_sorts
2552
2553 def getConstructorCodomainSort(self):
2554 """
2555 :return: the codomain sort of a constructor sort
2556 """
2557 cdef Sort sort = Sort(self.solver)
2558 sort.csort = self.csort.getConstructorCodomainSort()
2559 return sort
2560
2561 def getSelectorDomainSort(self):
2562 """
2563 :return: the domain sort of a selector sort
2564 """
2565 cdef Sort sort = Sort(self.solver)
2566 sort.csort = self.csort.getSelectorDomainSort()
2567 return sort
2568
2569 def getSelectorCodomainSort(self):
2570 """
2571 :return: the codomain sort of a selector sort
2572 """
2573 cdef Sort sort = Sort(self.solver)
2574 sort.csort = self.csort.getSelectorCodomainSort()
2575 return sort
2576
2577 def getTesterDomainSort(self):
2578 """
2579 :return: the domain sort of a tester sort
2580 """
2581 cdef Sort sort = Sort(self.solver)
2582 sort.csort = self.csort.getTesterDomainSort()
2583 return sort
2584
2585 def getTesterCodomainSort(self):
2586 """
2587 :return: the codomain sort of a tester sort, which is the Boolean sort
2588 """
2589 cdef Sort sort = Sort(self.solver)
2590 sort.csort = self.csort.getTesterCodomainSort()
2591 return sort
2592
2593 def getFunctionArity(self):
2594 """
2595 :return: the arity of a function sort
2596 """
2597 return self.csort.getFunctionArity()
2598
2599 def getFunctionDomainSorts(self):
2600 """
2601 :return: the domain sorts of a function sort
2602 """
2603 domain_sorts = []
2604 for s in self.csort.getFunctionDomainSorts():
2605 sort = Sort(self.solver)
2606 sort.csort = s
2607 domain_sorts.append(sort)
2608 return domain_sorts
2609
2610 def getFunctionCodomainSort(self):
2611 """
2612 :return: the codomain sort of a function sort
2613 """
2614 cdef Sort sort = Sort(self.solver)
2615 sort.csort = self.csort.getFunctionCodomainSort()
2616 return sort
2617
2618 def getArrayIndexSort(self):
2619 """
2620 :return: the array index sort of an array sort
2621 """
2622 cdef Sort sort = Sort(self.solver)
2623 sort.csort = self.csort.getArrayIndexSort()
2624 return sort
2625
2626 def getArrayElementSort(self):
2627 """
2628 :return: the array element sort of an array sort
2629 """
2630 cdef Sort sort = Sort(self.solver)
2631 sort.csort = self.csort.getArrayElementSort()
2632 return sort
2633
2634 def getSetElementSort(self):
2635 """
2636 :return: the element sort of a set sort
2637 """
2638 cdef Sort sort = Sort(self.solver)
2639 sort.csort = self.csort.getSetElementSort()
2640 return sort
2641
2642 def getBagElementSort(self):
2643 """
2644 :return: the element sort of a bag sort
2645 """
2646 cdef Sort sort = Sort(self.solver)
2647 sort.csort = self.csort.getBagElementSort()
2648 return sort
2649
2650 def getSequenceElementSort(self):
2651 """
2652 :return: the element sort of a sequence sort
2653 """
2654 cdef Sort sort = Sort(self.solver)
2655 sort.csort = self.csort.getSequenceElementSort()
2656 return sort
2657
2658 def getUninterpretedSortName(self):
2659 """
2660 :return: the name of an uninterpreted sort
2661 """
2662 return self.csort.getUninterpretedSortName().decode()
2663
2664 def isUninterpretedSortParameterized(self):
2665 """
2666 :return: True if an uninterpreted sort is parameterized
2667 """
2668 return self.csort.isUninterpretedSortParameterized()
2669
2670 def getUninterpretedSortParamSorts(self):
2671 """
2672 :return: the parameter sorts of an uninterpreted sort
2673 """
2674 param_sorts = []
2675 for s in self.csort.getUninterpretedSortParamSorts():
2676 sort = Sort(self.solver)
2677 sort.csort = s
2678 param_sorts.append(sort)
2679 return param_sorts
2680
2681 def getSortConstructorName(self):
2682 """
2683 :return: the name of a sort constructor sort
2684 """
2685 return self.csort.getSortConstructorName().decode()
2686
2687 def getSortConstructorArity(self):
2688 """
2689 :return: the arity of a sort constructor sort
2690 """
2691 return self.csort.getSortConstructorArity()
2692
2693 def getBitVectorSize(self):
2694 """
2695 :return: the bit-width of the bit-vector sort
2696 """
2697 return self.csort.getBitVectorSize()
2698
2699 def getFloatingPointExponentSize(self):
2700 """
2701 :return: the bit-width of the exponent of the floating-point sort
2702 """
2703 return self.csort.getFloatingPointExponentSize()
2704
2705 def getFloatingPointSignificandSize(self):
2706 """
2707 :return: the width of the significand of the floating-point sort
2708 """
2709 return self.csort.getFloatingPointSignificandSize()
2710
2711 def getDatatypeParamSorts(self):
2712 """
2713 :return: the parameter sorts of a datatype sort
2714 """
2715 param_sorts = []
2716 for s in self.csort.getDatatypeParamSorts():
2717 sort = Sort(self.solver)
2718 sort.csort = s
2719 param_sorts.append(sort)
2720 return param_sorts
2721
2722 def getDatatypeArity(self):
2723 """
2724 :return: the arity of a datatype sort
2725 """
2726 return self.csort.getDatatypeArity()
2727
2728 def getTupleLength(self):
2729 """
2730 :return: the length of a tuple sort
2731 """
2732 return self.csort.getTupleLength()
2733
2734 def getTupleSorts(self):
2735 """
2736 :return: the element sorts of a tuple sort
2737 """
2738 tuple_sorts = []
2739 for s in self.csort.getTupleSorts():
2740 sort = Sort(self.solver)
2741 sort.csort = s
2742 tuple_sorts.append(sort)
2743 return tuple_sorts
2744
2745
2746 cdef class Term:
2747 cdef c_Term cterm
2748 cdef Solver solver
2749 def __cinit__(self, Solver solver):
2750 # cterm always set in the Solver object
2751 self.solver = solver
2752
2753 def __eq__(self, Term other):
2754 return self.cterm == other.cterm
2755
2756 def __ne__(self, Term other):
2757 return self.cterm != other.cterm
2758
2759 def __lt__(self, Term other):
2760 return self.cterm < other.cterm
2761
2762 def __gt__(self, Term other):
2763 return self.cterm > other.cterm
2764
2765 def __le__(self, Term other):
2766 return self.cterm <= other.cterm
2767
2768 def __ge__(self, Term other):
2769 return self.cterm >= other.cterm
2770
2771 def __getitem__(self, int index):
2772 cdef Term term = Term(self.solver)
2773 if index >= 0:
2774 term.cterm = self.cterm[index]
2775 else:
2776 raise ValueError("Expecting a non-negative integer or string")
2777 return term
2778
2779 def __str__(self):
2780 return self.cterm.toString().decode()
2781
2782 def __repr__(self):
2783 return self.cterm.toString().decode()
2784
2785 def __iter__(self):
2786 for ci in self.cterm:
2787 term = Term(self.solver)
2788 term.cterm = ci
2789 yield term
2790
2791 def __hash__(self):
2792 return ctermhash(self.cterm)
2793
2794 def getNumChildren(self):
2795 return self.cterm.getNumChildren()
2796
2797 def getId(self):
2798 return self.cterm.getId()
2799
2800 def getKind(self):
2801 return kind(<int> self.cterm.getKind())
2802
2803 def getSort(self):
2804 cdef Sort sort = Sort(self.solver)
2805 sort.csort = self.cterm.getSort()
2806 return sort
2807
2808 def substitute(self, term_or_list_1, term_or_list_2):
2809 # The resulting term after substitution
2810 cdef Term term = Term(self.solver)
2811 # lists for substitutions
2812 cdef vector[c_Term] ces
2813 cdef vector[c_Term] creplacements
2814
2815 # normalize the input parameters to be lists
2816 if isinstance(term_or_list_1, list):
2817 assert isinstance(term_or_list_2, list)
2818 es = term_or_list_1
2819 replacements = term_or_list_2
2820 if len(es) != len(replacements):
2821 raise RuntimeError("Expecting list inputs to substitute to "
2822 "have the same length but got: "
2823 "{} and {}".format(len(es), len(replacements)))
2824
2825 for e, r in zip(es, replacements):
2826 ces.push_back((<Term?> e).cterm)
2827 creplacements.push_back((<Term?> r).cterm)
2828
2829 else:
2830 # add the single elements to the vectors
2831 ces.push_back((<Term?> term_or_list_1).cterm)
2832 creplacements.push_back((<Term?> term_or_list_2).cterm)
2833
2834 # call the API substitute method with lists
2835 term.cterm = self.cterm.substitute(ces, creplacements)
2836 return term
2837
2838 def hasOp(self):
2839 return self.cterm.hasOp()
2840
2841 def getOp(self):
2842 cdef Op op = Op(self.solver)
2843 op.cop = self.cterm.getOp()
2844 return op
2845
2846 def isNull(self):
2847 return self.cterm.isNull()
2848
2849 def notTerm(self):
2850 cdef Term term = Term(self.solver)
2851 term.cterm = self.cterm.notTerm()
2852 return term
2853
2854 def andTerm(self, Term t):
2855 cdef Term term = Term(self.solver)
2856 term.cterm = self.cterm.andTerm((<Term> t).cterm)
2857 return term
2858
2859 def orTerm(self, Term t):
2860 cdef Term term = Term(self.solver)
2861 term.cterm = self.cterm.orTerm(t.cterm)
2862 return term
2863
2864 def xorTerm(self, Term t):
2865 cdef Term term = Term(self.solver)
2866 term.cterm = self.cterm.xorTerm(t.cterm)
2867 return term
2868
2869 def eqTerm(self, Term t):
2870 cdef Term term = Term(self.solver)
2871 term.cterm = self.cterm.eqTerm(t.cterm)
2872 return term
2873
2874 def impTerm(self, Term t):
2875 cdef Term term = Term(self.solver)
2876 term.cterm = self.cterm.impTerm(t.cterm)
2877 return term
2878
2879 def iteTerm(self, Term then_t, Term else_t):
2880 cdef Term term = Term(self.solver)
2881 term.cterm = self.cterm.iteTerm(then_t.cterm, else_t.cterm)
2882 return term
2883
2884 def isConstArray(self):
2885 return self.cterm.isConstArray()
2886
2887 def getConstArrayBase(self):
2888 cdef Term term = Term(self.solver)
2889 term.cterm = self.cterm.getConstArrayBase()
2890 return term
2891
2892 def isBooleanValue(self):
2893 return self.cterm.isBooleanValue()
2894
2895 def getBooleanValue(self):
2896 return self.cterm.getBooleanValue()
2897
2898 def isStringValue(self):
2899 return self.cterm.isStringValue()
2900
2901 def getStringValue(self):
2902 cdef Py_ssize_t size
2903 cdef c_wstring s = self.cterm.getStringValue()
2904 return PyUnicode_FromWideChar(s.data(), s.size())
2905
2906 def isIntegerValue(self):
2907 return self.cterm.isIntegerValue()
2908 def isAbstractValue(self):
2909 return self.cterm.isAbstractValue()
2910
2911 def getAbstractValue(self):
2912 return self.cterm.getAbstractValue().decode()
2913
2914 def isFloatingPointPosZero(self):
2915 return self.cterm.isFloatingPointPosZero()
2916
2917 def isFloatingPointNegZero(self):
2918 return self.cterm.isFloatingPointNegZero()
2919
2920 def isFloatingPointPosInf(self):
2921 return self.cterm.isFloatingPointPosInf()
2922
2923 def isFloatingPointNegInf(self):
2924 return self.cterm.isFloatingPointNegInf()
2925
2926 def isFloatingPointNaN(self):
2927 return self.cterm.isFloatingPointNaN()
2928
2929 def isFloatingPointValue(self):
2930 return self.cterm.isFloatingPointValue()
2931
2932 def getFloatingPointValue(self):
2933 cdef c_tuple[uint32_t, uint32_t, c_Term] t = self.cterm.getFloatingPointValue()
2934 cdef Term term = Term(self.solver)
2935 term.cterm = get2(t)
2936 return (get0(t), get1(t), term)
2937
2938 def isSetValue(self):
2939 return self.cterm.isSetValue()
2940
2941 def getSetValue(self):
2942 elems = set()
2943 for e in self.cterm.getSetValue():
2944 term = Term(self.solver)
2945 term.cterm = e
2946 elems.add(term)
2947 return elems
2948
2949 def isSequenceValue(self):
2950 return self.cterm.isSequenceValue()
2951
2952 def getSequenceValue(self):
2953 elems = []
2954 for e in self.cterm.getSequenceValue():
2955 term = Term(self.solver)
2956 term.cterm = e
2957 elems.append(term)
2958 return elems
2959
2960 def isUninterpretedValue(self):
2961 return self.cterm.isUninterpretedValue()
2962
2963 def getUninterpretedValue(self):
2964 cdef pair[c_Sort, int32_t] p = self.cterm.getUninterpretedValue()
2965 cdef Sort sort = Sort(self.solver)
2966 sort.csort = p.first
2967 i = p.second
2968 return (sort, i)
2969
2970 def isTupleValue(self):
2971 return self.cterm.isTupleValue()
2972
2973 def getTupleValue(self):
2974 elems = []
2975 for e in self.cterm.getTupleValue():
2976 term = Term(self.solver)
2977 term.cterm = e
2978 elems.append(term)
2979 return elems
2980
2981 def getIntegerValue(self):
2982 return int(self.cterm.getIntegerValue().decode())
2983
2984 def isRealValue(self):
2985 return self.cterm.isRealValue()
2986
2987 def getRealValue(self):
2988 """Returns the value of a real term as a Fraction"""
2989 return Fraction(self.cterm.getRealValue().decode())
2990
2991 def isBitVectorValue(self):
2992 return self.cterm.isBitVectorValue()
2993
2994 def getBitVectorValue(self, base = 2):
2995 """Returns the value of a bit-vector term as a 0/1 string"""
2996 return self.cterm.getBitVectorValue(base).decode()
2997
2998 def toPythonObj(self):
2999 """
3000 Converts a constant value Term to a Python object.
3001
3002 Currently supports:
3003 Boolean -- returns a Python bool
3004 Int -- returns a Python int
3005 Real -- returns a Python Fraction
3006 BV -- returns a Python int (treats BV as unsigned)
3007 String -- returns a Python Unicode string
3008 Array -- returns a Python dict mapping indices to values
3009 -- the constant base is returned as the default value
3010 """
3011
3012 if self.isBooleanValue():
3013 return self.getBooleanValue()
3014 elif self.isIntegerValue():
3015 return self.getIntegerValue()
3016 elif self.isRealValue():
3017 return self.getRealValue()
3018 elif self.isBitVectorValue():
3019 return int(self.getBitVectorValue(), 2)
3020 elif self.isStringValue():
3021 return self.getStringValue()
3022 elif self.getSort().isArray():
3023 res = None
3024 keys = []
3025 values = []
3026 base_value = None
3027 to_visit = [self]
3028 # Array models are represented as a series of store operations
3029 # on a constant array
3030 while to_visit:
3031 t = to_visit.pop()
3032 if t.getKind() == kinds.Store:
3033 # save the mappings
3034 keys.append(t[1].toPythonObj())
3035 values.append(t[2].toPythonObj())
3036 to_visit.append(t[0])
3037 else:
3038 assert t.getKind() == kinds.ConstArray
3039 base_value = t.getConstArrayBase().toPythonObj()
3040
3041 assert len(keys) == len(values)
3042 assert base_value is not None
3043
3044 # put everything in a dictionary with the constant
3045 # base as the result for any index not included in the stores
3046 res = defaultdict(lambda : base_value)
3047 for k, v in zip(keys, values):
3048 res[k] = v
3049
3050 return res
3051
3052
3053 # Generate rounding modes
3054 cdef __rounding_modes = {
3055 <int> ROUND_NEAREST_TIES_TO_EVEN: "RoundNearestTiesToEven",
3056 <int> ROUND_TOWARD_POSITIVE: "RoundTowardPositive",
3057 <int> ROUND_TOWARD_NEGATIVE: "RoundTowardNegative",
3058 <int> ROUND_TOWARD_ZERO: "RoundTowardZero",
3059 <int> ROUND_NEAREST_TIES_TO_AWAY: "RoundNearestTiesToAway"
3060 }
3061
3062 mod_ref = sys.modules[__name__]
3063 for rm_int, name in __rounding_modes.items():
3064 r = RoundingMode(rm_int)
3065
3066 if name in dir(mod_ref):
3067 raise RuntimeError("Redefinition of Python RoundingMode %s."%name)
3068
3069 setattr(mod_ref, name, r)
3070
3071 del r
3072 del rm_int
3073 del name
3074
3075
3076 # Generate unknown explanations
3077 cdef __unknown_explanations = {
3078 <int> REQUIRES_FULL_CHECK: "RequiresFullCheck",
3079 <int> INCOMPLETE: "Incomplete",
3080 <int> TIMEOUT: "Timeout",
3081 <int> RESOURCEOUT: "Resourceout",
3082 <int> MEMOUT: "Memout",
3083 <int> INTERRUPTED: "Interrupted",
3084 <int> NO_STATUS: "NoStatus",
3085 <int> UNSUPPORTED: "Unsupported",
3086 <int> OTHER: "Other",
3087 <int> UNKNOWN_REASON: "UnknownReason"
3088 }
3089
3090 for ue_int, name in __unknown_explanations.items():
3091 u = UnknownExplanation(ue_int)
3092
3093 if name in dir(mod_ref):
3094 raise RuntimeError("Redefinition of Python UnknownExplanation %s."%name)
3095
3096 setattr(mod_ref, name, u)
3097
3098 del u
3099 del ue_int
3100 del name