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