Minor refactoring of API for eliminating arithmetic subtypes (#7833)
[cvc5.git] / src / api / cpp / cvc5.h
1 /******************************************************************************
2 * Top contributors (to current version):
3 * Aina Niemetz, Andrew Reynolds, Abdalrhman Mohamed
4 *
5 * This file is part of the cvc5 project.
6 *
7 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8 * in the top-level source directory and their institutional affiliations.
9 * All rights reserved. See the file COPYING in the top-level source
10 * directory for licensing information.
11 * ****************************************************************************
12 *
13 * The cvc5 C++ API.
14 */
15
16 #include "cvc5_export.h"
17
18 #ifndef CVC5__API__CVC5_H
19 #define CVC5__API__CVC5_H
20
21 #include <map>
22 #include <memory>
23 #include <optional>
24 #include <set>
25 #include <sstream>
26 #include <string>
27 #include <unordered_map>
28 #include <unordered_set>
29 #include <variant>
30 #include <vector>
31
32 #include "api/cpp/cvc5_kind.h"
33
34 namespace cvc5 {
35
36 #ifndef DOXYGEN_SKIP
37 template <bool ref_count>
38 class NodeTemplate;
39 typedef NodeTemplate<true> Node;
40 #endif
41
42 class Command;
43 class DType;
44 class DTypeConstructor;
45 class DTypeSelector;
46 class NodeManager;
47 class SolverEngine;
48 class TypeNode;
49 class Options;
50 class Random;
51 class Rational;
52 class Result;
53 class StatisticsRegistry;
54
55 namespace main {
56 class CommandExecutor;
57 }
58
59 namespace api {
60
61 class Solver;
62 class Statistics;
63 struct APIStatistics;
64
65 /* -------------------------------------------------------------------------- */
66 /* Exception */
67 /* -------------------------------------------------------------------------- */
68
69 /**
70 * Base class for all API exceptions.
71 * If thrown, all API objects may be in an unsafe state.
72 */
73 class CVC5_EXPORT CVC5ApiException : public std::exception
74 {
75 public:
76 /**
77 * Construct with message from a string.
78 * @param str The error message.
79 */
80 CVC5ApiException(const std::string& str) : d_msg(str) {}
81 /**
82 * Construct with message from a string stream.
83 * @param stream The error message.
84 */
85 CVC5ApiException(const std::stringstream& stream) : d_msg(stream.str()) {}
86 /**
87 * Retrieve the message from this exception.
88 * @return The error message.
89 */
90 const std::string& getMessage() const { return d_msg; }
91 /**
92 * Retrieve the message as a C-style array.
93 * @return The error message.
94 */
95 const char* what() const noexcept override { return d_msg.c_str(); }
96
97 private:
98 /** The stored error message. */
99 std::string d_msg;
100 };
101
102 /**
103 * A recoverable API exception.
104 * If thrown, API objects can still be used.
105 */
106 class CVC5_EXPORT CVC5ApiRecoverableException : public CVC5ApiException
107 {
108 public:
109 /**
110 * Construct with message from a string.
111 * @param str The error message.
112 */
113 CVC5ApiRecoverableException(const std::string& str) : CVC5ApiException(str) {}
114 /**
115 * Construct with message from a string stream.
116 * @param stream The error message.
117 */
118 CVC5ApiRecoverableException(const std::stringstream& stream)
119 : CVC5ApiException(stream.str())
120 {
121 }
122 };
123
124 /**
125 * Exception for unsupported command arguments.
126 * If thrown, API objects can still be used.
127 */
128 class CVC5_EXPORT CVC5ApiUnsupportedException : public CVC5ApiRecoverableException
129 {
130 public:
131 /**
132 * Construct with message from a string.
133 * @param str The error message.
134 */
135 CVC5ApiUnsupportedException(const std::string& str)
136 : CVC5ApiRecoverableException(str)
137 {
138 }
139 /**
140 * Construct with message from a string stream.
141 * @param stream The error message.
142 */
143 CVC5ApiUnsupportedException(const std::stringstream& stream)
144 : CVC5ApiRecoverableException(stream.str())
145 {
146 }
147 };
148
149 /**
150 * An option-related API exception.
151 * If thrown, API objects can still be used.
152 */
153 class CVC5_EXPORT CVC5ApiOptionException : public CVC5ApiRecoverableException
154 {
155 public:
156 /**
157 * Construct with message from a string.
158 * @param str The error message.
159 */
160 CVC5ApiOptionException(const std::string& str)
161 : CVC5ApiRecoverableException(str)
162 {
163 }
164 /**
165 * Construct with message from a string stream.
166 * @param stream The error message.
167 */
168 CVC5ApiOptionException(const std::stringstream& stream)
169 : CVC5ApiRecoverableException(stream.str())
170 {
171 }
172 };
173
174 /* -------------------------------------------------------------------------- */
175 /* Result */
176 /* -------------------------------------------------------------------------- */
177
178 /**
179 * Encapsulation of a three-valued solver result, with explanations.
180 */
181 class CVC5_EXPORT Result
182 {
183 friend class Solver;
184
185 public:
186 enum UnknownExplanation
187 {
188 REQUIRES_FULL_CHECK,
189 INCOMPLETE,
190 TIMEOUT,
191 RESOURCEOUT,
192 MEMOUT,
193 INTERRUPTED,
194 NO_STATUS,
195 UNSUPPORTED,
196 OTHER,
197 UNKNOWN_REASON
198 };
199
200 /** Constructor. */
201 Result();
202
203 /**
204 * Return true if Result is empty, i.e., a nullary Result, and not an actual
205 * result returned from a checkSat() (and friends) query.
206 */
207 bool isNull() const;
208
209 /**
210 * Return true if query was a satisfiable checkSat() or checkSatAssuming()
211 * query.
212 */
213 bool isSat() const;
214
215 /**
216 * Return true if query was an unsatisfiable checkSat() or
217 * checkSatAssuming() query.
218 */
219 bool isUnsat() const;
220
221 /**
222 * Return true if query was a checkSat() or checkSatAssuming() query and
223 * cvc5 was not able to determine (un)satisfiability.
224 */
225 bool isSatUnknown() const;
226
227 /**
228 * Return true if corresponding query was an entailed checkEntailed() query.
229 */
230 bool isEntailed() const;
231
232 /**
233 * Return true if corresponding query was a checkEntailed() query that is
234 * not entailed.
235 */
236 bool isNotEntailed() const;
237
238 /**
239 * Return true if query was a checkEntailed() query and cvc5 was not able to
240 * determine if it is entailed.
241 */
242 bool isEntailmentUnknown() const;
243
244 /**
245 * Operator overloading for equality of two results.
246 * @param r the result to compare to for equality
247 * @return true if the results are equal
248 */
249 bool operator==(const Result& r) const;
250
251 /**
252 * Operator overloading for disequality of two results.
253 * @param r the result to compare to for disequality
254 * @return true if the results are disequal
255 */
256 bool operator!=(const Result& r) const;
257
258 /**
259 * @return an explanation for an unknown query result.
260 */
261 UnknownExplanation getUnknownExplanation() const;
262
263 /**
264 * @return a string representation of this result.
265 */
266 std::string toString() const;
267
268 private:
269 /**
270 * Constructor.
271 * @param r the internal result that is to be wrapped by this result
272 * @return the Result
273 */
274 Result(const cvc5::Result& r);
275
276 /**
277 * The interal result wrapped by this result.
278 *
279 * @note This is a ``std::shared_ptr`` rather than a ``std::unique_ptr``
280 * since ``cvc5::Result`` is not ref counted.
281 */
282 std::shared_ptr<cvc5::Result> d_result;
283 };
284
285 /**
286 * Serialize a Result to given stream.
287 * @param out the output stream
288 * @param r the result to be serialized to the given output stream
289 * @return the output stream
290 */
291 std::ostream& operator<<(std::ostream& out, const Result& r) CVC5_EXPORT;
292
293 /**
294 * Serialize an UnknownExplanation to given stream.
295 * @param out the output stream
296 * @param e the explanation to be serialized to the given output stream
297 * @return the output stream
298 */
299 std::ostream& operator<<(std::ostream& out,
300 enum Result::UnknownExplanation e) CVC5_EXPORT;
301
302 /* -------------------------------------------------------------------------- */
303 /* Sort */
304 /* -------------------------------------------------------------------------- */
305
306 class Datatype;
307
308 /**
309 * The sort of a cvc5 term.
310 */
311 class CVC5_EXPORT Sort
312 {
313 friend class cvc5::Command;
314 friend class DatatypeConstructor;
315 friend class DatatypeConstructorDecl;
316 friend class DatatypeSelector;
317 friend class DatatypeDecl;
318 friend class Datatype;
319 friend class Op;
320 friend class Solver;
321 friend class Grammar;
322 friend struct std::hash<Sort>;
323 friend class Term;
324
325 public:
326 /**
327 * Constructor.
328 */
329 Sort();
330
331 /**
332 * Destructor.
333 */
334 ~Sort();
335
336 /**
337 * Comparison for structural equality.
338 * @param s the sort to compare to
339 * @return true if the sorts are equal
340 */
341 bool operator==(const Sort& s) const;
342
343 /**
344 * Comparison for structural disequality.
345 * @param s the sort to compare to
346 * @return true if the sorts are not equal
347 */
348 bool operator!=(const Sort& s) const;
349
350 /**
351 * Comparison for ordering on sorts.
352 * @param s the sort to compare to
353 * @return true if this sort is less than s
354 */
355 bool operator<(const Sort& s) const;
356
357 /**
358 * Comparison for ordering on sorts.
359 * @param s the sort to compare to
360 * @return true if this sort is greater than s
361 */
362 bool operator>(const Sort& s) const;
363
364 /**
365 * Comparison for ordering on sorts.
366 * @param s the sort to compare to
367 * @return true if this sort is less than or equal to s
368 */
369 bool operator<=(const Sort& s) const;
370
371 /**
372 * Comparison for ordering on sorts.
373 * @param s the sort to compare to
374 * @return true if this sort is greater than or equal to s
375 */
376 bool operator>=(const Sort& s) const;
377
378 /**
379 * @return true if the sort has a symbol.
380 */
381 bool hasSymbol() const;
382
383 /**
384 * Asserts hasSymbol().
385 * @return the raw symbol of the sort.
386 */
387 std::string getSymbol() const;
388
389 /**
390 * @return true if this Sort is a null sort.
391 */
392 bool isNull() const;
393
394 /**
395 * Is this a Boolean sort?
396 * @return true if the sort is the Boolean sort
397 */
398 bool isBoolean() const;
399
400 /**
401 * Is this a integer sort?
402 * @return true if the sort is the integer sort
403 */
404 bool isInteger() const;
405
406 /**
407 * Is this a real sort?
408 * @return true if the sort is the real sort
409 */
410 bool isReal() const;
411
412 /**
413 * Is this a string sort?
414 * @return true if the sort is the string sort
415 */
416 bool isString() const;
417
418 /**
419 * Is this a regexp sort?
420 * @return true if the sort is the regexp sort
421 */
422 bool isRegExp() const;
423
424 /**
425 * Is this a rounding mode sort?
426 * @return true if the sort is the rounding mode sort
427 */
428 bool isRoundingMode() const;
429
430 /**
431 * Is this a bit-vector sort?
432 * @return true if the sort is a bit-vector sort
433 */
434 bool isBitVector() const;
435
436 /**
437 * Is this a floating-point sort?
438 * @return true if the sort is a floating-point sort
439 */
440 bool isFloatingPoint() const;
441
442 /**
443 * Is this a datatype sort?
444 * @return true if the sort is a datatype sort
445 */
446 bool isDatatype() const;
447
448 /**
449 * Is this a parametric datatype sort? A parametric datatype sort is either
450 * one that is returned by a call to Solver::mkDatatypeSort() or
451 * Solver::mkDatatypeSorts() for a parametric datatype, or an instantiated
452 * datatype sort returned by Sort::instantiate() for parametric datatype
453 * sort `s`.
454 * @return true if the sort is a parametric datatype sort
455 */
456 bool isParametricDatatype() const;
457
458 /**
459 * Is this a constructor sort?
460 * @return true if the sort is a constructor sort
461 */
462 bool isConstructor() const;
463
464 /**
465 * Is this a selector sort?
466 * @return true if the sort is a selector sort
467 */
468 bool isSelector() const;
469
470 /**
471 * Is this a tester sort?
472 * @return true if the sort is a tester sort
473 */
474 bool isTester() const;
475 /**
476 * Is this a datatype updater sort?
477 * @return true if the sort is a datatype updater sort
478 */
479 bool isUpdater() const;
480 /**
481 * Is this a function sort?
482 * @return true if the sort is a function sort
483 */
484 bool isFunction() const;
485
486 /**
487 * Is this a predicate sort?
488 * That is, is this a function sort mapping to Boolean? All predicate
489 * sorts are also function sorts.
490 * @return true if the sort is a predicate sort
491 */
492 bool isPredicate() const;
493
494 /**
495 * Is this a tuple sort?
496 * @return true if the sort is a tuple sort
497 */
498 bool isTuple() const;
499
500 /**
501 * Is this a record sort?
502 * @return true if the sort is a record sort
503 */
504 bool isRecord() const;
505
506 /**
507 * Is this an array sort?
508 * @return true if the sort is an array sort
509 */
510 bool isArray() const;
511
512 /**
513 * Is this a Set sort?
514 * @return true if the sort is a Set sort
515 */
516 bool isSet() const;
517
518 /**
519 * Is this a Bag sort?
520 * @return true if the sort is a Bag sort
521 */
522 bool isBag() const;
523
524 /**
525 * Is this a Sequence sort?
526 * @return true if the sort is a Sequence sort
527 */
528 bool isSequence() const;
529
530 /**
531 * Is this an uninterpreted sort?
532 * @return true if this is an uninterpreted sort
533 */
534 bool isUninterpretedSort() const;
535
536 /**
537 * Is this a sort constructor kind?
538 * @return true if this is a sort constructor kind
539 */
540 bool isSortConstructor() const;
541
542 /**
543 * Is this a first-class sort?
544 * First-class sorts are sorts for which:
545 * 1. we handle equalities between terms of that type, and
546 * 2. they are allowed to be parameters of parametric sorts (e.g. index or
547 * element sorts of arrays).
548 *
549 * Examples of sorts that are not first-class include sort constructor sorts
550 * and regular expression sorts.
551 *
552 * @return true if this is a first-class sort
553 */
554 bool isFirstClass() const;
555
556 /**
557 * Is this a function-LIKE sort?
558 *
559 * Anything function-like except arrays (e.g., datatype selectors) is
560 * considered a function here. Function-like terms can not be the argument
561 * or return value for any term that is function-like.
562 * This is mainly to avoid higher order.
563 *
564 * @note Arrays are explicitly not considered function-like here.
565 *
566 * @return true if this is a function-like sort
567 */
568 bool isFunctionLike() const;
569
570 /**
571 * Is this sort a subsort of the given sort?
572 * @return true if this sort is a subsort of s
573 */
574 bool isSubsortOf(const Sort& s) const;
575
576 /**
577 * Is this sort comparable to the given sort (i.e., do they share
578 * a common ancestor in the subsort tree)?
579 * @return true if this sort is comparable to s
580 */
581 bool isComparableTo(const Sort& s) const;
582
583 /**
584 * @return the underlying datatype of a datatype sort
585 */
586 Datatype getDatatype() const;
587
588 /**
589 * Instantiate a parameterized datatype/sort sort.
590 * Create sorts parameter with Solver::mkParamSort().
591 * @param params the list of sort parameters to instantiate with
592 */
593 Sort instantiate(const std::vector<Sort>& params) const;
594
595 /**
596 * Substitution of Sorts.
597 * @param sort the subsort to be substituted within this sort.
598 * @param replacement the sort replacing the substituted subsort.
599 */
600 Sort substitute(const Sort& sort, const Sort& replacement) const;
601
602 /**
603 * Simultaneous substitution of Sorts.
604 * @param sorts the subsorts to be substituted within this sort.
605 * @param replacements the sort replacing the substituted subsorts.
606 */
607 Sort substitute(const std::vector<Sort>& sorts,
608 const std::vector<Sort>& replacements) const;
609
610 /**
611 * Output a string representation of this sort to a given stream.
612 * @param out the output stream
613 */
614 void toStream(std::ostream& out) const;
615
616 /**
617 * @return a string representation of this sort
618 */
619 std::string toString() const;
620
621 /* Constructor sort ------------------------------------------------------- */
622
623 /**
624 * @return the arity of a constructor sort
625 */
626 size_t getConstructorArity() const;
627
628 /**
629 * @return the domain sorts of a constructor sort
630 */
631 std::vector<Sort> getConstructorDomainSorts() const;
632
633 /**
634 * @return the codomain sort of a constructor sort
635 */
636 Sort getConstructorCodomainSort() const;
637
638 /* Selector sort ------------------------------------------------------- */
639
640 /**
641 * @return the domain sort of a selector sort
642 */
643 Sort getSelectorDomainSort() const;
644
645 /**
646 * @return the codomain sort of a selector sort
647 */
648 Sort getSelectorCodomainSort() const;
649
650 /* Tester sort ------------------------------------------------------- */
651
652 /**
653 * @return the domain sort of a tester sort
654 */
655 Sort getTesterDomainSort() const;
656
657 /**
658 * @return the codomain sort of a tester sort, which is the Boolean sort
659 *
660 * @note We mainly need this for the symbol table, which doesn't have
661 * access to the solver object.
662 */
663 Sort getTesterCodomainSort() const;
664
665 /* Function sort ------------------------------------------------------- */
666
667 /**
668 * @return the arity of a function sort
669 */
670 size_t getFunctionArity() const;
671
672 /**
673 * @return the domain sorts of a function sort
674 */
675 std::vector<Sort> getFunctionDomainSorts() const;
676
677 /**
678 * @return the codomain sort of a function sort
679 */
680 Sort getFunctionCodomainSort() const;
681
682 /* Array sort ---------------------------------------------------------- */
683
684 /**
685 * @return the array index sort of an array sort
686 */
687 Sort getArrayIndexSort() const;
688
689 /**
690 * @return the array element sort of an array sort
691 */
692 Sort getArrayElementSort() const;
693
694 /* Set sort ------------------------------------------------------------ */
695
696 /**
697 * @return the element sort of a set sort
698 */
699 Sort getSetElementSort() const;
700
701 /* Bag sort ------------------------------------------------------------ */
702
703 /**
704 * @return the element sort of a bag sort
705 */
706 Sort getBagElementSort() const;
707
708 /* Sequence sort ------------------------------------------------------- */
709
710 /**
711 * @return the element sort of a sequence sort
712 */
713 Sort getSequenceElementSort() const;
714
715 /* Uninterpreted sort -------------------------------------------------- */
716
717 /**
718 * @return the name of an uninterpreted sort
719 */
720 std::string getUninterpretedSortName() const;
721
722 /**
723 * @return true if an uninterpreted sort is parameterized
724 */
725 bool isUninterpretedSortParameterized() const;
726
727 /**
728 * @return the parameter sorts of an uninterpreted sort
729 */
730 std::vector<Sort> getUninterpretedSortParamSorts() const;
731
732 /* Sort constructor sort ----------------------------------------------- */
733
734 /**
735 * @return the name of a sort constructor sort
736 */
737 std::string getSortConstructorName() const;
738
739 /**
740 * @return the arity of a sort constructor sort
741 */
742 size_t getSortConstructorArity() const;
743
744 /* Bit-vector sort ----------------------------------------------------- */
745
746 /**
747 * @return the bit-width of the bit-vector sort
748 */
749 uint32_t getBitVectorSize() const;
750
751 /* Floating-point sort ------------------------------------------------- */
752
753 /**
754 * @return the bit-width of the exponent of the floating-point sort
755 */
756 uint32_t getFloatingPointExponentSize() const;
757
758 /**
759 * @return the width of the significand of the floating-point sort
760 */
761 uint32_t getFloatingPointSignificandSize() const;
762
763 /* Datatype sort ------------------------------------------------------- */
764
765 /**
766 *
767 * Return the parameters of a parametric datatype sort. If this sort is a
768 * non-instantiated parametric datatype, this returns the parameter sorts of
769 * the underlying datatype. If this sort is an instantiated parametric
770 * datatype, then this returns the sort parameters that were used to
771 * construct the sort via Sort::instantiate().
772 *
773 * @return the parameter sorts of a parametric datatype sort.
774 */
775 std::vector<Sort> getDatatypeParamSorts() const;
776
777 /**
778 * @return the arity of a datatype sort
779 */
780 size_t getDatatypeArity() const;
781
782 /* Tuple sort ---------------------------------------------------------- */
783
784 /**
785 * @return the length of a tuple sort
786 */
787 size_t getTupleLength() const;
788
789 /**
790 * @return the element sorts of a tuple sort
791 */
792 std::vector<Sort> getTupleSorts() const;
793
794 private:
795 /** @return the internal wrapped TypeNode of this sort. */
796 const cvc5::TypeNode& getTypeNode(void) const;
797
798 /** Helper to convert a set of Sorts to internal TypeNodes. */
799 std::set<TypeNode> static sortSetToTypeNodes(const std::set<Sort>& sorts);
800 /** Helper to convert a vector of Sorts to internal TypeNodes. */
801 std::vector<TypeNode> static sortVectorToTypeNodes(
802 const std::vector<Sort>& sorts);
803 /** Helper to convert a vector of internal TypeNodes to Sorts. */
804 std::vector<Sort> static typeNodeVectorToSorts(
805 const Solver* slv, const std::vector<TypeNode>& types);
806
807 /**
808 * Constructor.
809 * @param slv the associated solver object
810 * @param t the internal type that is to be wrapped by this sort
811 * @return the Sort
812 */
813 Sort(const Solver* slv, const cvc5::TypeNode& t);
814
815 /**
816 * Helper for isNull checks. This prevents calling an API function with
817 * CVC5_API_CHECK_NOT_NULL
818 */
819 bool isNullHelper() const;
820
821 /**
822 * The associated solver object.
823 */
824 const Solver* d_solver;
825
826 /**
827 * The internal type wrapped by this sort.
828 *
829 * @note This is a ``std::shared_ptr`` rather than a ``std::unique_ptr`` to
830 * avoid overhead due to memory allocation (``cvc5::Type`` is already
831 * ref counted, so this could be a ``std::unique_ptr`` instead).
832 */
833 std::shared_ptr<cvc5::TypeNode> d_type;
834 };
835
836 /**
837 * Serialize a sort to given stream.
838 * @param out the output stream
839 * @param s the sort to be serialized to the given output stream
840 * @return the output stream
841 */
842 std::ostream& operator<<(std::ostream& out, const Sort& s) CVC5_EXPORT;
843
844 } // namespace api
845 } // namespace cvc5
846
847 namespace std {
848
849 /**
850 * Hash function for Sorts.
851 */
852 template <>
853 struct CVC5_EXPORT hash<cvc5::api::Sort>
854 {
855 size_t operator()(const cvc5::api::Sort& s) const;
856 };
857
858 } // namespace std
859
860 namespace cvc5::api {
861
862 /* -------------------------------------------------------------------------- */
863 /* Op */
864 /* -------------------------------------------------------------------------- */
865
866 class Term;
867
868 /**
869 * A cvc5 operator.
870 * An operator is a term that represents certain operators, instantiated
871 * with its required parameters, e.g., a term of kind BITVECTOR_EXTRACT.
872 */
873 class CVC5_EXPORT Op
874 {
875 friend class Solver;
876 friend class Term;
877 friend struct std::hash<Op>;
878
879 public:
880 /**
881 * Constructor.
882 */
883 Op();
884
885 /**
886 * Destructor.
887 */
888 ~Op();
889
890 /**
891 * Syntactic equality operator.
892 * Return true if both operators are syntactically identical.
893 * Both operators must belong to the same solver object.
894 * @param t the operator to compare to for equality
895 * @return true if the operators are equal
896 */
897 bool operator==(const Op& t) const;
898
899 /**
900 * Syntactic disequality operator.
901 * Return true if both operators differ syntactically.
902 * Both terms must belong to the same solver object.
903 * @param t the operator to compare to for disequality
904 * @return true if operators are disequal
905 */
906 bool operator!=(const Op& t) const;
907
908 /**
909 * @return the kind of this operator
910 */
911 Kind getKind() const;
912
913 /**
914 * @return true if this operator is a null term
915 */
916 bool isNull() const;
917
918 /**
919 * @return true iff this operator is indexed
920 */
921 bool isIndexed() const;
922
923 /**
924 * @return the number of indices of this op
925 */
926 size_t getNumIndices() const;
927
928 /**
929 * Get the index at position i.
930 * @param i the position of the index to return
931 * @return the index at position i
932 */
933
934 Term operator[](size_t i) const;
935
936 /**
937 * Get the indices used to create this Op.
938 * Supports the following template arguments:
939 * - string
940 * - Kind
941 * - uint32_t
942 * - pair<uint32_t, uint32_t>
943 * Check the Op Kind with getKind() to determine which argument to use.
944 * @return the indices used to create this Op
945 */
946 template <typename T>
947 T getIndices() const;
948
949 /**
950 * @return a string representation of this operator
951 */
952 std::string toString() const;
953
954 private:
955 /**
956 * Constructor for a single kind (non-indexed operator).
957 * @param slv the associated solver object
958 * @param k the kind of this Op
959 */
960 Op(const Solver* slv, const Kind k);
961
962 /**
963 * Constructor.
964 * @param slv the associated solver object
965 * @param k the kind of this Op
966 * @param n the internal node that is to be wrapped by this term
967 * @return the Term
968 */
969 Op(const Solver* slv, const Kind k, const cvc5::Node& n);
970
971 /**
972 * Helper for isNull checks. This prevents calling an API function with
973 * CVC5_API_CHECK_NOT_NULL
974 */
975 bool isNullHelper() const;
976
977 /**
978 * @note An indexed operator has a non-null internal node (``d_node``).
979 *
980 * @note We use a helper method to avoid having API functions call other API
981 * functions (we need to call this internally).
982 *
983 * @return true iff this Op is indexed
984 */
985 bool isIndexedHelper() const;
986
987 /**
988 * Helper for getNumIndices
989 * @return the number of indices of this op
990 */
991 size_t getNumIndicesHelper() const;
992
993 /**
994 * Helper for operator[](size_t index).
995 * @param index position of the index. Should be less than getNumIndicesHelper().
996 * @return the index at position index
997 */
998 Term getIndexHelper(size_t index) const;
999
1000 /**
1001 * The associated solver object.
1002 */
1003 const Solver* d_solver;
1004
1005 /** The kind of this operator. */
1006 Kind d_kind;
1007
1008 /**
1009 * The internal node wrapped by this operator.
1010 *
1011 * @note This is a ``std::shared_ptr`` rather than a ``std::unique_ptr`` to
1012 * avoid overhead due to memory allocation (``cvc5::Node`` is already
1013 * ref counted, so this could be a ``std::unique_ptr`` instead).
1014 */
1015 std::shared_ptr<cvc5::Node> d_node;
1016 };
1017
1018 /**
1019 * Serialize an operator to given stream.
1020 * @param out the output stream
1021 * @param t the operator to be serialized to the given output stream
1022 * @return the output stream
1023 */
1024 std::ostream& operator<<(std::ostream& out, const Op& t) CVC5_EXPORT;
1025
1026 } // namespace cvc5::api
1027
1028 namespace std {
1029 /**
1030 * Hash function for Ops.
1031 */
1032 template <>
1033 struct CVC5_EXPORT hash<cvc5::api::Op>
1034 {
1035 size_t operator()(const cvc5::api::Op& t) const;
1036 };
1037 } // namespace std
1038
1039 namespace cvc5::api {
1040 /* -------------------------------------------------------------------------- */
1041 /* Term */
1042 /* -------------------------------------------------------------------------- */
1043
1044 /**
1045 * A cvc5 Term.
1046 */
1047 class CVC5_EXPORT Term
1048 {
1049 friend class cvc5::Command;
1050 friend class Datatype;
1051 friend class DatatypeConstructor;
1052 friend class DatatypeSelector;
1053 friend class Solver;
1054 friend class Grammar;
1055 friend struct std::hash<Term>;
1056
1057 public:
1058 /**
1059 * Constructor for a null term.
1060 */
1061 Term();
1062
1063 /**
1064 * Destructor.
1065 */
1066 ~Term();
1067
1068 /**
1069 * Syntactic equality operator.
1070 * Return true if both terms are syntactically identical.
1071 * Both terms must belong to the same solver object.
1072 * @param t the term to compare to for equality
1073 * @return true if the terms are equal
1074 */
1075 bool operator==(const Term& t) const;
1076
1077 /**
1078 * Syntactic disequality operator.
1079 * Return true if both terms differ syntactically.
1080 * Both terms must belong to the same solver object.
1081 * @param t the term to compare to for disequality
1082 * @return true if terms are disequal
1083 */
1084 bool operator!=(const Term& t) const;
1085
1086 /**
1087 * Comparison for ordering on terms by their id.
1088 * @param t the term to compare to
1089 * @return true if this term is less than t
1090 */
1091 bool operator<(const Term& t) const;
1092
1093 /**
1094 * Comparison for ordering on terms by their id.
1095 * @param t the term to compare to
1096 * @return true if this term is greater than t
1097 */
1098 bool operator>(const Term& t) const;
1099
1100 /**
1101 * Comparison for ordering on terms by their id.
1102 * @param t the term to compare to
1103 * @return true if this term is less than or equal to t
1104 */
1105 bool operator<=(const Term& t) const;
1106
1107 /**
1108 * Comparison for ordering on terms by their id.
1109 * @param t the term to compare to
1110 * @return true if this term is greater than or equal to t
1111 */
1112 bool operator>=(const Term& t) const;
1113
1114 /** @return the number of children of this term */
1115 size_t getNumChildren() const;
1116
1117 /**
1118 * Get the child term at a given index.
1119 * @param index the index of the child term to return
1120 * @return the child term with the given index
1121 */
1122 Term operator[](size_t index) const;
1123
1124 /**
1125 * @return the id of this term
1126 */
1127 uint64_t getId() const;
1128
1129 /**
1130 * @return the kind of this term
1131 */
1132 Kind getKind() const;
1133
1134 /**
1135 * @return the sort of this term
1136 */
1137 Sort getSort() const;
1138
1139 /**
1140 * @return the result of replacing 'term' by 'replacement' in this term
1141 */
1142 Term substitute(const Term& term, const Term& replacement) const;
1143
1144 /**
1145 * @return the result of simultaneously replacing 'terms' by 'replacements'
1146 * in this term
1147 */
1148 Term substitute(const std::vector<Term>& terms,
1149 const std::vector<Term>& replacements) const;
1150
1151 /**
1152 * @return true iff this term has an operator
1153 */
1154 bool hasOp() const;
1155
1156 /**
1157 * @note This is safe to call when hasOp() returns true.
1158 *
1159 * @return the Op used to create this term
1160 */
1161 Op getOp() const;
1162
1163 /**
1164 * @return true if the term has a symbol.
1165 */
1166 bool hasSymbol() const;
1167
1168 /**
1169 * Asserts hasSymbol().
1170 * @return the raw symbol of the term.
1171 */
1172 std::string getSymbol() const;
1173
1174 /**
1175 * @return true if this Term is a null term
1176 */
1177 bool isNull() const;
1178
1179 /**
1180 * Boolean negation.
1181 * @return the Boolean negation of this term
1182 */
1183 Term notTerm() const;
1184
1185 /**
1186 * Boolean and.
1187 * @param t a Boolean term
1188 * @return the conjunction of this term and the given term
1189 */
1190 Term andTerm(const Term& t) const;
1191
1192 /**
1193 * Boolean or.
1194 * @param t a Boolean term
1195 * @return the disjunction of this term and the given term
1196 */
1197 Term orTerm(const Term& t) const;
1198
1199 /**
1200 * Boolean exclusive or.
1201 * @param t a Boolean term
1202 * @return the exclusive disjunction of this term and the given term
1203 */
1204 Term xorTerm(const Term& t) const;
1205
1206 /**
1207 * Equality.
1208 * @param t a Boolean term
1209 * @return the Boolean equivalence of this term and the given term
1210 */
1211 Term eqTerm(const Term& t) const;
1212
1213 /**
1214 * Boolean implication.
1215 * @param t a Boolean term
1216 * @return the implication of this term and the given term
1217 */
1218 Term impTerm(const Term& t) const;
1219
1220 /**
1221 * If-then-else with this term as the Boolean condition.
1222 * @param then_t the 'then' term
1223 * @param else_t the 'else' term
1224 * @return the if-then-else term with this term as the Boolean condition
1225 */
1226 Term iteTerm(const Term& then_t, const Term& else_t) const;
1227
1228 /**
1229 * @return a string representation of this term
1230 */
1231 std::string toString() const;
1232
1233 /**
1234 * Iterator for the children of a Term.
1235 * @note This treats uninterpreted functions as Term just like any other term
1236 * for example, the term ``f(x, y)`` will have Kind ``APPLY_UF`` and
1237 * three children: ``f``, ``x``, and ``y``
1238 */
1239 class CVC5_EXPORT const_iterator
1240 {
1241 friend class Term;
1242
1243 public:
1244 /* The following types are required by trait std::iterator_traits */
1245
1246 /** Iterator tag */
1247 using iterator_category = std::forward_iterator_tag;
1248
1249 /** The type of the item */
1250 using value_type = Term;
1251
1252 /** The pointer type of the item */
1253 using pointer = const Term*;
1254
1255 /** The reference type of the item */
1256 using reference = const Term&;
1257
1258 /** The type returned when two iterators are subtracted */
1259 using difference_type = std::ptrdiff_t;
1260
1261 /* End of std::iterator_traits required types */
1262
1263 /**
1264 * Null Constructor.
1265 */
1266 const_iterator();
1267
1268 /**
1269 * Constructor
1270 * @param slv the associated solver object
1271 * @param e a ``std::shared pointer`` to the node that we're iterating over
1272 * @param p the position of the iterator (e.g. which child it's on)
1273 */
1274 const_iterator(const Solver* slv,
1275 const std::shared_ptr<cvc5::Node>& e,
1276 uint32_t p);
1277
1278 /**
1279 * Copy constructor.
1280 */
1281 const_iterator(const const_iterator& it);
1282
1283 /**
1284 * Assignment operator.
1285 * @param it the iterator to assign to
1286 * @return the reference to the iterator after assignment
1287 */
1288 const_iterator& operator=(const const_iterator& it);
1289
1290 /**
1291 * Equality operator.
1292 * @param it the iterator to compare to for equality
1293 * @return true if the iterators are equal
1294 */
1295 bool operator==(const const_iterator& it) const;
1296
1297 /**
1298 * Disequality operator.
1299 * @param it the iterator to compare to for disequality
1300 * @return true if the iterators are disequal
1301 */
1302 bool operator!=(const const_iterator& it) const;
1303
1304 /**
1305 * Increment operator (prefix).
1306 * @return a reference to the iterator after incrementing by one
1307 */
1308 const_iterator& operator++();
1309
1310 /**
1311 * Increment operator (postfix).
1312 * @return a reference to the iterator after incrementing by one
1313 */
1314 const_iterator operator++(int);
1315
1316 /**
1317 * Dereference operator.
1318 * @return the term this iterator points to
1319 */
1320 Term operator*() const;
1321
1322 private:
1323 /**
1324 * The associated solver object.
1325 */
1326 const Solver* d_solver;
1327 /** The original node to be iterated over. */
1328 std::shared_ptr<cvc5::Node> d_origNode;
1329 /** Keeps track of the iteration position. */
1330 uint32_t d_pos;
1331 };
1332
1333 /**
1334 * @return an iterator to the first child of this Term
1335 */
1336 const_iterator begin() const;
1337
1338 /**
1339 * @return an iterator to one-off-the-last child of this Term
1340 */
1341 const_iterator end() const;
1342
1343 /**
1344 * Get integer or real value sign. Must be called on integer or real values,
1345 * or otherwise an exception is thrown.
1346 * @return 0 if this term is zero, -1 if this term is a negative real or
1347 * integer value, 1 if this term is a positive real or integer value.
1348 */
1349 int32_t getRealOrIntegerValueSign() const;
1350 /**
1351 * @return true if the term is an integer value that fits within int32_t.
1352 */
1353 bool isInt32Value() const;
1354 /**
1355 * Asserts isInt32Value().
1356 * @return the integer term as a int32_t.
1357 */
1358 int32_t getInt32Value() const;
1359 /**
1360 * @return true if the term is an integer value that fits within uint32_t.
1361 */
1362 bool isUInt32Value() const;
1363 /**
1364 * Asserts isUInt32Value().
1365 * @return the integer term as a uint32_t.
1366 */
1367 uint32_t getUInt32Value() const;
1368 /**
1369 * @return true if the term is an integer value that fits within int64_t.
1370 */
1371 bool isInt64Value() const;
1372 /**
1373 * Asserts isInt64Value().
1374 * @return the integer term as a int64_t.
1375 */
1376 int64_t getInt64Value() const;
1377 /**
1378 * @return true if the term is an integer value that fits within uint64_t.
1379 */
1380 bool isUInt64Value() const;
1381 /**
1382 * Asserts isUInt64Value().
1383 * @return the integer term as a uint64_t.
1384 */
1385 uint64_t getUInt64Value() const;
1386 /**
1387 * @return true if the term is an integer value.
1388 */
1389 bool isIntegerValue() const;
1390 /**
1391 * Asserts isIntegerValue().
1392 * @return the integer term in (decimal) string representation.
1393 */
1394 std::string getIntegerValue() const;
1395
1396 /**
1397 * @return true if the term is a string value.
1398 */
1399 bool isStringValue() const;
1400 /**
1401 * Asserts isStringValue().
1402 * @note This method is not to be confused with toString(), which returns
1403 * some string representation of the term, whatever data it may hold.
1404 * @return the string term as a native string value.
1405 */
1406 std::wstring getStringValue() const;
1407
1408 /**
1409 * @return true if the term is a rational value whose numerator and
1410 * denominator fit within int32_t and uint32_t, respectively.
1411 */
1412 bool isReal32Value() const;
1413 /**
1414 * Asserts isReal32Value().
1415 * @return the representation of a rational value as a pair of its numerator
1416 * and denominator.
1417 */
1418 std::pair<int32_t, uint32_t> getReal32Value() const;
1419 /**
1420 * @return true if the term is a rational value whose numerator and
1421 * denominator fit within int64_t and uint64_t, respectively.
1422 */
1423 bool isReal64Value() const;
1424 /**
1425 * Asserts isReal64Value().
1426 * @return the representation of a rational value as a pair of its numerator
1427 * and denominator.
1428 */
1429 std::pair<int64_t, uint64_t> getReal64Value() const;
1430 /**
1431 * @note A term of kind PI is not considered to be a real value.
1432 * @return true if the term is a rational value.
1433 */
1434 bool isRealValue() const;
1435 /**
1436 * Asserts isRealValue().
1437 * @return the representation of a rational value as a (rational) string.
1438 */
1439 std::string getRealValue() const;
1440
1441 /**
1442 * @return true if the term is a constant array.
1443 */
1444 bool isConstArray() const;
1445 /**
1446 * Asserts isConstArray().
1447 * @return the base (element stored at all indices) of a constant array
1448 */
1449 Term getConstArrayBase() const;
1450
1451 /**
1452 * @return true if the term is a Boolean value.
1453 */
1454 bool isBooleanValue() const;
1455 /**
1456 * Asserts isBooleanValue().
1457 * @return the representation of a Boolean value as a native Boolean value.
1458 */
1459 bool getBooleanValue() const;
1460
1461 /**
1462 * @return true if the term is a bit-vector value.
1463 */
1464 bool isBitVectorValue() const;
1465 /**
1466 * Asserts isBitVectorValue().
1467 * @return the representation of a bit-vector value in string representation.
1468 * Supported bases are 2 (bit string), 10 (decimal string) or 16 (hexadecimal
1469 * string).
1470 */
1471 std::string getBitVectorValue(uint32_t base = 2) const;
1472
1473 /**
1474 * @return true if the term is an abstract value.
1475 */
1476 bool isAbstractValue() const;
1477 /**
1478 * Asserts isAbstractValue().
1479 * @return the representation of an abstract value as a string.
1480 */
1481 std::string getAbstractValue() const;
1482
1483 /**
1484 * @return true if the term is a tuple value.
1485 */
1486 bool isTupleValue() const;
1487 /**
1488 * Asserts isTupleValue().
1489 * @return the representation of a tuple value as a vector of terms.
1490 */
1491 std::vector<Term> getTupleValue() const;
1492
1493 /**
1494 * @return true if the term is the floating-point value for positive zero.
1495 */
1496 bool isFloatingPointPosZero() const;
1497 /**
1498 * @return true if the term is the floating-point value for negative zero.
1499 */
1500 bool isFloatingPointNegZero() const;
1501 /**
1502 * @return true if the term is the floating-point value for positive
1503 * infinity.
1504 */
1505 bool isFloatingPointPosInf() const;
1506 /**
1507 * @return true if the term is the floating-point value for negative
1508 * infinity.
1509 */
1510 bool isFloatingPointNegInf() const;
1511 /**
1512 * @return true if the term is the floating-point value for not a number.
1513 */
1514 bool isFloatingPointNaN() const;
1515 /**
1516 * @return true if the term is a floating-point value.
1517 */
1518 bool isFloatingPointValue() const;
1519 /**
1520 * Asserts isFloatingPointValue().
1521 * @return the representation of a floating-point value as a tuple of the
1522 * exponent width, the significand width and a bit-vector value.
1523 */
1524 std::tuple<uint32_t, uint32_t, Term> getFloatingPointValue() const;
1525
1526 /**
1527 * @return true if the term is a set value.
1528 *
1529 * A term is a set value if it is considered to be a (canonical) constant set
1530 * value. A canonical set value is one whose AST is:
1531 *
1532 * (union (singleton c1) ... (union (singleton c_{n-1}) (singleton c_n))))
1533 *
1534 * where `c1 ... cn` are values ordered by id such that `c1 > ... > cn` (see
1535 * also @ref Term::operator>(const Term&) const).
1536 *
1537 * @note A universe set term `(kind SET_UNIVERSE)` is not considered to be
1538 * a set value.
1539 */
1540 bool isSetValue() const;
1541 /**
1542 * Asserts isSetValue().
1543 * @return the representation of a set value as a set of terms.
1544 */
1545 std::set<Term> getSetValue() const;
1546
1547 /**
1548 * @return true if the term is a sequence value.
1549 */
1550 bool isSequenceValue() const;
1551 /**
1552 * Asserts isSequenceValue().
1553 * @note It is usually necessary for sequences to call Solver::simplify()
1554 * to turn a sequence that is constructed by, e.g., concatenation of
1555 * unit sequences, into a sequence value.
1556 * @return the representation of a sequence value as a vector of terms.
1557 */
1558 std::vector<Term> getSequenceValue() const;
1559
1560 /**
1561 * @return true if the term is a value from an uninterpreted sort.
1562 */
1563 bool isUninterpretedValue() const;
1564 /**
1565 bool @return() const;
1566 * Asserts isUninterpretedValue().
1567 * @return the representation of an uninterpreted value as a pair of its
1568 sort and its
1569 * index.
1570 */
1571 std::pair<Sort, int32_t> getUninterpretedValue() const;
1572
1573 protected:
1574 /**
1575 * The associated solver object.
1576 */
1577 const Solver* d_solver;
1578
1579 private:
1580 /** Helper to convert a vector of Terms to internal Nodes. */
1581 std::vector<Node> static termVectorToNodes(const std::vector<Term>& terms);
1582
1583 /** Helper method to collect all elements of a set. */
1584 static void collectSet(std::set<Term>& set,
1585 const cvc5::Node& node,
1586 const Solver* slv);
1587 /** Helper method to collect all elements of a sequence. */
1588 static void collectSequence(std::vector<Term>& seq,
1589 const cvc5::Node& node,
1590 const Solver* slv);
1591
1592 /**
1593 * Constructor.
1594 * @param slv the associated solver object
1595 * @param n the internal node that is to be wrapped by this term
1596 * @return the Term
1597 */
1598 Term(const Solver* slv, const cvc5::Node& n);
1599
1600 /** @return the internal wrapped Node of this term. */
1601 const cvc5::Node& getNode(void) const;
1602
1603 /**
1604 * Helper for isNull checks. This prevents calling an API function with
1605 * CVC5_API_CHECK_NOT_NULL
1606 */
1607 bool isNullHelper() const;
1608
1609 /**
1610 * Helper function that returns the kind of the term, which takes into
1611 * account special cases of the conversion for internal to external kinds.
1612 * @return the kind of this term
1613 */
1614 Kind getKindHelper() const;
1615
1616 /**
1617 * @return true if the current term is a constant integer that is casted into
1618 * real using the operator CAST_TO_REAL, and returns false otherwise
1619 */
1620 bool isCastedReal() const;
1621 /**
1622 * The internal node wrapped by this term.
1623 * @note This is a ``std::shared_ptr`` rather than a ``std::unique_ptr`` to
1624 * avoid overhead due to memory allocation (``cvc5::Node`` is already
1625 * ref counted, so this could be a ``std::unique_ptr`` instead).
1626 */
1627 std::shared_ptr<cvc5::Node> d_node;
1628 };
1629
1630 /**
1631 * Serialize a term to given stream.
1632 * @param out the output stream
1633 * @param t the term to be serialized to the given output stream
1634 * @return the output stream
1635 */
1636 std::ostream& operator<<(std::ostream& out, const Term& t) CVC5_EXPORT;
1637
1638 /**
1639 * Serialize a vector of terms to given stream.
1640 * @param out the output stream
1641 * @param vector the vector of terms to be serialized to the given stream
1642 * @return the output stream
1643 */
1644 std::ostream& operator<<(std::ostream& out,
1645 const std::vector<Term>& vector) CVC5_EXPORT;
1646
1647 /**
1648 * Serialize a set of terms to the given stream.
1649 * @param out the output stream
1650 * @param set the set of terms to be serialized to the given stream
1651 * @return the output stream
1652 */
1653 std::ostream& operator<<(std::ostream& out,
1654 const std::set<Term>& set) CVC5_EXPORT;
1655
1656 /**
1657 * Serialize an unordered_set of terms to the given stream.
1658 *
1659 * @param out the output stream
1660 * @param unordered_set the set of terms to be serialized to the given stream
1661 * @return the output stream
1662 */
1663 std::ostream& operator<<(std::ostream& out,
1664 const std::unordered_set<Term>& unordered_set)
1665 CVC5_EXPORT;
1666
1667 /**
1668 * Serialize a map of terms to the given stream.
1669 *
1670 * @param out the output stream
1671 * @param map the map of terms to be serialized to the given stream
1672 * @return the output stream
1673 */
1674 template <typename V>
1675 std::ostream& operator<<(std::ostream& out,
1676 const std::map<Term, V>& map) CVC5_EXPORT;
1677
1678 /**
1679 * Serialize an unordered_map of terms to the given stream.
1680 *
1681 * @param out the output stream
1682 * @param unordered_map the map of terms to be serialized to the given stream
1683 * @return the output stream
1684 */
1685 template <typename V>
1686 std::ostream& operator<<(std::ostream& out,
1687 const std::unordered_map<Term, V>& unordered_map)
1688 CVC5_EXPORT;
1689
1690 } // namespace cvc5::api
1691
1692 namespace std {
1693 /**
1694 * Hash function for Terms.
1695 */
1696 template <>
1697 struct CVC5_EXPORT hash<cvc5::api::Term>
1698 {
1699 size_t operator()(const cvc5::api::Term& t) const;
1700 };
1701 } // namespace std
1702
1703 namespace cvc5::api {
1704
1705 /* -------------------------------------------------------------------------- */
1706 /* Datatypes */
1707 /* -------------------------------------------------------------------------- */
1708
1709 class DatatypeConstructorIterator;
1710 class DatatypeIterator;
1711
1712 /**
1713 * A cvc5 datatype constructor declaration.
1714 */
1715 class CVC5_EXPORT DatatypeConstructorDecl
1716 {
1717 friend class DatatypeDecl;
1718 friend class Solver;
1719
1720 public:
1721 /** Constructor. */
1722 DatatypeConstructorDecl();
1723
1724 /**
1725 * Destructor.
1726 */
1727 ~DatatypeConstructorDecl();
1728
1729 /**
1730 * Add datatype selector declaration.
1731 * @param name the name of the datatype selector declaration to add
1732 * @param sort the codomain sort of the datatype selector declaration to add
1733 */
1734 void addSelector(const std::string& name, const Sort& sort);
1735 /**
1736 * Add datatype selector declaration whose codomain type is the datatype
1737 * itself.
1738 * @param name the name of the datatype selector declaration to add
1739 */
1740 void addSelectorSelf(const std::string& name);
1741
1742 /**
1743 * @return true if this DatatypeConstructorDecl is a null declaration.
1744 */
1745 bool isNull() const;
1746
1747 /**
1748 * @return a string representation of this datatype constructor declaration
1749 */
1750 std::string toString() const;
1751
1752 private:
1753 /**
1754 * Constructor.
1755 * @param slv the associated solver object
1756 * @param name the name of the datatype constructor
1757 * @return the DatatypeConstructorDecl
1758 */
1759 DatatypeConstructorDecl(const Solver* slv, const std::string& name);
1760
1761 /**
1762 * Helper for isNull checks. This prevents calling an API function with
1763 * CVC5_API_CHECK_NOT_NULL
1764 */
1765 bool isNullHelper() const;
1766
1767 /**
1768 * Is the underlying constructor resolved (i.e. has it been used to declare
1769 * a datatype already)?
1770 */
1771 bool isResolved() const;
1772
1773 /**
1774 * The associated solver object.
1775 */
1776 const Solver* d_solver;
1777
1778 /**
1779 * The internal (intermediate) datatype constructor wrapped by this
1780 * datatype constructor declaration.
1781 * @note This is a ``std::shared_ptr`` rather than a ``std::unique_ptr``
1782 * since ``cvc5::DTypeConstructor`` is not ref counted.
1783 */
1784 std::shared_ptr<cvc5::DTypeConstructor> d_ctor;
1785 };
1786
1787 class Solver;
1788
1789 /**
1790 * A cvc5 datatype declaration.
1791 */
1792 class CVC5_EXPORT DatatypeDecl
1793 {
1794 friend class DatatypeConstructorArg;
1795 friend class Solver;
1796 friend class Grammar;
1797
1798 public:
1799 /** Constructor. */
1800 DatatypeDecl();
1801
1802 /**
1803 * Destructor.
1804 */
1805 ~DatatypeDecl();
1806
1807 /**
1808 * Add datatype constructor declaration.
1809 * @param ctor the datatype constructor declaration to add
1810 */
1811 void addConstructor(const DatatypeConstructorDecl& ctor);
1812
1813 /** Get the number of constructors (so far) for this Datatype declaration. */
1814 size_t getNumConstructors() const;
1815
1816 /** Is this Datatype declaration parametric? */
1817 bool isParametric() const;
1818
1819 /**
1820 * @return true if this DatatypeDecl is a null object
1821 */
1822 bool isNull() const;
1823
1824 /**
1825 * @return a string representation of this datatype declaration
1826 */
1827 std::string toString() const;
1828
1829 /** @return the name of this datatype declaration. */
1830 std::string getName() const;
1831
1832 private:
1833 /**
1834 * Constructor.
1835 * @param slv the associated solver object
1836 * @param name the name of the datatype
1837 * @param isCoDatatype true if a codatatype is to be constructed
1838 * @return the DatatypeDecl
1839 */
1840 DatatypeDecl(const Solver* slv,
1841 const std::string& name,
1842 bool isCoDatatype = false);
1843
1844 /**
1845 * Constructor for parameterized datatype declaration.
1846 * Create sorts parameter with Solver::mkParamSort().
1847 * @param slv the associated solver object
1848 * @param name the name of the datatype
1849 * @param param the sort parameter
1850 * @param isCoDatatype true if a codatatype is to be constructed
1851 */
1852 DatatypeDecl(const Solver* slv,
1853 const std::string& name,
1854 const Sort& param,
1855 bool isCoDatatype = false);
1856
1857 /**
1858 * Constructor for parameterized datatype declaration.
1859 * Create sorts parameter with Solver::mkParamSort().
1860 * @param slv the associated solver object
1861 * @param name the name of the datatype
1862 * @param params a list of sort parameters
1863 * @param isCoDatatype true if a codatatype is to be constructed
1864 */
1865 DatatypeDecl(const Solver* slv,
1866 const std::string& name,
1867 const std::vector<Sort>& params,
1868 bool isCoDatatype = false);
1869
1870 /** @return the internal wrapped Dtype of this datatype declaration. */
1871 cvc5::DType& getDatatype(void) const;
1872
1873 /**
1874 * Helper for isNull checks. This prevents calling an API function with
1875 * CVC5_API_CHECK_NOT_NULL
1876 */
1877 bool isNullHelper() const;
1878
1879 /**
1880 * The associated solver object.
1881 */
1882 const Solver* d_solver;
1883
1884 /**
1885 * The internal (intermediate) datatype wrapped by this datatype
1886 * declaration.
1887 * @note This is a ``std::shared_ptr`` rather than a ``std::unique_ptr``
1888 * since ``cvc5::DType`` is not ref counted.
1889 */
1890 std::shared_ptr<cvc5::DType> d_dtype;
1891 };
1892
1893 /**
1894 * A cvc5 datatype selector.
1895 */
1896 class CVC5_EXPORT DatatypeSelector
1897 {
1898 friend class Datatype;
1899 friend class DatatypeConstructor;
1900 friend class Solver;
1901
1902 public:
1903 /**
1904 * Constructor.
1905 */
1906 DatatypeSelector();
1907
1908 /**
1909 * Destructor.
1910 */
1911 ~DatatypeSelector();
1912
1913 /** @return the name of this Datatype selector. */
1914 std::string getName() const;
1915
1916 /**
1917 * Get the selector operator of this datatype selector.
1918 * @return the selector term
1919 */
1920 Term getSelectorTerm() const;
1921
1922 /**
1923 * Get the updater operator of this datatype selector.
1924 * @return the updater term
1925 */
1926 Term getUpdaterTerm() const;
1927
1928 /** @return the codomain sort of this selector. */
1929 Sort getCodomainSort() const;
1930
1931 /**
1932 * @return true if this DatatypeSelector is a null object
1933 */
1934 bool isNull() const;
1935
1936 /**
1937 * @return a string representation of this datatype selector
1938 */
1939 std::string toString() const;
1940
1941 private:
1942 /**
1943 * Constructor.
1944 * @param slv the associated solver object
1945 * @param stor the internal datatype selector to be wrapped
1946 * @return the DatatypeSelector
1947 */
1948 DatatypeSelector(const Solver* slv, const cvc5::DTypeSelector& stor);
1949
1950 /**
1951 * Helper for isNull checks. This prevents calling an API function with
1952 * CVC5_API_CHECK_NOT_NULL
1953 */
1954 bool isNullHelper() const;
1955
1956 /**
1957 * The associated solver object.
1958 */
1959 const Solver* d_solver;
1960
1961 /**
1962 * The internal datatype selector wrapped by this datatype selector.
1963 * @note This is a ``std::shared_ptr`` rather than a ``std::unique_ptr``
1964 * since ``cvc5::DType`` is not ref counted.
1965 */
1966 std::shared_ptr<cvc5::DTypeSelector> d_stor;
1967 };
1968
1969 /**
1970 * A cvc5 datatype constructor.
1971 */
1972 class CVC5_EXPORT DatatypeConstructor
1973 {
1974 friend class Datatype;
1975 friend class Solver;
1976
1977 public:
1978 /**
1979 * Constructor.
1980 */
1981 DatatypeConstructor();
1982
1983 /**
1984 * Destructor.
1985 */
1986 ~DatatypeConstructor();
1987
1988 /** @return the name of this Datatype constructor. */
1989 std::string getName() const;
1990
1991 /**
1992 * Get the constructor operator of this datatype constructor.
1993 * @return the constructor term
1994 */
1995 Term getConstructorTerm() const;
1996
1997 /**
1998 * Get the constructor operator of this datatype constructor whose return
1999 * type is retSort. This method is intended to be used on constructors of
2000 * parametric datatypes and can be seen as returning the constructor
2001 * term that has been explicitly cast to the given sort.
2002 *
2003 * This method is required for constructors of parametric datatypes whose
2004 * return type cannot be determined by type inference. For example, given:
2005 *
2006 * \verbatim embed:rst:leading-asterisk
2007 * .. code:: smtlib
2008 *
2009 * (declare-datatype List
2010 * (par (T) ((nil) (cons (head T) (tail (List T))))))
2011 * \endverbatim
2012 *
2013 * The type of nil terms need to be provided by the user. In SMT version 2.6,
2014 * this is done via the syntax for qualified identifiers:
2015 *
2016 * \verbatim embed:rst:leading-asterisk
2017 * .. code:: smtlib
2018 *
2019 * (as nil (List Int))
2020 * \endverbatim
2021 *
2022 * This method is equivalent of applying the above, where this
2023 * DatatypeConstructor is the one corresponding to nil, and retSort is
2024 * ``(List Int)``.
2025 *
2026 * @note the returned constructor term ``t`` is an operator, while
2027 * ``Solver::mkTerm(APPLY_CONSTRUCTOR, t)`` is used to construct the
2028 * above (nullary) application of nil.
2029 *
2030 * @param retSort the desired return sort of the constructor
2031 * @return the constructor term
2032 */
2033 Term getInstantiatedConstructorTerm(const Sort& retSort) const;
2034
2035 /**
2036 * Get the tester operator of this datatype constructor.
2037 * @return the tester operator
2038 */
2039 Term getTesterTerm() const;
2040
2041 /**
2042 * @return the number of selectors (so far) of this Datatype constructor.
2043 */
2044 size_t getNumSelectors() const;
2045
2046 /** @return the i^th DatatypeSelector. */
2047 DatatypeSelector operator[](size_t index) const;
2048 /**
2049 * Get the datatype selector with the given name.
2050 * This is a linear search through the selectors, so in case of
2051 * multiple, similarly-named selectors, the first is returned.
2052 * @param name the name of the datatype selector
2053 * @return the first datatype selector with the given name
2054 */
2055 DatatypeSelector operator[](const std::string& name) const;
2056 DatatypeSelector getSelector(const std::string& name) const;
2057
2058 /**
2059 * Get the term representation of the datatype selector with the given name.
2060 * This is a linear search through the arguments, so in case of multiple,
2061 * similarly-named arguments, the selector for the first is returned.
2062 * @param name the name of the datatype selector
2063 * @return a term representing the datatype selector with the given name
2064 */
2065 Term getSelectorTerm(const std::string& name) const;
2066
2067 /**
2068 * @return true if this DatatypeConstructor is a null object
2069 */
2070 bool isNull() const;
2071
2072 /**
2073 * @return a string representation of this datatype constructor
2074 */
2075 std::string toString() const;
2076
2077 /**
2078 * Iterator for the selectors of a datatype constructor.
2079 */
2080 class const_iterator
2081 {
2082 friend class DatatypeConstructor; // to access constructor
2083
2084 public:
2085 /* The following types are required by trait std::iterator_traits */
2086
2087 /** Iterator tag */
2088 using iterator_category = std::forward_iterator_tag;
2089
2090 /** The type of the item */
2091 using value_type = DatatypeConstructor;
2092
2093 /** The pointer type of the item */
2094 using pointer = const DatatypeConstructor*;
2095
2096 /** The reference type of the item */
2097 using reference = const DatatypeConstructor&;
2098
2099 /** The type returned when two iterators are subtracted */
2100 using difference_type = std::ptrdiff_t;
2101
2102 /* End of std::iterator_traits required types */
2103
2104 /** Nullary constructor (required for Cython). */
2105 const_iterator();
2106
2107 /**
2108 * Assignment operator.
2109 * @param it the iterator to assign to
2110 * @return the reference to the iterator after assignment
2111 */
2112 const_iterator& operator=(const const_iterator& it);
2113
2114 /**
2115 * Equality operator.
2116 * @param it the iterator to compare to for equality
2117 * @return true if the iterators are equal
2118 */
2119 bool operator==(const const_iterator& it) const;
2120
2121 /**
2122 * Disequality operator.
2123 * @param it the iterator to compare to for disequality
2124 * @return true if the iterators are disequal
2125 */
2126 bool operator!=(const const_iterator& it) const;
2127
2128 /**
2129 * Increment operator (prefix).
2130 * @return a reference to the iterator after incrementing by one
2131 */
2132 const_iterator& operator++();
2133
2134 /**
2135 * Increment operator (postfix).
2136 * @return a reference to the iterator after incrementing by one
2137 */
2138 const_iterator operator++(int);
2139
2140 /**
2141 * Dereference operator.
2142 * @return a reference to the selector this iterator points to
2143 */
2144 const DatatypeSelector& operator*() const;
2145
2146 /**
2147 * Dereference operator.
2148 * @return a pointer to the selector this iterator points to
2149 */
2150 const DatatypeSelector* operator->() const;
2151
2152 private:
2153 /**
2154 * Constructor.
2155 * @param slv the associated Solver object
2156 * @param ctor the internal datatype constructor to iterate over
2157 * @param begin true if this is a begin() iterator
2158 */
2159 const_iterator(const Solver* slv,
2160 const cvc5::DTypeConstructor& ctor,
2161 bool begin);
2162
2163 /**
2164 * The associated solver object.
2165 */
2166 const Solver* d_solver;
2167
2168 /**
2169 * A pointer to the list of selectors of the internal datatype
2170 * constructor to iterate over.
2171 * This pointer is maintained for operators == and != only.
2172 */
2173 const void* d_int_stors;
2174
2175 /** The list of datatype selector (wrappers) to iterate over. */
2176 std::vector<DatatypeSelector> d_stors;
2177
2178 /** The current index of the iterator. */
2179 size_t d_idx;
2180 };
2181
2182 /**
2183 * @return an iterator to the first selector of this constructor
2184 */
2185 const_iterator begin() const;
2186
2187 /**
2188 * @return an iterator to one-off-the-last selector of this constructor
2189 */
2190 const_iterator end() const;
2191
2192 private:
2193 /**
2194 * Constructor.
2195 * @param slv the associated solver instance
2196 * @param ctor the internal datatype constructor to be wrapped
2197 * @return the DatatypeConstructor
2198 */
2199 DatatypeConstructor(const Solver* slv, const cvc5::DTypeConstructor& ctor);
2200
2201 /**
2202 * Return selector for name.
2203 * @param name The name of selector to find
2204 * @return the selector object for the name
2205 */
2206 DatatypeSelector getSelectorForName(const std::string& name) const;
2207
2208 /**
2209 * Helper for isNull checks. This prevents calling an API function with
2210 * CVC5_API_CHECK_NOT_NULL
2211 */
2212 bool isNullHelper() const;
2213
2214 /**
2215 * The associated solver object.
2216 */
2217 const Solver* d_solver;
2218
2219 /**
2220 * The internal datatype constructor wrapped by this datatype constructor.
2221 * @note This is a ``std::shared_ptr`` rather than a ``std::unique_ptr``
2222 * since ``cvc5::DType`` is not ref counted.
2223 */
2224 std::shared_ptr<cvc5::DTypeConstructor> d_ctor;
2225 };
2226
2227 /**
2228 * A cvc5 datatype.
2229 */
2230 class CVC5_EXPORT Datatype
2231 {
2232 friend class Solver;
2233 friend class Sort;
2234
2235 public:
2236 /** Constructor. */
2237 Datatype();
2238
2239 /**
2240 * Destructor.
2241 */
2242 ~Datatype();
2243
2244 /**
2245 * Get the datatype constructor at a given index.
2246 * @param idx the index of the datatype constructor to return
2247 * @return the datatype constructor with the given index
2248 */
2249 DatatypeConstructor operator[](size_t idx) const;
2250
2251 /**
2252 * Get the datatype constructor with the given name.
2253 * This is a linear search through the constructors, so in case of multiple,
2254 * similarly-named constructors, the first is returned.
2255 * @param name the name of the datatype constructor
2256 * @return the datatype constructor with the given name
2257 */
2258 DatatypeConstructor operator[](const std::string& name) const;
2259 DatatypeConstructor getConstructor(const std::string& name) const;
2260
2261 /**
2262 * Get a term representing the datatype constructor with the given name.
2263 * This is a linear search through the constructors, so in case of multiple,
2264 * similarly-named constructors, the
2265 * first is returned.
2266 */
2267 Term getConstructorTerm(const std::string& name) const;
2268
2269 /**
2270 * Get the datatype constructor with the given name.
2271 * This is a linear search through the constructors and their selectors, so
2272 * in case of multiple, similarly-named selectors, the first is returned.
2273 * @param name the name of the datatype selector
2274 * @return the datatype selector with the given name
2275 */
2276 DatatypeSelector getSelector(const std::string& name) const;
2277
2278 /** @return the name of this Datatype. */
2279 std::string getName() const;
2280
2281 /** @return the number of constructors for this Datatype. */
2282 size_t getNumConstructors() const;
2283
2284 /**
2285 * @return the parameters of this datatype, if it is parametric. An exception
2286 * is thrown if this datatype is not parametric.
2287 */
2288 std::vector<Sort> getParameters() const;
2289
2290 /** @return true if this datatype is parametric */
2291 bool isParametric() const;
2292
2293 /** @return true if this datatype corresponds to a co-datatype */
2294 bool isCodatatype() const;
2295
2296 /** @return true if this datatype corresponds to a tuple */
2297 bool isTuple() const;
2298
2299 /** @return true if this datatype corresponds to a record */
2300 bool isRecord() const;
2301
2302 /** @return true if this datatype is finite */
2303 bool isFinite() const;
2304
2305 /**
2306 * Is this datatype well-founded? If this datatype is not a codatatype,
2307 * this returns false if there are no values of this datatype that are of
2308 * finite size.
2309 *
2310 * @return true if this datatype is well-founded
2311 */
2312 bool isWellFounded() const;
2313
2314 /**
2315 * Does this datatype have nested recursion? This method returns false if a
2316 * value of this datatype includes a subterm of its type that is nested
2317 * beneath a non-datatype type constructor. For example, a datatype
2318 * T containing a constructor having a selector with codomain type (Set T)
2319 * has nested recursion.
2320 *
2321 * @return true if this datatype has nested recursion
2322 */
2323 bool hasNestedRecursion() const;
2324
2325 /**
2326 * @return true if this Datatype is a null object
2327 */
2328 bool isNull() const;
2329
2330 /**
2331 * @return a string representation of this datatype
2332 */
2333 std::string toString() const;
2334
2335 /**
2336 * Iterator for the constructors of a datatype.
2337 */
2338 class const_iterator
2339 {
2340 friend class Datatype; // to access constructor
2341
2342 public:
2343 /* The following types are required by trait std::iterator_traits */
2344
2345 /** Iterator tag */
2346 using iterator_category = std::forward_iterator_tag;
2347
2348 /** The type of the item */
2349 using value_type = Datatype;
2350
2351 /** The pointer type of the item */
2352 using pointer = const Datatype*;
2353
2354 /** The reference type of the item */
2355 using reference = const Datatype&;
2356
2357 /** The type returned when two iterators are subtracted */
2358 using difference_type = std::ptrdiff_t;
2359
2360 /* End of std::iterator_traits required types */
2361
2362 /** Nullary constructor (required for Cython). */
2363 const_iterator();
2364
2365 /**
2366 * Assignment operator.
2367 * @param it the iterator to assign to
2368 * @return the reference to the iterator after assignment
2369 */
2370 const_iterator& operator=(const const_iterator& it);
2371
2372 /**
2373 * Equality operator.
2374 * @param it the iterator to compare to for equality
2375 * @return true if the iterators are equal
2376 */
2377 bool operator==(const const_iterator& it) const;
2378
2379 /**
2380 * Disequality operator.
2381 * @param it the iterator to compare to for disequality
2382 * @return true if the iterators are disequal
2383 */
2384 bool operator!=(const const_iterator& it) const;
2385
2386 /**
2387 * Increment operator (prefix).
2388 * @return a reference to the iterator after incrementing by one
2389 */
2390 const_iterator& operator++();
2391
2392 /**
2393 * Increment operator (postfix).
2394 * @return a reference to the iterator after incrementing by one
2395 */
2396 const_iterator operator++(int);
2397
2398 /**
2399 * Dereference operator.
2400 * @return a reference to the constructor this iterator points to
2401 */
2402 const DatatypeConstructor& operator*() const;
2403
2404 /**
2405 * Dereference operator.
2406 * @return a pointer to the constructor this iterator points to
2407 */
2408 const DatatypeConstructor* operator->() const;
2409
2410 private:
2411 /**
2412 * Constructor.
2413 * @param slv the associated Solver object
2414 * @param dtype the internal datatype to iterate over
2415 * @param begin true if this is a begin() iterator
2416 */
2417 const_iterator(const Solver* slv, const cvc5::DType& dtype, bool begin);
2418
2419 /**
2420 * The associated solver object.
2421 */
2422 const Solver* d_solver;
2423
2424 /**
2425 * A pointer to the list of constructors of the internal datatype
2426 * to iterate over.
2427 * This pointer is maintained for operators == and != only.
2428 */
2429 const void* d_int_ctors;
2430
2431 /** The list of datatype constructor (wrappers) to iterate over. */
2432 std::vector<DatatypeConstructor> d_ctors;
2433
2434 /** The current index of the iterator. */
2435 size_t d_idx;
2436 };
2437
2438 /**
2439 * @return an iterator to the first constructor of this datatype
2440 */
2441 const_iterator begin() const;
2442
2443 /**
2444 * @return an iterator to one-off-the-last constructor of this datatype
2445 */
2446 const_iterator end() const;
2447
2448 private:
2449 /**
2450 * Constructor.
2451 * @param slv the associated solver instance
2452 * @param dtype the internal datatype to be wrapped
2453 * @return the Datatype
2454 */
2455 Datatype(const Solver* slv, const cvc5::DType& dtype);
2456
2457 /**
2458 * Return constructor for name.
2459 * @param name The name of constructor to find
2460 * @return the constructor object for the name
2461 */
2462 DatatypeConstructor getConstructorForName(const std::string& name) const;
2463
2464 /**
2465 * Return selector for name.
2466 * @param name The name of selector to find
2467 * @return the selector object for the name
2468 */
2469 DatatypeSelector getSelectorForName(const std::string& name) const;
2470
2471 /**
2472 * Helper for isNull checks. This prevents calling an API function with
2473 * CVC5_API_CHECK_NOT_NULL
2474 */
2475 bool isNullHelper() const;
2476
2477 /**
2478 * The associated solver object.
2479 */
2480 const Solver* d_solver;
2481
2482 /**
2483 * The internal datatype wrapped by this datatype.
2484 * @note This is a ``std::shared_ptr`` rather than a ``std::unique_ptr``
2485 * since ``cvc5::DType`` is not ref counted.
2486 */
2487 std::shared_ptr<cvc5::DType> d_dtype;
2488 };
2489
2490 /**
2491 * Serialize a datatype declaration to given stream.
2492 * @param out the output stream
2493 * @param dtdecl the datatype declaration to be serialized to the given stream
2494 * @return the output stream
2495 */
2496 std::ostream& operator<<(std::ostream& out,
2497 const DatatypeDecl& dtdecl) CVC5_EXPORT;
2498
2499 /**
2500 * Serialize a datatype constructor declaration to given stream.
2501 * @param out the output stream
2502 * @param ctordecl the datatype constructor declaration to be serialized
2503 * @return the output stream
2504 */
2505 std::ostream& operator<<(std::ostream& out,
2506 const DatatypeConstructorDecl& ctordecl) CVC5_EXPORT;
2507
2508 /**
2509 * Serialize a vector of datatype constructor declarations to given stream.
2510 * @param out the output stream
2511 * @param vector the vector of datatype constructor declarations to be
2512 * serialized to the given stream
2513 * @return the output stream
2514 */
2515 std::ostream& operator<<(std::ostream& out,
2516 const std::vector<DatatypeConstructorDecl>& vector)
2517 CVC5_EXPORT;
2518
2519 /**
2520 * Serialize a datatype to given stream.
2521 * @param out the output stream
2522 * @param dtype the datatype to be serialized to given stream
2523 * @return the output stream
2524 */
2525 std::ostream& operator<<(std::ostream& out, const Datatype& dtype) CVC5_EXPORT;
2526
2527 /**
2528 * Serialize a datatype constructor to given stream.
2529 * @param out the output stream
2530 * @param ctor the datatype constructor to be serialized to given stream
2531 * @return the output stream
2532 */
2533 std::ostream& operator<<(std::ostream& out,
2534 const DatatypeConstructor& ctor) CVC5_EXPORT;
2535
2536 /**
2537 * Serialize a datatype selector to given stream.
2538 * @param out the output stream
2539 * @param stor the datatype selector to be serialized to given stream
2540 * @return the output stream
2541 */
2542 std::ostream& operator<<(std::ostream& out,
2543 const DatatypeSelector& stor) CVC5_EXPORT;
2544
2545 /* -------------------------------------------------------------------------- */
2546 /* Grammar */
2547 /* -------------------------------------------------------------------------- */
2548
2549 /**
2550 * A Sygus Grammar.
2551 */
2552 class CVC5_EXPORT Grammar
2553 {
2554 friend class cvc5::Command;
2555 friend class Solver;
2556
2557 public:
2558 /**
2559 * Add \p rule to the set of rules corresponding to \p ntSymbol.
2560 * @param ntSymbol the non-terminal to which the rule is added
2561 * @param rule the rule to add
2562 */
2563 void addRule(const Term& ntSymbol, const Term& rule);
2564
2565 /**
2566 * Add \p rules to the set of rules corresponding to \p ntSymbol.
2567 * @param ntSymbol the non-terminal to which the rules are added
2568 * @param rules the rules to add
2569 */
2570 void addRules(const Term& ntSymbol, const std::vector<Term>& rules);
2571
2572 /**
2573 * Allow \p ntSymbol to be an arbitrary constant.
2574 * @param ntSymbol the non-terminal allowed to be any constant
2575 */
2576 void addAnyConstant(const Term& ntSymbol);
2577
2578 /**
2579 * Allow \p ntSymbol to be any input variable to corresponding
2580 * synth-fun/synth-inv with the same sort as \p ntSymbol.
2581 * @param ntSymbol the non-terminal allowed to be any input variable
2582 */
2583 void addAnyVariable(const Term& ntSymbol);
2584
2585 /**
2586 * @return a string representation of this grammar.
2587 */
2588 std::string toString() const;
2589
2590 /**
2591 * Nullary constructor. Needed for the Cython API.
2592 */
2593 Grammar();
2594
2595 private:
2596 /**
2597 * Constructor.
2598 * @param slv the solver that created this grammar
2599 * @param sygusVars the input variables to synth-fun/synth-var
2600 * @param ntSymbols the non-terminals of this grammar
2601 */
2602 Grammar(const Solver* slv,
2603 const std::vector<Term>& sygusVars,
2604 const std::vector<Term>& ntSymbols);
2605
2606 /**
2607 * @return the resolved datatype of the Start symbol of the grammar
2608 */
2609 Sort resolve();
2610
2611 /**
2612 * Adds a constructor to sygus datatype <dt> whose sygus operator is <term>.
2613 *
2614 * \p ntsToUnres contains a mapping from non-terminal symbols to the
2615 * unresolved sorts they correspond to. This map indicates how the argument
2616 * <term> should be interpreted (instances of symbols from the domain of
2617 * \p ntsToUnres correspond to constructor arguments).
2618 *
2619 * The sygus operator that is actually added to <dt> corresponds to replacing
2620 * each occurrence of non-terminal symbols from the domain of \p ntsToUnres
2621 * with bound variables via purifySygusGTerm, and binding these variables
2622 * via a lambda.
2623 *
2624 * @note Create unresolved sorts with Solver::mkUnresolvedSort().
2625 *
2626 * @param dt the non-terminal's datatype to which a constructor is added
2627 * @param term the sygus operator of the constructor
2628 * @param ntsToUnres mapping from non-terminals to their unresolved sorts
2629 */
2630 void addSygusConstructorTerm(
2631 DatatypeDecl& dt,
2632 const Term& term,
2633 const std::unordered_map<Term, Sort>& ntsToUnres) const;
2634
2635 /**
2636 * Purify SyGuS grammar term.
2637 *
2638 * This returns a term where all occurrences of non-terminal symbols (those
2639 * in the domain of \p ntsToUnres) are replaced by fresh variables. For
2640 * each variable replaced in this way, we add the fresh variable it is
2641 * replaced with to \p args, and the unresolved sorts corresponding to the
2642 * non-terminal symbol to \p cargs (constructor args). In other words,
2643 * \p args contains the free variables in the term returned by this method
2644 * (which should be bound by a lambda), and \p cargs contains the sorts of
2645 * the arguments of the sygus constructor.
2646 *
2647 * @param term the term to purify
2648 * @param args the free variables in the term returned by this method
2649 * @param cargs the sorts of the arguments of the sygus constructor
2650 * @param ntsToUnres mapping from non-terminals to their unresolved sorts
2651 * @return the purfied term
2652 */
2653 Term purifySygusGTerm(const Term& term,
2654 std::vector<Term>& args,
2655 std::vector<Sort>& cargs,
2656 const std::unordered_map<Term, Sort>& ntsToUnres) const;
2657
2658 /**
2659 * This adds constructors to \p dt for sygus variables in \p d_sygusVars
2660 * whose sort is argument \p sort. This method should be called when the
2661 * sygus grammar term (Variable sort) is encountered.
2662 *
2663 * @param dt the non-terminal's datatype to which the constructors are added
2664 * @param sort the sort of the sygus variables to add
2665 */
2666 void addSygusConstructorVariables(DatatypeDecl& dt, const Sort& sort) const;
2667
2668 /**
2669 * Check if \p rule contains variables that are neither parameters of
2670 * the corresponding synthFun/synthInv nor non-terminals.
2671 * @param rule the non-terminal allowed to be any constant
2672 * @return true if \p rule contains free variables and false otherwise
2673 */
2674 bool containsFreeVariables(const Term& rule) const;
2675
2676 /** The solver that created this grammar. */
2677 const Solver* d_solver;
2678 /** Input variables to the corresponding function/invariant to synthesize.*/
2679 std::vector<Term> d_sygusVars;
2680 /** The non-terminal symbols of this grammar. */
2681 std::vector<Term> d_ntSyms;
2682 /** The mapping from non-terminal symbols to their production terms. */
2683 std::unordered_map<Term, std::vector<Term>> d_ntsToTerms;
2684 /** The set of non-terminals that can be arbitrary constants. */
2685 std::unordered_set<Term> d_allowConst;
2686 /** The set of non-terminals that can be sygus variables. */
2687 std::unordered_set<Term> d_allowVars;
2688 /** Did we call resolve() before? */
2689 bool d_isResolved;
2690 };
2691
2692 /**
2693 * Serialize a grammar to given stream.
2694 * @param out the output stream
2695 * @param g the grammar to be serialized to the given output stream
2696 * @return the output stream
2697 */
2698 std::ostream& operator<<(std::ostream& out, const Grammar& g) CVC5_EXPORT;
2699
2700 /* -------------------------------------------------------------------------- */
2701 /* Rounding Mode for Floating-Points */
2702 /* -------------------------------------------------------------------------- */
2703
2704 /**
2705 * Rounding modes for floating-point numbers.
2706 *
2707 * For many floating-point operations, infinitely precise results may not be
2708 * representable with the number of available bits. Thus, the results are
2709 * rounded in a certain way to one of the representable floating-point numbers.
2710 *
2711 * \verbatim embed:rst:leading-asterisk
2712 * These rounding modes directly follow the SMT-LIB theory for floating-point
2713 * arithmetic, which in turn is based on IEEE Standard 754 :cite:`IEEE754`.
2714 * The rounding modes are specified in Sections 4.3.1 and 4.3.2 of the IEEE
2715 * Standard 754.
2716 * \endverbatim
2717 */
2718 enum RoundingMode
2719 {
2720 /**
2721 * Round to the nearest even number.
2722 * If the two nearest floating-point numbers bracketing an unrepresentable
2723 * infinitely precise result are equally near, the one with an even least
2724 * significant digit will be delivered.
2725 */
2726 ROUND_NEAREST_TIES_TO_EVEN,
2727 /**
2728 * Round towards positive infinity (+oo).
2729 * The result shall be the format's floating-point number (possibly +oo)
2730 * closest to and no less than the infinitely precise result.
2731 */
2732 ROUND_TOWARD_POSITIVE,
2733 /**
2734 * Round towards negative infinity (-oo).
2735 * The result shall be the format's floating-point number (possibly -oo)
2736 * closest to and no less than the infinitely precise result.
2737 */
2738 ROUND_TOWARD_NEGATIVE,
2739 /**
2740 * Round towards zero.
2741 * The result shall be the format's floating-point number closest to and no
2742 * greater in magnitude than the infinitely precise result.
2743 */
2744 ROUND_TOWARD_ZERO,
2745 /**
2746 * Round to the nearest number away from zero.
2747 * If the two nearest floating-point numbers bracketing an unrepresentable
2748 * infinitely precise result are equally near, the one with larger magnitude
2749 * will be selected.
2750 */
2751 ROUND_NEAREST_TIES_TO_AWAY,
2752 };
2753
2754 } // namespace cvc5::api
2755
2756 namespace std {
2757
2758 /**
2759 * Hash function for RoundingModes.
2760 */
2761 template <>
2762 struct CVC5_EXPORT hash<cvc5::api::RoundingMode>
2763 {
2764 size_t operator()(cvc5::api::RoundingMode rm) const;
2765 };
2766 } // namespace std
2767 namespace cvc5::api {
2768
2769 /* -------------------------------------------------------------------------- */
2770 /* Options */
2771 /* -------------------------------------------------------------------------- */
2772
2773 /**
2774 * Provides access to options that can not be communicated via the regular
2775 * getOption() or getOptionInfo() methods. This class does not store the options
2776 * itself, but only acts as a wrapper to the solver object. It can thus no
2777 * longer be used after the solver object has been destroyed.
2778 */
2779 class CVC5_EXPORT DriverOptions
2780 {
2781 friend class Solver;
2782
2783 public:
2784 /** Access the solvers input stream */
2785 std::istream& in() const;
2786 /** Access the solvers error output stream */
2787 std::ostream& err() const;
2788 /** Access the solvers output stream */
2789 std::ostream& out() const;
2790
2791 private:
2792 DriverOptions(const Solver& solver);
2793 const Solver& d_solver;
2794 };
2795
2796 /**
2797 * Holds some description about a particular option, including its name, its
2798 * aliases, whether the option was explicitly set by the user, and information
2799 * concerning its value. The `valueInfo` member holds any of the following
2800 * alternatives:
2801 * - VoidInfo if the option holds no value (or the value has no native type)
2802 * - ValueInfo<T> if the option is of type bool or std::string, holds the
2803 * current value and the default value.
2804 * - NumberInfo<T> if the option is of type int64_t, uint64_t or double, holds
2805 * the current and default value, as well as the minimum and maximum.
2806 * - ModeInfo if the option is a mode option, holds the current and default
2807 * values, as well as a list of valid modes.
2808 * Additionally, this class provides convenience functions to obtain the
2809 * current value of an option in a type-safe manner using boolValue(),
2810 * stringValue(), intValue(), uintValue() and doubleValue(). They assert that
2811 * the option has the respective type and return the current value.
2812 */
2813 struct CVC5_EXPORT OptionInfo
2814 {
2815 /** Has no value information */
2816 struct VoidInfo {};
2817 /** Has the current and the default value */
2818 template <typename T>
2819 struct ValueInfo
2820 {
2821 T defaultValue;
2822 T currentValue;
2823 };
2824 /** Default value, current value, minimum and maximum of a numeric value */
2825 template <typename T>
2826 struct NumberInfo
2827 {
2828 T defaultValue;
2829 T currentValue;
2830 std::optional<T> minimum;
2831 std::optional<T> maximum;
2832 };
2833 /** Default value, current value and choices of a mode option */
2834 struct ModeInfo
2835 {
2836 std::string defaultValue;
2837 std::string currentValue;
2838 std::vector<std::string> modes;
2839 };
2840
2841 /** The option name */
2842 std::string name;
2843 /** The option name aliases */
2844 std::vector<std::string> aliases;
2845 /** Whether the option was explicitly set by the user */
2846 bool setByUser;
2847 /** The option value information */
2848 std::variant<VoidInfo,
2849 ValueInfo<bool>,
2850 ValueInfo<std::string>,
2851 NumberInfo<int64_t>,
2852 NumberInfo<uint64_t>,
2853 NumberInfo<double>,
2854 ModeInfo>
2855 valueInfo;
2856 /** Obtain the current value as a bool. Asserts that valueInfo holds a bool.
2857 */
2858 bool boolValue() const;
2859 /** Obtain the current value as a string. Asserts that valueInfo holds a
2860 * string. */
2861 std::string stringValue() const;
2862 /** Obtain the current value as as int. Asserts that valueInfo holds an int.
2863 */
2864 int64_t intValue() const;
2865 /** Obtain the current value as a uint. Asserts that valueInfo holds a uint.
2866 */
2867 uint64_t uintValue() const;
2868 /** Obtain the current value as a double. Asserts that valueInfo holds a
2869 * double. */
2870 double doubleValue() const;
2871 };
2872
2873 /**
2874 * Print a `OptionInfo` object to an ``std::ostream``.
2875 */
2876 std::ostream& operator<<(std::ostream& os, const OptionInfo& oi) CVC5_EXPORT;
2877
2878 /* -------------------------------------------------------------------------- */
2879 /* Statistics */
2880 /* -------------------------------------------------------------------------- */
2881
2882 /**
2883 * Represents a snapshot of a single statistic value.
2884 * A value can be of type `int64_t`, `double`, `std::string` or a histogram
2885 * (`std::map<std::string, uint64_t>`).
2886 * The value type can be queried (using `isInt()`, `isDouble()`, etc.) and
2887 * the stored value can be accessed (using `getInt()`, `getDouble()`, etc.).
2888 * It is possible to query whether this statistic is an expert statistic by
2889 * `isExpert()` and whether its value is the default value by `isDefault()`.
2890 */
2891 class CVC5_EXPORT Stat
2892 {
2893 struct StatData;
2894
2895 public:
2896 friend class Statistics;
2897 friend std::ostream& operator<<(std::ostream& os, const Stat& sv);
2898 /** Representation of a histogram: maps names to frequencies. */
2899 using HistogramData = std::map<std::string, uint64_t>;
2900 /** Can only be obtained from a `Statistics` object. */
2901 Stat() = delete;
2902 /** Copy constructor */
2903 Stat(const Stat& s);
2904 /** Destructor */
2905 ~Stat();
2906 /** Copy assignment */
2907 Stat& operator=(const Stat& s);
2908
2909 /**
2910 * Is this value intended for experts only?
2911 * @return Whether this is an expert statistic.
2912 */
2913 bool isExpert() const;
2914 /**
2915 * Does this value hold the default value?
2916 * @return Whether this is a defaulted statistic.
2917 */
2918 bool isDefault() const;
2919
2920 /**
2921 * Is this value an integer?
2922 * @return Whether the value is an integer.
2923 */
2924 bool isInt() const;
2925 /**
2926 * Return the integer value.
2927 * @return The integer value.
2928 */
2929 int64_t getInt() const;
2930 /**
2931 * Is this value a double?
2932 * @return Whether the value is a double.
2933 */
2934 bool isDouble() const;
2935 /**
2936 * Return the double value.
2937 * @return The double value.
2938 */
2939 double getDouble() const;
2940 /**
2941 * Is this value a string?
2942 * @return Whether the value is a string.
2943 */
2944 bool isString() const;
2945 /**
2946 * Return the string value.
2947 * @return The string value.
2948 */
2949 const std::string& getString() const;
2950 /**
2951 * Is this value a histogram?
2952 * @return Whether the value is a histogram.
2953 */
2954 bool isHistogram() const;
2955 /**
2956 * Return the histogram value.
2957 * @return The histogram value.
2958 */
2959 const HistogramData& getHistogram() const;
2960
2961 private:
2962 Stat(bool expert, bool def, StatData&& sd);
2963 /** Whether this statistic is only meant for experts */
2964 bool d_expert;
2965 /** Whether this statistic has the default value */
2966 bool d_default;
2967 std::unique_ptr<StatData> d_data;
2968 };
2969
2970 /**
2971 * Print a `Stat` object to an ``std::ostream``.
2972 */
2973 std::ostream& operator<<(std::ostream& os, const Stat& sv) CVC5_EXPORT;
2974
2975 /**
2976 * Represents a snapshot of the solver statistics.
2977 * Once obtained, an instance of this class is independent of the `Solver`
2978 * object: it will not change when the solvers internal statistics do, it
2979 * will not be invalidated if the solver is destroyed.
2980 * Iterating on this class (via `begin()` and `end()`) shows only public
2981 * statistics that have been changed. By passing appropriate flags to
2982 * `begin()`, statistics that are expert, defaulted, or both, can be
2983 * included as well. A single statistic value is represented as `Stat`.
2984 */
2985 class CVC5_EXPORT Statistics
2986 {
2987 public:
2988 friend class Solver;
2989 /** How the statistics are stored internally. */
2990 using BaseType = std::map<std::string, Stat>;
2991
2992 /** Custom iterator to hide certain statistics from regular iteration */
2993 class CVC5_EXPORT iterator
2994 {
2995 public:
2996 friend class Statistics;
2997 BaseType::const_reference operator*() const;
2998 BaseType::const_pointer operator->() const;
2999 iterator& operator++();
3000 iterator operator++(int);
3001 iterator& operator--();
3002 iterator operator--(int);
3003 bool operator==(const iterator& rhs) const;
3004 bool operator!=(const iterator& rhs) const;
3005
3006 private:
3007 iterator(BaseType::const_iterator it,
3008 const BaseType& base,
3009 bool expert,
3010 bool defaulted);
3011 bool isVisible() const;
3012 BaseType::const_iterator d_it;
3013 const BaseType* d_base;
3014 bool d_showExpert = false;
3015 bool d_showDefault = false;
3016 };
3017
3018 /**
3019 * Retrieve the statistic with the given name.
3020 * Asserts that a statistic with the given name actually exists and throws
3021 * a `CVC5ApiRecoverableException` if it does not.
3022 * @param name Name of the statistic.
3023 * @return The statistic with the given name.
3024 */
3025 const Stat& get(const std::string& name);
3026 /**
3027 * Begin iteration over the statistics values.
3028 * By default, only entries that are public (non-expert) and have been set
3029 * are visible while the others are skipped.
3030 * @param expert If set to true, expert statistics are shown as well.
3031 * @param defaulted If set to true, defaulted statistics are shown as well.
3032 */
3033 iterator begin(bool expert = false, bool defaulted = false) const;
3034 /** End iteration */
3035 iterator end() const;
3036
3037 private:
3038 Statistics() = default;
3039 Statistics(const StatisticsRegistry& reg);
3040 /** Internal data */
3041 BaseType d_stats;
3042 };
3043 std::ostream& operator<<(std::ostream& out,
3044 const Statistics& stats) CVC5_EXPORT;
3045
3046 /* -------------------------------------------------------------------------- */
3047 /* Solver */
3048 /* -------------------------------------------------------------------------- */
3049
3050 /**
3051 * A cvc5 solver.
3052 */
3053 class CVC5_EXPORT Solver
3054 {
3055 friend class Datatype;
3056 friend class DatatypeDecl;
3057 friend class DatatypeConstructor;
3058 friend class DatatypeConstructorDecl;
3059 friend class DatatypeSelector;
3060 friend class DriverOptions;
3061 friend class Grammar;
3062 friend class Op;
3063 friend class cvc5::Command;
3064 friend class cvc5::main::CommandExecutor;
3065 friend class Sort;
3066 friend class Term;
3067
3068 private:
3069 /*
3070 * Constructs a solver with the given original options. This should only be
3071 * used internally when the Solver is reset.
3072 */
3073 Solver(std::unique_ptr<Options>&& original);
3074
3075 public:
3076 /* .................................................................... */
3077 /* Constructors/Destructors */
3078 /* .................................................................... */
3079
3080 /**
3081 * Constructor.
3082 * @return the Solver
3083 */
3084 Solver();
3085
3086 /**
3087 * Destructor.
3088 */
3089 ~Solver();
3090
3091 /**
3092 * Disallow copy/assignment.
3093 */
3094 Solver(const Solver&) = delete;
3095 Solver& operator=(const Solver&) = delete;
3096
3097 /* .................................................................... */
3098 /* Sorts Handling */
3099 /* .................................................................... */
3100
3101 /**
3102 * @return sort null
3103 */
3104 Sort getNullSort() const;
3105
3106 /**
3107 * @return sort Boolean
3108 */
3109 Sort getBooleanSort() const;
3110
3111 /**
3112 * @return sort Integer (in cvc5, Integer is a subtype of Real)
3113 */
3114 Sort getIntegerSort() const;
3115
3116 /**
3117 * @return sort Real
3118 */
3119 Sort getRealSort() const;
3120
3121 /**
3122 * @return sort RegExp
3123 */
3124 Sort getRegExpSort() const;
3125
3126 /**
3127 * @return sort RoundingMode
3128 */
3129 Sort getRoundingModeSort() const;
3130
3131 /**
3132 * @return sort String
3133 */
3134 Sort getStringSort() const;
3135
3136 /**
3137 * Create an array sort.
3138 * @param indexSort the array index sort
3139 * @param elemSort the array element sort
3140 * @return the array sort
3141 */
3142 Sort mkArraySort(const Sort& indexSort, const Sort& elemSort) const;
3143
3144 /**
3145 * Create a bit-vector sort.
3146 * @param size the bit-width of the bit-vector sort
3147 * @return the bit-vector sort
3148 */
3149 Sort mkBitVectorSort(uint32_t size) const;
3150
3151 /**
3152 * Create a floating-point sort.
3153 * @param exp the bit-width of the exponent of the floating-point sort.
3154 * @param sig the bit-width of the significand of the floating-point sort.
3155 */
3156 Sort mkFloatingPointSort(uint32_t exp, uint32_t sig) const;
3157
3158 /**
3159 * Create a datatype sort.
3160 * @param dtypedecl the datatype declaration from which the sort is created
3161 * @return the datatype sort
3162 */
3163 Sort mkDatatypeSort(const DatatypeDecl& dtypedecl) const;
3164
3165 /**
3166 * Create a vector of datatype sorts. The names of the datatype declarations
3167 * must be distinct.
3168 *
3169 * @param dtypedecls the datatype declarations from which the sort is created
3170 * @return the datatype sorts
3171 */
3172 std::vector<Sort> mkDatatypeSorts(
3173 const std::vector<DatatypeDecl>& dtypedecls) const;
3174
3175 /**
3176 * Create a vector of datatype sorts using unresolved sorts. The names of
3177 * the datatype declarations in dtypedecls must be distinct.
3178 *
3179 * This method is called when the DatatypeDecl objects dtypedecls have been
3180 * built using "unresolved" sorts.
3181 *
3182 * We associate each sort in unresolvedSorts with exactly one datatype from
3183 * dtypedecls. In particular, it must have the same name as exactly one
3184 * datatype declaration in dtypedecls.
3185 *
3186 * When constructing datatypes, unresolved sorts are replaced by the datatype
3187 * sort constructed for the datatype declaration it is associated with.
3188 *
3189 * @note Create unresolved sorts with Solver::mkUnresolvedSort().
3190 *
3191 * @param dtypedecls the datatype declarations from which the sort is created
3192 * @param unresolvedSorts the list of unresolved sorts
3193 * @return the datatype sorts
3194 */
3195 std::vector<Sort> mkDatatypeSorts(
3196 const std::vector<DatatypeDecl>& dtypedecls,
3197 const std::set<Sort>& unresolvedSorts) const;
3198
3199 /**
3200 * Create function sort.
3201 * @param domain the sort of the function argument
3202 * @param codomain the sort of the function return value
3203 * @return the function sort
3204 */
3205 Sort mkFunctionSort(const Sort& domain, const Sort& codomain) const;
3206
3207 /**
3208 * Create function sort.
3209 * @param sorts the sort of the function arguments
3210 * @param codomain the sort of the function return value
3211 * @return the function sort
3212 */
3213 Sort mkFunctionSort(const std::vector<Sort>& sorts,
3214 const Sort& codomain) const;
3215
3216 /**
3217 * Create a sort parameter.
3218 * @param symbol the name of the sort
3219 * @return the sort parameter
3220 */
3221 Sort mkParamSort(const std::string& symbol) const;
3222
3223 /**
3224 * Create a predicate sort.
3225 * @param sorts the list of sorts of the predicate
3226 * @return the predicate sort
3227 */
3228 Sort mkPredicateSort(const std::vector<Sort>& sorts) const;
3229
3230 /**
3231 * Create a record sort
3232 * @param fields the list of fields of the record
3233 * @return the record sort
3234 */
3235 Sort mkRecordSort(
3236 const std::vector<std::pair<std::string, Sort>>& fields) const;
3237
3238 /**
3239 * Create a set sort.
3240 * @param elemSort the sort of the set elements
3241 * @return the set sort
3242 */
3243 Sort mkSetSort(const Sort& elemSort) const;
3244
3245 /**
3246 * Create a bag sort.
3247 * @param elemSort the sort of the bag elements
3248 * @return the bag sort
3249 */
3250 Sort mkBagSort(const Sort& elemSort) const;
3251
3252 /**
3253 * Create a sequence sort.
3254 * @param elemSort the sort of the sequence elements
3255 * @return the sequence sort
3256 */
3257 Sort mkSequenceSort(const Sort& elemSort) const;
3258
3259 /**
3260 * Create an uninterpreted sort.
3261 * @param symbol the name of the sort
3262 * @return the uninterpreted sort
3263 */
3264 Sort mkUninterpretedSort(const std::string& symbol) const;
3265
3266 /**
3267 * Create an unresolved sort.
3268 *
3269 * This is for creating yet unresolved sort placeholders for mutually
3270 * recursive datatypes.
3271 *
3272 * @param symbol the symbol of the sort
3273 * @param arity the number of sort parameters of the sort
3274 * @return the unresolved sort
3275 */
3276 Sort mkUnresolvedSort(const std::string& symbol, size_t arity = 0) const;
3277
3278 /**
3279 * Create a sort constructor sort.
3280 * @param symbol the symbol of the sort
3281 * @param arity the arity of the sort
3282 * @return the sort constructor sort
3283 */
3284 Sort mkSortConstructorSort(const std::string& symbol, size_t arity) const;
3285
3286 /**
3287 * Create a tuple sort.
3288 * @param sorts of the elements of the tuple
3289 * @return the tuple sort
3290 */
3291 Sort mkTupleSort(const std::vector<Sort>& sorts) const;
3292
3293 /* .................................................................... */
3294 /* Create Terms */
3295 /* .................................................................... */
3296
3297 /**
3298 * Create 0-ary term of given kind.
3299 * @param kind the kind of the term
3300 * @return the Term
3301 */
3302 Term mkTerm(Kind kind) const;
3303
3304 /**
3305 * Create a unary term of given kind.
3306 * @param kind the kind of the term
3307 * @param child the child of the term
3308 * @return the Term
3309 */
3310 Term mkTerm(Kind kind, const Term& child) const;
3311
3312 /**
3313 * Create binary term of given kind.
3314 * @param kind the kind of the term
3315 * @param child1 the first child of the term
3316 * @param child2 the second child of the term
3317 * @return the Term
3318 */
3319 Term mkTerm(Kind kind, const Term& child1, const Term& child2) const;
3320
3321 /**
3322 * Create ternary term of given kind.
3323 * @param kind the kind of the term
3324 * @param child1 the first child of the term
3325 * @param child2 the second child of the term
3326 * @param child3 the third child of the term
3327 * @return the Term
3328 */
3329 Term mkTerm(Kind kind,
3330 const Term& child1,
3331 const Term& child2,
3332 const Term& child3) const;
3333
3334 /**
3335 * Create n-ary term of given kind.
3336 * @param kind the kind of the term
3337 * @param children the children of the term
3338 * @return the Term
3339 */
3340 Term mkTerm(Kind kind, const std::vector<Term>& children) const;
3341
3342 /**
3343 * Create nullary term of given kind from a given operator.
3344 * Create operators with mkOp().
3345 * @param op the operator
3346 * @return the Term
3347 */
3348 Term mkTerm(const Op& op) const;
3349
3350 /**
3351 * Create unary term of given kind from a given operator.
3352 * Create operators with mkOp().
3353 * @param op the operator
3354 * @param child the child of the term
3355 * @return the Term
3356 */
3357 Term mkTerm(const Op& op, const Term& child) const;
3358
3359 /**
3360 * Create binary term of given kind from a given operator.
3361 * Create operators with mkOp().
3362 * @param op the operator
3363 * @param child1 the first child of the term
3364 * @param child2 the second child of the term
3365 * @return the Term
3366 */
3367 Term mkTerm(const Op& op, const Term& child1, const Term& child2) const;
3368
3369 /**
3370 * Create ternary term of given kind from a given operator.
3371 * Create operators with mkOp().
3372 * @param op the operator
3373 * @param child1 the first child of the term
3374 * @param child2 the second child of the term
3375 * @param child3 the third child of the term
3376 * @return the Term
3377 */
3378 Term mkTerm(const Op& op,
3379 const Term& child1,
3380 const Term& child2,
3381 const Term& child3) const;
3382
3383 /**
3384 * Create n-ary term of given kind from a given operator.
3385 * Create operators with mkOp().
3386 * @param op the operator
3387 * @param children the children of the term
3388 * @return the Term
3389 */
3390 Term mkTerm(const Op& op, const std::vector<Term>& children) const;
3391
3392 /**
3393 * Create a tuple term. Terms are automatically converted if sorts are
3394 * compatible.
3395 * @param sorts The sorts of the elements in the tuple
3396 * @param terms The elements in the tuple
3397 * @return the tuple Term
3398 */
3399 Term mkTuple(const std::vector<Sort>& sorts,
3400 const std::vector<Term>& terms) const;
3401
3402 /* .................................................................... */
3403 /* Create Operators */
3404 /* .................................................................... */
3405
3406 /**
3407 * Create an operator for a builtin Kind.
3408 *
3409 * The Kind may not be the Kind for an indexed operator
3410 * (e.g. BITVECTOR_EXTRACT).
3411 *
3412 * @note In this case, the ``Op`` simply wraps the ``Kind``. The Kind can be
3413 * used in ``Solver::mkTerm`` directly without creating an ``Op`` first.
3414 * @param kind the kind to wrap
3415 */
3416 Op mkOp(Kind kind) const;
3417
3418 /**
3419 * Create operator of kind:
3420 * - DIVISIBLE (to support arbitrary precision integers)
3421 * See enum Kind for a description of the parameters.
3422 * @param kind the kind of the operator
3423 * @param arg the string argument to this operator
3424 */
3425 Op mkOp(Kind kind, const std::string& arg) const;
3426
3427 /**
3428 * Create operator of kind:
3429 * - DIVISIBLE
3430 * - BITVECTOR_REPEAT
3431 * - BITVECTOR_ZERO_EXTEND
3432 * - BITVECTOR_SIGN_EXTEND
3433 * - BITVECTOR_ROTATE_LEFT
3434 * - BITVECTOR_ROTATE_RIGHT
3435 * - INT_TO_BITVECTOR
3436 * - FLOATINGPOINT_TO_UBV
3437 * - FLOATINGPOINT_TO_UBV_TOTAL
3438 * - FLOATINGPOINT_TO_SBV
3439 * - FLOATINGPOINT_TO_SBV_TOTAL
3440 * - TUPLE_UPDATE
3441 * See enum Kind for a description of the parameters.
3442 * @param kind the kind of the operator
3443 * @param arg the uint32_t argument to this operator
3444 */
3445 Op mkOp(Kind kind, uint32_t arg) const;
3446
3447 /**
3448 * Create operator of Kind:
3449 * - BITVECTOR_EXTRACT
3450 * - FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
3451 * - FLOATINGPOINT_TO_FP_FLOATINGPOINT
3452 * - FLOATINGPOINT_TO_FP_REAL
3453 * - FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
3454 * - FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
3455 * - FLOATINGPOINT_TO_FP_GENERIC
3456 * See enum Kind for a description of the parameters.
3457 * @param kind the kind of the operator
3458 * @param arg1 the first uint32_t argument to this operator
3459 * @param arg2 the second uint32_t argument to this operator
3460 */
3461 Op mkOp(Kind kind, uint32_t arg1, uint32_t arg2) const;
3462
3463 /**
3464 * Create operator of Kind:
3465 * - TUPLE_PROJECT
3466 * See enum Kind for a description of the parameters.
3467 * @param kind the kind of the operator
3468 * @param args the arguments (indices) of the operator
3469 */
3470 Op mkOp(Kind kind, const std::vector<uint32_t>& args) const;
3471
3472 /* .................................................................... */
3473 /* Create Constants */
3474 /* .................................................................... */
3475
3476 /**
3477 * Create a Boolean true constant.
3478 * @return the true constant
3479 */
3480 Term mkTrue() const;
3481
3482 /**
3483 * Create a Boolean false constant.
3484 * @return the false constant
3485 */
3486 Term mkFalse() const;
3487
3488 /**
3489 * Create a Boolean constant.
3490 * @return the Boolean constant
3491 * @param val the value of the constant
3492 */
3493 Term mkBoolean(bool val) const;
3494
3495 /**
3496 * Create a constant representing the number Pi.
3497 * @return a constant representing Pi
3498 */
3499 Term mkPi() const;
3500 /**
3501 * Create an integer constant from a string.
3502 * @param s the string representation of the constant, may represent an
3503 * integer (e.g., "123").
3504 * @return a constant of sort Integer assuming 's' represents an integer)
3505 */
3506 Term mkInteger(const std::string& s) const;
3507
3508 /**
3509 * Create an integer constant from a c++ int.
3510 * @param val the value of the constant
3511 * @return a constant of sort Integer
3512 */
3513 Term mkInteger(int64_t val) const;
3514
3515 /**
3516 * Create a real constant from a string.
3517 * @param s the string representation of the constant, may represent an
3518 * integer (e.g., "123") or real constant (e.g., "12.34" or "12/34").
3519 * @return a constant of sort Real
3520 */
3521 Term mkReal(const std::string& s) const;
3522
3523 /**
3524 * Create a real constant from an integer.
3525 * @param val the value of the constant
3526 * @return a constant of sort Integer
3527 */
3528 Term mkReal(int64_t val) const;
3529
3530 /**
3531 * Create a real constant from a rational.
3532 * @param num the value of the numerator
3533 * @param den the value of the denominator
3534 * @return a constant of sort Real
3535 */
3536 Term mkReal(int64_t num, int64_t den) const;
3537
3538 /**
3539 * Create a regular expression all (re.all) term.
3540 * @return the all term
3541 */
3542 Term mkRegexpAll() const;
3543
3544 /**
3545 * Create a regular expression allchar (re.allchar) term.
3546 * @return the allchar term
3547 */
3548 Term mkRegexpAllchar() const;
3549
3550 /**
3551 * Create a regular expression none (re.none) term.
3552 * @return the none term
3553 */
3554 Term mkRegexpNone() const;
3555
3556 /**
3557 * Create a constant representing an empty set of the given sort.
3558 * @param sort the sort of the set elements.
3559 * @return the empty set constant
3560 */
3561 Term mkEmptySet(const Sort& sort) const;
3562
3563 /**
3564 * Create a constant representing an empty bag of the given sort.
3565 * @param sort the sort of the bag elements.
3566 * @return the empty bag constant
3567 */
3568 Term mkEmptyBag(const Sort& sort) const;
3569
3570 /**
3571 * Create a separation logic empty term.
3572 * @return the separation logic empty term
3573 */
3574 Term mkSepEmp() const;
3575
3576 /**
3577 * Create a separation logic nil term.
3578 * @param sort the sort of the nil term
3579 * @return the separation logic nil term
3580 */
3581 Term mkSepNil(const Sort& sort) const;
3582
3583 /**
3584 * Create a String constant from a `std::string` which may contain SMT-LIB
3585 * compatible escape sequences like `\u1234` to encode unicode characters.
3586 * @param s the string this constant represents
3587 * @param useEscSequences determines whether escape sequences in `s` should
3588 * be converted to the corresponding unicode character
3589 * @return the String constant
3590 */
3591 Term mkString(const std::string& s, bool useEscSequences = false) const;
3592
3593 /**
3594 * Create a String constant from a `std::wstring`.
3595 * This method does not support escape sequences as `std::wstring` already
3596 * supports unicode characters.
3597 * @param s the string this constant represents
3598 * @return the String constant
3599 */
3600 Term mkString(const std::wstring& s) const;
3601
3602 /**
3603 * Create an empty sequence of the given element sort.
3604 * @param sort The element sort of the sequence.
3605 * @return the empty sequence with given element sort.
3606 */
3607 Term mkEmptySequence(const Sort& sort) const;
3608
3609 /**
3610 * Create a universe set of the given sort.
3611 * @param sort the sort of the set elements
3612 * @return the universe set constant
3613 */
3614 Term mkUniverseSet(const Sort& sort) const;
3615
3616 /**
3617 * Create a bit-vector constant of given size and value.
3618 *
3619 * @note The given value must fit into a bit-vector of the given size.
3620 *
3621 * @param size the bit-width of the bit-vector sort
3622 * @param val the value of the constant
3623 * @return the bit-vector constant
3624 */
3625 Term mkBitVector(uint32_t size, uint64_t val = 0) const;
3626
3627 /**
3628 * Create a bit-vector constant of a given bit-width from a given string of
3629 * base 2, 10 or 16.
3630 *
3631 * @note The given value must fit into a bit-vector of the given size.
3632 *
3633 * @param size the bit-width of the constant
3634 * @param s the string representation of the constant
3635 * @param base the base of the string representation (2, 10, or 16)
3636 * @return the bit-vector constant
3637 */
3638 Term mkBitVector(uint32_t size, const std::string& s, uint32_t base) const;
3639
3640 /**
3641 * Create a constant array with the provided constant value stored at every
3642 * index
3643 * @param sort the sort of the constant array (must be an array sort)
3644 * @param val the constant value to store (must match the sort's element sort)
3645 * @return the constant array term
3646 */
3647 Term mkConstArray(const Sort& sort, const Term& val) const;
3648
3649 /**
3650 * Create a positive infinity floating-point constant.
3651 * @param exp Number of bits in the exponent
3652 * @param sig Number of bits in the significand
3653 * @return the floating-point constant
3654 */
3655 Term mkPosInf(uint32_t exp, uint32_t sig) const;
3656
3657 /**
3658 * Create a negative infinity floating-point constant.
3659 * @param exp Number of bits in the exponent
3660 * @param sig Number of bits in the significand
3661 * @return the floating-point constant
3662 */
3663 Term mkNegInf(uint32_t exp, uint32_t sig) const;
3664
3665 /**
3666 * Create a not-a-number (NaN) floating-point constant.
3667 * @param exp Number of bits in the exponent
3668 * @param sig Number of bits in the significand
3669 * @return the floating-point constant
3670 */
3671 Term mkNaN(uint32_t exp, uint32_t sig) const;
3672
3673 /**
3674 * Create a positive zero (+0.0) floating-point constant.
3675 * @param exp Number of bits in the exponent
3676 * @param sig Number of bits in the significand
3677 * @return the floating-point constant
3678 */
3679 Term mkPosZero(uint32_t exp, uint32_t sig) const;
3680
3681 /**
3682 * Create a negative zero (-0.0) floating-point constant.
3683 * @param exp Number of bits in the exponent
3684 * @param sig Number of bits in the significand
3685 * @return the floating-point constant
3686 */
3687 Term mkNegZero(uint32_t exp, uint32_t sig) const;
3688
3689 /**
3690 * Create a roundingmode constant.
3691 * @param rm the floating point rounding mode this constant represents
3692 */
3693 Term mkRoundingMode(RoundingMode rm) const;
3694
3695 /**
3696 * Create uninterpreted constant.
3697 * @param sort Sort of the constant
3698 * @param index Index of the constant
3699 */
3700 Term mkUninterpretedConst(const Sort& sort, int32_t index) const;
3701
3702 /**
3703 * Create an abstract value constant.
3704 * The given index needs to be a positive integer in base 10.
3705 * @param index Index of the abstract value
3706 */
3707 Term mkAbstractValue(const std::string& index) const;
3708
3709 /**
3710 * Create an abstract value constant.
3711 * The given index needs to be positive.
3712 * @param index Index of the abstract value
3713 */
3714 Term mkAbstractValue(uint64_t index) const;
3715
3716 /**
3717 * Create a floating-point constant.
3718 * @param exp Size of the exponent
3719 * @param sig Size of the significand
3720 * @param val Value of the floating-point constant as a bit-vector term
3721 */
3722 Term mkFloatingPoint(uint32_t exp, uint32_t sig, Term val) const;
3723
3724 /**
3725 * Create a cardinality constraint for an uninterpreted sort.
3726 * @param sort the sort the cardinality constraint is for
3727 * @param upperBound the upper bound on the cardinality of the sort
3728 * @return the cardinality constraint
3729 */
3730 Term mkCardinalityConstraint(const Sort& sort, uint32_t upperBound) const;
3731
3732 /* .................................................................... */
3733 /* Create Variables */
3734 /* .................................................................... */
3735
3736 /**
3737 * Create (first-order) constant (0-arity function symbol).
3738 *
3739 * SMT-LIB:
3740 *
3741 * \verbatim embed:rst:leading-asterisk
3742 * .. code:: smtlib
3743 *
3744 * (declare-const <symbol> <sort>)
3745 * (declare-fun <symbol> () <sort>)
3746 * \endverbatim
3747 *
3748 * @param sort the sort of the constant
3749 * @param symbol the name of the constant
3750 * @return the first-order constant
3751 */
3752 Term mkConst(const Sort& sort, const std::string& symbol) const;
3753 /**
3754 * Create (first-order) constant (0-arity function symbol), with a default
3755 * symbol name.
3756 *
3757 * @param sort the sort of the constant
3758 * @return the first-order constant
3759 */
3760 Term mkConst(const Sort& sort) const;
3761
3762 /**
3763 * Create a bound variable to be used in a binder (i.e. a quantifier, a
3764 * lambda, or a witness binder).
3765 * @param sort the sort of the variable
3766 * @param symbol the name of the variable
3767 * @return the variable
3768 */
3769 Term mkVar(const Sort& sort, const std::string& symbol = std::string()) const;
3770
3771 /* .................................................................... */
3772 /* Create datatype constructor declarations */
3773 /* .................................................................... */
3774
3775 DatatypeConstructorDecl mkDatatypeConstructorDecl(const std::string& name);
3776
3777 /* .................................................................... */
3778 /* Create datatype declarations */
3779 /* .................................................................... */
3780
3781 /**
3782 * Create a datatype declaration.
3783 * @param name the name of the datatype
3784 * @param isCoDatatype true if a codatatype is to be constructed
3785 * @return the DatatypeDecl
3786 */
3787 DatatypeDecl mkDatatypeDecl(const std::string& name,
3788 bool isCoDatatype = false);
3789
3790 /**
3791 * Create a datatype declaration.
3792 * Create sorts parameter with Solver::mkParamSort().
3793 * @param name the name of the datatype
3794 * @param param the sort parameter
3795 * @param isCoDatatype true if a codatatype is to be constructed
3796 * @return the DatatypeDecl
3797 */
3798 DatatypeDecl mkDatatypeDecl(const std::string& name,
3799 Sort param,
3800 bool isCoDatatype = false);
3801
3802 /**
3803 * Create a datatype declaration.
3804 * Create sorts parameter with Solver::mkParamSort().
3805 * @param name the name of the datatype
3806 * @param params a list of sort parameters
3807 * @param isCoDatatype true if a codatatype is to be constructed
3808 * @return the DatatypeDecl
3809 */
3810 DatatypeDecl mkDatatypeDecl(const std::string& name,
3811 const std::vector<Sort>& params,
3812 bool isCoDatatype = false);
3813
3814 /* .................................................................... */
3815 /* Formula Handling */
3816 /* .................................................................... */
3817
3818 /**
3819 * Simplify a formula without doing "much" work. Does not involve
3820 * the SAT Engine in the simplification, but uses the current
3821 * definitions, assertions, and the current partial model, if one
3822 * has been constructed. It also involves theory normalization.
3823 * @param t the formula to simplify
3824 * @return the simplified formula
3825 */
3826 Term simplify(const Term& t);
3827
3828 /**
3829 * Assert a formula.
3830 *
3831 * SMT-LIB:
3832 *
3833 * \verbatim embed:rst:leading-asterisk
3834 * .. code:: smtlib
3835 *
3836 * (assert <term>)
3837 * \endverbatim
3838 *
3839 * @param term the formula to assert
3840 */
3841 void assertFormula(const Term& term) const;
3842
3843 /**
3844 * Check satisfiability.
3845 *
3846 * SMT-LIB:
3847 *
3848 * \verbatim embed:rst:leading-asterisk
3849 * .. code:: smtlib
3850 *
3851 * (check-sat)
3852 * \endverbatim
3853 *
3854 * @return the result of the satisfiability check.
3855 */
3856 Result checkSat() const;
3857
3858 /**
3859 * Check satisfiability assuming the given formula.
3860 *
3861 * SMT-LIB:
3862 *
3863 * \verbatim embed:rst:leading-asterisk
3864 * .. code:: smtlib
3865 *
3866 * (check-sat-assuming ( <prop_literal> ))
3867 * \endverbatim
3868 *
3869 * @param assumption the formula to assume
3870 * @return the result of the satisfiability check.
3871 */
3872 Result checkSatAssuming(const Term& assumption) const;
3873
3874 /**
3875 * Check satisfiability assuming the given formulas.
3876 *
3877 * SMT-LIB:
3878 *
3879 * \verbatim embed:rst:leading-asterisk
3880 * .. code:: smtlib
3881 *
3882 * (check-sat-assuming ( <prop_literal>+ ))
3883 * \endverbatim
3884 *
3885 * @param assumptions the formulas to assume
3886 * @return the result of the satisfiability check.
3887 */
3888 Result checkSatAssuming(const std::vector<Term>& assumptions) const;
3889
3890 /**
3891 * Check entailment of the given formula w.r.t. the current set of assertions.
3892 * @param term the formula to check entailment for
3893 * @return the result of the entailment check.
3894 */
3895 Result checkEntailed(const Term& term) const;
3896
3897 /**
3898 * Check entailment of the given set of given formulas w.r.t. the current
3899 * set of assertions.
3900 * @param terms the terms to check entailment for
3901 * @return the result of the entailmentcheck.
3902 */
3903 Result checkEntailed(const std::vector<Term>& terms) const;
3904
3905 /**
3906 * Create datatype sort.
3907 *
3908 * SMT-LIB:
3909 *
3910 * \verbatim embed:rst:leading-asterisk
3911 * .. code:: smtlib
3912 *
3913 * (declare-datatype <symbol> <datatype_decl>)
3914 * \endverbatim
3915 *
3916 * @param symbol the name of the datatype sort
3917 * @param ctors the constructor declarations of the datatype sort
3918 * @return the datatype sort
3919 */
3920 Sort declareDatatype(const std::string& symbol,
3921 const std::vector<DatatypeConstructorDecl>& ctors) const;
3922
3923 /**
3924 * Declare n-ary function symbol.
3925 *
3926 * SMT-LIB:
3927 *
3928 * \verbatim embed:rst:leading-asterisk
3929 * .. code:: smtlib
3930 *
3931 * (declare-fun <symbol> ( <sort>* ) <sort>)
3932 * \endverbatim
3933 *
3934 * @param symbol the name of the function
3935 * @param sorts the sorts of the parameters to this function
3936 * @param sort the sort of the return value of this function
3937 * @return the function
3938 */
3939 Term declareFun(const std::string& symbol,
3940 const std::vector<Sort>& sorts,
3941 const Sort& sort) const;
3942
3943 /**
3944 * Declare uninterpreted sort.
3945 *
3946 * SMT-LIB:
3947 *
3948 * \verbatim embed:rst:leading-asterisk
3949 * .. code:: smtlib
3950 *
3951 * (declare-sort <symbol> <numeral>)
3952 * \endverbatim
3953 *
3954 * @param symbol the name of the sort
3955 * @param arity the arity of the sort
3956 * @return the sort
3957 */
3958 Sort declareSort(const std::string& symbol, uint32_t arity) const;
3959
3960 /**
3961 * Define n-ary function.
3962 *
3963 * SMT-LIB:
3964 *
3965 * \verbatim embed:rst:leading-asterisk
3966 * .. code:: smtlib
3967 *
3968 * (define-fun <function_def>)
3969 * \endverbatim
3970 *
3971 * @param symbol the name of the function
3972 * @param bound_vars the parameters to this function
3973 * @param sort the sort of the return value of this function
3974 * @param term the function body
3975 * @param global determines whether this definition is global (i.e. persists
3976 * when popping the context)
3977 * @return the function
3978 */
3979 Term defineFun(const std::string& symbol,
3980 const std::vector<Term>& bound_vars,
3981 const Sort& sort,
3982 const Term& term,
3983 bool global = false) const;
3984
3985 /**
3986 * Define recursive function.
3987 *
3988 * SMT-LIB:
3989 *
3990 * \verbatim embed:rst:leading-asterisk
3991 * .. code:: smtlib
3992 *
3993 * (define-fun-rec <function_def>)
3994 * \endverbatim
3995 *
3996 * @param symbol the name of the function
3997 * @param bound_vars the parameters to this function
3998 * @param sort the sort of the return value of this function
3999 * @param term the function body
4000 * @param global determines whether this definition is global (i.e. persists
4001 * when popping the context)
4002 * @return the function
4003 */
4004 Term defineFunRec(const std::string& symbol,
4005 const std::vector<Term>& bound_vars,
4006 const Sort& sort,
4007 const Term& term,
4008 bool global = false) const;
4009
4010 /**
4011 * Define recursive function.
4012 *
4013 * SMT-LIB:
4014 *
4015 * \verbatim embed:rst:leading-asterisk
4016 * .. code:: smtlib
4017 *
4018 * (define-fun-rec <function_def>)
4019 * \endverbatim
4020 *
4021 * Create parameter 'fun' with mkConst().
4022 * @param fun the sorted function
4023 * @param bound_vars the parameters to this function
4024 * @param term the function body
4025 * @param global determines whether this definition is global (i.e. persists
4026 * when popping the context)
4027 * @return the function
4028 */
4029 Term defineFunRec(const Term& fun,
4030 const std::vector<Term>& bound_vars,
4031 const Term& term,
4032 bool global = false) const;
4033
4034 /**
4035 * Define recursive functions.
4036 *
4037 * SMT-LIB:
4038 *
4039 * \verbatim embed:rst:leading-asterisk
4040 * .. code:: smtlib
4041 *
4042 * (define-funs-rec
4043 * ( <function_decl>_1 ... <function_decl>_n )
4044 * ( <term>_1 ... <term>_n )
4045 * )
4046 * \endverbatim
4047 *
4048 * Create elements of parameter 'funs' with mkConst().
4049 * @param funs the sorted functions
4050 * @param bound_vars the list of parameters to the functions
4051 * @param terms the list of function bodies of the functions
4052 * @param global determines whether this definition is global (i.e. persists
4053 * when popping the context)
4054 * @return the function
4055 */
4056 void defineFunsRec(const std::vector<Term>& funs,
4057 const std::vector<std::vector<Term>>& bound_vars,
4058 const std::vector<Term>& terms,
4059 bool global = false) const;
4060
4061 /**
4062 * Echo a given string to the given output stream.
4063 *
4064 * SMT-LIB:
4065 *
4066 * \verbatim embed:rst:leading-asterisk
4067 * .. code:: smtlib
4068 *
4069 * (echo <string>)
4070 * \endverbatim
4071 *
4072 * @param out the output stream
4073 * @param str the string to echo
4074 */
4075 void echo(std::ostream& out, const std::string& str) const;
4076
4077 /**
4078 * Get the list of asserted formulas.
4079 *
4080 * SMT-LIB:
4081 *
4082 * \verbatim embed:rst:leading-asterisk
4083 * .. code:: smtlib
4084 *
4085 * (get-assertions)
4086 * \endverbatim
4087 *
4088 * @return the list of asserted formulas
4089 */
4090 std::vector<Term> getAssertions() const;
4091
4092 /**
4093 * Get info from the solver.
4094 *
4095 * SMT-LIB:
4096 *
4097 * \verbatim embed:rst:leading-asterisk
4098 * .. code:: smtlib
4099 *
4100 * (get-info <info_flag>)
4101 * \endverbatim
4102 *
4103 * @return the info
4104 */
4105 std::string getInfo(const std::string& flag) const;
4106
4107 /**
4108 * Get the value of a given option.
4109 *
4110 * SMT-LIB:
4111 *
4112 * \verbatim embed:rst:leading-asterisk
4113 * .. code:: smtlib
4114 *
4115 * (get-option <keyword>)
4116 * \endverbatim
4117 *
4118 * @param option the option for which the value is queried
4119 * @return a string representation of the option value
4120 */
4121 std::string getOption(const std::string& option) const;
4122
4123 /**
4124 * Get all option names that can be used with `setOption`, `getOption` and
4125 * `getOptionInfo`.
4126 * @return all option names
4127 */
4128 std::vector<std::string> getOptionNames() const;
4129
4130 /**
4131 * Get some information about the given option. Check the `OptionInfo` class
4132 * for more details on which information is available.
4133 * @return information about the given option
4134 */
4135 OptionInfo getOptionInfo(const std::string& option) const;
4136
4137 /**
4138 * Get the driver options, which provide access to options that can not be
4139 * communicated properly via getOption() and getOptionInfo().
4140 * @return a DriverOptions object.
4141 */
4142 DriverOptions getDriverOptions() const;
4143
4144 /**
4145 * Get the set of unsat ("failed") assumptions.
4146 *
4147 * SMT-LIB:
4148 *
4149 * \verbatim embed:rst:leading-asterisk
4150 * .. code:: smtlib
4151 *
4152 * (get-unsat-assumptions)
4153 *
4154 * Requires to enable option
4155 * :ref:`produce-unsat-assumptions <lbl-option-produce-unsat-assumptions>`.
4156 * \endverbatim
4157 *
4158 * @return the set of unsat assumptions.
4159 */
4160 std::vector<Term> getUnsatAssumptions() const;
4161
4162 /**
4163 * Get the unsatisfiable core.
4164 *
4165 * SMT-LIB:
4166 *
4167 * \verbatim embed:rst:leading-asterisk
4168 * .. code:: smtlib
4169 *
4170 * (get-unsat-core)
4171 *
4172 * Requires to enable option
4173 * :ref:`produce-unsat-cores <lbl-option-produce-unsat-cores>`.
4174 * \endverbatim
4175 *
4176 * @return a set of terms representing the unsatisfiable core
4177 */
4178 std::vector<Term> getUnsatCore() const;
4179
4180 /**
4181 * Get a difficulty estimate for an asserted formula. This method is
4182 * intended to be called immediately after any response to a checkSat.
4183 *
4184 * @return a map from (a subset of) the input assertions to a real value that
4185 * is an estimate of how difficult each assertion was to solve.
4186 * Unmentioned assertions can be assumed to have zero difficulty.
4187 */
4188 std::map<Term, Term> getDifficulty() const;
4189
4190 /**
4191 * Get the refutation proof
4192 *
4193 * SMT-LIB:
4194 *
4195 * \verbatim embed:rst:leading-asterisk
4196 * .. code:: smtlib
4197 *
4198 * (get-proof)
4199 *
4200 * Requires to enable option
4201 * :ref:`produce-proofs <lbl-option-produce-proofs>`.
4202 * \endverbatim
4203 *
4204 * @return a string representing the proof, according to the value of
4205 * proof-format-mode.
4206 */
4207 std::string getProof() const;
4208
4209 /**
4210 * Get the value of the given term in the current model.
4211 *
4212 * SMT-LIB:
4213 *
4214 * \verbatim embed:rst:leading-asterisk
4215 * .. code:: smtlib
4216 *
4217 * (get-value ( <term> ))
4218 * \endverbatim
4219 *
4220 * @param term the term for which the value is queried
4221 * @return the value of the given term
4222 */
4223 Term getValue(const Term& term) const;
4224
4225 /**
4226 * Get the values of the given terms in the current model.
4227 *
4228 * SMT-LIB:
4229 *
4230 * \verbatim embed:rst:leading-asterisk
4231 * .. code:: smtlib
4232 *
4233 * (get-value ( <term>* ))
4234 * \endverbatim
4235 *
4236 * @param terms the terms for which the value is queried
4237 * @return the values of the given terms
4238 */
4239 std::vector<Term> getValue(const std::vector<Term>& terms) const;
4240
4241 /**
4242 * Get the domain elements of uninterpreted sort s in the current model. The
4243 * current model interprets s as the finite sort whose domain elements are
4244 * given in the return value of this method.
4245 *
4246 * @param s The uninterpreted sort in question
4247 * @return the domain elements of s in the current model
4248 */
4249 std::vector<Term> getModelDomainElements(const Sort& s) const;
4250
4251 /**
4252 * This returns false if the model value of free constant v was not essential
4253 * for showing the satisfiability of the last call to checkSat using the
4254 * current model. This method will only return false (for any v) if
4255 * option
4256 * \verbatim:rst:inline
4257 * :ref:`model-cores <lbl-option-model-cores>`
4258 * \endverbatim
4259 * has been set.
4260 *
4261 * @param v The term in question
4262 * @return true if v is a model core symbol
4263 */
4264 bool isModelCoreSymbol(const Term& v) const;
4265
4266 /**
4267 * Get the model
4268 *
4269 * SMT-LIB:
4270 *
4271 * \verbatim embed:rst:leading-asterisk
4272 * .. code:: smtlib
4273 *
4274 * (get-model)
4275 *
4276 * Requires to enable option
4277 * :ref:`produce-models <lbl-option-produce-models>`.
4278 * \endverbatim
4279 *
4280 * \endverbatim
4281 *
4282 * @param sorts The list of uninterpreted sorts that should be printed in the
4283 * model.
4284 * @param vars The list of free constants that should be printed in the
4285 * model. A subset of these may be printed based on isModelCoreSymbol.
4286 * @return a string representing the model.
4287 */
4288 std::string getModel(const std::vector<Sort>& sorts,
4289 const std::vector<Term>& vars) const;
4290
4291 /**
4292 * Do quantifier elimination.
4293 *
4294 * SMT-LIB:
4295 *
4296 * \verbatim embed:rst:leading-asterisk
4297 * .. code:: smtlib
4298 *
4299 * (get-qe <q>)
4300 * \endverbatim
4301 *
4302 * Requires a logic that supports quantifier elimination. Currently, the only
4303 * logics supported by quantifier elimination is LRA and LIA.
4304 *
4305 * @note Quantifier Elimination is is only complete for LRA and LIA.
4306 *
4307 * @param q a quantified formula of the form
4308 * @f$Q\bar{x}_1... Q\bar{x}_n. P( x_1...x_i, y_1...y_j)@f$
4309 * where
4310 * @f$Q\bar{x}@f$ is a set of quantified variables of the form
4311 * @f$Q x_1...x_k@f$ and
4312 * @f$P( x_1...x_i, y_1...y_j )@f$ is a quantifier-free formula
4313 * @return a formula @f$\phi@f$ such that, given the current set of formulas
4314 * @f$A@f$ asserted to this solver:
4315 * - @f$(A \wedge q)@f$ and @f$(A \wedge \phi)@f$ are equivalent
4316 * - @f$\phi@f$ is quantifier-free formula containing only free
4317 * variables in @f$y_1...y_n@f$.
4318 */
4319 Term getQuantifierElimination(const Term& q) const;
4320
4321 /**
4322 * Do partial quantifier elimination, which can be used for incrementally
4323 * computing the result of a quantifier elimination.
4324 *
4325 * SMT-LIB:
4326 *
4327 * \verbatim embed:rst:leading-asterisk
4328 * .. code:: smtlib
4329 *
4330 * (get-qe-disjunct <q>)
4331 * \endverbatim
4332 *
4333 * Requires a logic that supports quantifier elimination. Currently, the only
4334 * logics supported by quantifier elimination is LRA and LIA.
4335 * @param q a quantified formula of the form
4336 * @f$Q\bar{x}_1... Q\bar{x}_n. P( x_1...x_i, y_1...y_j)@f$
4337 * where
4338 * @f$Q\bar{x}@f$ is a set of quantified variables of the form
4339 * @f$Q x_1...x_k@f$ and
4340 * @f$P( x_1...x_i, y_1...y_j )@f$ is a quantifier-free formula
4341 * @return a formula @f$\phi@f$ such that, given the current set of formulas
4342 * @f$A@f$ asserted to this solver:
4343 * - @f$(A \wedge q \implies A \wedge \phi)@f$ if @f$Q@f$ is
4344 * @f$\forall@f$, and @f$(A \wedge \phi \implies A \wedge q)@f$ if
4345 * @f$Q@f$ is @f$\exists@f$
4346 * - @f$\phi@f$ is quantifier-free formula containing only free
4347 * variables in @f$y_1...y_n@f$
4348 * - If @f$Q@f$ is @f$\exists@f$, let @f$(A \wedge Q_n)@f$ be the
4349 * formula
4350 * @f$(A \wedge \neg (\phi \wedge Q_1) \wedge ... \wedge
4351 * \neg (\phi \wedge Q_n))@f$
4352 * where for each @f$i = 1...n@f$,
4353 * formula @f$(\phi \wedge Q_i)@f$ is the result of calling
4354 * Solver::getQuantifierEliminationDisjunct() for @f$q@f$ with the
4355 * set of assertions @f$(A \wedge Q_{i-1})@f$.
4356 * Similarly, if @f$Q@f$ is @f$\forall@f$, then let
4357 * @f$(A \wedge Q_n)@f$ be
4358 * @f$(A \wedge (\phi \wedge Q_1) \wedge ... \wedge (\phi \wedge
4359 * Q_n))@f$
4360 * where @f$(\phi \wedge Q_i)@f$ is the same as above.
4361 * In either case, we have that @f$(\phi \wedge Q_j)@f$ will
4362 * eventually be true or false, for some finite j.
4363 */
4364 Term getQuantifierEliminationDisjunct(const Term& q) const;
4365
4366 /**
4367 * When using separation logic, this sets the location sort and the
4368 * datatype sort to the given ones. This method should be invoked exactly
4369 * once, before any separation logic constraints are provided.
4370 * @param locSort The location sort of the heap
4371 * @param dataSort The data sort of the heap
4372 */
4373 void declareSepHeap(const Sort& locSort, const Sort& dataSort) const;
4374
4375 /**
4376 * When using separation logic, obtain the term for the heap.
4377 * @return The term for the heap
4378 */
4379 Term getValueSepHeap() const;
4380
4381 /**
4382 * When using separation logic, obtain the term for nil.
4383 * @return The term for nil
4384 */
4385 Term getValueSepNil() const;
4386
4387 /**
4388 * Declare a symbolic pool of terms with the given initial value.
4389 *
4390 * SMT-LIB:
4391 *
4392 * \verbatim embed:rst:leading-asterisk
4393 * .. code:: smtlib
4394 *
4395 * (declare-pool <symbol> <sort> ( <term>* ))
4396 * \endverbatim
4397 *
4398 * @param symbol The name of the pool
4399 * @param sort The sort of the elements of the pool.
4400 * @param initValue The initial value of the pool
4401 */
4402 Term declarePool(const std::string& symbol,
4403 const Sort& sort,
4404 const std::vector<Term>& initValue) const;
4405 /**
4406 * Pop (a) level(s) from the assertion stack.
4407 *
4408 * SMT-LIB:
4409 *
4410 * \verbatim embed:rst:leading-asterisk
4411 * .. code:: smtlib
4412 *
4413 * (pop <numeral>)
4414 * \endverbatim
4415 *
4416 * @param nscopes the number of levels to pop
4417 */
4418 void pop(uint32_t nscopes = 1) const;
4419
4420 /**
4421 * Get an interpolant
4422 *
4423 * SMT-LIB:
4424 *
4425 * \verbatim embed:rst:leading-asterisk
4426 * .. code:: smtlib
4427 *
4428 * (get-interpol <conj>)
4429 *
4430 * Requires to enable option
4431 * :ref:`produce-interpols <lbl-option-produce-interpols>`.
4432 * \endverbatim
4433 *
4434 * @param conj the conjecture term
4435 * @param output a Term I such that A->I and I->B are valid, where A is the
4436 * current set of assertions and B is given in the input by conj.
4437 * @return true if it gets I successfully, false otherwise.
4438 */
4439 bool getInterpolant(const Term& conj, Term& output) const;
4440
4441 /**
4442 * Get an interpolant
4443 *
4444 * SMT-LIB:
4445 *
4446 * \verbatim embed:rst:leading-asterisk
4447 * .. code:: smtlib
4448 *
4449 * (get-interpol <conj> <grammar>)
4450 *
4451 * Requires to enable option
4452 * :ref:`produce-interpols <lbl-option-produce-interpols>`.
4453 * \endverbatim
4454 *
4455 * @param conj the conjecture term
4456 * @param grammar the grammar for the interpolant I
4457 * @param output a Term I such that A->I and I->B are valid, where A is the
4458 * current set of assertions and B is given in the input by conj.
4459 * @return true if it gets I successfully, false otherwise.
4460 */
4461 bool getInterpolant(const Term& conj, Grammar& grammar, Term& output) const;
4462
4463 /**
4464 * Get an abduct.
4465 *
4466 * SMT-LIB:
4467 *
4468 * \verbatim embed:rst:leading-asterisk
4469 * .. code:: smtlib
4470 *
4471 * (get-abduct <conj>)
4472 *
4473 * Requires to enable option
4474 * :ref:`produce-abducts <lbl-option-produce-abducts>`.
4475 * \endverbatim
4476 *
4477 * @param conj the conjecture term
4478 * @param output a term @f$C@f$ such that @f$(A \wedge C)@f$ is satisfiable,
4479 * and @f$(A \wedge \neg B \wedge C)@f$ is unsatisfiable, where
4480 * @f$A@f$ is the current set of assertions and @f$B@f$ is
4481 * given in the input by ``conj``.
4482 * @return true if it gets abduct @f$C@f$ successfully, false otherwise
4483 */
4484 bool getAbduct(const Term& conj, Term& output) const;
4485
4486 /**
4487 * Get an abduct.
4488 *
4489 * SMT-LIB:
4490 *
4491 * \verbatim embed:rst:leading-asterisk
4492 * .. code:: smtlib
4493 *
4494 * (get-abduct <conj> <grammar>)
4495 *
4496 * Requires to enable option
4497 * :ref:`produce-abducts <lbl-option-produce-abducts>`.
4498 * \endverbatim
4499 *
4500 * @param conj the conjecture term
4501 * @param grammar the grammar for the abduct @f$C@f$
4502 * @param output a term C such that @f$(A \wedge C)@f$ is satisfiable, and
4503 * @f$(A \wedge \neg B \wedge C)@f$ is unsatisfiable, where @f$A@f$ is
4504 * the current set of assertions and @f$B@f$ is given in the input by
4505 * ``conj``
4506 * @return true if it gets abduct @f$C@f$ successfully, false otherwise
4507 */
4508 bool getAbduct(const Term& conj, Grammar& grammar, Term& output) const;
4509
4510 /**
4511 * Block the current model. Can be called only if immediately preceded by a
4512 * SAT or INVALID query.
4513 *
4514 * SMT-LIB:
4515 *
4516 * \verbatim embed:rst:leading-asterisk
4517 * .. code:: smtlib
4518 *
4519 * (block-model)
4520 *
4521 * Requires enabling option
4522 * :ref:`produce-models <lbl-option-produce-models>`.
4523 * 'produce-models' and setting option
4524 * :ref:`block-models <lbl-option-block-models>`.
4525 * to a mode other than ``none``.
4526 * \endverbatim
4527 */
4528 void blockModel() const;
4529
4530 /**
4531 * Block the current model values of (at least) the values in terms. Can be
4532 * called only if immediately preceded by a SAT or NOT_ENTAILED query.
4533 *
4534 * SMT-LIB:
4535 *
4536 * \verbatim embed:rst:leading-asterisk
4537 * .. code:: smtlib
4538 *
4539 * (block-model-values ( <terms>+ ))
4540 *
4541 * Requires enabling option
4542 * :ref:`produce-models <lbl-option-produce-models>`.
4543 * 'produce-models' and setting option
4544 * :ref:`block-models <lbl-option-block-models>`.
4545 * to a mode other than ``none``.
4546 * \endverbatim
4547 */
4548 void blockModelValues(const std::vector<Term>& terms) const;
4549
4550 /**
4551 * Print all instantiations made by the quantifiers module.
4552 * @param out the output stream
4553 */
4554 void printInstantiations(std::ostream& out) const;
4555
4556 /**
4557 * Push (a) level(s) to the assertion stack.
4558 *
4559 * SMT-LIB:
4560 *
4561 * \verbatim embed:rst:leading-asterisk
4562 * .. code:: smtlib
4563 *
4564 * (push <numeral>)
4565 * \endverbatim
4566 *
4567 * @param nscopes the number of levels to push
4568 */
4569 void push(uint32_t nscopes = 1) const;
4570
4571 /**
4572 * Remove all assertions.
4573 *
4574 * SMT-LIB:
4575 *
4576 * \verbatim embed:rst:leading-asterisk
4577 * .. code:: smtlib
4578 *
4579 * (reset-assertions)
4580 * \endverbatim
4581 *
4582 */
4583 void resetAssertions() const;
4584
4585 /**
4586 * Set info.
4587 *
4588 * SMT-LIB:
4589 *
4590 * \verbatim embed:rst:leading-asterisk
4591 * .. code:: smtlib
4592 *
4593 * (set-info <attribute>)
4594 * \endverbatim
4595 *
4596 * @param keyword the info flag
4597 * @param value the value of the info flag
4598 */
4599 void setInfo(const std::string& keyword, const std::string& value) const;
4600
4601 /**
4602 * Set logic.
4603 *
4604 * SMT-LIB:
4605 *
4606 * \verbatim embed:rst:leading-asterisk
4607 * .. code:: smtlib
4608 *
4609 * (set-logic <symbol>)
4610 * \endverbatim
4611 *
4612 * @param logic the logic to set
4613 */
4614 void setLogic(const std::string& logic) const;
4615
4616 /**
4617 * Set option.
4618 *
4619 * SMT-LIB:
4620 *
4621 * \verbatim embed:rst:leading-asterisk
4622 * .. code:: smtlib
4623 *
4624 * (set-option :<option> <value>)
4625 * \endverbatim
4626 *
4627 * @param option the option name
4628 * @param value the option value
4629 */
4630 void setOption(const std::string& option, const std::string& value) const;
4631
4632 /**
4633 * If needed, convert this term to a given sort.
4634 *
4635 * @note The sort of the term must be convertible into the target sort.
4636 * Currently only Int to Real conversions are supported.
4637 * @param t the term
4638 * @param s the target sort
4639 * @return the term wrapped into a sort conversion if needed
4640 */
4641 Term ensureTermSort(const Term& t, const Sort& s) const;
4642
4643 /**
4644 * Append \p symbol to the current list of universal variables.
4645 *
4646 * SyGuS v2:
4647 *
4648 * \verbatim embed:rst:leading-asterisk
4649 * .. code:: smtlib
4650 *
4651 * (declare-var <symbol> <sort>)
4652 * \endverbatim
4653 *
4654 * @param sort the sort of the universal variable
4655 * @param symbol the name of the universal variable
4656 * @return the universal variable
4657 */
4658 Term mkSygusVar(const Sort& sort,
4659 const std::string& symbol = std::string()) const;
4660
4661 /**
4662 * Create a Sygus grammar. The first non-terminal is treated as the starting
4663 * non-terminal, so the order of non-terminals matters.
4664 *
4665 * @param boundVars the parameters to corresponding synth-fun/synth-inv
4666 * @param ntSymbols the pre-declaration of the non-terminal symbols
4667 * @return the grammar
4668 */
4669 Grammar mkSygusGrammar(const std::vector<Term>& boundVars,
4670 const std::vector<Term>& ntSymbols) const;
4671
4672 /**
4673 * Synthesize n-ary function.
4674 *
4675 * SyGuS v2:
4676 *
4677 * \verbatim embed:rst:leading-asterisk
4678 * .. code:: smtlib
4679 *
4680 * (synth-fun <symbol> ( <boundVars>* ) <sort>)
4681 * \endverbatim
4682 *
4683 * @param symbol the name of the function
4684 * @param boundVars the parameters to this function
4685 * @param sort the sort of the return value of this function
4686 * @return the function
4687 */
4688 Term synthFun(const std::string& symbol,
4689 const std::vector<Term>& boundVars,
4690 const Sort& sort) const;
4691
4692 /**
4693 * Synthesize n-ary function following specified syntactic constraints.
4694 *
4695 * SyGuS v2:
4696 *
4697 * \verbatim embed:rst:leading-asterisk
4698 * .. code:: smtlib
4699 *
4700 * (synth-fun <symbol> ( <boundVars>* ) <sort> <grammar>)
4701 * \endverbatim
4702 *
4703 * @param symbol the name of the function
4704 * @param boundVars the parameters to this function
4705 * @param sort the sort of the return value of this function
4706 * @param grammar the syntactic constraints
4707 * @return the function
4708 */
4709 Term synthFun(const std::string& symbol,
4710 const std::vector<Term>& boundVars,
4711 Sort sort,
4712 Grammar& grammar) const;
4713
4714 /**
4715 * Synthesize invariant.
4716 *
4717 * SyGuS v2:
4718 *
4719 * \verbatim embed:rst:leading-asterisk
4720 * .. code:: smtlib
4721 *
4722 * (synth-inv <symbol> ( <boundVars>* ))
4723 * \endverbatim
4724 *
4725 * @param symbol the name of the invariant
4726 * @param boundVars the parameters to this invariant
4727 * @return the invariant
4728 */
4729 Term synthInv(const std::string& symbol,
4730 const std::vector<Term>& boundVars) const;
4731
4732 /**
4733 * Synthesize invariant following specified syntactic constraints.
4734 *
4735 * SyGuS v2:
4736 *
4737 * \verbatim embed:rst:leading-asterisk
4738 * .. code:: smtlib
4739 *
4740 * (synth-inv <symbol> ( <boundVars>* ) <grammar>)
4741 * \endverbatim
4742 *
4743 * @param symbol the name of the invariant
4744 * @param boundVars the parameters to this invariant
4745 * @param grammar the syntactic constraints
4746 * @return the invariant
4747 */
4748 Term synthInv(const std::string& symbol,
4749 const std::vector<Term>& boundVars,
4750 Grammar& grammar) const;
4751
4752 /**
4753 * Add a forumla to the set of Sygus constraints.
4754 *
4755 * SyGuS v2:
4756 *
4757 * \verbatim embed:rst:leading-asterisk
4758 * .. code:: smtlib
4759 *
4760 * (constraint <term>)
4761 * \endverbatim
4762 *
4763 * @param term the formula to add as a constraint
4764 */
4765 void addSygusConstraint(const Term& term) const;
4766
4767 /**
4768 * Add a forumla to the set of Sygus assumptions.
4769 *
4770 * SyGuS v2:
4771 *
4772 * \verbatim embed:rst:leading-asterisk
4773 * .. code:: smtlib
4774 *
4775 * (assume <term>)
4776 * \endverbatim
4777 *
4778 * @param term the formula to add as an assumption
4779 */
4780 void addSygusAssume(const Term& term) const;
4781
4782 /**
4783 * Add a set of Sygus constraints to the current state that correspond to an
4784 * invariant synthesis problem.
4785 *
4786 * SyGuS v2:
4787 *
4788 * \verbatim embed:rst:leading-asterisk
4789 * .. code:: smtlib
4790 *
4791 * (inv-constraint <inv> <pre> <trans> <post>)
4792 * \endverbatim
4793 *
4794 * @param inv the function-to-synthesize
4795 * @param pre the pre-condition
4796 * @param trans the transition relation
4797 * @param post the post-condition
4798 */
4799 void addSygusInvConstraint(Term inv, Term pre, Term trans, Term post) const;
4800
4801 /**
4802 * Try to find a solution for the synthesis conjecture corresponding to the
4803 * current list of functions-to-synthesize, universal variables and
4804 * constraints.
4805 *
4806 * SyGuS v2:
4807 *
4808 * \verbatim embed:rst:leading-asterisk
4809 * .. code:: smtlib
4810 *
4811 * (check-synth)
4812 * \endverbatim
4813 *
4814 * @return the result of the synthesis conjecture.
4815 */
4816 Result checkSynth() const;
4817
4818 /**
4819 * Get the synthesis solution of the given term. This method should be called
4820 * immediately after the solver answers unsat for sygus input.
4821 * @param term the term for which the synthesis solution is queried
4822 * @return the synthesis solution of the given term
4823 */
4824 Term getSynthSolution(Term term) const;
4825
4826 /**
4827 * Get the synthesis solutions of the given terms. This method should be
4828 * called immediately after the solver answers unsat for sygus input.
4829 * @param terms the terms for which the synthesis solutions is queried
4830 * @return the synthesis solutions of the given terms
4831 */
4832 std::vector<Term> getSynthSolutions(const std::vector<Term>& terms) const;
4833
4834 /**
4835 * Returns a snapshot of the current state of the statistic values of this
4836 * solver. The returned object is completely decoupled from the solver and
4837 * will not change when the solver is used again.
4838 */
4839 Statistics getStatistics() const;
4840
4841 /**
4842 * Whether the output stream for the given tag is enabled. Tags can be enabled
4843 * with the `output` option (and `-o <tag>` on the command line). Raises an
4844 * exception when an invalid tag is given.
4845 */
4846 bool isOutputOn(const std::string& tag) const;
4847
4848 /**
4849 * Returns an output stream for the given tag. Tags can be enabled with the
4850 * `output` option (and `-o <tag>` on the command line). Raises an exception
4851 * when an invalid tag is given.
4852 */
4853 std::ostream& getOutput(const std::string& tag) const;
4854
4855 private:
4856 /** @return the node manager of this solver */
4857 NodeManager* getNodeManager(void) const;
4858 /** Reset the API statistics */
4859 void resetStatistics();
4860
4861 /**
4862 * Print the statistics to the given file descriptor, suitable for usage in
4863 * signal handlers.
4864 */
4865 void printStatisticsSafe(int fd) const;
4866
4867 /** Helper to check for API misuse in mkOp functions. */
4868 void checkMkTerm(Kind kind, uint32_t nchildren) const;
4869 /** Helper for mk-functions that call d_nodeMgr->mkConst(). */
4870 template <typename T>
4871 Term mkValHelper(const T& t) const;
4872 /** Helper for making rational values. */
4873 Term mkRationalValHelper(const Rational& r, bool isInt = true) const;
4874 /** Helper for mkReal functions that take a string as argument. */
4875 Term mkRealOrIntegerFromStrHelper(const std::string& s,
4876 bool isInt = true) const;
4877 /** Helper for mkBitVector functions that take a string as argument. */
4878 Term mkBVFromStrHelper(const std::string& s, uint32_t base) const;
4879 /**
4880 * Helper for mkBitVector functions that take a string and a size as
4881 * arguments.
4882 */
4883 Term mkBVFromStrHelper(uint32_t size,
4884 const std::string& s,
4885 uint32_t base) const;
4886 /** Helper for mkBitVector functions that take an integer as argument. */
4887 Term mkBVFromIntHelper(uint32_t size, uint64_t val) const;
4888 /** Helper for functions that create tuple sorts. */
4889 Sort mkTupleSortHelper(const std::vector<Sort>& sorts) const;
4890 /** Helper for mkTerm functions that create Term from a Kind */
4891 Term mkTermFromKind(Kind kind) const;
4892 /** Helper for mkChar functions that take a string as argument. */
4893 Term mkCharFromStrHelper(const std::string& s) const;
4894 /** Get value helper, which accounts for subtyping */
4895 Term getValueHelper(const Term& term) const;
4896
4897 /**
4898 * Helper function that ensures that a given term is of sort real (as opposed
4899 * to being of sort integer).
4900 * @param t a term of sort integer or real
4901 * @return a term of sort real
4902 */
4903 Term ensureRealSort(const Term& t) const;
4904
4905 /**
4906 * Create n-ary term of given kind. This handles the cases of left/right
4907 * associative operators, chainable operators, and cases when the number of
4908 * children exceeds the maximum arity for the kind.
4909 * @param kind the kind of the term
4910 * @param children the children of the term
4911 * @return the Term
4912 */
4913 Term mkTermHelper(Kind kind, const std::vector<Term>& children) const;
4914
4915 /**
4916 * Create n-ary term of given kind from a given operator.
4917 * @param op the operator
4918 * @param children the children of the term
4919 * @return the Term
4920 */
4921 Term mkTermHelper(const Op& op, const std::vector<Term>& children) const;
4922
4923 /**
4924 * Create a vector of datatype sorts, using unresolved sorts.
4925 * @param dtypedecls the datatype declarations from which the sort is created
4926 * @param unresolvedSorts the list of unresolved sorts
4927 * @return the datatype sorts
4928 */
4929 std::vector<Sort> mkDatatypeSortsInternal(
4930 const std::vector<DatatypeDecl>& dtypedecls,
4931 const std::set<Sort>& unresolvedSorts) const;
4932
4933 /**
4934 * Synthesize n-ary function following specified syntactic constraints.
4935 *
4936 * SMT-LIB:
4937 *
4938 * \verbatim embed:rst:leading-asterisk
4939 * .. code:: smtlib
4940 *
4941 * (synth-fun <symbol> ( <boundVars>* ) <sort> <grammar>?)
4942 * \endverbatim
4943 *
4944 * @param symbol the name of the function
4945 * @param boundVars the parameters to this function
4946 * @param sort the sort of the return value of this function
4947 * @param isInv determines whether this is synth-fun or synth-inv
4948 * @param grammar the syntactic constraints
4949 * @return the function
4950 */
4951 Term synthFunHelper(const std::string& symbol,
4952 const std::vector<Term>& boundVars,
4953 const Sort& sort,
4954 bool isInv = false,
4955 Grammar* grammar = nullptr) const;
4956
4957 /** Check whether string s is a valid decimal integer. */
4958 bool isValidInteger(const std::string& s) const;
4959
4960 /** Increment the term stats counter. */
4961 void increment_term_stats(Kind kind) const;
4962 /** Increment the vars stats (if 'is_var') or consts stats counter. */
4963 void increment_vars_consts_stats(const Sort& sort, bool is_var) const;
4964
4965 /** Keep a copy of the original option settings (for resets). */
4966 std::unique_ptr<Options> d_originalOptions;
4967 /** The node manager of this solver. */
4968 NodeManager* d_nodeMgr;
4969 /** The statistics collected on the Api level. */
4970 std::unique_ptr<APIStatistics> d_stats;
4971 /** The SMT engine of this solver. */
4972 std::unique_ptr<SolverEngine> d_slv;
4973 /** The random number generator of this solver. */
4974 std::unique_ptr<Random> d_rng;
4975 };
4976
4977 } // namespace cvc5::api
4978
4979 #endif