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