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