GCC Code Coverage Report
Directory: . Exec Total Coverage
File: src/api/cpp/cvc5.h Lines: 13 19 68.4 %
Date: 2021-08-14 Branches: 1 2 50.0 %

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