1 /********************* */
4 ** Top contributors (to current version):
5 ** Aina Niemetz, Andrew Reynolds, Andres Noetzli
6 ** This file is part of the CVC4 project.
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.\endverbatim
12 ** \brief The CVC4 C++ API.
16 ** A brief note on how to guard API functions:
18 ** In general, we think of API guards as a fence -- they are supposed to make
19 ** sure that no invalid arguments get passed into internal realms of CVC4.
20 ** Thus we always want to catch such cases on the API level (and can then
21 ** assert internally that no invalid argument is passed in).
23 ** The only special case is when we use 3rd party back-ends we have no control
24 ** over, and which throw (invalid_argument) exceptions anyways. In this case,
25 ** we do not replicate argument checks but delegate them to the back-end,
26 ** catch thrown exceptions, and raise a CVC4ApiException.
28 ** Our Integer implementation, e.g., is such a special case since we support
29 ** two different back end implementations (GMP, CLN). Be aware that they do
30 ** not fully agree on what is (in)valid input, which requires extra checks for
31 ** consistent behavior (see Solver::mkRealFromStrHelper for an example).
34 #include "api/cvc4cpp.h"
39 #include "base/check.h"
40 #include "base/configuration.h"
41 #include "expr/dtype.h"
42 #include "expr/dtype_cons.h"
43 #include "expr/dtype_selector.h"
44 #include "expr/kind.h"
45 #include "expr/metakind.h"
46 #include "expr/node.h"
47 #include "expr/node_manager.h"
48 #include "expr/sequence.h"
49 #include "expr/type_node.h"
50 #include "options/main_options.h"
51 #include "options/options.h"
52 #include "options/smt_options.h"
53 #include "proof/unsat_core.h"
54 #include "smt/model.h"
55 #include "smt/smt_engine.h"
56 #include "smt/smt_mode.h"
57 #include "theory/logic_info.h"
58 #include "theory/theory_model.h"
59 #include "util/random.h"
60 #include "util/result.h"
61 #include "util/statistics_registry.h"
62 #include "util/stats_histogram.h"
63 #include "util/utility.h"
68 /* -------------------------------------------------------------------------- */
70 /* -------------------------------------------------------------------------- */
75 : d_consts("api::CONSTANT"), d_vars("api::VARIABLE"), d_terms("api::TERM")
78 IntegralHistogramStat
<TypeConstant
> d_consts
;
79 IntegralHistogramStat
<TypeConstant
> d_vars
;
80 IntegralHistogramStat
<Kind
> d_terms
;
83 /* -------------------------------------------------------------------------- */
85 /* -------------------------------------------------------------------------- */
87 /* Mapping from external (API) kind to internal kind. */
88 const static std::unordered_map
<Kind
, CVC4::Kind
, KindHashFunction
> s_kinds
{
89 {INTERNAL_KIND
, CVC4::Kind::UNDEFINED_KIND
},
90 {UNDEFINED_KIND
, CVC4::Kind::UNDEFINED_KIND
},
91 {NULL_EXPR
, CVC4::Kind::NULL_EXPR
},
92 /* Builtin ------------------------------------------------------------- */
93 {UNINTERPRETED_CONSTANT
, CVC4::Kind::UNINTERPRETED_CONSTANT
},
94 {ABSTRACT_VALUE
, CVC4::Kind::ABSTRACT_VALUE
},
95 {EQUAL
, CVC4::Kind::EQUAL
},
96 {DISTINCT
, CVC4::Kind::DISTINCT
},
97 {CONSTANT
, CVC4::Kind::VARIABLE
},
98 {VARIABLE
, CVC4::Kind::BOUND_VARIABLE
},
99 {SEXPR
, CVC4::Kind::SEXPR
},
100 {LAMBDA
, CVC4::Kind::LAMBDA
},
101 {WITNESS
, CVC4::Kind::WITNESS
},
102 /* Boolean ------------------------------------------------------------- */
103 {CONST_BOOLEAN
, CVC4::Kind::CONST_BOOLEAN
},
104 {NOT
, CVC4::Kind::NOT
},
105 {AND
, CVC4::Kind::AND
},
106 {IMPLIES
, CVC4::Kind::IMPLIES
},
107 {OR
, CVC4::Kind::OR
},
108 {XOR
, CVC4::Kind::XOR
},
109 {ITE
, CVC4::Kind::ITE
},
110 {MATCH
, CVC4::Kind::MATCH
},
111 {MATCH_CASE
, CVC4::Kind::MATCH_CASE
},
112 {MATCH_BIND_CASE
, CVC4::Kind::MATCH_BIND_CASE
},
113 /* UF ------------------------------------------------------------------ */
114 {APPLY_UF
, CVC4::Kind::APPLY_UF
},
115 {CARDINALITY_CONSTRAINT
, CVC4::Kind::CARDINALITY_CONSTRAINT
},
116 {CARDINALITY_VALUE
, CVC4::Kind::CARDINALITY_VALUE
},
117 {HO_APPLY
, CVC4::Kind::HO_APPLY
},
118 /* Arithmetic ---------------------------------------------------------- */
119 {PLUS
, CVC4::Kind::PLUS
},
120 {MULT
, CVC4::Kind::MULT
},
121 {IAND
, CVC4::Kind::IAND
},
122 {MINUS
, CVC4::Kind::MINUS
},
123 {UMINUS
, CVC4::Kind::UMINUS
},
124 {DIVISION
, CVC4::Kind::DIVISION
},
125 {INTS_DIVISION
, CVC4::Kind::INTS_DIVISION
},
126 {INTS_MODULUS
, CVC4::Kind::INTS_MODULUS
},
127 {ABS
, CVC4::Kind::ABS
},
128 {DIVISIBLE
, CVC4::Kind::DIVISIBLE
},
129 {POW
, CVC4::Kind::POW
},
130 {EXPONENTIAL
, CVC4::Kind::EXPONENTIAL
},
131 {SINE
, CVC4::Kind::SINE
},
132 {COSINE
, CVC4::Kind::COSINE
},
133 {TANGENT
, CVC4::Kind::TANGENT
},
134 {COSECANT
, CVC4::Kind::COSECANT
},
135 {SECANT
, CVC4::Kind::SECANT
},
136 {COTANGENT
, CVC4::Kind::COTANGENT
},
137 {ARCSINE
, CVC4::Kind::ARCSINE
},
138 {ARCCOSINE
, CVC4::Kind::ARCCOSINE
},
139 {ARCTANGENT
, CVC4::Kind::ARCTANGENT
},
140 {ARCCOSECANT
, CVC4::Kind::ARCCOSECANT
},
141 {ARCSECANT
, CVC4::Kind::ARCSECANT
},
142 {ARCCOTANGENT
, CVC4::Kind::ARCCOTANGENT
},
143 {SQRT
, CVC4::Kind::SQRT
},
144 {CONST_RATIONAL
, CVC4::Kind::CONST_RATIONAL
},
145 {LT
, CVC4::Kind::LT
},
146 {LEQ
, CVC4::Kind::LEQ
},
147 {GT
, CVC4::Kind::GT
},
148 {GEQ
, CVC4::Kind::GEQ
},
149 {IS_INTEGER
, CVC4::Kind::IS_INTEGER
},
150 {TO_INTEGER
, CVC4::Kind::TO_INTEGER
},
151 {TO_REAL
, CVC4::Kind::TO_REAL
},
152 {PI
, CVC4::Kind::PI
},
153 /* BV ------------------------------------------------------------------ */
154 {CONST_BITVECTOR
, CVC4::Kind::CONST_BITVECTOR
},
155 {BITVECTOR_CONCAT
, CVC4::Kind::BITVECTOR_CONCAT
},
156 {BITVECTOR_AND
, CVC4::Kind::BITVECTOR_AND
},
157 {BITVECTOR_OR
, CVC4::Kind::BITVECTOR_OR
},
158 {BITVECTOR_XOR
, CVC4::Kind::BITVECTOR_XOR
},
159 {BITVECTOR_NOT
, CVC4::Kind::BITVECTOR_NOT
},
160 {BITVECTOR_NAND
, CVC4::Kind::BITVECTOR_NAND
},
161 {BITVECTOR_NOR
, CVC4::Kind::BITVECTOR_NOR
},
162 {BITVECTOR_XNOR
, CVC4::Kind::BITVECTOR_XNOR
},
163 {BITVECTOR_COMP
, CVC4::Kind::BITVECTOR_COMP
},
164 {BITVECTOR_MULT
, CVC4::Kind::BITVECTOR_MULT
},
165 {BITVECTOR_PLUS
, CVC4::Kind::BITVECTOR_PLUS
},
166 {BITVECTOR_SUB
, CVC4::Kind::BITVECTOR_SUB
},
167 {BITVECTOR_NEG
, CVC4::Kind::BITVECTOR_NEG
},
168 {BITVECTOR_UDIV
, CVC4::Kind::BITVECTOR_UDIV
},
169 {BITVECTOR_UREM
, CVC4::Kind::BITVECTOR_UREM
},
170 {BITVECTOR_SDIV
, CVC4::Kind::BITVECTOR_SDIV
},
171 {BITVECTOR_SREM
, CVC4::Kind::BITVECTOR_SREM
},
172 {BITVECTOR_SMOD
, CVC4::Kind::BITVECTOR_SMOD
},
173 {BITVECTOR_SHL
, CVC4::Kind::BITVECTOR_SHL
},
174 {BITVECTOR_LSHR
, CVC4::Kind::BITVECTOR_LSHR
},
175 {BITVECTOR_ASHR
, CVC4::Kind::BITVECTOR_ASHR
},
176 {BITVECTOR_ULT
, CVC4::Kind::BITVECTOR_ULT
},
177 {BITVECTOR_ULE
, CVC4::Kind::BITVECTOR_ULE
},
178 {BITVECTOR_UGT
, CVC4::Kind::BITVECTOR_UGT
},
179 {BITVECTOR_UGE
, CVC4::Kind::BITVECTOR_UGE
},
180 {BITVECTOR_SLT
, CVC4::Kind::BITVECTOR_SLT
},
181 {BITVECTOR_SLE
, CVC4::Kind::BITVECTOR_SLE
},
182 {BITVECTOR_SGT
, CVC4::Kind::BITVECTOR_SGT
},
183 {BITVECTOR_SGE
, CVC4::Kind::BITVECTOR_SGE
},
184 {BITVECTOR_ULTBV
, CVC4::Kind::BITVECTOR_ULTBV
},
185 {BITVECTOR_SLTBV
, CVC4::Kind::BITVECTOR_SLTBV
},
186 {BITVECTOR_ITE
, CVC4::Kind::BITVECTOR_ITE
},
187 {BITVECTOR_REDOR
, CVC4::Kind::BITVECTOR_REDOR
},
188 {BITVECTOR_REDAND
, CVC4::Kind::BITVECTOR_REDAND
},
189 {BITVECTOR_EXTRACT
, CVC4::Kind::BITVECTOR_EXTRACT
},
190 {BITVECTOR_REPEAT
, CVC4::Kind::BITVECTOR_REPEAT
},
191 {BITVECTOR_ZERO_EXTEND
, CVC4::Kind::BITVECTOR_ZERO_EXTEND
},
192 {BITVECTOR_SIGN_EXTEND
, CVC4::Kind::BITVECTOR_SIGN_EXTEND
},
193 {BITVECTOR_ROTATE_LEFT
, CVC4::Kind::BITVECTOR_ROTATE_LEFT
},
194 {BITVECTOR_ROTATE_RIGHT
, CVC4::Kind::BITVECTOR_ROTATE_RIGHT
},
195 {INT_TO_BITVECTOR
, CVC4::Kind::INT_TO_BITVECTOR
},
196 {BITVECTOR_TO_NAT
, CVC4::Kind::BITVECTOR_TO_NAT
},
197 /* FP ------------------------------------------------------------------ */
198 {CONST_FLOATINGPOINT
, CVC4::Kind::CONST_FLOATINGPOINT
},
199 {CONST_ROUNDINGMODE
, CVC4::Kind::CONST_ROUNDINGMODE
},
200 {FLOATINGPOINT_FP
, CVC4::Kind::FLOATINGPOINT_FP
},
201 {FLOATINGPOINT_EQ
, CVC4::Kind::FLOATINGPOINT_EQ
},
202 {FLOATINGPOINT_ABS
, CVC4::Kind::FLOATINGPOINT_ABS
},
203 {FLOATINGPOINT_NEG
, CVC4::Kind::FLOATINGPOINT_NEG
},
204 {FLOATINGPOINT_PLUS
, CVC4::Kind::FLOATINGPOINT_PLUS
},
205 {FLOATINGPOINT_SUB
, CVC4::Kind::FLOATINGPOINT_SUB
},
206 {FLOATINGPOINT_MULT
, CVC4::Kind::FLOATINGPOINT_MULT
},
207 {FLOATINGPOINT_DIV
, CVC4::Kind::FLOATINGPOINT_DIV
},
208 {FLOATINGPOINT_FMA
, CVC4::Kind::FLOATINGPOINT_FMA
},
209 {FLOATINGPOINT_SQRT
, CVC4::Kind::FLOATINGPOINT_SQRT
},
210 {FLOATINGPOINT_REM
, CVC4::Kind::FLOATINGPOINT_REM
},
211 {FLOATINGPOINT_RTI
, CVC4::Kind::FLOATINGPOINT_RTI
},
212 {FLOATINGPOINT_MIN
, CVC4::Kind::FLOATINGPOINT_MIN
},
213 {FLOATINGPOINT_MAX
, CVC4::Kind::FLOATINGPOINT_MAX
},
214 {FLOATINGPOINT_LEQ
, CVC4::Kind::FLOATINGPOINT_LEQ
},
215 {FLOATINGPOINT_LT
, CVC4::Kind::FLOATINGPOINT_LT
},
216 {FLOATINGPOINT_GEQ
, CVC4::Kind::FLOATINGPOINT_GEQ
},
217 {FLOATINGPOINT_GT
, CVC4::Kind::FLOATINGPOINT_GT
},
218 {FLOATINGPOINT_ISN
, CVC4::Kind::FLOATINGPOINT_ISN
},
219 {FLOATINGPOINT_ISSN
, CVC4::Kind::FLOATINGPOINT_ISSN
},
220 {FLOATINGPOINT_ISZ
, CVC4::Kind::FLOATINGPOINT_ISZ
},
221 {FLOATINGPOINT_ISINF
, CVC4::Kind::FLOATINGPOINT_ISINF
},
222 {FLOATINGPOINT_ISNAN
, CVC4::Kind::FLOATINGPOINT_ISNAN
},
223 {FLOATINGPOINT_ISNEG
, CVC4::Kind::FLOATINGPOINT_ISNEG
},
224 {FLOATINGPOINT_ISPOS
, CVC4::Kind::FLOATINGPOINT_ISPOS
},
225 {FLOATINGPOINT_TO_FP_FLOATINGPOINT
,
226 CVC4::Kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT
},
227 {FLOATINGPOINT_TO_FP_REAL
, CVC4::Kind::FLOATINGPOINT_TO_FP_REAL
},
228 {FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
,
229 CVC4::Kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
},
230 {FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
,
231 CVC4::Kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
},
232 {FLOATINGPOINT_TO_FP_GENERIC
, CVC4::Kind::FLOATINGPOINT_TO_FP_GENERIC
},
233 {FLOATINGPOINT_TO_UBV
, CVC4::Kind::FLOATINGPOINT_TO_UBV
},
234 {FLOATINGPOINT_TO_SBV
, CVC4::Kind::FLOATINGPOINT_TO_SBV
},
235 {FLOATINGPOINT_TO_REAL
, CVC4::Kind::FLOATINGPOINT_TO_REAL
},
236 /* Arrays -------------------------------------------------------------- */
237 {SELECT
, CVC4::Kind::SELECT
},
238 {STORE
, CVC4::Kind::STORE
},
239 {CONST_ARRAY
, CVC4::Kind::STORE_ALL
},
240 {EQ_RANGE
, CVC4::Kind::EQ_RANGE
},
241 /* Datatypes ----------------------------------------------------------- */
242 {APPLY_SELECTOR
, CVC4::Kind::APPLY_SELECTOR
},
243 {APPLY_CONSTRUCTOR
, CVC4::Kind::APPLY_CONSTRUCTOR
},
244 {APPLY_TESTER
, CVC4::Kind::APPLY_TESTER
},
245 {TUPLE_UPDATE
, CVC4::Kind::TUPLE_UPDATE
},
246 {RECORD_UPDATE
, CVC4::Kind::RECORD_UPDATE
},
247 {DT_SIZE
, CVC4::Kind::DT_SIZE
},
248 {TUPLE_PROJECT
, CVC4::Kind::TUPLE_PROJECT
},
249 /* Separation Logic ---------------------------------------------------- */
250 {SEP_NIL
, CVC4::Kind::SEP_NIL
},
251 {SEP_EMP
, CVC4::Kind::SEP_EMP
},
252 {SEP_PTO
, CVC4::Kind::SEP_PTO
},
253 {SEP_STAR
, CVC4::Kind::SEP_STAR
},
254 {SEP_WAND
, CVC4::Kind::SEP_WAND
},
255 /* Sets ---------------------------------------------------------------- */
256 {EMPTYSET
, CVC4::Kind::EMPTYSET
},
257 {UNION
, CVC4::Kind::UNION
},
258 {INTERSECTION
, CVC4::Kind::INTERSECTION
},
259 {SETMINUS
, CVC4::Kind::SETMINUS
},
260 {SUBSET
, CVC4::Kind::SUBSET
},
261 {MEMBER
, CVC4::Kind::MEMBER
},
262 {SINGLETON
, CVC4::Kind::SINGLETON
},
263 {INSERT
, CVC4::Kind::INSERT
},
264 {CARD
, CVC4::Kind::CARD
},
265 {COMPLEMENT
, CVC4::Kind::COMPLEMENT
},
266 {UNIVERSE_SET
, CVC4::Kind::UNIVERSE_SET
},
267 {JOIN
, CVC4::Kind::JOIN
},
268 {PRODUCT
, CVC4::Kind::PRODUCT
},
269 {TRANSPOSE
, CVC4::Kind::TRANSPOSE
},
270 {TCLOSURE
, CVC4::Kind::TCLOSURE
},
271 {JOIN_IMAGE
, CVC4::Kind::JOIN_IMAGE
},
272 {IDEN
, CVC4::Kind::IDEN
},
273 {COMPREHENSION
, CVC4::Kind::COMPREHENSION
},
274 {CHOOSE
, CVC4::Kind::CHOOSE
},
275 {IS_SINGLETON
, CVC4::Kind::IS_SINGLETON
},
276 /* Bags ---------------------------------------------------------------- */
277 {UNION_MAX
, CVC4::Kind::UNION_MAX
},
278 {UNION_DISJOINT
, CVC4::Kind::UNION_DISJOINT
},
279 {INTERSECTION_MIN
, CVC4::Kind::INTERSECTION_MIN
},
280 {DIFFERENCE_SUBTRACT
, CVC4::Kind::DIFFERENCE_SUBTRACT
},
281 {DIFFERENCE_REMOVE
, CVC4::Kind::DIFFERENCE_REMOVE
},
282 {SUBBAG
, CVC4::Kind::SUBBAG
},
283 {BAG_COUNT
, CVC4::Kind::BAG_COUNT
},
284 {DUPLICATE_REMOVAL
, CVC4::Kind::DUPLICATE_REMOVAL
},
285 {MK_BAG
, CVC4::Kind::MK_BAG
},
286 {EMPTYBAG
, CVC4::Kind::EMPTYBAG
},
287 {BAG_CARD
, CVC4::Kind::BAG_CARD
},
288 {BAG_CHOOSE
, CVC4::Kind::BAG_CHOOSE
},
289 {BAG_IS_SINGLETON
, CVC4::Kind::BAG_IS_SINGLETON
},
290 {BAG_FROM_SET
, CVC4::Kind::BAG_FROM_SET
},
291 {BAG_TO_SET
, CVC4::Kind::BAG_TO_SET
},
292 /* Strings ------------------------------------------------------------- */
293 {STRING_CONCAT
, CVC4::Kind::STRING_CONCAT
},
294 {STRING_IN_REGEXP
, CVC4::Kind::STRING_IN_REGEXP
},
295 {STRING_LENGTH
, CVC4::Kind::STRING_LENGTH
},
296 {STRING_SUBSTR
, CVC4::Kind::STRING_SUBSTR
},
297 {STRING_UPDATE
, CVC4::Kind::STRING_UPDATE
},
298 {STRING_CHARAT
, CVC4::Kind::STRING_CHARAT
},
299 {STRING_CONTAINS
, CVC4::Kind::STRING_STRCTN
},
300 {STRING_INDEXOF
, CVC4::Kind::STRING_STRIDOF
},
301 {STRING_REPLACE
, CVC4::Kind::STRING_STRREPL
},
302 {STRING_REPLACE_ALL
, CVC4::Kind::STRING_STRREPLALL
},
303 {STRING_REPLACE_RE
, CVC4::Kind::STRING_REPLACE_RE
},
304 {STRING_REPLACE_RE_ALL
, CVC4::Kind::STRING_REPLACE_RE_ALL
},
305 {STRING_TOLOWER
, CVC4::Kind::STRING_TOLOWER
},
306 {STRING_TOUPPER
, CVC4::Kind::STRING_TOUPPER
},
307 {STRING_REV
, CVC4::Kind::STRING_REV
},
308 {STRING_FROM_CODE
, CVC4::Kind::STRING_FROM_CODE
},
309 {STRING_TO_CODE
, CVC4::Kind::STRING_TO_CODE
},
310 {STRING_LT
, CVC4::Kind::STRING_LT
},
311 {STRING_LEQ
, CVC4::Kind::STRING_LEQ
},
312 {STRING_PREFIX
, CVC4::Kind::STRING_PREFIX
},
313 {STRING_SUFFIX
, CVC4::Kind::STRING_SUFFIX
},
314 {STRING_IS_DIGIT
, CVC4::Kind::STRING_IS_DIGIT
},
315 {STRING_FROM_INT
, CVC4::Kind::STRING_ITOS
},
316 {STRING_TO_INT
, CVC4::Kind::STRING_STOI
},
317 {CONST_STRING
, CVC4::Kind::CONST_STRING
},
318 {STRING_TO_REGEXP
, CVC4::Kind::STRING_TO_REGEXP
},
319 {REGEXP_CONCAT
, CVC4::Kind::REGEXP_CONCAT
},
320 {REGEXP_UNION
, CVC4::Kind::REGEXP_UNION
},
321 {REGEXP_INTER
, CVC4::Kind::REGEXP_INTER
},
322 {REGEXP_DIFF
, CVC4::Kind::REGEXP_DIFF
},
323 {REGEXP_STAR
, CVC4::Kind::REGEXP_STAR
},
324 {REGEXP_PLUS
, CVC4::Kind::REGEXP_PLUS
},
325 {REGEXP_OPT
, CVC4::Kind::REGEXP_OPT
},
326 {REGEXP_RANGE
, CVC4::Kind::REGEXP_RANGE
},
327 {REGEXP_REPEAT
, CVC4::Kind::REGEXP_REPEAT
},
328 {REGEXP_LOOP
, CVC4::Kind::REGEXP_LOOP
},
329 {REGEXP_EMPTY
, CVC4::Kind::REGEXP_EMPTY
},
330 {REGEXP_SIGMA
, CVC4::Kind::REGEXP_SIGMA
},
331 {REGEXP_COMPLEMENT
, CVC4::Kind::REGEXP_COMPLEMENT
},
332 // maps to the same kind as the string versions
333 {SEQ_CONCAT
, CVC4::Kind::STRING_CONCAT
},
334 {SEQ_LENGTH
, CVC4::Kind::STRING_LENGTH
},
335 {SEQ_EXTRACT
, CVC4::Kind::STRING_SUBSTR
},
336 {SEQ_UPDATE
, CVC4::Kind::STRING_UPDATE
},
337 {SEQ_AT
, CVC4::Kind::STRING_CHARAT
},
338 {SEQ_CONTAINS
, CVC4::Kind::STRING_STRCTN
},
339 {SEQ_INDEXOF
, CVC4::Kind::STRING_STRIDOF
},
340 {SEQ_REPLACE
, CVC4::Kind::STRING_STRREPL
},
341 {SEQ_REPLACE_ALL
, CVC4::Kind::STRING_STRREPLALL
},
342 {SEQ_REV
, CVC4::Kind::STRING_REV
},
343 {SEQ_PREFIX
, CVC4::Kind::STRING_PREFIX
},
344 {SEQ_SUFFIX
, CVC4::Kind::STRING_SUFFIX
},
345 {CONST_SEQUENCE
, CVC4::Kind::CONST_SEQUENCE
},
346 {SEQ_UNIT
, CVC4::Kind::SEQ_UNIT
},
347 {SEQ_NTH
, CVC4::Kind::SEQ_NTH
},
348 /* Quantifiers --------------------------------------------------------- */
349 {FORALL
, CVC4::Kind::FORALL
},
350 {EXISTS
, CVC4::Kind::EXISTS
},
351 {BOUND_VAR_LIST
, CVC4::Kind::BOUND_VAR_LIST
},
352 {INST_PATTERN
, CVC4::Kind::INST_PATTERN
},
353 {INST_NO_PATTERN
, CVC4::Kind::INST_NO_PATTERN
},
354 {INST_ATTRIBUTE
, CVC4::Kind::INST_ATTRIBUTE
},
355 {INST_PATTERN_LIST
, CVC4::Kind::INST_PATTERN_LIST
},
356 {LAST_KIND
, CVC4::Kind::LAST_KIND
},
359 /* Mapping from internal kind to external (API) kind. */
360 const static std::unordered_map
<CVC4::Kind
, Kind
, CVC4::kind::KindHashFunction
>
362 {CVC4::Kind::UNDEFINED_KIND
, UNDEFINED_KIND
},
363 {CVC4::Kind::NULL_EXPR
, NULL_EXPR
},
364 /* Builtin --------------------------------------------------------- */
365 {CVC4::Kind::UNINTERPRETED_CONSTANT
, UNINTERPRETED_CONSTANT
},
366 {CVC4::Kind::ABSTRACT_VALUE
, ABSTRACT_VALUE
},
367 {CVC4::Kind::EQUAL
, EQUAL
},
368 {CVC4::Kind::DISTINCT
, DISTINCT
},
369 {CVC4::Kind::VARIABLE
, CONSTANT
},
370 {CVC4::Kind::BOUND_VARIABLE
, VARIABLE
},
371 {CVC4::Kind::SEXPR
, SEXPR
},
372 {CVC4::Kind::LAMBDA
, LAMBDA
},
373 {CVC4::Kind::WITNESS
, WITNESS
},
374 /* Boolean --------------------------------------------------------- */
375 {CVC4::Kind::CONST_BOOLEAN
, CONST_BOOLEAN
},
376 {CVC4::Kind::NOT
, NOT
},
377 {CVC4::Kind::AND
, AND
},
378 {CVC4::Kind::IMPLIES
, IMPLIES
},
379 {CVC4::Kind::OR
, OR
},
380 {CVC4::Kind::XOR
, XOR
},
381 {CVC4::Kind::ITE
, ITE
},
382 {CVC4::Kind::MATCH
, MATCH
},
383 {CVC4::Kind::MATCH_CASE
, MATCH_CASE
},
384 {CVC4::Kind::MATCH_BIND_CASE
, MATCH_BIND_CASE
},
385 /* UF -------------------------------------------------------------- */
386 {CVC4::Kind::APPLY_UF
, APPLY_UF
},
387 {CVC4::Kind::CARDINALITY_CONSTRAINT
, CARDINALITY_CONSTRAINT
},
388 {CVC4::Kind::CARDINALITY_VALUE
, CARDINALITY_VALUE
},
389 {CVC4::Kind::HO_APPLY
, HO_APPLY
},
390 /* Arithmetic ------------------------------------------------------ */
391 {CVC4::Kind::PLUS
, PLUS
},
392 {CVC4::Kind::MULT
, MULT
},
393 {CVC4::Kind::IAND
, IAND
},
394 {CVC4::Kind::MINUS
, MINUS
},
395 {CVC4::Kind::UMINUS
, UMINUS
},
396 {CVC4::Kind::DIVISION
, DIVISION
},
397 {CVC4::Kind::DIVISION_TOTAL
, INTERNAL_KIND
},
398 {CVC4::Kind::INTS_DIVISION
, INTS_DIVISION
},
399 {CVC4::Kind::INTS_DIVISION_TOTAL
, INTERNAL_KIND
},
400 {CVC4::Kind::INTS_MODULUS
, INTS_MODULUS
},
401 {CVC4::Kind::INTS_MODULUS_TOTAL
, INTERNAL_KIND
},
402 {CVC4::Kind::ABS
, ABS
},
403 {CVC4::Kind::DIVISIBLE
, DIVISIBLE
},
404 {CVC4::Kind::POW
, POW
},
405 {CVC4::Kind::EXPONENTIAL
, EXPONENTIAL
},
406 {CVC4::Kind::SINE
, SINE
},
407 {CVC4::Kind::COSINE
, COSINE
},
408 {CVC4::Kind::TANGENT
, TANGENT
},
409 {CVC4::Kind::COSECANT
, COSECANT
},
410 {CVC4::Kind::SECANT
, SECANT
},
411 {CVC4::Kind::COTANGENT
, COTANGENT
},
412 {CVC4::Kind::ARCSINE
, ARCSINE
},
413 {CVC4::Kind::ARCCOSINE
, ARCCOSINE
},
414 {CVC4::Kind::ARCTANGENT
, ARCTANGENT
},
415 {CVC4::Kind::ARCCOSECANT
, ARCCOSECANT
},
416 {CVC4::Kind::ARCSECANT
, ARCSECANT
},
417 {CVC4::Kind::ARCCOTANGENT
, ARCCOTANGENT
},
418 {CVC4::Kind::SQRT
, SQRT
},
419 {CVC4::Kind::DIVISIBLE_OP
, DIVISIBLE
},
420 {CVC4::Kind::CONST_RATIONAL
, CONST_RATIONAL
},
421 {CVC4::Kind::LT
, LT
},
422 {CVC4::Kind::LEQ
, LEQ
},
423 {CVC4::Kind::GT
, GT
},
424 {CVC4::Kind::GEQ
, GEQ
},
425 {CVC4::Kind::IS_INTEGER
, IS_INTEGER
},
426 {CVC4::Kind::TO_INTEGER
, TO_INTEGER
},
427 {CVC4::Kind::TO_REAL
, TO_REAL
},
428 {CVC4::Kind::PI
, PI
},
429 /* BV -------------------------------------------------------------- */
430 {CVC4::Kind::CONST_BITVECTOR
, CONST_BITVECTOR
},
431 {CVC4::Kind::BITVECTOR_CONCAT
, BITVECTOR_CONCAT
},
432 {CVC4::Kind::BITVECTOR_AND
, BITVECTOR_AND
},
433 {CVC4::Kind::BITVECTOR_OR
, BITVECTOR_OR
},
434 {CVC4::Kind::BITVECTOR_XOR
, BITVECTOR_XOR
},
435 {CVC4::Kind::BITVECTOR_NOT
, BITVECTOR_NOT
},
436 {CVC4::Kind::BITVECTOR_NAND
, BITVECTOR_NAND
},
437 {CVC4::Kind::BITVECTOR_NOR
, BITVECTOR_NOR
},
438 {CVC4::Kind::BITVECTOR_XNOR
, BITVECTOR_XNOR
},
439 {CVC4::Kind::BITVECTOR_COMP
, BITVECTOR_COMP
},
440 {CVC4::Kind::BITVECTOR_MULT
, BITVECTOR_MULT
},
441 {CVC4::Kind::BITVECTOR_PLUS
, BITVECTOR_PLUS
},
442 {CVC4::Kind::BITVECTOR_SUB
, BITVECTOR_SUB
},
443 {CVC4::Kind::BITVECTOR_NEG
, BITVECTOR_NEG
},
444 {CVC4::Kind::BITVECTOR_UDIV
, BITVECTOR_UDIV
},
445 {CVC4::Kind::BITVECTOR_UREM
, BITVECTOR_UREM
},
446 {CVC4::Kind::BITVECTOR_SDIV
, BITVECTOR_SDIV
},
447 {CVC4::Kind::BITVECTOR_SREM
, BITVECTOR_SREM
},
448 {CVC4::Kind::BITVECTOR_SMOD
, BITVECTOR_SMOD
},
449 {CVC4::Kind::BITVECTOR_SHL
, BITVECTOR_SHL
},
450 {CVC4::Kind::BITVECTOR_LSHR
, BITVECTOR_LSHR
},
451 {CVC4::Kind::BITVECTOR_ASHR
, BITVECTOR_ASHR
},
452 {CVC4::Kind::BITVECTOR_ULT
, BITVECTOR_ULT
},
453 {CVC4::Kind::BITVECTOR_ULE
, BITVECTOR_ULE
},
454 {CVC4::Kind::BITVECTOR_UGT
, BITVECTOR_UGT
},
455 {CVC4::Kind::BITVECTOR_UGE
, BITVECTOR_UGE
},
456 {CVC4::Kind::BITVECTOR_SLT
, BITVECTOR_SLT
},
457 {CVC4::Kind::BITVECTOR_SLE
, BITVECTOR_SLE
},
458 {CVC4::Kind::BITVECTOR_SGT
, BITVECTOR_SGT
},
459 {CVC4::Kind::BITVECTOR_SGE
, BITVECTOR_SGE
},
460 {CVC4::Kind::BITVECTOR_ULTBV
, BITVECTOR_ULTBV
},
461 {CVC4::Kind::BITVECTOR_SLTBV
, BITVECTOR_SLTBV
},
462 {CVC4::Kind::BITVECTOR_ITE
, BITVECTOR_ITE
},
463 {CVC4::Kind::BITVECTOR_REDOR
, BITVECTOR_REDOR
},
464 {CVC4::Kind::BITVECTOR_REDAND
, BITVECTOR_REDAND
},
465 {CVC4::Kind::BITVECTOR_EXTRACT_OP
, BITVECTOR_EXTRACT
},
466 {CVC4::Kind::BITVECTOR_REPEAT_OP
, BITVECTOR_REPEAT
},
467 {CVC4::Kind::BITVECTOR_ZERO_EXTEND_OP
, BITVECTOR_ZERO_EXTEND
},
468 {CVC4::Kind::BITVECTOR_SIGN_EXTEND_OP
, BITVECTOR_SIGN_EXTEND
},
469 {CVC4::Kind::BITVECTOR_ROTATE_LEFT_OP
, BITVECTOR_ROTATE_LEFT
},
470 {CVC4::Kind::BITVECTOR_ROTATE_RIGHT_OP
, BITVECTOR_ROTATE_RIGHT
},
471 {CVC4::Kind::BITVECTOR_EXTRACT
, BITVECTOR_EXTRACT
},
472 {CVC4::Kind::BITVECTOR_REPEAT
, BITVECTOR_REPEAT
},
473 {CVC4::Kind::BITVECTOR_ZERO_EXTEND
, BITVECTOR_ZERO_EXTEND
},
474 {CVC4::Kind::BITVECTOR_SIGN_EXTEND
, BITVECTOR_SIGN_EXTEND
},
475 {CVC4::Kind::BITVECTOR_ROTATE_LEFT
, BITVECTOR_ROTATE_LEFT
},
476 {CVC4::Kind::BITVECTOR_ROTATE_RIGHT
, BITVECTOR_ROTATE_RIGHT
},
477 {CVC4::Kind::INT_TO_BITVECTOR_OP
, INT_TO_BITVECTOR
},
478 {CVC4::Kind::INT_TO_BITVECTOR
, INT_TO_BITVECTOR
},
479 {CVC4::Kind::BITVECTOR_TO_NAT
, BITVECTOR_TO_NAT
},
480 /* FP -------------------------------------------------------------- */
481 {CVC4::Kind::CONST_FLOATINGPOINT
, CONST_FLOATINGPOINT
},
482 {CVC4::Kind::CONST_ROUNDINGMODE
, CONST_ROUNDINGMODE
},
483 {CVC4::Kind::FLOATINGPOINT_FP
, FLOATINGPOINT_FP
},
484 {CVC4::Kind::FLOATINGPOINT_EQ
, FLOATINGPOINT_EQ
},
485 {CVC4::Kind::FLOATINGPOINT_ABS
, FLOATINGPOINT_ABS
},
486 {CVC4::Kind::FLOATINGPOINT_NEG
, FLOATINGPOINT_NEG
},
487 {CVC4::Kind::FLOATINGPOINT_PLUS
, FLOATINGPOINT_PLUS
},
488 {CVC4::Kind::FLOATINGPOINT_SUB
, FLOATINGPOINT_SUB
},
489 {CVC4::Kind::FLOATINGPOINT_MULT
, FLOATINGPOINT_MULT
},
490 {CVC4::Kind::FLOATINGPOINT_DIV
, FLOATINGPOINT_DIV
},
491 {CVC4::Kind::FLOATINGPOINT_FMA
, FLOATINGPOINT_FMA
},
492 {CVC4::Kind::FLOATINGPOINT_SQRT
, FLOATINGPOINT_SQRT
},
493 {CVC4::Kind::FLOATINGPOINT_REM
, FLOATINGPOINT_REM
},
494 {CVC4::Kind::FLOATINGPOINT_RTI
, FLOATINGPOINT_RTI
},
495 {CVC4::Kind::FLOATINGPOINT_MIN
, FLOATINGPOINT_MIN
},
496 {CVC4::Kind::FLOATINGPOINT_MAX
, FLOATINGPOINT_MAX
},
497 {CVC4::Kind::FLOATINGPOINT_LEQ
, FLOATINGPOINT_LEQ
},
498 {CVC4::Kind::FLOATINGPOINT_LT
, FLOATINGPOINT_LT
},
499 {CVC4::Kind::FLOATINGPOINT_GEQ
, FLOATINGPOINT_GEQ
},
500 {CVC4::Kind::FLOATINGPOINT_GT
, FLOATINGPOINT_GT
},
501 {CVC4::Kind::FLOATINGPOINT_ISN
, FLOATINGPOINT_ISN
},
502 {CVC4::Kind::FLOATINGPOINT_ISSN
, FLOATINGPOINT_ISSN
},
503 {CVC4::Kind::FLOATINGPOINT_ISZ
, FLOATINGPOINT_ISZ
},
504 {CVC4::Kind::FLOATINGPOINT_ISINF
, FLOATINGPOINT_ISINF
},
505 {CVC4::Kind::FLOATINGPOINT_ISNAN
, FLOATINGPOINT_ISNAN
},
506 {CVC4::Kind::FLOATINGPOINT_ISNEG
, FLOATINGPOINT_ISNEG
},
507 {CVC4::Kind::FLOATINGPOINT_ISPOS
, FLOATINGPOINT_ISPOS
},
508 {CVC4::Kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR_OP
,
509 FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
},
510 {CVC4::Kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
,
511 FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
},
512 {CVC4::Kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT_OP
,
513 FLOATINGPOINT_TO_FP_FLOATINGPOINT
},
514 {CVC4::Kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT
,
515 FLOATINGPOINT_TO_FP_FLOATINGPOINT
},
516 {CVC4::Kind::FLOATINGPOINT_TO_FP_REAL_OP
, FLOATINGPOINT_TO_FP_REAL
},
517 {CVC4::Kind::FLOATINGPOINT_TO_FP_REAL
, FLOATINGPOINT_TO_FP_REAL
},
518 {CVC4::Kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR_OP
,
519 FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
},
520 {CVC4::Kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
,
521 FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
},
522 {CVC4::Kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR_OP
,
523 FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
},
524 {CVC4::Kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
,
525 FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
},
526 {CVC4::Kind::FLOATINGPOINT_TO_FP_GENERIC_OP
,
527 FLOATINGPOINT_TO_FP_GENERIC
},
528 {CVC4::Kind::FLOATINGPOINT_TO_FP_GENERIC
, FLOATINGPOINT_TO_FP_GENERIC
},
529 {CVC4::Kind::FLOATINGPOINT_TO_UBV_OP
, FLOATINGPOINT_TO_UBV
},
530 {CVC4::Kind::FLOATINGPOINT_TO_UBV
, FLOATINGPOINT_TO_UBV
},
531 {CVC4::Kind::FLOATINGPOINT_TO_UBV_TOTAL_OP
, INTERNAL_KIND
},
532 {CVC4::Kind::FLOATINGPOINT_TO_UBV_TOTAL
, INTERNAL_KIND
},
533 {CVC4::Kind::FLOATINGPOINT_TO_SBV_OP
, FLOATINGPOINT_TO_SBV
},
534 {CVC4::Kind::FLOATINGPOINT_TO_SBV
, FLOATINGPOINT_TO_SBV
},
535 {CVC4::Kind::FLOATINGPOINT_TO_SBV_TOTAL_OP
, INTERNAL_KIND
},
536 {CVC4::Kind::FLOATINGPOINT_TO_SBV_TOTAL
, INTERNAL_KIND
},
537 {CVC4::Kind::FLOATINGPOINT_TO_REAL
, FLOATINGPOINT_TO_REAL
},
538 {CVC4::Kind::FLOATINGPOINT_TO_REAL_TOTAL
, INTERNAL_KIND
},
539 /* Arrays ---------------------------------------------------------- */
540 {CVC4::Kind::SELECT
, SELECT
},
541 {CVC4::Kind::STORE
, STORE
},
542 {CVC4::Kind::STORE_ALL
, CONST_ARRAY
},
543 /* Datatypes ------------------------------------------------------- */
544 {CVC4::Kind::APPLY_SELECTOR
, APPLY_SELECTOR
},
545 {CVC4::Kind::APPLY_CONSTRUCTOR
, APPLY_CONSTRUCTOR
},
546 {CVC4::Kind::APPLY_SELECTOR_TOTAL
, INTERNAL_KIND
},
547 {CVC4::Kind::APPLY_TESTER
, APPLY_TESTER
},
548 {CVC4::Kind::TUPLE_UPDATE_OP
, TUPLE_UPDATE
},
549 {CVC4::Kind::TUPLE_UPDATE
, TUPLE_UPDATE
},
550 {CVC4::Kind::RECORD_UPDATE_OP
, RECORD_UPDATE
},
551 {CVC4::Kind::RECORD_UPDATE
, RECORD_UPDATE
},
552 {CVC4::Kind::DT_SIZE
, DT_SIZE
},
553 {CVC4::Kind::TUPLE_PROJECT
, TUPLE_PROJECT
},
554 /* Separation Logic ------------------------------------------------ */
555 {CVC4::Kind::SEP_NIL
, SEP_NIL
},
556 {CVC4::Kind::SEP_EMP
, SEP_EMP
},
557 {CVC4::Kind::SEP_PTO
, SEP_PTO
},
558 {CVC4::Kind::SEP_STAR
, SEP_STAR
},
559 {CVC4::Kind::SEP_WAND
, SEP_WAND
},
560 /* Sets ------------------------------------------------------------ */
561 {CVC4::Kind::EMPTYSET
, EMPTYSET
},
562 {CVC4::Kind::UNION
, UNION
},
563 {CVC4::Kind::INTERSECTION
, INTERSECTION
},
564 {CVC4::Kind::SETMINUS
, SETMINUS
},
565 {CVC4::Kind::SUBSET
, SUBSET
},
566 {CVC4::Kind::MEMBER
, MEMBER
},
567 {CVC4::Kind::SINGLETON
, SINGLETON
},
568 {CVC4::Kind::INSERT
, INSERT
},
569 {CVC4::Kind::CARD
, CARD
},
570 {CVC4::Kind::COMPLEMENT
, COMPLEMENT
},
571 {CVC4::Kind::UNIVERSE_SET
, UNIVERSE_SET
},
572 {CVC4::Kind::JOIN
, JOIN
},
573 {CVC4::Kind::PRODUCT
, PRODUCT
},
574 {CVC4::Kind::TRANSPOSE
, TRANSPOSE
},
575 {CVC4::Kind::TCLOSURE
, TCLOSURE
},
576 {CVC4::Kind::JOIN_IMAGE
, JOIN_IMAGE
},
577 {CVC4::Kind::IDEN
, IDEN
},
578 {CVC4::Kind::COMPREHENSION
, COMPREHENSION
},
579 {CVC4::Kind::CHOOSE
, CHOOSE
},
580 {CVC4::Kind::IS_SINGLETON
, IS_SINGLETON
},
581 /* Bags ------------------------------------------------------------ */
582 {CVC4::Kind::UNION_MAX
, UNION_MAX
},
583 {CVC4::Kind::UNION_DISJOINT
, UNION_DISJOINT
},
584 {CVC4::Kind::INTERSECTION_MIN
, INTERSECTION_MIN
},
585 {CVC4::Kind::DIFFERENCE_SUBTRACT
, DIFFERENCE_SUBTRACT
},
586 {CVC4::Kind::DIFFERENCE_REMOVE
, DIFFERENCE_REMOVE
},
587 {CVC4::Kind::SUBBAG
, SUBBAG
},
588 {CVC4::Kind::BAG_COUNT
, BAG_COUNT
},
589 {CVC4::Kind::DUPLICATE_REMOVAL
, DUPLICATE_REMOVAL
},
590 {CVC4::Kind::MK_BAG
, MK_BAG
},
591 {CVC4::Kind::EMPTYBAG
, EMPTYBAG
},
592 {CVC4::Kind::BAG_CARD
, BAG_CARD
},
593 {CVC4::Kind::BAG_CHOOSE
, BAG_CHOOSE
},
594 {CVC4::Kind::BAG_IS_SINGLETON
, BAG_IS_SINGLETON
},
595 {CVC4::Kind::BAG_FROM_SET
, BAG_FROM_SET
},
596 {CVC4::Kind::BAG_TO_SET
, BAG_TO_SET
},
597 /* Strings --------------------------------------------------------- */
598 {CVC4::Kind::STRING_CONCAT
, STRING_CONCAT
},
599 {CVC4::Kind::STRING_IN_REGEXP
, STRING_IN_REGEXP
},
600 {CVC4::Kind::STRING_LENGTH
, STRING_LENGTH
},
601 {CVC4::Kind::STRING_SUBSTR
, STRING_SUBSTR
},
602 {CVC4::Kind::STRING_UPDATE
, STRING_UPDATE
},
603 {CVC4::Kind::STRING_CHARAT
, STRING_CHARAT
},
604 {CVC4::Kind::STRING_STRCTN
, STRING_CONTAINS
},
605 {CVC4::Kind::STRING_STRIDOF
, STRING_INDEXOF
},
606 {CVC4::Kind::STRING_STRREPL
, STRING_REPLACE
},
607 {CVC4::Kind::STRING_STRREPLALL
, STRING_REPLACE_ALL
},
608 {CVC4::Kind::STRING_REPLACE_RE
, STRING_REPLACE_RE
},
609 {CVC4::Kind::STRING_REPLACE_RE_ALL
, STRING_REPLACE_RE_ALL
},
610 {CVC4::Kind::STRING_TOLOWER
, STRING_TOLOWER
},
611 {CVC4::Kind::STRING_TOUPPER
, STRING_TOUPPER
},
612 {CVC4::Kind::STRING_REV
, STRING_REV
},
613 {CVC4::Kind::STRING_FROM_CODE
, STRING_FROM_CODE
},
614 {CVC4::Kind::STRING_TO_CODE
, STRING_TO_CODE
},
615 {CVC4::Kind::STRING_LT
, STRING_LT
},
616 {CVC4::Kind::STRING_LEQ
, STRING_LEQ
},
617 {CVC4::Kind::STRING_PREFIX
, STRING_PREFIX
},
618 {CVC4::Kind::STRING_SUFFIX
, STRING_SUFFIX
},
619 {CVC4::Kind::STRING_IS_DIGIT
, STRING_IS_DIGIT
},
620 {CVC4::Kind::STRING_ITOS
, STRING_FROM_INT
},
621 {CVC4::Kind::STRING_STOI
, STRING_TO_INT
},
622 {CVC4::Kind::CONST_STRING
, CONST_STRING
},
623 {CVC4::Kind::STRING_TO_REGEXP
, STRING_TO_REGEXP
},
624 {CVC4::Kind::REGEXP_CONCAT
, REGEXP_CONCAT
},
625 {CVC4::Kind::REGEXP_UNION
, REGEXP_UNION
},
626 {CVC4::Kind::REGEXP_INTER
, REGEXP_INTER
},
627 {CVC4::Kind::REGEXP_DIFF
, REGEXP_DIFF
},
628 {CVC4::Kind::REGEXP_STAR
, REGEXP_STAR
},
629 {CVC4::Kind::REGEXP_PLUS
, REGEXP_PLUS
},
630 {CVC4::Kind::REGEXP_OPT
, REGEXP_OPT
},
631 {CVC4::Kind::REGEXP_RANGE
, REGEXP_RANGE
},
632 {CVC4::Kind::REGEXP_REPEAT
, REGEXP_REPEAT
},
633 {CVC4::Kind::REGEXP_REPEAT_OP
, REGEXP_REPEAT
},
634 {CVC4::Kind::REGEXP_LOOP
, REGEXP_LOOP
},
635 {CVC4::Kind::REGEXP_LOOP_OP
, REGEXP_LOOP
},
636 {CVC4::Kind::REGEXP_EMPTY
, REGEXP_EMPTY
},
637 {CVC4::Kind::REGEXP_SIGMA
, REGEXP_SIGMA
},
638 {CVC4::Kind::REGEXP_COMPLEMENT
, REGEXP_COMPLEMENT
},
639 {CVC4::Kind::CONST_SEQUENCE
, CONST_SEQUENCE
},
640 {CVC4::Kind::SEQ_UNIT
, SEQ_UNIT
},
641 {CVC4::Kind::SEQ_NTH
, SEQ_NTH
},
642 /* Quantifiers ----------------------------------------------------- */
643 {CVC4::Kind::FORALL
, FORALL
},
644 {CVC4::Kind::EXISTS
, EXISTS
},
645 {CVC4::Kind::BOUND_VAR_LIST
, BOUND_VAR_LIST
},
646 {CVC4::Kind::INST_PATTERN
, INST_PATTERN
},
647 {CVC4::Kind::INST_NO_PATTERN
, INST_NO_PATTERN
},
648 {CVC4::Kind::INST_ATTRIBUTE
, INST_ATTRIBUTE
},
649 {CVC4::Kind::INST_PATTERN_LIST
, INST_PATTERN_LIST
},
650 /* ----------------------------------------------------------------- */
651 {CVC4::Kind::LAST_KIND
, LAST_KIND
},
654 /* Set of kinds for indexed operators */
655 const static std::unordered_set
<Kind
, KindHashFunction
> s_indexed_kinds(
660 BITVECTOR_ZERO_EXTEND
,
661 BITVECTOR_SIGN_EXTEND
,
662 BITVECTOR_ROTATE_LEFT
,
663 BITVECTOR_ROTATE_RIGHT
,
665 FLOATINGPOINT_TO_UBV
,
666 FLOATINGPOINT_TO_SBV
,
669 FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
,
670 FLOATINGPOINT_TO_FP_FLOATINGPOINT
,
671 FLOATINGPOINT_TO_FP_REAL
,
672 FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
,
673 FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
,
674 FLOATINGPOINT_TO_FP_GENERIC
});
678 /** Convert a CVC4::Kind (internal) to a CVC4::api::Kind (external). */
679 CVC4::api::Kind
intToExtKind(CVC4::Kind k
)
681 auto it
= api::s_kinds_internal
.find(k
);
682 if (it
== api::s_kinds_internal
.end())
684 return api::INTERNAL_KIND
;
689 /** Convert a CVC4::api::Kind (external) to a CVC4::Kind (internal). */
690 CVC4::Kind
extToIntKind(CVC4::api::Kind k
)
692 auto it
= api::s_kinds
.find(k
);
693 if (it
== api::s_kinds
.end())
695 return CVC4::Kind::UNDEFINED_KIND
;
700 /** Return true if given kind is a defined external kind. */
701 bool isDefinedKind(Kind k
) { return k
> UNDEFINED_KIND
&& k
< LAST_KIND
; }
704 * Return true if the internal kind is one where the API term structure
705 * differs from internal structure. This happens for APPLY_* kinds.
706 * The API takes a "higher-order" perspective and treats functions as well
707 * as datatype constructors/selectors/testers as terms
708 * but interally they are not
710 bool isApplyKind(CVC4::Kind k
)
712 return (k
== CVC4::Kind::APPLY_UF
|| k
== CVC4::Kind::APPLY_CONSTRUCTOR
713 || k
== CVC4::Kind::APPLY_SELECTOR
|| k
== CVC4::Kind::APPLY_TESTER
);
716 #ifdef CVC4_ASSERTIONS
717 /** Return true if given kind is a defined internal kind. */
718 bool isDefinedIntKind(CVC4::Kind k
)
720 return k
!= CVC4::Kind::UNDEFINED_KIND
&& k
!= CVC4::Kind::LAST_KIND
;
724 /** Return the minimum arity of given kind. */
725 uint32_t minArity(Kind k
)
727 Assert(isDefinedKind(k
));
728 Assert(isDefinedIntKind(extToIntKind(k
)));
729 uint32_t min
= CVC4::kind::metakind::getMinArityForKind(extToIntKind(k
));
731 // At the API level, we treat functions/constructors/selectors/testers as
732 // normal terms instead of making them part of the operator
733 if (isApplyKind(extToIntKind(k
)))
740 /** Return the maximum arity of given kind. */
741 uint32_t maxArity(Kind k
)
743 Assert(isDefinedKind(k
));
744 Assert(isDefinedIntKind(extToIntKind(k
)));
745 uint32_t max
= CVC4::kind::metakind::getMaxArityForKind(extToIntKind(k
));
747 // At the API level, we treat functions/constructors/selectors/testers as
748 // normal terms instead of making them part of the operator
749 if (isApplyKind(extToIntKind(k
))
750 && max
!= std::numeric_limits
<uint32_t>::max()) // be careful not to
760 std::string
kindToString(Kind k
)
762 return k
== INTERNAL_KIND
? "INTERNAL_KIND"
763 : CVC4::kind::kindToString(extToIntKind(k
));
766 std::ostream
& operator<<(std::ostream
& out
, Kind k
)
770 case INTERNAL_KIND
: out
<< "INTERNAL_KIND"; break;
771 default: out
<< extToIntKind(k
);
776 size_t KindHashFunction::operator()(Kind k
) const { return k
; }
778 /* -------------------------------------------------------------------------- */
779 /* API guard helpers */
780 /* -------------------------------------------------------------------------- */
784 class CVC4ApiExceptionStream
787 CVC4ApiExceptionStream() {}
788 /* Note: This needs to be explicitly set to 'noexcept(false)' since it is
789 * a destructor that throws an exception and in C++11 all destructors
790 * default to noexcept(true) (else this triggers a call to std::terminate). */
791 ~CVC4ApiExceptionStream() noexcept(false)
793 if (std::uncaught_exceptions() == 0)
795 throw CVC4ApiException(d_stream
.str());
799 std::ostream
& ostream() { return d_stream
; }
802 std::stringstream d_stream
;
805 class CVC4ApiRecoverableExceptionStream
808 CVC4ApiRecoverableExceptionStream() {}
809 /* Note: This needs to be explicitly set to 'noexcept(false)' since it is
810 * a destructor that throws an exception and in C++11 all destructors
811 * default to noexcept(true) (else this triggers a call to std::terminate). */
812 ~CVC4ApiRecoverableExceptionStream() noexcept(false)
814 if (std::uncaught_exceptions() == 0)
816 throw CVC4ApiRecoverableException(d_stream
.str());
820 std::ostream
& ostream() { return d_stream
; }
823 std::stringstream d_stream
;
826 #define CVC4_API_CHECK(cond) \
827 CVC4_PREDICT_TRUE(cond) \
828 ? (void)0 : OstreamVoider() & CVC4ApiExceptionStream().ostream()
830 #define CVC4_API_RECOVERABLE_CHECK(cond) \
831 CVC4_PREDICT_TRUE(cond) \
832 ? (void)0 : OstreamVoider() & CVC4ApiRecoverableExceptionStream().ostream()
834 #define CVC4_API_CHECK_NOT_NULL \
835 CVC4_API_CHECK(!isNullHelper()) \
836 << "Invalid call to '" << __PRETTY_FUNCTION__ \
837 << "', expected non-null object";
839 #define CVC4_API_ARG_CHECK_NOT_NULL(arg) \
840 CVC4_API_CHECK(!arg.isNull()) << "Invalid null argument for '" << #arg << "'";
842 #define CVC4_API_ARG_CHECK_NOT_NULLPTR(arg) \
843 CVC4_API_CHECK(arg != nullptr) \
844 << "Invalid null argument for '" << #arg << "'";
846 #define CVC4_API_KIND_CHECK(kind) \
847 CVC4_API_CHECK(isDefinedKind(kind)) \
848 << "Invalid kind '" << kindToString(kind) << "'";
850 #define CVC4_API_KIND_CHECK_EXPECTED(cond, kind) \
851 CVC4_PREDICT_TRUE(cond) \
854 & CVC4ApiExceptionStream().ostream() \
855 << "Invalid kind '" << kindToString(kind) << "', expected "
857 #define CVC4_API_ARG_CHECK_EXPECTED(cond, arg) \
858 CVC4_PREDICT_TRUE(cond) \
861 & CVC4ApiExceptionStream().ostream() \
862 << "Invalid argument '" << arg << "' for '" << #arg \
865 #define CVC4_API_RECOVERABLE_ARG_CHECK_EXPECTED(cond, arg) \
866 CVC4_PREDICT_TRUE(cond) \
869 & CVC4ApiRecoverableExceptionStream().ostream() \
870 << "Invalid argument '" << arg << "' for '" << #arg \
873 #define CVC4_API_ARG_SIZE_CHECK_EXPECTED(cond, arg) \
874 CVC4_PREDICT_TRUE(cond) \
877 & CVC4ApiExceptionStream().ostream() \
878 << "Invalid size of argument '" << #arg << "', expected "
880 #define CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(cond, what, arg, idx) \
881 CVC4_PREDICT_TRUE(cond) \
884 & CVC4ApiExceptionStream().ostream() \
885 << "Invalid " << what << " '" << arg << "' at index " << idx \
888 #define CVC4_API_TRY_CATCH_BEGIN \
891 #define CVC4_API_TRY_CATCH_END \
893 catch (const UnrecognizedOptionException& e) \
895 throw CVC4ApiRecoverableException(e.getMessage()); \
897 catch (const CVC4::RecoverableModalException& e) \
899 throw CVC4ApiRecoverableException(e.getMessage()); \
901 catch (const CVC4::Exception& e) { throw CVC4ApiException(e.getMessage()); } \
902 catch (const std::invalid_argument& e) { throw CVC4ApiException(e.what()); }
904 #define CVC4_API_SOLVER_CHECK_SORT(sort) \
905 CVC4_API_CHECK(this == sort.d_solver) \
906 << "Given sort is not associated with this solver";
908 #define CVC4_API_SOLVER_CHECK_TERM(term) \
909 CVC4_API_CHECK(this == term.d_solver) \
910 << "Given term is not associated with this solver";
912 #define CVC4_API_SOLVER_CHECK_OP(op) \
913 CVC4_API_CHECK(this == op.d_solver) \
914 << "Given operator is not associated with this solver";
918 /* -------------------------------------------------------------------------- */
920 /* -------------------------------------------------------------------------- */
922 Result::Result(const CVC4::Result
& r
) : d_result(new CVC4::Result(r
)) {}
924 Result::Result() : d_result(new CVC4::Result()) {}
926 bool Result::isNull() const
928 return d_result
->getType() == CVC4::Result::TYPE_NONE
;
931 bool Result::isSat(void) const
933 return d_result
->getType() == CVC4::Result::TYPE_SAT
934 && d_result
->isSat() == CVC4::Result::SAT
;
937 bool Result::isUnsat(void) const
939 return d_result
->getType() == CVC4::Result::TYPE_SAT
940 && d_result
->isSat() == CVC4::Result::UNSAT
;
943 bool Result::isSatUnknown(void) const
945 return d_result
->getType() == CVC4::Result::TYPE_SAT
946 && d_result
->isSat() == CVC4::Result::SAT_UNKNOWN
;
949 bool Result::isEntailed(void) const
951 return d_result
->getType() == CVC4::Result::TYPE_ENTAILMENT
952 && d_result
->isEntailed() == CVC4::Result::ENTAILED
;
955 bool Result::isNotEntailed(void) const
957 return d_result
->getType() == CVC4::Result::TYPE_ENTAILMENT
958 && d_result
->isEntailed() == CVC4::Result::NOT_ENTAILED
;
961 bool Result::isEntailmentUnknown(void) const
963 return d_result
->getType() == CVC4::Result::TYPE_ENTAILMENT
964 && d_result
->isEntailed() == CVC4::Result::ENTAILMENT_UNKNOWN
;
967 bool Result::operator==(const Result
& r
) const
969 return *d_result
== *r
.d_result
;
972 bool Result::operator!=(const Result
& r
) const
974 return *d_result
!= *r
.d_result
;
977 Result::UnknownExplanation
Result::getUnknownExplanation(void) const
979 CVC4::Result::UnknownExplanation expl
= d_result
->whyUnknown();
982 case CVC4::Result::REQUIRES_FULL_CHECK
: return REQUIRES_FULL_CHECK
;
983 case CVC4::Result::INCOMPLETE
: return INCOMPLETE
;
984 case CVC4::Result::TIMEOUT
: return TIMEOUT
;
985 case CVC4::Result::RESOURCEOUT
: return RESOURCEOUT
;
986 case CVC4::Result::MEMOUT
: return MEMOUT
;
987 case CVC4::Result::INTERRUPTED
: return INTERRUPTED
;
988 case CVC4::Result::NO_STATUS
: return NO_STATUS
;
989 case CVC4::Result::UNSUPPORTED
: return UNSUPPORTED
;
990 case CVC4::Result::OTHER
: return OTHER
;
991 default: return UNKNOWN_REASON
;
993 return UNKNOWN_REASON
;
996 std::string
Result::toString(void) const { return d_result
->toString(); }
998 std::ostream
& operator<<(std::ostream
& out
, const Result
& r
)
1000 out
<< r
.toString();
1004 std::ostream
& operator<<(std::ostream
& out
, enum Result::UnknownExplanation e
)
1008 case Result::REQUIRES_FULL_CHECK
: out
<< "REQUIRES_FULL_CHECK"; break;
1009 case Result::INCOMPLETE
: out
<< "INCOMPLETE"; break;
1010 case Result::TIMEOUT
: out
<< "TIMEOUT"; break;
1011 case Result::RESOURCEOUT
: out
<< "RESOURCEOUT"; break;
1012 case Result::MEMOUT
: out
<< "MEMOUT"; break;
1013 case Result::INTERRUPTED
: out
<< "INTERRUPTED"; break;
1014 case Result::NO_STATUS
: out
<< "NO_STATUS"; break;
1015 case Result::UNSUPPORTED
: out
<< "UNSUPPORTED"; break;
1016 case Result::OTHER
: out
<< "OTHER"; break;
1017 case Result::UNKNOWN_REASON
: out
<< "UNKNOWN_REASON"; break;
1018 default: Unhandled() << e
;
1023 /* -------------------------------------------------------------------------- */
1025 /* -------------------------------------------------------------------------- */
1027 Sort::Sort(const Solver
* slv
, const CVC4::TypeNode
& t
)
1028 : d_solver(slv
), d_type(new CVC4::TypeNode(t
))
1032 Sort::Sort() : d_solver(nullptr), d_type(new CVC4::TypeNode()) {}
1036 if (d_solver
!= nullptr)
1038 // Ensure that the correct node manager is in scope when the node is
1040 NodeManagerScope
scope(d_solver
->getNodeManager());
1045 std::set
<TypeNode
> Sort::sortSetToTypeNodes(const std::set
<Sort
>& sorts
)
1047 std::set
<TypeNode
> types
;
1048 for (const Sort
& s
: sorts
)
1050 types
.insert(s
.getTypeNode());
1055 std::vector
<TypeNode
> Sort::sortVectorToTypeNodes(
1056 const std::vector
<Sort
>& sorts
)
1058 std::vector
<TypeNode
> typeNodes
;
1059 for (const Sort
& sort
: sorts
)
1061 typeNodes
.push_back(sort
.getTypeNode());
1066 std::vector
<Sort
> Sort::typeNodeVectorToSorts(
1067 const Solver
* slv
, const std::vector
<TypeNode
>& types
)
1069 std::vector
<Sort
> sorts
;
1070 for (size_t i
= 0, tsize
= types
.size(); i
< tsize
; i
++)
1072 sorts
.push_back(Sort(slv
, types
[i
]));
1078 /* -------------------------------------------------------------------------- */
1080 /* Split out to avoid nested API calls (problematic with API tracing). */
1081 /* .......................................................................... */
1083 bool Sort::isNullHelper() const { return d_type
->isNull(); }
1085 bool Sort::operator==(const Sort
& s
) const { return *d_type
== *s
.d_type
; }
1087 bool Sort::operator!=(const Sort
& s
) const { return *d_type
!= *s
.d_type
; }
1089 bool Sort::operator<(const Sort
& s
) const { return *d_type
< *s
.d_type
; }
1091 bool Sort::operator>(const Sort
& s
) const { return *d_type
> *s
.d_type
; }
1093 bool Sort::operator<=(const Sort
& s
) const { return *d_type
<= *s
.d_type
; }
1095 bool Sort::operator>=(const Sort
& s
) const { return *d_type
>= *s
.d_type
; }
1097 bool Sort::isNull() const { return isNullHelper(); }
1099 bool Sort::isBoolean() const { return d_type
->isBoolean(); }
1101 bool Sort::isInteger() const { return d_type
->isInteger(); }
1103 bool Sort::isReal() const { return d_type
->isReal(); }
1105 bool Sort::isString() const { return d_type
->isString(); }
1107 bool Sort::isRegExp() const { return d_type
->isRegExp(); }
1109 bool Sort::isRoundingMode() const { return d_type
->isRoundingMode(); }
1111 bool Sort::isBitVector() const { return d_type
->isBitVector(); }
1113 bool Sort::isFloatingPoint() const { return d_type
->isFloatingPoint(); }
1115 bool Sort::isDatatype() const { return d_type
->isDatatype(); }
1117 bool Sort::isParametricDatatype() const
1119 if (!d_type
->isDatatype()) return false;
1120 return d_type
->isParametricDatatype();
1123 bool Sort::isConstructor() const { return d_type
->isConstructor(); }
1124 bool Sort::isSelector() const { return d_type
->isSelector(); }
1125 bool Sort::isTester() const { return d_type
->isTester(); }
1127 bool Sort::isFunction() const { return d_type
->isFunction(); }
1129 bool Sort::isPredicate() const { return d_type
->isPredicate(); }
1131 bool Sort::isTuple() const { return d_type
->isTuple(); }
1133 bool Sort::isRecord() const { return d_type
->isRecord(); }
1135 bool Sort::isArray() const { return d_type
->isArray(); }
1137 bool Sort::isSet() const { return d_type
->isSet(); }
1139 bool Sort::isBag() const { return d_type
->isBag(); }
1141 bool Sort::isSequence() const { return d_type
->isSequence(); }
1143 bool Sort::isUninterpretedSort() const { return d_type
->isSort(); }
1145 bool Sort::isSortConstructor() const { return d_type
->isSortConstructor(); }
1147 bool Sort::isFirstClass() const { return d_type
->isFirstClass(); }
1149 bool Sort::isFunctionLike() const { return d_type
->isFunctionLike(); }
1151 bool Sort::isSubsortOf(const Sort
& s
) const
1153 return d_type
->isSubtypeOf(*s
.d_type
);
1156 bool Sort::isComparableTo(const Sort
& s
) const
1158 return d_type
->isComparableTo(*s
.d_type
);
1161 Datatype
Sort::getDatatype() const
1163 NodeManagerScope
scope(d_solver
->getNodeManager());
1164 CVC4_API_CHECK(isDatatype()) << "Expected datatype sort.";
1165 return Datatype(d_solver
, d_type
->getDType());
1168 Sort
Sort::instantiate(const std::vector
<Sort
>& params
) const
1170 NodeManagerScope
scope(d_solver
->getNodeManager());
1171 CVC4_API_CHECK(isParametricDatatype() || isSortConstructor())
1172 << "Expected parametric datatype or sort constructor sort.";
1173 std::vector
<CVC4::TypeNode
> tparams
= sortVectorToTypeNodes(params
);
1174 if (d_type
->isDatatype())
1176 return Sort(d_solver
, d_type
->instantiateParametricDatatype(tparams
));
1178 Assert(d_type
->isSortConstructor());
1179 return Sort(d_solver
, d_solver
->getNodeManager()->mkSort(*d_type
, tparams
));
1182 Sort
Sort::substitute(const Sort
& sort
, const Sort
& replacement
) const
1184 NodeManagerScope
scope(d_solver
->getNodeManager());
1187 d_type
->substitute(sort
.getTypeNode(), replacement
.getTypeNode()));
1190 Sort
Sort::substitute(const std::vector
<Sort
>& sorts
,
1191 const std::vector
<Sort
>& replacements
) const
1193 NodeManagerScope
scope(d_solver
->getNodeManager());
1195 std::vector
<CVC4::TypeNode
> tSorts
= sortVectorToTypeNodes(sorts
),
1197 sortVectorToTypeNodes(replacements
);
1199 return Sort(d_solver
,
1200 d_type
->substitute(tSorts
.begin(),
1202 tReplacements
.begin(),
1203 tReplacements
.end()));
1206 std::string
Sort::toString() const
1208 if (d_solver
!= nullptr)
1210 NodeManagerScope
scope(d_solver
->getNodeManager());
1211 return d_type
->toString();
1213 return d_type
->toString();
1216 const CVC4::TypeNode
& Sort::getTypeNode(void) const { return *d_type
; }
1218 /* Constructor sort ------------------------------------------------------- */
1220 size_t Sort::getConstructorArity() const
1222 CVC4_API_CHECK(isConstructor()) << "Not a constructor sort: " << (*this);
1223 return d_type
->getNumChildren() - 1;
1226 std::vector
<Sort
> Sort::getConstructorDomainSorts() const
1228 CVC4_API_CHECK(isConstructor()) << "Not a constructor sort: " << (*this);
1229 return typeNodeVectorToSorts(d_solver
, d_type
->getArgTypes());
1232 Sort
Sort::getConstructorCodomainSort() const
1234 CVC4_API_CHECK(isConstructor()) << "Not a constructor sort: " << (*this);
1235 return Sort(d_solver
, d_type
->getConstructorRangeType());
1238 /* Selector sort ------------------------------------------------------- */
1240 Sort
Sort::getSelectorDomainSort() const
1242 CVC4_API_CHECK(isSelector()) << "Not a selector sort: " << (*this);
1243 return Sort(d_solver
, d_type
->getSelectorDomainType());
1246 Sort
Sort::getSelectorCodomainSort() const
1248 CVC4_API_CHECK(isSelector()) << "Not a selector sort: " << (*this);
1249 return Sort(d_solver
, d_type
->getSelectorRangeType());
1252 /* Tester sort ------------------------------------------------------- */
1254 Sort
Sort::getTesterDomainSort() const
1256 CVC4_API_CHECK(isTester()) << "Not a tester sort: " << (*this);
1257 return Sort(d_solver
, d_type
->getTesterDomainType());
1260 Sort
Sort::getTesterCodomainSort() const
1262 CVC4_API_CHECK(isTester()) << "Not a tester sort: " << (*this);
1263 return d_solver
->getBooleanSort();
1266 /* Function sort ------------------------------------------------------- */
1268 size_t Sort::getFunctionArity() const
1270 CVC4_API_CHECK(isFunction()) << "Not a function sort: " << (*this);
1271 return d_type
->getNumChildren() - 1;
1274 std::vector
<Sort
> Sort::getFunctionDomainSorts() const
1276 CVC4_API_CHECK(isFunction()) << "Not a function sort: " << (*this);
1277 return typeNodeVectorToSorts(d_solver
, d_type
->getArgTypes());
1280 Sort
Sort::getFunctionCodomainSort() const
1282 CVC4_API_CHECK(isFunction()) << "Not a function sort" << (*this);
1283 return Sort(d_solver
, d_type
->getRangeType());
1286 /* Array sort ---------------------------------------------------------- */
1288 Sort
Sort::getArrayIndexSort() const
1290 CVC4_API_CHECK(isArray()) << "Not an array sort.";
1291 return Sort(d_solver
, d_type
->getArrayIndexType());
1294 Sort
Sort::getArrayElementSort() const
1296 CVC4_API_CHECK(isArray()) << "Not an array sort.";
1297 return Sort(d_solver
, d_type
->getArrayConstituentType());
1300 /* Set sort ------------------------------------------------------------ */
1302 Sort
Sort::getSetElementSort() const
1304 CVC4_API_CHECK(isSet()) << "Not a set sort.";
1305 return Sort(d_solver
, d_type
->getSetElementType());
1308 /* Bag sort ------------------------------------------------------------ */
1310 Sort
Sort::getBagElementSort() const
1312 CVC4_API_CHECK(isBag()) << "Not a bag sort.";
1313 return Sort(d_solver
, d_type
->getBagElementType());
1316 /* Sequence sort ------------------------------------------------------- */
1318 Sort
Sort::getSequenceElementSort() const
1320 CVC4_API_CHECK(isSequence()) << "Not a sequence sort.";
1321 return Sort(d_solver
, d_type
->getSequenceElementType());
1324 /* Uninterpreted sort -------------------------------------------------- */
1326 std::string
Sort::getUninterpretedSortName() const
1328 CVC4_API_CHECK(isUninterpretedSort()) << "Not an uninterpreted sort.";
1329 return d_type
->getName();
1332 bool Sort::isUninterpretedSortParameterized() const
1334 CVC4_API_CHECK(isUninterpretedSort()) << "Not an uninterpreted sort.";
1335 // This method is not implemented in the NodeManager, since whether a
1336 // uninterpreted sort is parametrized is irrelevant for solving.
1337 return d_type
->getNumChildren() > 0;
1340 std::vector
<Sort
> Sort::getUninterpretedSortParamSorts() const
1342 CVC4_API_CHECK(isUninterpretedSort()) << "Not an uninterpreted sort.";
1343 // This method is not implemented in the NodeManager, since whether a
1344 // uninterpreted sort is parametrized is irrelevant for solving.
1345 std::vector
<TypeNode
> params
;
1346 for (size_t i
= 0, nchildren
= d_type
->getNumChildren(); i
< nchildren
; i
++)
1348 params
.push_back((*d_type
)[i
]);
1350 return typeNodeVectorToSorts(d_solver
, params
);
1353 /* Sort constructor sort ----------------------------------------------- */
1355 std::string
Sort::getSortConstructorName() const
1357 CVC4_API_CHECK(isSortConstructor()) << "Not a sort constructor sort.";
1358 return d_type
->getName();
1361 size_t Sort::getSortConstructorArity() const
1363 CVC4_API_CHECK(isSortConstructor()) << "Not a sort constructor sort.";
1364 return d_type
->getSortConstructorArity();
1367 /* Bit-vector sort ----------------------------------------------------- */
1369 uint32_t Sort::getBVSize() const
1371 CVC4_API_CHECK(isBitVector()) << "Not a bit-vector sort.";
1372 return d_type
->getBitVectorSize();
1375 /* Floating-point sort ------------------------------------------------- */
1377 uint32_t Sort::getFPExponentSize() const
1379 CVC4_API_CHECK(isFloatingPoint()) << "Not a floating-point sort.";
1380 return d_type
->getFloatingPointExponentSize();
1383 uint32_t Sort::getFPSignificandSize() const
1385 CVC4_API_CHECK(isFloatingPoint()) << "Not a floating-point sort.";
1386 return d_type
->getFloatingPointSignificandSize();
1389 /* Datatype sort ------------------------------------------------------- */
1391 std::vector
<Sort
> Sort::getDatatypeParamSorts() const
1393 CVC4_API_CHECK(isParametricDatatype()) << "Not a parametric datatype sort.";
1394 std::vector
<CVC4::TypeNode
> typeNodes
= d_type
->getParamTypes();
1395 return typeNodeVectorToSorts(d_solver
, typeNodes
);
1398 size_t Sort::getDatatypeArity() const
1400 CVC4_API_CHECK(isDatatype()) << "Not a datatype sort.";
1401 return d_type
->getNumChildren() - 1;
1404 /* Tuple sort ---------------------------------------------------------- */
1406 size_t Sort::getTupleLength() const
1408 CVC4_API_CHECK(isTuple()) << "Not a tuple sort.";
1409 return d_type
->getTupleLength();
1412 std::vector
<Sort
> Sort::getTupleSorts() const
1414 CVC4_API_CHECK(isTuple()) << "Not a tuple sort.";
1415 std::vector
<CVC4::TypeNode
> typeNodes
= d_type
->getTupleTypes();
1416 return typeNodeVectorToSorts(d_solver
, typeNodes
);
1419 /* --------------------------------------------------------------------- */
1421 std::ostream
& operator<<(std::ostream
& out
, const Sort
& s
)
1423 out
<< s
.toString();
1427 size_t SortHashFunction::operator()(const Sort
& s
) const
1429 return TypeNodeHashFunction()(*s
.d_type
);
1432 /* -------------------------------------------------------------------------- */
1434 /* -------------------------------------------------------------------------- */
1436 Op::Op() : d_solver(nullptr), d_kind(NULL_EXPR
), d_node(new CVC4::Node()) {}
1438 Op::Op(const Solver
* slv
, const Kind k
)
1439 : d_solver(slv
), d_kind(k
), d_node(new CVC4::Node())
1443 Op::Op(const Solver
* slv
, const Kind k
, const CVC4::Node
& n
)
1444 : d_solver(slv
), d_kind(k
), d_node(new CVC4::Node(n
))
1450 if (d_solver
!= nullptr)
1452 // Ensure that the correct node manager is in scope when the type node is
1454 NodeManagerScope
scope(d_solver
->getNodeManager());
1460 /* -------------------------------------------------------------------------- */
1462 /* Split out to avoid nested API calls (problematic with API tracing). */
1463 /* .......................................................................... */
1465 bool Op::isNullHelper() const
1467 return (d_node
->isNull() && (d_kind
== NULL_EXPR
));
1470 bool Op::isIndexedHelper() const { return !d_node
->isNull(); }
1472 /* Public methods */
1473 bool Op::operator==(const Op
& t
) const
1475 if (d_node
->isNull() && t
.d_node
->isNull())
1477 return (d_kind
== t
.d_kind
);
1479 else if (d_node
->isNull() || t
.d_node
->isNull())
1483 return (d_kind
== t
.d_kind
) && (*d_node
== *t
.d_node
);
1486 bool Op::operator!=(const Op
& t
) const { return !(*this == t
); }
1488 Kind
Op::getKind() const
1490 CVC4_API_CHECK(d_kind
!= NULL_EXPR
) << "Expecting a non-null Kind";
1494 bool Op::isNull() const { return isNullHelper(); }
1496 bool Op::isIndexed() const { return isIndexedHelper(); }
1499 std::string
Op::getIndices() const
1501 CVC4_API_CHECK_NOT_NULL
;
1502 CVC4_API_CHECK(!d_node
->isNull())
1503 << "Expecting a non-null internal expression. This Op is not indexed.";
1506 Kind k
= intToExtKind(d_node
->getKind());
1510 // DIVISIBLE returns a string index to support
1511 // arbitrary precision integers
1512 CVC4::Integer _int
= d_node
->getConst
<Divisible
>().k
;
1513 i
= _int
.toString();
1515 else if (k
== RECORD_UPDATE
)
1517 i
= d_node
->getConst
<RecordUpdate
>().getField();
1521 CVC4_API_CHECK(false) << "Can't get string index from"
1522 << " kind " << kindToString(k
);
1529 uint32_t Op::getIndices() const
1531 CVC4_API_CHECK_NOT_NULL
;
1532 CVC4_API_CHECK(!d_node
->isNull())
1533 << "Expecting a non-null internal expression. This Op is not indexed.";
1536 Kind k
= intToExtKind(d_node
->getKind());
1539 case BITVECTOR_REPEAT
:
1540 i
= d_node
->getConst
<BitVectorRepeat
>().d_repeatAmount
;
1542 case BITVECTOR_ZERO_EXTEND
:
1543 i
= d_node
->getConst
<BitVectorZeroExtend
>().d_zeroExtendAmount
;
1545 case BITVECTOR_SIGN_EXTEND
:
1546 i
= d_node
->getConst
<BitVectorSignExtend
>().d_signExtendAmount
;
1548 case BITVECTOR_ROTATE_LEFT
:
1549 i
= d_node
->getConst
<BitVectorRotateLeft
>().d_rotateLeftAmount
;
1551 case BITVECTOR_ROTATE_RIGHT
:
1552 i
= d_node
->getConst
<BitVectorRotateRight
>().d_rotateRightAmount
;
1554 case INT_TO_BITVECTOR
: i
= d_node
->getConst
<IntToBitVector
>().d_size
; break;
1555 case IAND
: i
= d_node
->getConst
<IntAnd
>().d_size
; break;
1556 case FLOATINGPOINT_TO_UBV
:
1557 i
= d_node
->getConst
<FloatingPointToUBV
>().d_bv_size
.d_size
;
1559 case FLOATINGPOINT_TO_SBV
:
1560 i
= d_node
->getConst
<FloatingPointToSBV
>().d_bv_size
.d_size
;
1562 case TUPLE_UPDATE
: i
= d_node
->getConst
<TupleUpdate
>().getIndex(); break;
1564 i
= d_node
->getConst
<RegExpRepeat
>().d_repeatAmount
;
1567 CVC4ApiExceptionStream().ostream() << "Can't get uint32_t index from"
1568 << " kind " << kindToString(k
);
1574 std::pair
<uint32_t, uint32_t> Op::getIndices() const
1576 CVC4_API_CHECK_NOT_NULL
;
1577 CVC4_API_CHECK(!d_node
->isNull())
1578 << "Expecting a non-null internal expression. This Op is not indexed.";
1580 std::pair
<uint32_t, uint32_t> indices
;
1581 Kind k
= intToExtKind(d_node
->getKind());
1583 // using if/else instead of case statement because want local variables
1584 if (k
== BITVECTOR_EXTRACT
)
1586 CVC4::BitVectorExtract ext
= d_node
->getConst
<BitVectorExtract
>();
1587 indices
= std::make_pair(ext
.d_high
, ext
.d_low
);
1589 else if (k
== FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
)
1591 CVC4::FloatingPointToFPIEEEBitVector ext
=
1592 d_node
->getConst
<FloatingPointToFPIEEEBitVector
>();
1593 indices
= std::make_pair(ext
.d_fp_size
.exponentWidth(),
1594 ext
.d_fp_size
.significandWidth());
1596 else if (k
== FLOATINGPOINT_TO_FP_FLOATINGPOINT
)
1598 CVC4::FloatingPointToFPFloatingPoint ext
=
1599 d_node
->getConst
<FloatingPointToFPFloatingPoint
>();
1600 indices
= std::make_pair(ext
.d_fp_size
.exponentWidth(),
1601 ext
.d_fp_size
.significandWidth());
1603 else if (k
== FLOATINGPOINT_TO_FP_REAL
)
1605 CVC4::FloatingPointToFPReal ext
= d_node
->getConst
<FloatingPointToFPReal
>();
1606 indices
= std::make_pair(ext
.d_fp_size
.exponentWidth(),
1607 ext
.d_fp_size
.significandWidth());
1609 else if (k
== FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
)
1611 CVC4::FloatingPointToFPSignedBitVector ext
=
1612 d_node
->getConst
<FloatingPointToFPSignedBitVector
>();
1613 indices
= std::make_pair(ext
.d_fp_size
.exponentWidth(),
1614 ext
.d_fp_size
.significandWidth());
1616 else if (k
== FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
)
1618 CVC4::FloatingPointToFPUnsignedBitVector ext
=
1619 d_node
->getConst
<FloatingPointToFPUnsignedBitVector
>();
1620 indices
= std::make_pair(ext
.d_fp_size
.exponentWidth(),
1621 ext
.d_fp_size
.significandWidth());
1623 else if (k
== FLOATINGPOINT_TO_FP_GENERIC
)
1625 CVC4::FloatingPointToFPGeneric ext
=
1626 d_node
->getConst
<FloatingPointToFPGeneric
>();
1627 indices
= std::make_pair(ext
.d_fp_size
.exponentWidth(),
1628 ext
.d_fp_size
.significandWidth());
1630 else if (k
== REGEXP_LOOP
)
1632 CVC4::RegExpLoop ext
= d_node
->getConst
<RegExpLoop
>();
1633 indices
= std::make_pair(ext
.d_loopMinOcc
, ext
.d_loopMaxOcc
);
1637 CVC4_API_CHECK(false) << "Can't get pair<uint32_t, uint32_t> indices from"
1638 << " kind " << kindToString(k
);
1643 std::string
Op::toString() const
1645 CVC4_API_CHECK_NOT_NULL
;
1646 if (d_node
->isNull())
1648 return kindToString(d_kind
);
1652 CVC4_API_CHECK(!d_node
->isNull())
1653 << "Expecting a non-null internal expression";
1654 if (d_solver
!= nullptr)
1656 NodeManagerScope
scope(d_solver
->getNodeManager());
1657 return d_node
->toString();
1659 return d_node
->toString();
1663 std::ostream
& operator<<(std::ostream
& out
, const Op
& t
)
1665 out
<< t
.toString();
1669 size_t OpHashFunction::operator()(const Op
& t
) const
1671 if (t
.isIndexedHelper())
1673 return NodeHashFunction()(*t
.d_node
);
1677 return KindHashFunction()(t
.d_kind
);
1681 /* -------------------------------------------------------------------------- */
1683 /* -------------------------------------------------------------------------- */
1685 Term::Term() : d_solver(nullptr), d_node(new CVC4::Node()) {}
1687 Term::Term(const Solver
* slv
, const CVC4::Node
& n
) : d_solver(slv
)
1689 // Ensure that we create the node in the correct node manager.
1690 NodeManagerScope
scope(d_solver
->getNodeManager());
1691 d_node
.reset(new CVC4::Node(n
));
1696 if (d_solver
!= nullptr)
1698 // Ensure that the correct node manager is in scope when the node is
1700 NodeManagerScope
scope(d_solver
->getNodeManager());
1705 bool Term::isNullHelper() const
1707 /* Split out to avoid nested API calls (problematic with API tracing). */
1708 return d_node
->isNull();
1711 Kind
Term::getKindHelper() const
1713 // Sequence kinds do not exist internally, so we must convert their internal
1714 // (string) versions back to sequence. All operators where this is
1715 // necessary are such that their first child is of sequence type, which
1717 if (d_node
->getNumChildren() > 0 && (*d_node
)[0].getType().isSequence())
1719 switch (d_node
->getKind())
1721 case CVC4::Kind::STRING_CONCAT
: return SEQ_CONCAT
;
1722 case CVC4::Kind::STRING_LENGTH
: return SEQ_LENGTH
;
1723 case CVC4::Kind::STRING_SUBSTR
: return SEQ_EXTRACT
;
1724 case CVC4::Kind::STRING_UPDATE
: return SEQ_UPDATE
;
1725 case CVC4::Kind::STRING_CHARAT
: return SEQ_AT
;
1726 case CVC4::Kind::STRING_STRCTN
: return SEQ_CONTAINS
;
1727 case CVC4::Kind::STRING_STRIDOF
: return SEQ_INDEXOF
;
1728 case CVC4::Kind::STRING_STRREPL
: return SEQ_REPLACE
;
1729 case CVC4::Kind::STRING_STRREPLALL
: return SEQ_REPLACE_ALL
;
1730 case CVC4::Kind::STRING_REV
: return SEQ_REV
;
1731 case CVC4::Kind::STRING_PREFIX
: return SEQ_PREFIX
;
1732 case CVC4::Kind::STRING_SUFFIX
: return SEQ_SUFFIX
;
1734 // fall through to conversion below
1738 // Notice that kinds like APPLY_TYPE_ASCRIPTION will be converted to
1742 return CONST_RATIONAL
;
1744 return intToExtKind(d_node
->getKind());
1747 bool Term::isCastedReal() const
1749 if(d_node
->getKind() == kind::CAST_TO_REAL
)
1751 return (*d_node
)[0].isConst() && (*d_node
)[0].getType().isInteger();
1756 bool Term::operator==(const Term
& t
) const { return *d_node
== *t
.d_node
; }
1758 bool Term::operator!=(const Term
& t
) const { return *d_node
!= *t
.d_node
; }
1760 bool Term::operator<(const Term
& t
) const { return *d_node
< *t
.d_node
; }
1762 bool Term::operator>(const Term
& t
) const { return *d_node
> *t
.d_node
; }
1764 bool Term::operator<=(const Term
& t
) const { return *d_node
<= *t
.d_node
; }
1766 bool Term::operator>=(const Term
& t
) const { return *d_node
>= *t
.d_node
; }
1768 size_t Term::getNumChildren() const
1770 CVC4_API_CHECK_NOT_NULL
;
1771 // special case for apply kinds
1772 if (isApplyKind(d_node
->getKind()))
1774 return d_node
->getNumChildren() + 1;
1780 return d_node
->getNumChildren();
1783 Term
Term::operator[](size_t index
) const
1785 CVC4_API_CHECK_NOT_NULL
;
1787 // check the index within the number of children
1788 CVC4_API_CHECK(index
< getNumChildren()) << "index out of bound";
1790 // special cases for apply kinds
1791 if (isApplyKind(d_node
->getKind()))
1793 CVC4_API_CHECK(d_node
->hasOperator())
1794 << "Expected apply kind to have operator when accessing child of Term";
1797 // return the operator
1798 return Term(d_solver
, d_node
->getOperator());
1800 // otherwise we are looking up child at (index-1)
1803 return Term(d_solver
, (*d_node
)[index
]);
1806 uint64_t Term::getId() const
1808 CVC4_API_CHECK_NOT_NULL
;
1809 return d_node
->getId();
1812 Kind
Term::getKind() const
1814 CVC4_API_CHECK_NOT_NULL
;
1815 return getKindHelper();
1818 Sort
Term::getSort() const
1820 CVC4_API_CHECK_NOT_NULL
;
1821 NodeManagerScope
scope(d_solver
->getNodeManager());
1822 return Sort(d_solver
, d_node
->getType());
1825 Term
Term::substitute(const Term
& e
, const Term
& replacement
) const
1827 CVC4_API_CHECK_NOT_NULL
;
1828 CVC4_API_CHECK(!e
.isNull())
1829 << "Expected non-null term to replace in substitute";
1830 CVC4_API_CHECK(!replacement
.isNull())
1831 << "Expected non-null term as replacement in substitute";
1832 CVC4_API_CHECK(e
.getSort().isComparableTo(replacement
.getSort()))
1833 << "Expecting terms of comparable sort in substitute";
1834 return Term(d_solver
,
1835 d_node
->substitute(TNode(*e
.d_node
), TNode(*replacement
.d_node
)));
1838 Term
Term::substitute(const std::vector
<Term
>& es
,
1839 const std::vector
<Term
>& replacements
) const
1841 CVC4_API_CHECK_NOT_NULL
;
1842 CVC4_API_CHECK(es
.size() == replacements
.size())
1843 << "Expecting vectors of the same arity in substitute";
1844 for (unsigned i
= 0, nterms
= es
.size(); i
< nterms
; i
++)
1846 CVC4_API_CHECK(!es
[i
].isNull())
1847 << "Expected non-null term to replace in substitute";
1848 CVC4_API_CHECK(!replacements
[i
].isNull())
1849 << "Expected non-null term as replacement in substitute";
1850 CVC4_API_CHECK(es
[i
].getSort().isComparableTo(replacements
[i
].getSort()))
1851 << "Expecting terms of comparable sort in substitute";
1854 std::vector
<Node
> nodes
= Term::termVectorToNodes(es
);
1855 std::vector
<Node
> nodeReplacements
= Term::termVectorToNodes(replacements
);
1856 return Term(d_solver
,
1857 d_node
->substitute(nodes
.begin(),
1859 nodeReplacements
.begin(),
1860 nodeReplacements
.end()));
1863 bool Term::hasOp() const
1865 CVC4_API_CHECK_NOT_NULL
;
1866 return d_node
->hasOperator();
1869 Op
Term::getOp() const
1871 CVC4_API_CHECK_NOT_NULL
;
1872 CVC4_API_CHECK(d_node
->hasOperator())
1873 << "Expecting Term to have an Op when calling getOp()";
1875 // special cases for parameterized operators that are not indexed operators
1876 // the API level differs from the internal structure
1877 // indexed operators are stored in Ops
1878 // whereas functions and datatype operators are terms, and the Op
1879 // is one of the APPLY_* kinds
1880 if (isApplyKind(d_node
->getKind()))
1882 return Op(d_solver
, intToExtKind(d_node
->getKind()));
1884 else if (d_node
->getMetaKind() == kind::metakind::PARAMETERIZED
)
1886 // it's an indexed operator
1887 // so we should return the indexed op
1888 CVC4::Node op
= d_node
->getOperator();
1889 return Op(d_solver
, intToExtKind(d_node
->getKind()), op
);
1891 // Notice this is the only case where getKindHelper is used, since the
1892 // cases above do not have special cases for intToExtKind.
1893 return Op(d_solver
, getKindHelper());
1896 bool Term::isNull() const { return isNullHelper(); }
1898 Term
Term::getConstArrayBase() const
1900 NodeManagerScope
scope(d_solver
->getNodeManager());
1901 CVC4_API_CHECK_NOT_NULL
;
1902 // CONST_ARRAY kind maps to STORE_ALL internal kind
1903 CVC4_API_CHECK(d_node
->getKind() == CVC4::Kind::STORE_ALL
)
1904 << "Expecting a CONST_ARRAY Term when calling getConstArrayBase()";
1905 return Term(d_solver
, d_node
->getConst
<ArrayStoreAll
>().getValue());
1908 std::vector
<Term
> Term::getConstSequenceElements() const
1910 CVC4_API_CHECK_NOT_NULL
;
1911 CVC4_API_CHECK(d_node
->getKind() == CVC4::Kind::CONST_SEQUENCE
)
1912 << "Expecting a CONST_SEQUENCE Term when calling "
1913 "getConstSequenceElements()";
1914 const std::vector
<Node
>& elems
= d_node
->getConst
<Sequence
>().getVec();
1915 std::vector
<Term
> terms
;
1916 for (const Node
& t
: elems
)
1918 terms
.push_back(Term(d_solver
, t
));
1923 Term
Term::notTerm() const
1925 CVC4_API_CHECK_NOT_NULL
;
1928 Node res
= d_node
->notNode();
1929 (void)res
.getType(true); /* kick off type checking */
1930 return Term(d_solver
, res
);
1932 catch (const CVC4::TypeCheckingExceptionPrivate
& e
)
1934 throw CVC4ApiException(e
.getMessage());
1938 Term
Term::andTerm(const Term
& t
) const
1940 CVC4_API_CHECK_NOT_NULL
;
1941 CVC4_API_ARG_CHECK_NOT_NULL(t
);
1944 Node res
= d_node
->andNode(*t
.d_node
);
1945 (void)res
.getType(true); /* kick off type checking */
1946 return Term(d_solver
, res
);
1948 catch (const CVC4::TypeCheckingExceptionPrivate
& e
)
1950 throw CVC4ApiException(e
.getMessage());
1954 Term
Term::orTerm(const Term
& t
) const
1956 CVC4_API_CHECK_NOT_NULL
;
1957 CVC4_API_ARG_CHECK_NOT_NULL(t
);
1960 Node res
= d_node
->orNode(*t
.d_node
);
1961 (void)res
.getType(true); /* kick off type checking */
1962 return Term(d_solver
, res
);
1964 catch (const CVC4::TypeCheckingExceptionPrivate
& e
)
1966 throw CVC4ApiException(e
.getMessage());
1970 Term
Term::xorTerm(const Term
& t
) const
1972 CVC4_API_CHECK_NOT_NULL
;
1973 CVC4_API_ARG_CHECK_NOT_NULL(t
);
1976 Node res
= d_node
->xorNode(*t
.d_node
);
1977 (void)res
.getType(true); /* kick off type checking */
1978 return Term(d_solver
, res
);
1980 catch (const CVC4::TypeCheckingExceptionPrivate
& e
)
1982 throw CVC4ApiException(e
.getMessage());
1986 Term
Term::eqTerm(const Term
& t
) const
1988 CVC4_API_CHECK_NOT_NULL
;
1989 CVC4_API_ARG_CHECK_NOT_NULL(t
);
1992 Node res
= d_node
->eqNode(*t
.d_node
);
1993 (void)res
.getType(true); /* kick off type checking */
1994 return Term(d_solver
, res
);
1996 catch (const CVC4::TypeCheckingExceptionPrivate
& e
)
1998 throw CVC4ApiException(e
.getMessage());
2002 Term
Term::impTerm(const Term
& t
) const
2004 CVC4_API_CHECK_NOT_NULL
;
2005 CVC4_API_ARG_CHECK_NOT_NULL(t
);
2008 Node res
= d_node
->impNode(*t
.d_node
);
2009 (void)res
.getType(true); /* kick off type checking */
2010 return Term(d_solver
, res
);
2012 catch (const CVC4::TypeCheckingExceptionPrivate
& e
)
2014 throw CVC4ApiException(e
.getMessage());
2018 Term
Term::iteTerm(const Term
& then_t
, const Term
& else_t
) const
2020 CVC4_API_CHECK_NOT_NULL
;
2021 CVC4_API_ARG_CHECK_NOT_NULL(then_t
);
2022 CVC4_API_ARG_CHECK_NOT_NULL(else_t
);
2025 Node res
= d_node
->iteNode(*then_t
.d_node
, *else_t
.d_node
);
2026 (void)res
.getType(true); /* kick off type checking */
2027 return Term(d_solver
, res
);
2029 catch (const CVC4::TypeCheckingExceptionPrivate
& e
)
2031 throw CVC4ApiException(e
.getMessage());
2035 std::string
Term::toString() const
2037 if (d_solver
!= nullptr)
2039 NodeManagerScope
scope(d_solver
->getNodeManager());
2040 return d_node
->toString();
2042 return d_node
->toString();
2045 Term::const_iterator::const_iterator()
2046 : d_solver(nullptr), d_origNode(nullptr), d_pos(0)
2050 Term::const_iterator::const_iterator(const Solver
* slv
,
2051 const std::shared_ptr
<CVC4::Node
>& n
,
2053 : d_solver(slv
), d_origNode(n
), d_pos(p
)
2057 Term::const_iterator::const_iterator(const const_iterator
& it
)
2058 : d_solver(nullptr), d_origNode(nullptr)
2060 if (it
.d_origNode
!= nullptr)
2062 d_solver
= it
.d_solver
;
2063 d_origNode
= it
.d_origNode
;
2068 Term::const_iterator
& Term::const_iterator::operator=(const const_iterator
& it
)
2070 d_solver
= it
.d_solver
;
2071 d_origNode
= it
.d_origNode
;
2076 bool Term::const_iterator::operator==(const const_iterator
& it
) const
2078 if (d_origNode
== nullptr || it
.d_origNode
== nullptr)
2082 return (d_solver
== it
.d_solver
&& *d_origNode
== *it
.d_origNode
)
2083 && (d_pos
== it
.d_pos
);
2086 bool Term::const_iterator::operator!=(const const_iterator
& it
) const
2088 return !(*this == it
);
2091 Term::const_iterator
& Term::const_iterator::operator++()
2093 Assert(d_origNode
!= nullptr);
2098 Term::const_iterator
Term::const_iterator::operator++(int)
2100 Assert(d_origNode
!= nullptr);
2101 const_iterator it
= *this;
2106 Term
Term::const_iterator::operator*() const
2108 Assert(d_origNode
!= nullptr);
2109 // this term has an extra child (mismatch between API and internal structure)
2110 // the extra child will be the first child
2111 bool extra_child
= isApplyKind(d_origNode
->getKind());
2113 if (!d_pos
&& extra_child
)
2115 return Term(d_solver
, d_origNode
->getOperator());
2119 uint32_t idx
= d_pos
;
2126 return Term(d_solver
, (*d_origNode
)[idx
]);
2130 Term::const_iterator
Term::begin() const
2132 return Term::const_iterator(d_solver
, d_node
, 0);
2135 Term::const_iterator
Term::end() const
2137 int endpos
= d_node
->getNumChildren();
2138 // special cases for APPLY_*
2139 // the API differs from the internal structure
2140 // the API takes a "higher-order" perspective and the applied
2141 // function or datatype constructor/selector/tester is a Term
2142 // which means it needs to be one of the children, even though
2143 // internally it is not
2144 if (isApplyKind(d_node
->getKind()))
2146 // one more child if this is a UF application (count the UF as a child)
2149 return Term::const_iterator(d_solver
, d_node
, endpos
);
2152 const CVC4::Node
& Term::getNode(void) const { return *d_node
; }
2155 const Rational
& getRational(const CVC4::Node
& node
)
2157 return node
.getConst
<Rational
>();
2159 Integer
getInteger(const CVC4::Node
& node
)
2161 return node
.getConst
<Rational
>().getNumerator();
2163 template <typename T
>
2164 bool checkIntegerBounds(const Integer
& i
)
2166 return i
>= std::numeric_limits
<T
>::min()
2167 && i
<= std::numeric_limits
<T
>::max();
2169 bool checkReal32Bounds(const Rational
& r
)
2171 return checkIntegerBounds
<std::int32_t>(r
.getNumerator())
2172 && checkIntegerBounds
<std::uint32_t>(r
.getDenominator());
2174 bool checkReal64Bounds(const Rational
& r
)
2176 return checkIntegerBounds
<std::int64_t>(r
.getNumerator())
2177 && checkIntegerBounds
<std::uint64_t>(r
.getDenominator());
2180 bool isInteger(const Node
& node
)
2182 return node
.getKind() == CVC4::Kind::CONST_RATIONAL
2183 && node
.getConst
<Rational
>().isIntegral();
2185 bool isInt32(const Node
& node
)
2187 return isInteger(node
)
2188 && checkIntegerBounds
<std::int32_t>(getInteger(node
));
2190 bool isUInt32(const Node
& node
)
2192 return isInteger(node
)
2193 && checkIntegerBounds
<std::uint32_t>(getInteger(node
));
2195 bool isInt64(const Node
& node
)
2197 return isInteger(node
)
2198 && checkIntegerBounds
<std::int64_t>(getInteger(node
));
2200 bool isUInt64(const Node
& node
)
2202 return isInteger(node
)
2203 && checkIntegerBounds
<std::uint64_t>(getInteger(node
));
2205 } // namespace detail
2207 bool Term::isInt32() const { return detail::isInt32(*d_node
); }
2208 std::int32_t Term::getInt32() const
2210 CVC4_API_CHECK(detail::isInt32(*d_node
))
2211 << "Term should be a Int32 when calling getInt32()";
2212 return detail::getInteger(*d_node
).getSignedInt();
2214 bool Term::isUInt32() const { return detail::isUInt32(*d_node
); }
2215 std::uint32_t Term::getUInt32() const
2217 CVC4_API_CHECK(detail::isUInt32(*d_node
))
2218 << "Term should be a UInt32 when calling getUInt32()";
2219 return detail::getInteger(*d_node
).getUnsignedInt();
2221 bool Term::isInt64() const { return detail::isInt64(*d_node
); }
2222 std::int64_t Term::getInt64() const
2224 CVC4_API_CHECK(detail::isInt64(*d_node
))
2225 << "Term should be a Int64 when calling getInt64()";
2226 return detail::getInteger(*d_node
).getLong();
2228 bool Term::isUInt64() const { return detail::isUInt64(*d_node
); }
2229 std::uint64_t Term::getUInt64() const
2231 CVC4_API_CHECK(detail::isUInt64(*d_node
))
2232 << "Term should be a UInt64 when calling getUInt64()";
2233 return detail::getInteger(*d_node
).getUnsignedLong();
2235 bool Term::isInteger() const { return detail::isInteger(*d_node
); }
2236 std::string
Term::getInteger() const
2238 CVC4_API_CHECK(detail::isInteger(*d_node
))
2239 << "Term should be an Int when calling getIntString()";
2240 return detail::getInteger(*d_node
).toString();
2243 bool Term::isString() const
2245 return d_node
->getKind() == CVC4::Kind::CONST_STRING
;
2248 std::wstring
Term::getString() const
2250 CVC4_API_CHECK(d_node
->getKind() == CVC4::Kind::CONST_STRING
)
2251 << "Term should be a String when calling getString()";
2252 return d_node
->getConst
<CVC4::String
>().toWString();
2255 std::vector
<Node
> Term::termVectorToNodes(const std::vector
<Term
>& terms
)
2257 std::vector
<Node
> res
;
2258 for (const Term
& t
: terms
)
2260 res
.push_back(t
.getNode());
2265 std::ostream
& operator<<(std::ostream
& out
, const Term
& t
)
2267 out
<< t
.toString();
2271 std::ostream
& operator<<(std::ostream
& out
, const std::vector
<Term
>& vector
)
2273 container_to_stream(out
, vector
);
2277 std::ostream
& operator<<(std::ostream
& out
, const std::set
<Term
>& set
)
2279 container_to_stream(out
, set
);
2283 std::ostream
& operator<<(
2285 const std::unordered_set
<Term
, TermHashFunction
>& unordered_set
)
2287 container_to_stream(out
, unordered_set
);
2291 template <typename V
>
2292 std::ostream
& operator<<(std::ostream
& out
, const std::map
<Term
, V
>& map
)
2294 container_to_stream(out
, map
);
2298 template <typename V
>
2299 std::ostream
& operator<<(
2301 const std::unordered_map
<Term
, V
, TermHashFunction
>& unordered_map
)
2303 container_to_stream(out
, unordered_map
);
2307 size_t TermHashFunction::operator()(const Term
& t
) const
2309 return NodeHashFunction()(*t
.d_node
);
2312 /* -------------------------------------------------------------------------- */
2314 /* -------------------------------------------------------------------------- */
2316 /* DatatypeConstructorDecl -------------------------------------------------- */
2318 DatatypeConstructorDecl::DatatypeConstructorDecl()
2319 : d_solver(nullptr), d_ctor(nullptr)
2323 DatatypeConstructorDecl::DatatypeConstructorDecl(const Solver
* slv
,
2324 const std::string
& name
)
2325 : d_solver(slv
), d_ctor(new CVC4::DTypeConstructor(name
))
2328 DatatypeConstructorDecl::~DatatypeConstructorDecl()
2330 if (d_ctor
!= nullptr)
2332 // ensure proper node manager is in scope
2333 NodeManagerScope
scope(d_solver
->getNodeManager());
2338 void DatatypeConstructorDecl::addSelector(const std::string
& name
,
2341 NodeManagerScope
scope(d_solver
->getNodeManager());
2342 CVC4_API_ARG_CHECK_EXPECTED(!sort
.isNull(), sort
)
2343 << "non-null range sort for selector";
2344 d_ctor
->addArg(name
, *sort
.d_type
);
2347 void DatatypeConstructorDecl::addSelectorSelf(const std::string
& name
)
2349 NodeManagerScope
scope(d_solver
->getNodeManager());
2350 d_ctor
->addArgSelf(name
);
2353 std::string
DatatypeConstructorDecl::toString() const
2355 std::stringstream ss
;
2360 std::ostream
& operator<<(std::ostream
& out
,
2361 const DatatypeConstructorDecl
& ctordecl
)
2363 out
<< ctordecl
.toString();
2367 std::ostream
& operator<<(std::ostream
& out
,
2368 const std::vector
<DatatypeConstructorDecl
>& vector
)
2370 container_to_stream(out
, vector
);
2374 /* DatatypeDecl ------------------------------------------------------------- */
2376 DatatypeDecl::DatatypeDecl() : d_solver(nullptr), d_dtype(nullptr) {}
2378 DatatypeDecl::DatatypeDecl(const Solver
* slv
,
2379 const std::string
& name
,
2381 : d_solver(slv
), d_dtype(new CVC4::DType(name
, isCoDatatype
))
2385 DatatypeDecl::DatatypeDecl(const Solver
* slv
,
2386 const std::string
& name
,
2390 d_dtype(new CVC4::DType(
2391 name
, std::vector
<TypeNode
>{*param
.d_type
}, isCoDatatype
))
2395 DatatypeDecl::DatatypeDecl(const Solver
* slv
,
2396 const std::string
& name
,
2397 const std::vector
<Sort
>& params
,
2401 std::vector
<TypeNode
> tparams
= Sort::sortVectorToTypeNodes(params
);
2402 d_dtype
= std::shared_ptr
<CVC4::DType
>(
2403 new CVC4::DType(name
, tparams
, isCoDatatype
));
2406 bool DatatypeDecl::isNullHelper() const { return !d_dtype
; }
2408 DatatypeDecl::~DatatypeDecl()
2410 if (d_dtype
!= nullptr)
2412 // ensure proper node manager is in scope
2413 NodeManagerScope
scope(d_solver
->getNodeManager());
2418 void DatatypeDecl::addConstructor(const DatatypeConstructorDecl
& ctor
)
2420 NodeManagerScope
scope(d_solver
->getNodeManager());
2421 CVC4_API_CHECK_NOT_NULL
;
2422 d_dtype
->addConstructor(ctor
.d_ctor
);
2425 size_t DatatypeDecl::getNumConstructors() const
2427 CVC4_API_CHECK_NOT_NULL
;
2428 return d_dtype
->getNumConstructors();
2431 bool DatatypeDecl::isParametric() const
2433 CVC4_API_CHECK_NOT_NULL
;
2434 return d_dtype
->isParametric();
2437 std::string
DatatypeDecl::toString() const
2439 CVC4_API_CHECK_NOT_NULL
;
2440 std::stringstream ss
;
2445 std::string
DatatypeDecl::getName() const
2447 CVC4_API_CHECK_NOT_NULL
;
2448 return d_dtype
->getName();
2451 bool DatatypeDecl::isNull() const { return isNullHelper(); }
2453 std::ostream
& operator<<(std::ostream
& out
, const DatatypeDecl
& dtdecl
)
2455 out
<< dtdecl
.toString();
2459 CVC4::DType
& DatatypeDecl::getDatatype(void) const { return *d_dtype
; }
2461 /* DatatypeSelector --------------------------------------------------------- */
2463 DatatypeSelector::DatatypeSelector() : d_solver(nullptr), d_stor(nullptr) {}
2465 DatatypeSelector::DatatypeSelector(const Solver
* slv
,
2466 const CVC4::DTypeSelector
& stor
)
2467 : d_solver(slv
), d_stor(new CVC4::DTypeSelector(stor
))
2469 CVC4_API_CHECK(d_stor
->isResolved()) << "Expected resolved datatype selector";
2472 DatatypeSelector::~DatatypeSelector()
2474 if (d_stor
!= nullptr)
2476 // ensure proper node manager is in scope
2477 NodeManagerScope
scope(d_solver
->getNodeManager());
2482 std::string
DatatypeSelector::getName() const { return d_stor
->getName(); }
2484 Term
DatatypeSelector::getSelectorTerm() const
2486 Term sel
= Term(d_solver
, d_stor
->getSelector());
2490 Sort
DatatypeSelector::getRangeSort() const
2492 return Sort(d_solver
, d_stor
->getRangeType());
2495 std::string
DatatypeSelector::toString() const
2497 std::stringstream ss
;
2502 std::ostream
& operator<<(std::ostream
& out
, const DatatypeSelector
& stor
)
2504 out
<< stor
.toString();
2508 /* DatatypeConstructor ------------------------------------------------------ */
2510 DatatypeConstructor::DatatypeConstructor() : d_solver(nullptr), d_ctor(nullptr)
2514 DatatypeConstructor::DatatypeConstructor(const Solver
* slv
,
2515 const CVC4::DTypeConstructor
& ctor
)
2516 : d_solver(slv
), d_ctor(new CVC4::DTypeConstructor(ctor
))
2518 CVC4_API_CHECK(d_ctor
->isResolved())
2519 << "Expected resolved datatype constructor";
2522 DatatypeConstructor::~DatatypeConstructor()
2524 if (d_ctor
!= nullptr)
2526 // ensure proper node manager is in scope
2527 NodeManagerScope
scope(d_solver
->getNodeManager());
2532 std::string
DatatypeConstructor::getName() const { return d_ctor
->getName(); }
2534 Term
DatatypeConstructor::getConstructorTerm() const
2536 Term ctor
= Term(d_solver
, d_ctor
->getConstructor());
2540 Term
DatatypeConstructor::getSpecializedConstructorTerm(
2541 const Sort
& retSort
) const
2543 NodeManagerScope
scope(d_solver
->getNodeManager());
2544 CVC4_API_CHECK(d_ctor
->isResolved())
2545 << "Expected resolved datatype constructor";
2546 CVC4_API_CHECK(retSort
.isDatatype())
2547 << "Cannot get specialized constructor type for non-datatype type "
2549 CVC4_API_TRY_CATCH_BEGIN
;
2551 NodeManager
* nm
= d_solver
->getNodeManager();
2553 nm
->mkNode(kind::APPLY_TYPE_ASCRIPTION
,
2554 nm
->mkConst(AscriptionType(
2555 d_ctor
->getSpecializedConstructorType(*retSort
.d_type
))),
2556 d_ctor
->getConstructor());
2557 (void)ret
.getType(true); /* kick off type checking */
2558 // apply type ascription to the operator
2559 Term sctor
= api::Term(d_solver
, ret
);
2562 CVC4_API_TRY_CATCH_END
;
2565 Term
DatatypeConstructor::getTesterTerm() const
2567 Term tst
= Term(d_solver
, d_ctor
->getTester());
2571 size_t DatatypeConstructor::getNumSelectors() const
2573 return d_ctor
->getNumArgs();
2576 DatatypeSelector
DatatypeConstructor::operator[](size_t index
) const
2578 return DatatypeSelector(d_solver
, (*d_ctor
)[index
]);
2581 DatatypeSelector
DatatypeConstructor::operator[](const std::string
& name
) const
2583 return getSelectorForName(name
);
2586 DatatypeSelector
DatatypeConstructor::getSelector(const std::string
& name
) const
2588 return getSelectorForName(name
);
2591 Term
DatatypeConstructor::getSelectorTerm(const std::string
& name
) const
2593 DatatypeSelector sel
= getSelector(name
);
2594 return sel
.getSelectorTerm();
2597 DatatypeConstructor::const_iterator
DatatypeConstructor::begin() const
2599 return DatatypeConstructor::const_iterator(d_solver
, *d_ctor
, true);
2602 DatatypeConstructor::const_iterator
DatatypeConstructor::end() const
2604 return DatatypeConstructor::const_iterator(d_solver
, *d_ctor
, false);
2607 DatatypeConstructor::const_iterator::const_iterator(
2608 const Solver
* slv
, const CVC4::DTypeConstructor
& ctor
, bool begin
)
2611 d_int_stors
= &ctor
.getArgs();
2613 const std::vector
<std::shared_ptr
<CVC4::DTypeSelector
>>& sels
=
2615 for (const std::shared_ptr
<CVC4::DTypeSelector
>& s
: sels
)
2617 /* Can not use emplace_back here since constructor is private. */
2618 d_stors
.push_back(DatatypeSelector(d_solver
, *s
.get()));
2620 d_idx
= begin
? 0 : sels
.size();
2623 DatatypeConstructor::const_iterator::const_iterator()
2624 : d_solver(nullptr), d_int_stors(nullptr), d_idx(0)
2628 DatatypeConstructor::const_iterator
&
2629 DatatypeConstructor::const_iterator::operator=(
2630 const DatatypeConstructor::const_iterator
& it
)
2632 d_solver
= it
.d_solver
;
2633 d_int_stors
= it
.d_int_stors
;
2634 d_stors
= it
.d_stors
;
2639 const DatatypeSelector
& DatatypeConstructor::const_iterator::operator*() const
2641 return d_stors
[d_idx
];
2644 const DatatypeSelector
* DatatypeConstructor::const_iterator::operator->() const
2646 return &d_stors
[d_idx
];
2649 DatatypeConstructor::const_iterator
&
2650 DatatypeConstructor::const_iterator::operator++()
2656 DatatypeConstructor::const_iterator
2657 DatatypeConstructor::const_iterator::operator++(int)
2659 DatatypeConstructor::const_iterator
it(*this);
2664 bool DatatypeConstructor::const_iterator::operator==(
2665 const DatatypeConstructor::const_iterator
& other
) const
2667 return d_int_stors
== other
.d_int_stors
&& d_idx
== other
.d_idx
;
2670 bool DatatypeConstructor::const_iterator::operator!=(
2671 const DatatypeConstructor::const_iterator
& other
) const
2673 return d_int_stors
!= other
.d_int_stors
|| d_idx
!= other
.d_idx
;
2676 std::string
DatatypeConstructor::toString() const
2678 std::stringstream ss
;
2683 DatatypeSelector
DatatypeConstructor::getSelectorForName(
2684 const std::string
& name
) const
2686 bool foundSel
= false;
2688 for (size_t i
= 0, nsels
= getNumSelectors(); i
< nsels
; i
++)
2690 if ((*d_ctor
)[i
].getName() == name
)
2699 std::stringstream snames
;
2701 for (size_t i
= 0, ncons
= getNumSelectors(); i
< ncons
; i
++)
2703 snames
<< (*d_ctor
)[i
].getName() << " ";
2706 CVC4_API_CHECK(foundSel
) << "No selector " << name
<< " for constructor "
2707 << getName() << " exists among " << snames
.str();
2709 return DatatypeSelector(d_solver
, (*d_ctor
)[index
]);
2712 std::ostream
& operator<<(std::ostream
& out
, const DatatypeConstructor
& ctor
)
2714 out
<< ctor
.toString();
2718 /* Datatype ----------------------------------------------------------------- */
2720 Datatype::Datatype(const Solver
* slv
, const CVC4::DType
& dtype
)
2721 : d_solver(slv
), d_dtype(new CVC4::DType(dtype
))
2723 CVC4_API_CHECK(d_dtype
->isResolved()) << "Expected resolved datatype";
2726 Datatype::Datatype() : d_solver(nullptr), d_dtype(nullptr) {}
2728 Datatype::~Datatype()
2730 if (d_dtype
!= nullptr)
2732 // ensure proper node manager is in scope
2733 NodeManagerScope
scope(d_solver
->getNodeManager());
2738 DatatypeConstructor
Datatype::operator[](size_t idx
) const
2740 CVC4_API_CHECK(idx
< getNumConstructors()) << "Index out of bounds.";
2741 return DatatypeConstructor(d_solver
, (*d_dtype
)[idx
]);
2744 DatatypeConstructor
Datatype::operator[](const std::string
& name
) const
2746 return getConstructorForName(name
);
2749 DatatypeConstructor
Datatype::getConstructor(const std::string
& name
) const
2751 return getConstructorForName(name
);
2754 Term
Datatype::getConstructorTerm(const std::string
& name
) const
2756 DatatypeConstructor ctor
= getConstructor(name
);
2757 return ctor
.getConstructorTerm();
2760 std::string
Datatype::getName() const { return d_dtype
->getName(); }
2762 size_t Datatype::getNumConstructors() const
2764 return d_dtype
->getNumConstructors();
2767 bool Datatype::isParametric() const { return d_dtype
->isParametric(); }
2768 bool Datatype::isCodatatype() const { return d_dtype
->isCodatatype(); }
2770 bool Datatype::isTuple() const { return d_dtype
->isTuple(); }
2772 bool Datatype::isRecord() const { return d_dtype
->isRecord(); }
2774 bool Datatype::isFinite() const { return d_dtype
->isFinite(); }
2775 bool Datatype::isWellFounded() const { return d_dtype
->isWellFounded(); }
2776 bool Datatype::hasNestedRecursion() const
2778 return d_dtype
->hasNestedRecursion();
2781 std::string
Datatype::toString() const { return d_dtype
->getName(); }
2783 Datatype::const_iterator
Datatype::begin() const
2785 return Datatype::const_iterator(d_solver
, *d_dtype
, true);
2788 Datatype::const_iterator
Datatype::end() const
2790 return Datatype::const_iterator(d_solver
, *d_dtype
, false);
2793 DatatypeConstructor
Datatype::getConstructorForName(
2794 const std::string
& name
) const
2796 bool foundCons
= false;
2798 for (size_t i
= 0, ncons
= getNumConstructors(); i
< ncons
; i
++)
2800 if ((*d_dtype
)[i
].getName() == name
)
2809 std::stringstream snames
;
2811 for (size_t i
= 0, ncons
= getNumConstructors(); i
< ncons
; i
++)
2813 snames
<< (*d_dtype
)[i
].getName() << " ";
2816 CVC4_API_CHECK(foundCons
) << "No constructor " << name
<< " for datatype "
2817 << getName() << " exists, among " << snames
.str();
2819 return DatatypeConstructor(d_solver
, (*d_dtype
)[index
]);
2822 Datatype::const_iterator::const_iterator(const Solver
* slv
,
2823 const CVC4::DType
& dtype
,
2825 : d_solver(slv
), d_int_ctors(&dtype
.getConstructors())
2827 const std::vector
<std::shared_ptr
<DTypeConstructor
>>& cons
=
2828 dtype
.getConstructors();
2829 for (const std::shared_ptr
<DTypeConstructor
>& c
: cons
)
2831 /* Can not use emplace_back here since constructor is private. */
2832 d_ctors
.push_back(DatatypeConstructor(d_solver
, *c
.get()));
2834 d_idx
= begin
? 0 : cons
.size();
2837 Datatype::const_iterator::const_iterator()
2838 : d_solver(nullptr), d_int_ctors(nullptr), d_idx(0)
2842 Datatype::const_iterator
& Datatype::const_iterator::operator=(
2843 const Datatype::const_iterator
& it
)
2845 d_solver
= it
.d_solver
;
2846 d_int_ctors
= it
.d_int_ctors
;
2847 d_ctors
= it
.d_ctors
;
2852 const DatatypeConstructor
& Datatype::const_iterator::operator*() const
2854 return d_ctors
[d_idx
];
2857 const DatatypeConstructor
* Datatype::const_iterator::operator->() const
2859 return &d_ctors
[d_idx
];
2862 Datatype::const_iterator
& Datatype::const_iterator::operator++()
2868 Datatype::const_iterator
Datatype::const_iterator::operator++(int)
2870 Datatype::const_iterator
it(*this);
2875 bool Datatype::const_iterator::operator==(
2876 const Datatype::const_iterator
& other
) const
2878 return d_int_ctors
== other
.d_int_ctors
&& d_idx
== other
.d_idx
;
2881 bool Datatype::const_iterator::operator!=(
2882 const Datatype::const_iterator
& other
) const
2884 return d_int_ctors
!= other
.d_int_ctors
|| d_idx
!= other
.d_idx
;
2887 /* -------------------------------------------------------------------------- */
2889 /* -------------------------------------------------------------------------- */
2892 : d_solver(nullptr),
2902 Grammar::Grammar(const Solver
* slv
,
2903 const std::vector
<Term
>& sygusVars
,
2904 const std::vector
<Term
>& ntSymbols
)
2906 d_sygusVars(sygusVars
),
2907 d_ntSyms(ntSymbols
),
2908 d_ntsToTerms(ntSymbols
.size()),
2913 for (Term ntsymbol
: d_ntSyms
)
2915 d_ntsToTerms
.emplace(ntsymbol
, std::vector
<Term
>());
2919 void Grammar::addRule(const Term
& ntSymbol
, const Term
& rule
)
2921 CVC4_API_CHECK(!d_isResolved
) << "Grammar cannot be modified after passing "
2922 "it as an argument to synthFun/synthInv";
2923 CVC4_API_ARG_CHECK_NOT_NULL(ntSymbol
);
2924 CVC4_API_ARG_CHECK_NOT_NULL(rule
);
2925 CVC4_API_ARG_CHECK_EXPECTED(
2926 d_ntsToTerms
.find(ntSymbol
) != d_ntsToTerms
.cend(), ntSymbol
)
2927 << "ntSymbol to be one of the non-terminal symbols given in the "
2929 CVC4_API_CHECK(ntSymbol
.d_node
->getType() == rule
.d_node
->getType())
2930 << "Expected ntSymbol and rule to have the same sort";
2932 d_ntsToTerms
[ntSymbol
].push_back(rule
);
2935 void Grammar::addRules(const Term
& ntSymbol
, const std::vector
<Term
>& rules
)
2937 CVC4_API_CHECK(!d_isResolved
) << "Grammar cannot be modified after passing "
2938 "it as an argument to synthFun/synthInv";
2939 CVC4_API_ARG_CHECK_NOT_NULL(ntSymbol
);
2940 CVC4_API_ARG_CHECK_EXPECTED(
2941 d_ntsToTerms
.find(ntSymbol
) != d_ntsToTerms
.cend(), ntSymbol
)
2942 << "ntSymbol to be one of the non-terminal symbols given in the "
2945 for (size_t i
= 0, n
= rules
.size(); i
< n
; ++i
)
2947 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
2948 !rules
[i
].isNull(), "parameter rule", rules
[i
], i
)
2950 CVC4_API_CHECK(ntSymbol
.d_node
->getType() == rules
[i
].d_node
->getType())
2951 << "Expected ntSymbol and rule at index " << i
2952 << " to have the same sort";
2955 d_ntsToTerms
[ntSymbol
].insert(
2956 d_ntsToTerms
[ntSymbol
].cend(), rules
.cbegin(), rules
.cend());
2959 void Grammar::addAnyConstant(const Term
& ntSymbol
)
2961 CVC4_API_CHECK(!d_isResolved
) << "Grammar cannot be modified after passing "
2962 "it as an argument to synthFun/synthInv";
2963 CVC4_API_ARG_CHECK_NOT_NULL(ntSymbol
);
2964 CVC4_API_ARG_CHECK_EXPECTED(
2965 d_ntsToTerms
.find(ntSymbol
) != d_ntsToTerms
.cend(), ntSymbol
)
2966 << "ntSymbol to be one of the non-terminal symbols given in the "
2969 d_allowConst
.insert(ntSymbol
);
2972 void Grammar::addAnyVariable(const Term
& ntSymbol
)
2974 CVC4_API_CHECK(!d_isResolved
) << "Grammar cannot be modified after passing "
2975 "it as an argument to synthFun/synthInv";
2976 CVC4_API_ARG_CHECK_NOT_NULL(ntSymbol
);
2977 CVC4_API_ARG_CHECK_EXPECTED(
2978 d_ntsToTerms
.find(ntSymbol
) != d_ntsToTerms
.cend(), ntSymbol
)
2979 << "ntSymbol to be one of the non-terminal symbols given in the "
2982 d_allowVars
.insert(ntSymbol
);
2986 * this function concatinates the outputs of calling f on each element between
2987 * first and last, seperated by sep.
2988 * @param first the beginning of the range
2989 * @param last the end of the range
2990 * @param f the function to call on each element in the range, its output must
2991 * be overloaded for operator<<
2992 * @param sep the string to add between successive calls to f
2994 template <typename Iterator
, typename Function
>
2995 std::string
join(Iterator first
, Iterator last
, Function f
, std::string sep
)
2997 std::stringstream ss
;
3015 std::string
Grammar::toString() const
3017 std::stringstream ss
;
3018 ss
<< " (" // pre-declaration
3023 std::stringstream s
;
3024 s
<< '(' << t
<< ' ' << t
.getSort() << ')';
3028 << ")\n (" // grouped rule listing
3032 [this](const Term
& t
) {
3033 bool allowConst
= d_allowConst
.find(t
) != d_allowConst
.cend(),
3034 allowVars
= d_allowVars
.find(t
) != d_allowVars
.cend();
3035 const std::vector
<Term
>& rules
= d_ntsToTerms
.at(t
);
3036 std::stringstream s
;
3037 s
<< '(' << t
<< ' ' << t
.getSort() << " ("
3038 << (allowConst
? "(Constant " + t
.getSort().toString() + ")"
3040 << (allowConst
&& allowVars
? " " : "")
3041 << (allowVars
? "(Var " + t
.getSort().toString() + ")" : "")
3042 << ((allowConst
|| allowVars
) && !rules
.empty() ? " " : "")
3046 [](const Term
& rule
) { return rule
.toString(); },
3057 Sort
Grammar::resolve()
3059 d_isResolved
= true;
3063 if (!d_sygusVars
.empty())
3067 d_solver
->getNodeManager()->mkNode(
3068 CVC4::kind::BOUND_VAR_LIST
, Term::termVectorToNodes(d_sygusVars
)));
3071 std::unordered_map
<Term
, Sort
, TermHashFunction
> ntsToUnres(d_ntSyms
.size());
3073 for (Term ntsymbol
: d_ntSyms
)
3075 // make the unresolved type, used for referencing the final version of
3076 // the ntsymbol's datatype
3077 ntsToUnres
[ntsymbol
] =
3078 Sort(d_solver
, d_solver
->getNodeManager()->mkSort(ntsymbol
.toString()));
3081 std::vector
<CVC4::DType
> datatypes
;
3082 std::set
<TypeNode
> unresTypes
;
3084 datatypes
.reserve(d_ntSyms
.size());
3086 for (const Term
& ntSym
: d_ntSyms
)
3088 // make the datatype, which encodes terms generated by this non-terminal
3089 DatatypeDecl
dtDecl(d_solver
, ntSym
.toString());
3091 for (const Term
& consTerm
: d_ntsToTerms
[ntSym
])
3093 addSygusConstructorTerm(dtDecl
, consTerm
, ntsToUnres
);
3096 if (d_allowVars
.find(ntSym
) != d_allowVars
.cend())
3098 addSygusConstructorVariables(dtDecl
,
3099 Sort(d_solver
, ntSym
.d_node
->getType()));
3102 bool aci
= d_allowConst
.find(ntSym
) != d_allowConst
.end();
3103 TypeNode btt
= ntSym
.d_node
->getType();
3104 dtDecl
.d_dtype
->setSygus(btt
, *bvl
.d_node
, aci
, false);
3106 // We can be in a case where the only rule specified was (Variable T)
3107 // and there are no variables of type T, in which case this is a bogus
3108 // grammar. This results in the error below.
3109 CVC4_API_CHECK(dtDecl
.d_dtype
->getNumConstructors() != 0)
3110 << "Grouped rule listing for " << *dtDecl
.d_dtype
3111 << " produced an empty rule list";
3113 datatypes
.push_back(*dtDecl
.d_dtype
);
3114 unresTypes
.insert(*ntsToUnres
[ntSym
].d_type
);
3117 std::vector
<TypeNode
> datatypeTypes
=
3118 d_solver
->getNodeManager()->mkMutualDatatypeTypes(
3119 datatypes
, unresTypes
, NodeManager::DATATYPE_FLAG_PLACEHOLDER
);
3121 // return is the first datatype
3122 return Sort(d_solver
, datatypeTypes
[0]);
3125 void Grammar::addSygusConstructorTerm(
3128 const std::unordered_map
<Term
, Sort
, TermHashFunction
>& ntsToUnres
) const
3130 // At this point, we should know that dt is well founded, and that its
3131 // builtin sygus operators are well-typed.
3132 // Now, purify each occurrence of a non-terminal symbol in term, replace by
3133 // free variables. These become arguments to constructors. Notice we must do
3134 // a tree traversal in this function, since unique paths to the same term
3135 // should be treated as distinct terms.
3136 // Notice that let expressions are forbidden in the input syntax of term, so
3137 // this does not lead to exponential behavior with respect to input size.
3138 std::vector
<Term
> args
;
3139 std::vector
<Sort
> cargs
;
3140 Term op
= purifySygusGTerm(term
, args
, cargs
, ntsToUnres
);
3141 std::stringstream ssCName
;
3142 ssCName
<< op
.getKind();
3147 d_solver
->getNodeManager()->mkNode(CVC4::kind::BOUND_VAR_LIST
,
3148 Term::termVectorToNodes(args
)));
3149 // its operator is a lambda
3151 d_solver
->getNodeManager()->mkNode(
3152 CVC4::kind::LAMBDA
, *lbvl
.d_node
, *op
.d_node
));
3154 std::vector
<TypeNode
> cargst
= Sort::sortVectorToTypeNodes(cargs
);
3155 dt
.d_dtype
->addSygusConstructor(*op
.d_node
, ssCName
.str(), cargst
);
3158 Term
Grammar::purifySygusGTerm(
3160 std::vector
<Term
>& args
,
3161 std::vector
<Sort
>& cargs
,
3162 const std::unordered_map
<Term
, Sort
, TermHashFunction
>& ntsToUnres
) const
3164 std::unordered_map
<Term
, Sort
, TermHashFunction
>::const_iterator itn
=
3165 ntsToUnres
.find(term
);
3166 if (itn
!= ntsToUnres
.cend())
3170 d_solver
->getNodeManager()->mkBoundVar(term
.d_node
->getType()));
3171 args
.push_back(ret
);
3172 cargs
.push_back(itn
->second
);
3175 std::vector
<Term
> pchildren
;
3176 bool childChanged
= false;
3177 for (unsigned i
= 0, nchild
= term
.d_node
->getNumChildren(); i
< nchild
; i
++)
3179 Term ptermc
= purifySygusGTerm(
3180 Term(d_solver
, (*term
.d_node
)[i
]), args
, cargs
, ntsToUnres
);
3181 pchildren
.push_back(ptermc
);
3182 childChanged
= childChanged
|| *ptermc
.d_node
!= (*term
.d_node
)[i
];
3191 if (term
.d_node
->getMetaKind() == kind::metakind::PARAMETERIZED
)
3193 // it's an indexed operator so we should provide the op
3194 NodeBuilder
<> nb(term
.d_node
->getKind());
3195 nb
<< term
.d_node
->getOperator();
3196 nb
.append(Term::termVectorToNodes(pchildren
));
3197 nret
= nb
.constructNode();
3201 nret
= d_solver
->getNodeManager()->mkNode(
3202 term
.d_node
->getKind(), Term::termVectorToNodes(pchildren
));
3205 return Term(d_solver
, nret
);
3208 void Grammar::addSygusConstructorVariables(DatatypeDecl
& dt
,
3209 const Sort
& sort
) const
3211 Assert(!sort
.isNull());
3212 // each variable of appropriate type becomes a sygus constructor in dt.
3213 for (unsigned i
= 0, size
= d_sygusVars
.size(); i
< size
; i
++)
3215 Term v
= d_sygusVars
[i
];
3216 if (v
.d_node
->getType() == *sort
.d_type
)
3218 std::stringstream ss
;
3220 std::vector
<TypeNode
> cargs
;
3221 dt
.d_dtype
->addSygusConstructor(*v
.d_node
, ss
.str(), cargs
);
3226 std::ostream
& operator<<(std::ostream
& out
, const Grammar
& g
)
3228 return out
<< g
.toString();
3231 /* -------------------------------------------------------------------------- */
3232 /* Rounding Mode for Floating Points */
3233 /* -------------------------------------------------------------------------- */
3236 unordered_map
<RoundingMode
, CVC4::RoundingMode
, RoundingModeHashFunction
>
3238 {ROUND_NEAREST_TIES_TO_EVEN
,
3239 CVC4::RoundingMode::ROUND_NEAREST_TIES_TO_EVEN
},
3240 {ROUND_TOWARD_POSITIVE
, CVC4::RoundingMode::ROUND_TOWARD_POSITIVE
},
3241 {ROUND_TOWARD_NEGATIVE
, CVC4::RoundingMode::ROUND_TOWARD_NEGATIVE
},
3242 {ROUND_TOWARD_ZERO
, CVC4::RoundingMode::ROUND_TOWARD_ZERO
},
3243 {ROUND_NEAREST_TIES_TO_AWAY
,
3244 CVC4::RoundingMode::ROUND_NEAREST_TIES_TO_AWAY
},
3247 const static std::unordered_map
<CVC4::RoundingMode
,
3249 CVC4::RoundingModeHashFunction
>
3251 {CVC4::RoundingMode::ROUND_NEAREST_TIES_TO_EVEN
,
3252 ROUND_NEAREST_TIES_TO_EVEN
},
3253 {CVC4::RoundingMode::ROUND_TOWARD_POSITIVE
, ROUND_TOWARD_POSITIVE
},
3254 {CVC4::RoundingMode::ROUND_TOWARD_POSITIVE
, ROUND_TOWARD_NEGATIVE
},
3255 {CVC4::RoundingMode::ROUND_TOWARD_ZERO
, ROUND_TOWARD_ZERO
},
3256 {CVC4::RoundingMode::ROUND_NEAREST_TIES_TO_AWAY
,
3257 ROUND_NEAREST_TIES_TO_AWAY
},
3260 size_t RoundingModeHashFunction::operator()(const RoundingMode
& rm
) const
3265 /* -------------------------------------------------------------------------- */
3267 /* -------------------------------------------------------------------------- */
3269 Solver::Solver(Options
* opts
)
3271 d_nodeMgr
.reset(new NodeManager());
3272 d_smtEngine
.reset(new SmtEngine(d_nodeMgr
.get(), opts
));
3273 d_smtEngine
->setSolver(this);
3274 Options
& o
= d_smtEngine
->getOptions();
3275 d_rng
.reset(new Random(o
[options::seed
]));
3276 #if CVC4_STATISTICS_ON
3277 d_stats
.reset(new Statistics());
3278 d_nodeMgr
->getStatisticsRegistry()->registerStat(&d_stats
->d_consts
);
3279 d_nodeMgr
->getStatisticsRegistry()->registerStat(&d_stats
->d_vars
);
3280 d_nodeMgr
->getStatisticsRegistry()->registerStat(&d_stats
->d_terms
);
3284 Solver::~Solver() {}
3286 /* Helpers and private functions */
3287 /* -------------------------------------------------------------------------- */
3289 NodeManager
* Solver::getNodeManager(void) const { return d_nodeMgr
.get(); }
3291 void Solver::increment_term_stats(Kind kind
) const
3293 #ifdef CVC4_STATISTICS_ON
3294 d_stats
->d_terms
<< kind
;
3298 void Solver::increment_vars_consts_stats(const Sort
& sort
, bool is_var
) const
3300 #ifdef CVC4_STATISTICS_ON
3301 const TypeNode tn
= sort
.getTypeNode();
3302 TypeConstant tc
= tn
.getKind() == CVC4::kind::TYPE_CONSTANT
3303 ? tn
.getConst
<TypeConstant
>()
3307 d_stats
->d_vars
<< tc
;
3311 d_stats
->d_consts
<< tc
;
3316 /* Split out to avoid nested API calls (problematic with API tracing). */
3317 /* .......................................................................... */
3319 template <typename T
>
3320 Term
Solver::mkValHelper(T t
) const
3322 NodeManagerScope
scope(getNodeManager());
3323 Node res
= getNodeManager()->mkConst(t
);
3324 (void)res
.getType(true); /* kick off type checking */
3325 return Term(this, res
);
3328 Term
Solver::mkRealFromStrHelper(const std::string
& s
) const
3332 CVC4::Rational r
= s
.find('/') != std::string::npos
3334 : CVC4::Rational::fromDecimal(s
);
3335 return mkValHelper
<CVC4::Rational
>(r
);
3337 catch (const std::invalid_argument
& e
)
3339 std::stringstream message
;
3340 message
<< "Cannot construct Real or Int from string argument '" << s
<< "'"
3342 throw std::invalid_argument(message
.str());
3346 Term
Solver::mkBVFromIntHelper(uint32_t size
, uint64_t val
) const
3348 CVC4_API_TRY_CATCH_BEGIN
;
3349 CVC4_API_ARG_CHECK_EXPECTED(size
> 0, size
) << "a bit-width > 0";
3351 return mkValHelper
<CVC4::BitVector
>(CVC4::BitVector(size
, val
));
3353 CVC4_API_TRY_CATCH_END
;
3356 Term
Solver::mkBVFromStrHelper(const std::string
& s
, uint32_t base
) const
3358 CVC4_API_ARG_CHECK_EXPECTED(!s
.empty(), s
) << "a non-empty string";
3359 CVC4_API_ARG_CHECK_EXPECTED(base
== 2 || base
== 10 || base
== 16, base
)
3360 << "base 2, 10, or 16";
3362 return mkValHelper
<CVC4::BitVector
>(CVC4::BitVector(s
, base
));
3365 Term
Solver::mkBVFromStrHelper(uint32_t size
,
3366 const std::string
& s
,
3367 uint32_t base
) const
3369 CVC4_API_ARG_CHECK_EXPECTED(!s
.empty(), s
) << "a non-empty string";
3370 CVC4_API_ARG_CHECK_EXPECTED(base
== 2 || base
== 10 || base
== 16, base
)
3371 << "base 2, 10, or 16";
3373 Integer
val(s
, base
);
3375 if (val
.strictlyNegative())
3377 CVC4_API_CHECK(val
>= -Integer("2", 10).pow(size
- 1))
3378 << "Overflow in bitvector construction (specified bitvector size "
3379 << size
<< " too small to hold value " << s
<< ")";
3383 CVC4_API_CHECK(val
.modByPow2(size
) == val
)
3384 << "Overflow in bitvector construction (specified bitvector size "
3385 << size
<< " too small to hold value " << s
<< ")";
3388 return mkValHelper
<CVC4::BitVector
>(CVC4::BitVector(size
, val
));
3391 Term
Solver::mkCharFromStrHelper(const std::string
& s
) const
3393 CVC4_API_CHECK(s
.find_first_not_of("0123456789abcdefABCDEF", 0)
3394 == std::string::npos
3395 && s
.size() <= 5 && s
.size() > 0)
3396 << "Unexpected string for hexadecimal character " << s
;
3397 uint32_t val
= static_cast<uint32_t>(std::stoul(s
, 0, 16));
3398 CVC4_API_CHECK(val
< String::num_codes())
3399 << "Not a valid code point for hexadecimal character " << s
;
3400 std::vector
<unsigned> cpts
;
3401 cpts
.push_back(val
);
3402 return mkValHelper
<CVC4::String
>(CVC4::String(cpts
));
3405 Term
Solver::getValueHelper(const Term
& term
) const
3407 // Note: Term is checked in the caller to avoid double checks
3408 Node value
= d_smtEngine
->getValue(*term
.d_node
);
3409 Term res
= Term(this, value
);
3410 // May need to wrap in real cast so that user know this is a real.
3411 TypeNode tn
= (*term
.d_node
).getType();
3412 if (!tn
.isInteger() && value
.getType().isInteger())
3414 return ensureRealSort(res
);
3419 Sort
Solver::mkTupleSortHelper(const std::vector
<Sort
>& sorts
) const
3421 // Note: Sorts are checked in the caller to avoid double checks
3422 std::vector
<TypeNode
> typeNodes
= Sort::sortVectorToTypeNodes(sorts
);
3423 return Sort(this, getNodeManager()->mkTupleType(typeNodes
));
3426 Term
Solver::mkTermFromKind(Kind kind
) const
3428 CVC4_API_KIND_CHECK_EXPECTED(
3429 kind
== PI
|| kind
== REGEXP_EMPTY
|| kind
== REGEXP_SIGMA
, kind
)
3430 << "PI or REGEXP_EMPTY or REGEXP_SIGMA";
3433 if (kind
== REGEXP_EMPTY
|| kind
== REGEXP_SIGMA
)
3435 CVC4::Kind k
= extToIntKind(kind
);
3436 Assert(isDefinedIntKind(k
));
3437 res
= d_nodeMgr
->mkNode(k
, std::vector
<Node
>());
3442 res
= d_nodeMgr
->mkNullaryOperator(d_nodeMgr
->realType(), CVC4::kind::PI
);
3444 (void)res
.getType(true); /* kick off type checking */
3445 increment_term_stats(kind
);
3446 return Term(this, res
);
3449 Term
Solver::mkTermHelper(Kind kind
, const std::vector
<Term
>& children
) const
3451 for (size_t i
= 0, size
= children
.size(); i
< size
; ++i
)
3453 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3454 !children
[i
].isNull(), "child term", children
[i
], i
)
3456 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3457 this == children
[i
].d_solver
, "child term", children
[i
], i
)
3458 << "a child term associated to this solver object";
3461 std::vector
<Node
> echildren
= Term::termVectorToNodes(children
);
3462 CVC4::Kind k
= extToIntKind(kind
);
3463 Assert(isDefinedIntKind(k
))
3464 << "Not a defined internal kind : " << k
<< " " << kind
;
3467 if (echildren
.size() > 2)
3469 if (kind
== INTS_DIVISION
|| kind
== XOR
|| kind
== MINUS
3470 || kind
== DIVISION
|| kind
== HO_APPLY
|| kind
== REGEXP_DIFF
)
3472 // left-associative, but CVC4 internally only supports 2 args
3473 res
= d_nodeMgr
->mkLeftAssociative(k
, echildren
);
3475 else if (kind
== IMPLIES
)
3477 // right-associative, but CVC4 internally only supports 2 args
3478 res
= d_nodeMgr
->mkRightAssociative(k
, echildren
);
3480 else if (kind
== EQUAL
|| kind
== LT
|| kind
== GT
|| kind
== LEQ
3483 // "chainable", but CVC4 internally only supports 2 args
3484 res
= d_nodeMgr
->mkChain(k
, echildren
);
3486 else if (kind::isAssociative(k
))
3488 // mkAssociative has special treatment for associative operators with lots
3490 res
= d_nodeMgr
->mkAssociative(k
, echildren
);
3494 // default case, must check kind
3495 checkMkTerm(kind
, children
.size());
3496 res
= d_nodeMgr
->mkNode(k
, echildren
);
3499 else if (kind::isAssociative(k
))
3501 // associative case, same as above
3502 res
= d_nodeMgr
->mkAssociative(k
, echildren
);
3506 // default case, same as above
3507 checkMkTerm(kind
, children
.size());
3508 if (kind
== api::SINGLETON
)
3510 // the type of the term is the same as the type of the internal node
3511 // see Term::getSort()
3512 TypeNode type
= children
[0].d_node
->getType();
3513 // Internally NodeManager::mkSingleton needs a type argument
3514 // to construct a singleton, since there is no difference between
3515 // integers and reals (both are Rationals).
3516 // At the API, mkReal and mkInteger are different and therefore the
3517 // element type can be used safely here.
3518 res
= getNodeManager()->mkSingleton(type
, *children
[0].d_node
);
3520 else if (kind
== api::MK_BAG
)
3522 // the type of the term is the same as the type of the internal node
3523 // see Term::getSort()
3524 TypeNode type
= children
[0].d_node
->getType();
3525 // Internally NodeManager::mkBag needs a type argument
3526 // to construct a bag, since there is no difference between
3527 // integers and reals (both are Rationals).
3528 // At the API, mkReal and mkInteger are different and therefore the
3529 // element type can be used safely here.
3530 res
= getNodeManager()->mkBag(
3531 type
, *children
[0].d_node
, *children
[1].d_node
);
3535 res
= d_nodeMgr
->mkNode(k
, echildren
);
3539 (void)res
.getType(true); /* kick off type checking */
3540 increment_term_stats(kind
);
3541 return Term(this, res
);
3544 Term
Solver::mkTermHelper(const Op
& op
, const std::vector
<Term
>& children
) const
3546 CVC4_API_SOLVER_CHECK_OP(op
);
3548 if (!op
.isIndexedHelper())
3550 return mkTermHelper(op
.d_kind
, children
);
3553 for (size_t i
= 0, size
= children
.size(); i
< size
; ++i
)
3555 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3556 !children
[i
].isNull(), "child term", children
[i
], i
)
3558 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3559 this == children
[i
].d_solver
, "child term", children
[i
], i
)
3560 << "child term associated to this solver object";
3562 checkMkTerm(op
.d_kind
, children
.size());
3564 const CVC4::Kind int_kind
= extToIntKind(op
.d_kind
);
3565 std::vector
<Node
> echildren
= Term::termVectorToNodes(children
);
3567 NodeBuilder
<> nb(int_kind
);
3569 nb
.append(echildren
);
3570 Node res
= nb
.constructNode();
3572 (void)res
.getType(true); /* kick off type checking */
3573 return Term(this, res
);
3576 std::vector
<Sort
> Solver::mkDatatypeSortsInternal(
3577 const std::vector
<DatatypeDecl
>& dtypedecls
,
3578 const std::set
<Sort
>& unresolvedSorts
) const
3580 std::vector
<CVC4::DType
> datatypes
;
3581 for (size_t i
= 0, ndts
= dtypedecls
.size(); i
< ndts
; ++i
)
3583 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(this == dtypedecls
[i
].d_solver
,
3584 "datatype declaration",
3587 << "a datatype declaration associated to this solver object";
3588 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(dtypedecls
[i
].getNumConstructors() > 0,
3589 "datatype declaration",
3592 << "a datatype declaration with at least one constructor";
3593 datatypes
.push_back(dtypedecls
[i
].getDatatype());
3596 for (auto& sort
: unresolvedSorts
)
3598 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3599 !sort
.isNull(), "unresolved sort", sort
, i
)
3601 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3602 this == sort
.d_solver
, "unresolved sort", sort
, i
)
3603 << "an unresolved sort associated to this solver object";
3607 std::set
<TypeNode
> utypes
= Sort::sortSetToTypeNodes(unresolvedSorts
);
3608 std::vector
<CVC4::TypeNode
> dtypes
=
3609 getNodeManager()->mkMutualDatatypeTypes(datatypes
, utypes
);
3610 std::vector
<Sort
> retTypes
= Sort::typeNodeVectorToSorts(this, dtypes
);
3614 Term
Solver::synthFunHelper(const std::string
& symbol
,
3615 const std::vector
<Term
>& boundVars
,
3620 CVC4_API_ARG_CHECK_NOT_NULL(sort
);
3622 std::vector
<TypeNode
> varTypes
;
3623 for (size_t i
= 0, n
= boundVars
.size(); i
< n
; ++i
)
3625 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3626 this == boundVars
[i
].d_solver
, "bound variable", boundVars
[i
], i
)
3627 << "bound variable associated to this solver object";
3628 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3629 !boundVars
[i
].isNull(), "bound variable", boundVars
[i
], i
)
3630 << "a non-null term";
3631 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3632 boundVars
[i
].d_node
->getKind() == CVC4::Kind::BOUND_VARIABLE
,
3636 << "a bound variable";
3637 varTypes
.push_back(boundVars
[i
].d_node
->getType());
3639 CVC4_API_SOLVER_CHECK_SORT(sort
);
3643 CVC4_API_CHECK(g
->d_ntSyms
[0].d_node
->getType() == *sort
.d_type
)
3644 << "Invalid Start symbol for Grammar g, Expected Start's sort to be "
3645 << *sort
.d_type
<< " but found " << g
->d_ntSyms
[0].d_node
->getType();
3648 TypeNode funType
= varTypes
.empty() ? *sort
.d_type
3649 : getNodeManager()->mkFunctionType(
3650 varTypes
, *sort
.d_type
);
3652 Node fun
= getNodeManager()->mkBoundVar(symbol
, funType
);
3653 (void)fun
.getType(true); /* kick off type checking */
3655 std::vector
<Node
> bvns
= Term::termVectorToNodes(boundVars
);
3657 d_smtEngine
->declareSynthFun(
3658 fun
, g
== nullptr ? funType
: *g
->resolve().d_type
, isInv
, bvns
);
3660 return Term(this, fun
);
3663 Term
Solver::ensureTermSort(const Term
& term
, const Sort
& sort
) const
3665 // Note: Term and sort are checked in the caller to avoid double checks
3666 CVC4_API_CHECK(term
.getSort() == sort
3667 || (term
.getSort().isInteger() && sort
.isReal()))
3668 << "Expected conversion from Int to Real";
3670 Sort t
= term
.getSort();
3671 if (term
.getSort() == sort
)
3676 // Integers are reals, too
3681 // Must cast to Real to ensure correct type is passed to parametric type
3682 // constructors. We do this cast using division with 1. This has the
3683 // advantage wrt using TO_REAL since (constant) division is always included
3686 d_nodeMgr
->mkNode(extToIntKind(DIVISION
),
3688 d_nodeMgr
->mkConst(CVC4::Rational(1))));
3690 Assert(res
.getSort() == sort
);
3694 Term
Solver::ensureRealSort(const Term
& t
) const
3696 Assert(this == t
.d_solver
);
3697 CVC4_API_ARG_CHECK_EXPECTED(
3698 t
.getSort() == getIntegerSort() || t
.getSort() == getRealSort(),
3699 " an integer or real term");
3700 if (t
.getSort() == getIntegerSort())
3702 Node n
= getNodeManager()->mkNode(kind::CAST_TO_REAL
, *t
.d_node
);
3703 return Term(this, n
);
3708 bool Solver::isValidInteger(const std::string
& s
) const
3710 if (s
.length() == 0)
3712 // string should not be empty
3717 if (s
[index
] == '-')
3719 if (s
.length() == 1)
3721 // negative integers should contain at least one digit
3727 if (s
[index
] == '0' && s
.length() > (index
+ 1))
3729 // From SMT-Lib 2.6: A <numeral> is the digit 0 or a non-empty sequence of
3730 // digits not starting with 0. So integers like 001, 000 are not allowed
3734 // all remaining characters should be decimal digits
3735 for (; index
< s
.length(); ++index
)
3737 if (!std::isdigit(s
[index
]))
3746 /* Helpers for mkTerm checks. */
3747 /* .......................................................................... */
3749 void Solver::checkMkTerm(Kind kind
, uint32_t nchildren
) const
3751 CVC4_API_KIND_CHECK(kind
);
3752 Assert(isDefinedIntKind(extToIntKind(kind
)));
3753 const CVC4::kind::MetaKind mk
= kind::metaKindOf(extToIntKind(kind
));
3754 CVC4_API_KIND_CHECK_EXPECTED(
3755 mk
== kind::metakind::PARAMETERIZED
|| mk
== kind::metakind::OPERATOR
,
3757 << "Only operator-style terms are created with mkTerm(), "
3758 "to create variables, constants and values see mkVar(), mkConst() "
3759 "and the respective theory-specific functions to create values, "
3760 "e.g., mkBitVector().";
3761 CVC4_API_KIND_CHECK_EXPECTED(
3762 nchildren
>= minArity(kind
) && nchildren
<= maxArity(kind
), kind
)
3763 << "Terms with kind " << kindToString(kind
) << " must have at least "
3764 << minArity(kind
) << " children and at most " << maxArity(kind
)
3765 << " children (the one under construction has " << nchildren
<< ")";
3768 /* Solver Configuration */
3769 /* -------------------------------------------------------------------------- */
3771 bool Solver::supportsFloatingPoint() const
3773 return Configuration::isBuiltWithSymFPU();
3776 /* Sorts Handling */
3777 /* -------------------------------------------------------------------------- */
3779 Sort
Solver::getNullSort(void) const
3781 CVC4_API_TRY_CATCH_BEGIN
;
3782 return Sort(this, TypeNode());
3784 CVC4_API_TRY_CATCH_END
;
3787 Sort
Solver::getBooleanSort(void) const
3789 NodeManagerScope
scope(getNodeManager());
3790 CVC4_API_TRY_CATCH_BEGIN
;
3791 return Sort(this, getNodeManager()->booleanType());
3793 CVC4_API_TRY_CATCH_END
;
3796 Sort
Solver::getIntegerSort(void) const
3798 NodeManagerScope
scope(getNodeManager());
3799 CVC4_API_TRY_CATCH_BEGIN
;
3800 return Sort(this, getNodeManager()->integerType());
3802 CVC4_API_TRY_CATCH_END
;
3805 Sort
Solver::getRealSort(void) const
3807 NodeManagerScope
scope(getNodeManager());
3808 CVC4_API_TRY_CATCH_BEGIN
;
3809 return Sort(this, getNodeManager()->realType());
3811 CVC4_API_TRY_CATCH_END
;
3814 Sort
Solver::getRegExpSort(void) const
3816 NodeManagerScope
scope(getNodeManager());
3817 CVC4_API_TRY_CATCH_BEGIN
;
3818 return Sort(this, getNodeManager()->regExpType());
3820 CVC4_API_TRY_CATCH_END
;
3823 Sort
Solver::getStringSort(void) const
3825 NodeManagerScope
scope(getNodeManager());
3826 CVC4_API_TRY_CATCH_BEGIN
;
3827 return Sort(this, getNodeManager()->stringType());
3829 CVC4_API_TRY_CATCH_END
;
3832 Sort
Solver::getRoundingModeSort(void) const
3834 NodeManagerScope
scope(getNodeManager());
3835 CVC4_API_TRY_CATCH_BEGIN
;
3836 CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
3837 << "Expected CVC4 to be compiled with SymFPU support";
3838 return Sort(this, getNodeManager()->roundingModeType());
3840 CVC4_API_TRY_CATCH_END
;
3843 /* Create sorts ------------------------------------------------------- */
3845 Sort
Solver::mkArraySort(const Sort
& indexSort
, const Sort
& elemSort
) const
3847 NodeManagerScope
scope(getNodeManager());
3848 CVC4_API_TRY_CATCH_BEGIN
;
3849 CVC4_API_ARG_CHECK_EXPECTED(!indexSort
.isNull(), indexSort
)
3850 << "non-null index sort";
3851 CVC4_API_ARG_CHECK_EXPECTED(!elemSort
.isNull(), elemSort
)
3852 << "non-null element sort";
3853 CVC4_API_SOLVER_CHECK_SORT(indexSort
);
3854 CVC4_API_SOLVER_CHECK_SORT(elemSort
);
3857 this, getNodeManager()->mkArrayType(*indexSort
.d_type
, *elemSort
.d_type
));
3859 CVC4_API_TRY_CATCH_END
;
3862 Sort
Solver::mkBitVectorSort(uint32_t size
) const
3864 NodeManagerScope
scope(getNodeManager());
3865 CVC4_API_TRY_CATCH_BEGIN
;
3866 CVC4_API_ARG_CHECK_EXPECTED(size
> 0, size
) << "size > 0";
3868 return Sort(this, getNodeManager()->mkBitVectorType(size
));
3870 CVC4_API_TRY_CATCH_END
;
3873 Sort
Solver::mkFloatingPointSort(uint32_t exp
, uint32_t sig
) const
3875 NodeManagerScope
scope(getNodeManager());
3876 CVC4_API_TRY_CATCH_BEGIN
;
3877 CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
3878 << "Expected CVC4 to be compiled with SymFPU support";
3879 CVC4_API_ARG_CHECK_EXPECTED(exp
> 0, exp
) << "exponent size > 0";
3880 CVC4_API_ARG_CHECK_EXPECTED(sig
> 0, sig
) << "significand size > 0";
3882 return Sort(this, getNodeManager()->mkFloatingPointType(exp
, sig
));
3884 CVC4_API_TRY_CATCH_END
;
3887 Sort
Solver::mkDatatypeSort(const DatatypeDecl
& dtypedecl
) const
3889 NodeManagerScope
scope(getNodeManager());
3890 CVC4_API_TRY_CATCH_BEGIN
;
3891 CVC4_API_CHECK(this == dtypedecl
.d_solver
)
3892 << "Given datatype declaration is not associated with this solver";
3893 CVC4_API_ARG_CHECK_EXPECTED(dtypedecl
.getNumConstructors() > 0, dtypedecl
)
3894 << "a datatype declaration with at least one constructor";
3896 return Sort(this, getNodeManager()->mkDatatypeType(*dtypedecl
.d_dtype
));
3898 CVC4_API_TRY_CATCH_END
;
3901 std::vector
<Sort
> Solver::mkDatatypeSorts(
3902 const std::vector
<DatatypeDecl
>& dtypedecls
) const
3904 NodeManagerScope
scope(getNodeManager());
3905 CVC4_API_TRY_CATCH_BEGIN
;
3906 std::set
<Sort
> unresolvedSorts
;
3907 return mkDatatypeSortsInternal(dtypedecls
, unresolvedSorts
);
3909 CVC4_API_TRY_CATCH_END
;
3912 std::vector
<Sort
> Solver::mkDatatypeSorts(
3913 const std::vector
<DatatypeDecl
>& dtypedecls
,
3914 const std::set
<Sort
>& unresolvedSorts
) const
3916 NodeManagerScope
scope(getNodeManager());
3917 CVC4_API_TRY_CATCH_BEGIN
;
3918 return mkDatatypeSortsInternal(dtypedecls
, unresolvedSorts
);
3920 CVC4_API_TRY_CATCH_END
;
3923 Sort
Solver::mkFunctionSort(const Sort
& domain
, const Sort
& codomain
) const
3925 NodeManagerScope
scope(getNodeManager());
3926 CVC4_API_TRY_CATCH_BEGIN
;
3927 CVC4_API_ARG_CHECK_EXPECTED(!codomain
.isNull(), codomain
)
3928 << "non-null codomain sort";
3929 CVC4_API_SOLVER_CHECK_SORT(domain
);
3930 CVC4_API_SOLVER_CHECK_SORT(codomain
);
3931 CVC4_API_ARG_CHECK_EXPECTED(domain
.isFirstClass(), domain
)
3932 << "first-class sort as domain sort for function sort";
3933 CVC4_API_ARG_CHECK_EXPECTED(codomain
.isFirstClass(), codomain
)
3934 << "first-class sort as codomain sort for function sort";
3935 Assert(!codomain
.isFunction()); /* A function sort is not first-class. */
3938 this, getNodeManager()->mkFunctionType(*domain
.d_type
, *codomain
.d_type
));
3940 CVC4_API_TRY_CATCH_END
;
3943 Sort
Solver::mkFunctionSort(const std::vector
<Sort
>& sorts
,
3944 const Sort
& codomain
) const
3946 NodeManagerScope
scope(getNodeManager());
3947 CVC4_API_TRY_CATCH_BEGIN
;
3948 CVC4_API_ARG_SIZE_CHECK_EXPECTED(sorts
.size() >= 1, sorts
)
3949 << "at least one parameter sort for function sort";
3950 for (size_t i
= 0, size
= sorts
.size(); i
< size
; ++i
)
3952 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3953 !sorts
[i
].isNull(), "parameter sort", sorts
[i
], i
)
3955 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3956 this == sorts
[i
].d_solver
, "parameter sort", sorts
[i
], i
)
3957 << "sort associated to this solver object";
3958 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3959 sorts
[i
].isFirstClass(), "parameter sort", sorts
[i
], i
)
3960 << "first-class sort as parameter sort for function sort";
3962 CVC4_API_ARG_CHECK_EXPECTED(!codomain
.isNull(), codomain
)
3963 << "non-null codomain sort";
3964 CVC4_API_SOLVER_CHECK_SORT(codomain
);
3965 CVC4_API_ARG_CHECK_EXPECTED(codomain
.isFirstClass(), codomain
)
3966 << "first-class sort as codomain sort for function sort";
3967 Assert(!codomain
.isFunction()); /* A function sort is not first-class. */
3969 std::vector
<TypeNode
> argTypes
= Sort::sortVectorToTypeNodes(sorts
);
3971 getNodeManager()->mkFunctionType(argTypes
, *codomain
.d_type
));
3973 CVC4_API_TRY_CATCH_END
;
3976 Sort
Solver::mkParamSort(const std::string
& symbol
) const
3978 NodeManagerScope
scope(getNodeManager());
3979 CVC4_API_TRY_CATCH_BEGIN
;
3982 getNodeManager()->mkSort(symbol
, NodeManager::SORT_FLAG_PLACEHOLDER
));
3984 CVC4_API_TRY_CATCH_END
;
3987 Sort
Solver::mkPredicateSort(const std::vector
<Sort
>& sorts
) const
3989 NodeManagerScope
scope(getNodeManager());
3990 CVC4_API_TRY_CATCH_BEGIN
;
3991 CVC4_API_ARG_SIZE_CHECK_EXPECTED(sorts
.size() >= 1, sorts
)
3992 << "at least one parameter sort for predicate sort";
3993 for (size_t i
= 0, size
= sorts
.size(); i
< size
; ++i
)
3995 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3996 !sorts
[i
].isNull(), "parameter sort", sorts
[i
], i
)
3998 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
3999 this == sorts
[i
].d_solver
, "parameter sort", sorts
[i
], i
)
4000 << "sort associated to this solver object";
4001 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4002 sorts
[i
].isFirstClass(), "parameter sort", sorts
[i
], i
)
4003 << "first-class sort as parameter sort for predicate sort";
4005 std::vector
<TypeNode
> types
= Sort::sortVectorToTypeNodes(sorts
);
4007 return Sort(this, getNodeManager()->mkPredicateType(types
));
4009 CVC4_API_TRY_CATCH_END
;
4012 Sort
Solver::mkRecordSort(
4013 const std::vector
<std::pair
<std::string
, Sort
>>& fields
) const
4015 NodeManagerScope
scope(getNodeManager());
4016 CVC4_API_TRY_CATCH_BEGIN
;
4017 std::vector
<std::pair
<std::string
, TypeNode
>> f
;
4019 for (const auto& p
: fields
)
4021 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4022 !p
.second
.isNull(), "parameter sort", p
.second
, i
)
4024 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4025 this == p
.second
.d_solver
, "parameter sort", p
.second
, i
)
4026 << "sort associated to this solver object";
4028 f
.emplace_back(p
.first
, *p
.second
.d_type
);
4031 return Sort(this, getNodeManager()->mkRecordType(f
));
4033 CVC4_API_TRY_CATCH_END
;
4036 Sort
Solver::mkSetSort(const Sort
& elemSort
) const
4038 NodeManagerScope
scope(getNodeManager());
4039 CVC4_API_TRY_CATCH_BEGIN
;
4040 CVC4_API_ARG_CHECK_EXPECTED(!elemSort
.isNull(), elemSort
)
4041 << "non-null element sort";
4042 CVC4_API_SOLVER_CHECK_SORT(elemSort
);
4044 return Sort(this, getNodeManager()->mkSetType(*elemSort
.d_type
));
4046 CVC4_API_TRY_CATCH_END
;
4049 Sort
Solver::mkBagSort(const Sort
& elemSort
) const
4051 NodeManagerScope
scope(getNodeManager());
4052 CVC4_API_TRY_CATCH_BEGIN
;
4053 CVC4_API_ARG_CHECK_EXPECTED(!elemSort
.isNull(), elemSort
)
4054 << "non-null element sort";
4055 CVC4_API_SOLVER_CHECK_SORT(elemSort
);
4057 return Sort(this, getNodeManager()->mkBagType(*elemSort
.d_type
));
4059 CVC4_API_TRY_CATCH_END
;
4062 Sort
Solver::mkSequenceSort(const Sort
& elemSort
) const
4064 NodeManagerScope
scope(getNodeManager());
4065 CVC4_API_TRY_CATCH_BEGIN
;
4066 CVC4_API_ARG_CHECK_EXPECTED(!elemSort
.isNull(), elemSort
)
4067 << "non-null element sort";
4068 CVC4_API_SOLVER_CHECK_SORT(elemSort
);
4070 return Sort(this, getNodeManager()->mkSequenceType(*elemSort
.d_type
));
4072 CVC4_API_TRY_CATCH_END
;
4075 Sort
Solver::mkUninterpretedSort(const std::string
& symbol
) const
4077 NodeManagerScope
scope(getNodeManager());
4078 CVC4_API_TRY_CATCH_BEGIN
;
4079 return Sort(this, getNodeManager()->mkSort(symbol
));
4081 CVC4_API_TRY_CATCH_END
;
4084 Sort
Solver::mkSortConstructorSort(const std::string
& symbol
,
4087 NodeManagerScope
scope(getNodeManager());
4088 CVC4_API_TRY_CATCH_BEGIN
;
4089 CVC4_API_ARG_CHECK_EXPECTED(arity
> 0, arity
) << "an arity > 0";
4091 return Sort(this, getNodeManager()->mkSortConstructor(symbol
, arity
));
4093 CVC4_API_TRY_CATCH_END
;
4096 Sort
Solver::mkTupleSort(const std::vector
<Sort
>& sorts
) const
4098 NodeManagerScope
scope(getNodeManager());
4099 CVC4_API_TRY_CATCH_BEGIN
;
4100 for (size_t i
= 0, size
= sorts
.size(); i
< size
; ++i
)
4102 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4103 !sorts
[i
].isNull(), "parameter sort", sorts
[i
], i
)
4105 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4106 this == sorts
[i
].d_solver
, "parameter sort", sorts
[i
], i
)
4107 << "sort associated to this solver object";
4108 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4109 !sorts
[i
].isFunctionLike(), "parameter sort", sorts
[i
], i
)
4110 << "non-function-like sort as parameter sort for tuple sort";
4112 return mkTupleSortHelper(sorts
);
4114 CVC4_API_TRY_CATCH_END
;
4118 /* -------------------------------------------------------------------------- */
4120 Term
Solver::mkTrue(void) const
4122 CVC4_API_TRY_CATCH_BEGIN
;
4123 return Term(this, d_nodeMgr
->mkConst
<bool>(true));
4125 CVC4_API_TRY_CATCH_END
;
4128 Term
Solver::mkFalse(void) const
4130 CVC4_API_TRY_CATCH_BEGIN
;
4131 return Term(this, d_nodeMgr
->mkConst
<bool>(false));
4133 CVC4_API_TRY_CATCH_END
;
4136 Term
Solver::mkBoolean(bool val
) const
4138 CVC4_API_TRY_CATCH_BEGIN
;
4139 return Term(this, d_nodeMgr
->mkConst
<bool>(val
));
4141 CVC4_API_TRY_CATCH_END
;
4144 Term
Solver::mkPi() const
4146 CVC4_API_TRY_CATCH_BEGIN
;
4149 d_nodeMgr
->mkNullaryOperator(d_nodeMgr
->realType(), CVC4::kind::PI
);
4150 (void)res
.getType(true); /* kick off type checking */
4151 return Term(this, res
);
4153 CVC4_API_TRY_CATCH_END
;
4156 Term
Solver::mkInteger(const std::string
& s
) const
4158 CVC4_API_TRY_CATCH_BEGIN
;
4159 CVC4_API_ARG_CHECK_EXPECTED(isValidInteger(s
), s
) << " an integer ";
4160 Term integer
= mkRealFromStrHelper(s
);
4161 CVC4_API_ARG_CHECK_EXPECTED(integer
.getSort() == getIntegerSort(), s
)
4165 CVC4_API_TRY_CATCH_END
;
4168 Term
Solver::mkInteger(int64_t val
) const
4170 CVC4_API_TRY_CATCH_BEGIN
;
4171 Term integer
= mkValHelper
<CVC4::Rational
>(CVC4::Rational(val
));
4172 Assert(integer
.getSort() == getIntegerSort());
4175 CVC4_API_TRY_CATCH_END
;
4178 Term
Solver::mkReal(const std::string
& s
) const
4180 CVC4_API_TRY_CATCH_BEGIN
;
4181 /* CLN and GMP handle this case differently, CLN interprets it as 0, GMP
4182 * throws an std::invalid_argument exception. For consistency, we treat it
4184 CVC4_API_ARG_CHECK_EXPECTED(s
!= ".", s
)
4185 << "a string representing a real or rational value.";
4186 Term rational
= mkRealFromStrHelper(s
);
4187 return ensureRealSort(rational
);
4189 CVC4_API_TRY_CATCH_END
;
4192 Term
Solver::mkReal(int64_t val
) const
4194 CVC4_API_TRY_CATCH_BEGIN
;
4195 Term rational
= mkValHelper
<CVC4::Rational
>(CVC4::Rational(val
));
4196 return ensureRealSort(rational
);
4198 CVC4_API_TRY_CATCH_END
;
4201 Term
Solver::mkReal(int64_t num
, int64_t den
) const
4203 CVC4_API_TRY_CATCH_BEGIN
;
4204 Term rational
= mkValHelper
<CVC4::Rational
>(CVC4::Rational(num
, den
));
4205 return ensureRealSort(rational
);
4207 CVC4_API_TRY_CATCH_END
;
4210 Term
Solver::mkRegexpEmpty() const
4212 CVC4_API_TRY_CATCH_BEGIN
;
4215 d_nodeMgr
->mkNode(CVC4::kind::REGEXP_EMPTY
, std::vector
<CVC4::Node
>());
4216 (void)res
.getType(true); /* kick off type checking */
4217 return Term(this, res
);
4219 CVC4_API_TRY_CATCH_END
;
4222 Term
Solver::mkRegexpSigma() const
4224 CVC4_API_TRY_CATCH_BEGIN
;
4227 d_nodeMgr
->mkNode(CVC4::kind::REGEXP_SIGMA
, std::vector
<CVC4::Node
>());
4228 (void)res
.getType(true); /* kick off type checking */
4229 return Term(this, res
);
4231 CVC4_API_TRY_CATCH_END
;
4234 Term
Solver::mkEmptySet(const Sort
& s
) const
4236 CVC4_API_TRY_CATCH_BEGIN
;
4237 CVC4_API_ARG_CHECK_EXPECTED(s
.isNull() || s
.isSet(), s
)
4238 << "null sort or set sort";
4239 CVC4_API_ARG_CHECK_EXPECTED(s
.isNull() || this == s
.d_solver
, s
)
4240 << "set sort associated to this solver object";
4242 return mkValHelper
<CVC4::EmptySet
>(CVC4::EmptySet(*s
.d_type
));
4244 CVC4_API_TRY_CATCH_END
;
4247 Term
Solver::mkEmptyBag(const Sort
& s
) const
4249 CVC4_API_TRY_CATCH_BEGIN
;
4250 CVC4_API_ARG_CHECK_EXPECTED(s
.isNull() || s
.isBag(), s
)
4251 << "null sort or bag sort";
4253 CVC4_API_ARG_CHECK_EXPECTED(s
.isNull() || this == s
.d_solver
, s
)
4254 << "bag sort associated to this solver object";
4256 return mkValHelper
<CVC4::EmptyBag
>(CVC4::EmptyBag(*s
.d_type
));
4258 CVC4_API_TRY_CATCH_END
;
4261 Term
Solver::mkSepNil(const Sort
& sort
) const
4263 CVC4_API_TRY_CATCH_BEGIN
;
4264 CVC4_API_ARG_CHECK_EXPECTED(!sort
.isNull(), sort
) << "non-null sort";
4265 CVC4_API_SOLVER_CHECK_SORT(sort
);
4268 getNodeManager()->mkNullaryOperator(*sort
.d_type
, CVC4::kind::SEP_NIL
);
4269 (void)res
.getType(true); /* kick off type checking */
4270 return Term(this, res
);
4272 CVC4_API_TRY_CATCH_END
;
4275 Term
Solver::mkString(const std::string
& s
, bool useEscSequences
) const
4277 CVC4_API_TRY_CATCH_BEGIN
;
4278 return mkValHelper
<CVC4::String
>(CVC4::String(s
, useEscSequences
));
4280 CVC4_API_TRY_CATCH_END
;
4283 Term
Solver::mkString(const unsigned char c
) const
4285 CVC4_API_TRY_CATCH_BEGIN
;
4286 return mkValHelper
<CVC4::String
>(CVC4::String(std::string(1, c
)));
4288 CVC4_API_TRY_CATCH_END
;
4291 Term
Solver::mkString(const std::vector
<uint32_t>& s
) const
4293 CVC4_API_TRY_CATCH_BEGIN
;
4294 return mkValHelper
<CVC4::String
>(CVC4::String(s
));
4296 CVC4_API_TRY_CATCH_END
;
4299 Term
Solver::mkChar(const std::string
& s
) const
4301 CVC4_API_TRY_CATCH_BEGIN
;
4302 return mkCharFromStrHelper(s
);
4304 CVC4_API_TRY_CATCH_END
;
4307 Term
Solver::mkEmptySequence(const Sort
& sort
) const
4309 CVC4_API_TRY_CATCH_BEGIN
;
4310 CVC4_API_ARG_CHECK_EXPECTED(!sort
.isNull(), sort
) << "non-null sort";
4311 CVC4_API_SOLVER_CHECK_SORT(sort
);
4313 std::vector
<Node
> seq
;
4314 Node res
= d_nodeMgr
->mkConst(Sequence(*sort
.d_type
, seq
));
4315 return Term(this, res
);
4317 CVC4_API_TRY_CATCH_END
;
4320 Term
Solver::mkUniverseSet(const Sort
& sort
) const
4322 CVC4_API_TRY_CATCH_BEGIN
;
4323 CVC4_API_ARG_CHECK_EXPECTED(!sort
.isNull(), sort
) << "non-null sort";
4324 CVC4_API_SOLVER_CHECK_SORT(sort
);
4326 Node res
= getNodeManager()->mkNullaryOperator(*sort
.d_type
,
4327 CVC4::kind::UNIVERSE_SET
);
4328 // TODO(#2771): Reenable?
4329 // (void)res->getType(true); /* kick off type checking */
4330 return Term(this, res
);
4332 CVC4_API_TRY_CATCH_END
;
4335 Term
Solver::mkBitVector(uint32_t size
, uint64_t val
) const
4337 CVC4_API_TRY_CATCH_BEGIN
;
4338 return mkBVFromIntHelper(size
, val
);
4340 CVC4_API_TRY_CATCH_END
;
4343 Term
Solver::mkBitVector(const std::string
& s
, uint32_t base
) const
4345 CVC4_API_TRY_CATCH_BEGIN
;
4346 return mkBVFromStrHelper(s
, base
);
4348 CVC4_API_TRY_CATCH_END
;
4351 Term
Solver::mkBitVector(uint32_t size
,
4352 const std::string
& s
,
4353 uint32_t base
) const
4355 CVC4_API_TRY_CATCH_BEGIN
;
4356 return mkBVFromStrHelper(size
, s
, base
);
4358 CVC4_API_TRY_CATCH_END
;
4361 Term
Solver::mkConstArray(const Sort
& sort
, const Term
& val
) const
4363 CVC4_API_TRY_CATCH_BEGIN
;
4364 NodeManagerScope
scope(getNodeManager());
4365 CVC4_API_ARG_CHECK_NOT_NULL(sort
);
4366 CVC4_API_ARG_CHECK_NOT_NULL(val
);
4367 CVC4_API_SOLVER_CHECK_SORT(sort
);
4368 CVC4_API_SOLVER_CHECK_TERM(val
);
4369 CVC4_API_CHECK(sort
.isArray()) << "Not an array sort.";
4370 CVC4_API_CHECK(val
.getSort().isSubsortOf(sort
.getArrayElementSort()))
4371 << "Value does not match element sort.";
4372 // handle the special case of (CAST_TO_REAL n) where n is an integer
4373 Node n
= *val
.d_node
;
4374 if (val
.isCastedReal())
4376 // this is safe because the constant array stores its type
4379 Term res
= mkValHelper
<CVC4::ArrayStoreAll
>(
4380 CVC4::ArrayStoreAll(*sort
.d_type
, n
));
4383 CVC4_API_TRY_CATCH_END
;
4386 Term
Solver::mkPosInf(uint32_t exp
, uint32_t sig
) const
4388 CVC4_API_TRY_CATCH_BEGIN
;
4389 CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
4390 << "Expected CVC4 to be compiled with SymFPU support";
4392 return mkValHelper
<CVC4::FloatingPoint
>(
4393 FloatingPoint::makeInf(FloatingPointSize(exp
, sig
), false));
4395 CVC4_API_TRY_CATCH_END
;
4398 Term
Solver::mkNegInf(uint32_t exp
, uint32_t sig
) const
4400 CVC4_API_TRY_CATCH_BEGIN
;
4401 CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
4402 << "Expected CVC4 to be compiled with SymFPU support";
4404 return mkValHelper
<CVC4::FloatingPoint
>(
4405 FloatingPoint::makeInf(FloatingPointSize(exp
, sig
), true));
4407 CVC4_API_TRY_CATCH_END
;
4410 Term
Solver::mkNaN(uint32_t exp
, uint32_t sig
) const
4412 CVC4_API_TRY_CATCH_BEGIN
;
4413 CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
4414 << "Expected CVC4 to be compiled with SymFPU support";
4416 return mkValHelper
<CVC4::FloatingPoint
>(
4417 FloatingPoint::makeNaN(FloatingPointSize(exp
, sig
)));
4419 CVC4_API_TRY_CATCH_END
;
4422 Term
Solver::mkPosZero(uint32_t exp
, uint32_t sig
) const
4424 CVC4_API_TRY_CATCH_BEGIN
;
4425 CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
4426 << "Expected CVC4 to be compiled with SymFPU support";
4428 return mkValHelper
<CVC4::FloatingPoint
>(
4429 FloatingPoint::makeZero(FloatingPointSize(exp
, sig
), false));
4431 CVC4_API_TRY_CATCH_END
;
4434 Term
Solver::mkNegZero(uint32_t exp
, uint32_t sig
) const
4436 CVC4_API_TRY_CATCH_BEGIN
;
4437 CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
4438 << "Expected CVC4 to be compiled with SymFPU support";
4440 return mkValHelper
<CVC4::FloatingPoint
>(
4441 FloatingPoint::makeZero(FloatingPointSize(exp
, sig
), true));
4443 CVC4_API_TRY_CATCH_END
;
4446 Term
Solver::mkRoundingMode(RoundingMode rm
) const
4448 CVC4_API_TRY_CATCH_BEGIN
;
4449 CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
4450 << "Expected CVC4 to be compiled with SymFPU support";
4451 return mkValHelper
<CVC4::RoundingMode
>(s_rmodes
.at(rm
));
4453 CVC4_API_TRY_CATCH_END
;
4456 Term
Solver::mkUninterpretedConst(const Sort
& sort
, int32_t index
) const
4458 CVC4_API_TRY_CATCH_BEGIN
;
4459 CVC4_API_ARG_CHECK_EXPECTED(!sort
.isNull(), sort
) << "non-null sort";
4460 CVC4_API_SOLVER_CHECK_SORT(sort
);
4462 return mkValHelper
<CVC4::UninterpretedConstant
>(
4463 CVC4::UninterpretedConstant(*sort
.d_type
, index
));
4465 CVC4_API_TRY_CATCH_END
;
4468 Term
Solver::mkAbstractValue(const std::string
& index
) const
4470 CVC4_API_TRY_CATCH_BEGIN
;
4471 CVC4_API_ARG_CHECK_EXPECTED(!index
.empty(), index
) << "a non-empty string";
4473 CVC4::Integer
idx(index
, 10);
4474 CVC4_API_ARG_CHECK_EXPECTED(idx
> 0, index
)
4475 << "a string representing an integer > 0";
4476 return Term(this, getNodeManager()->mkConst(CVC4::AbstractValue(idx
)));
4477 // do not call getType(), for abstract values, type can not be computed
4478 // until it is substituted away
4480 CVC4_API_TRY_CATCH_END
;
4483 Term
Solver::mkAbstractValue(uint64_t index
) const
4485 CVC4_API_TRY_CATCH_BEGIN
;
4486 CVC4_API_ARG_CHECK_EXPECTED(index
> 0, index
) << "an integer > 0";
4489 getNodeManager()->mkConst(CVC4::AbstractValue(Integer(index
))));
4490 // do not call getType(), for abstract values, type can not be computed
4491 // until it is substituted away
4493 CVC4_API_TRY_CATCH_END
;
4496 Term
Solver::mkFloatingPoint(uint32_t exp
, uint32_t sig
, Term val
) const
4498 CVC4_API_TRY_CATCH_BEGIN
;
4499 CVC4_API_CHECK(Configuration::isBuiltWithSymFPU())
4500 << "Expected CVC4 to be compiled with SymFPU support";
4501 CVC4_API_ARG_CHECK_EXPECTED(exp
> 0, exp
) << "a value > 0";
4502 CVC4_API_ARG_CHECK_EXPECTED(sig
> 0, sig
) << "a value > 0";
4503 uint32_t bw
= exp
+ sig
;
4504 CVC4_API_ARG_CHECK_EXPECTED(bw
== val
.getSort().getBVSize(), val
)
4505 << "a bit-vector constant with bit-width '" << bw
<< "'";
4506 CVC4_API_ARG_CHECK_EXPECTED(!val
.isNull(), val
) << "non-null term";
4507 CVC4_API_SOLVER_CHECK_TERM(val
);
4508 CVC4_API_ARG_CHECK_EXPECTED(
4509 val
.getSort().isBitVector() && val
.d_node
->isConst(), val
)
4510 << "bit-vector constant";
4512 return mkValHelper
<CVC4::FloatingPoint
>(
4513 CVC4::FloatingPoint(exp
, sig
, val
.d_node
->getConst
<BitVector
>()));
4515 CVC4_API_TRY_CATCH_END
;
4518 /* Create constants */
4519 /* -------------------------------------------------------------------------- */
4521 Term
Solver::mkConst(const Sort
& sort
, const std::string
& symbol
) const
4523 NodeManagerScope
scope(getNodeManager());
4524 CVC4_API_TRY_CATCH_BEGIN
;
4525 CVC4_API_ARG_CHECK_EXPECTED(!sort
.isNull(), sort
) << "non-null sort";
4526 CVC4_API_SOLVER_CHECK_SORT(sort
);
4528 Node res
= d_nodeMgr
->mkVar(symbol
, *sort
.d_type
);
4529 (void)res
.getType(true); /* kick off type checking */
4530 increment_vars_consts_stats(sort
, false);
4531 return Term(this, res
);
4533 CVC4_API_TRY_CATCH_END
;
4536 Term
Solver::mkConst(const Sort
& sort
) const
4538 NodeManagerScope
scope(getNodeManager());
4539 CVC4_API_TRY_CATCH_BEGIN
;
4540 CVC4_API_ARG_CHECK_EXPECTED(!sort
.isNull(), sort
) << "non-null sort";
4541 CVC4_API_SOLVER_CHECK_SORT(sort
);
4543 Node res
= d_nodeMgr
->mkVar(*sort
.d_type
);
4544 (void)res
.getType(true); /* kick off type checking */
4545 increment_vars_consts_stats(sort
, false);
4546 return Term(this, res
);
4548 CVC4_API_TRY_CATCH_END
;
4551 /* Create variables */
4552 /* -------------------------------------------------------------------------- */
4554 Term
Solver::mkVar(const Sort
& sort
, const std::string
& symbol
) const
4556 NodeManagerScope
scope(getNodeManager());
4557 CVC4_API_TRY_CATCH_BEGIN
;
4558 CVC4_API_ARG_CHECK_EXPECTED(!sort
.isNull(), sort
) << "non-null sort";
4559 CVC4_API_SOLVER_CHECK_SORT(sort
);
4561 Node res
= symbol
.empty() ? d_nodeMgr
->mkBoundVar(*sort
.d_type
)
4562 : d_nodeMgr
->mkBoundVar(symbol
, *sort
.d_type
);
4563 (void)res
.getType(true); /* kick off type checking */
4564 increment_vars_consts_stats(sort
, true);
4565 return Term(this, res
);
4567 CVC4_API_TRY_CATCH_END
;
4570 /* Create datatype constructor declarations */
4571 /* -------------------------------------------------------------------------- */
4573 DatatypeConstructorDecl
Solver::mkDatatypeConstructorDecl(
4574 const std::string
& name
)
4576 NodeManagerScope
scope(getNodeManager());
4577 return DatatypeConstructorDecl(this, name
);
4580 /* Create datatype declarations */
4581 /* -------------------------------------------------------------------------- */
4583 DatatypeDecl
Solver::mkDatatypeDecl(const std::string
& name
, bool isCoDatatype
)
4585 NodeManagerScope
scope(getNodeManager());
4586 CVC4_API_TRY_CATCH_BEGIN
;
4587 return DatatypeDecl(this, name
, isCoDatatype
);
4589 CVC4_API_TRY_CATCH_END
;
4592 DatatypeDecl
Solver::mkDatatypeDecl(const std::string
& name
,
4596 NodeManagerScope
scope(getNodeManager());
4597 CVC4_API_TRY_CATCH_BEGIN
;
4598 CVC4_API_ARG_CHECK_NOT_NULL(param
);
4599 CVC4_API_SOLVER_CHECK_SORT(param
);
4600 return DatatypeDecl(this, name
, param
, isCoDatatype
);
4602 CVC4_API_TRY_CATCH_END
;
4605 DatatypeDecl
Solver::mkDatatypeDecl(const std::string
& name
,
4606 const std::vector
<Sort
>& params
,
4609 NodeManagerScope
scope(getNodeManager());
4610 CVC4_API_TRY_CATCH_BEGIN
;
4611 for (size_t i
= 0, size
= params
.size(); i
< size
; ++i
)
4613 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4614 !params
[i
].isNull(), "parameter sort", params
[i
], i
)
4616 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4617 this == params
[i
].d_solver
, "parameter sort", params
[i
], i
)
4618 << "sort associated to this solver object";
4620 return DatatypeDecl(this, name
, params
, isCoDatatype
);
4622 CVC4_API_TRY_CATCH_END
;
4626 /* -------------------------------------------------------------------------- */
4628 Term
Solver::mkTerm(Kind kind
) const
4630 NodeManagerScope
scope(getNodeManager());
4631 CVC4_API_TRY_CATCH_BEGIN
;
4632 return mkTermFromKind(kind
);
4634 CVC4_API_TRY_CATCH_END
;
4637 Term
Solver::mkTerm(Kind kind
, const Term
& child
) const
4639 NodeManagerScope
scope(getNodeManager());
4640 CVC4_API_TRY_CATCH_BEGIN
;
4641 return mkTermHelper(kind
, std::vector
<Term
>{child
});
4643 CVC4_API_TRY_CATCH_END
;
4646 Term
Solver::mkTerm(Kind kind
, const Term
& child1
, const Term
& child2
) const
4648 NodeManagerScope
scope(getNodeManager());
4649 CVC4_API_TRY_CATCH_BEGIN
;
4650 return mkTermHelper(kind
, std::vector
<Term
>{child1
, child2
});
4652 CVC4_API_TRY_CATCH_END
;
4655 Term
Solver::mkTerm(Kind kind
,
4658 const Term
& child3
) const
4660 NodeManagerScope
scope(getNodeManager());
4661 CVC4_API_TRY_CATCH_BEGIN
;
4662 // need to use internal term call to check e.g. associative construction
4663 return mkTermHelper(kind
, std::vector
<Term
>{child1
, child2
, child3
});
4665 CVC4_API_TRY_CATCH_END
;
4668 Term
Solver::mkTerm(Kind kind
, const std::vector
<Term
>& children
) const
4670 NodeManagerScope
scope(getNodeManager());
4671 CVC4_API_TRY_CATCH_BEGIN
;
4672 return mkTermHelper(kind
, children
);
4674 CVC4_API_TRY_CATCH_END
;
4677 Term
Solver::mkTerm(const Op
& op
) const
4679 NodeManagerScope
scope(getNodeManager());
4680 CVC4_API_TRY_CATCH_BEGIN
;
4681 CVC4_API_SOLVER_CHECK_OP(op
);
4682 checkMkTerm(op
.d_kind
, 0);
4684 if (!op
.isIndexedHelper())
4686 return mkTermFromKind(op
.d_kind
);
4689 const CVC4::Kind int_kind
= extToIntKind(op
.d_kind
);
4690 Term res
= Term(this, getNodeManager()->mkNode(int_kind
, *op
.d_node
));
4692 (void)res
.d_node
->getType(true); /* kick off type checking */
4695 CVC4_API_TRY_CATCH_END
;
4698 Term
Solver::mkTerm(const Op
& op
, const Term
& child
) const
4700 NodeManagerScope
scope(getNodeManager());
4701 CVC4_API_TRY_CATCH_BEGIN
;
4702 return mkTermHelper(op
, std::vector
<Term
>{child
});
4704 CVC4_API_TRY_CATCH_END
;
4707 Term
Solver::mkTerm(const Op
& op
, const Term
& child1
, const Term
& child2
) const
4709 NodeManagerScope
scope(getNodeManager());
4710 CVC4_API_TRY_CATCH_BEGIN
;
4711 return mkTermHelper(op
, std::vector
<Term
>{child1
, child2
});
4713 CVC4_API_TRY_CATCH_END
;
4716 Term
Solver::mkTerm(const Op
& op
,
4719 const Term
& child3
) const
4721 NodeManagerScope
scope(getNodeManager());
4722 CVC4_API_TRY_CATCH_BEGIN
;
4723 return mkTermHelper(op
, std::vector
<Term
>{child1
, child2
, child3
});
4725 CVC4_API_TRY_CATCH_END
;
4728 Term
Solver::mkTerm(const Op
& op
, const std::vector
<Term
>& children
) const
4730 NodeManagerScope
scope(getNodeManager());
4731 CVC4_API_TRY_CATCH_BEGIN
;
4732 return mkTermHelper(op
, children
);
4734 CVC4_API_TRY_CATCH_END
;
4737 Term
Solver::mkTuple(const std::vector
<Sort
>& sorts
,
4738 const std::vector
<Term
>& terms
) const
4740 NodeManagerScope
scope(getNodeManager());
4741 CVC4_API_TRY_CATCH_BEGIN
;
4742 CVC4_API_CHECK(sorts
.size() == terms
.size())
4743 << "Expected the same number of sorts and elements";
4744 std::vector
<CVC4::Node
> args
;
4745 for (size_t i
= 0, size
= sorts
.size(); i
< size
; i
++)
4747 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4748 !sorts
[i
].isNull(), "sort", sorts
[i
], i
)
4750 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4751 !terms
[i
].isNull(), "term", terms
[i
], i
)
4753 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4754 this == terms
[i
].d_solver
, "child term", terms
[i
], i
)
4755 << "child term associated to this solver object";
4756 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
4757 this == sorts
[i
].d_solver
, "child sort", sorts
[i
], i
)
4758 << "child sort associated to this solver object";
4759 args
.push_back(*(ensureTermSort(terms
[i
], sorts
[i
])).d_node
);
4762 Sort s
= mkTupleSortHelper(sorts
);
4763 Datatype dt
= s
.getDatatype();
4764 NodeBuilder
<> nb(extToIntKind(APPLY_CONSTRUCTOR
));
4765 nb
<< *dt
[0].getConstructorTerm().d_node
;
4767 Node res
= nb
.constructNode();
4768 (void)res
.getType(true); /* kick off type checking */
4769 return Term(this, res
);
4771 CVC4_API_TRY_CATCH_END
;
4774 /* Create operators */
4775 /* -------------------------------------------------------------------------- */
4777 Op
Solver::mkOp(Kind kind
) const
4779 CVC4_API_TRY_CATCH_BEGIN
;
4780 CVC4_API_CHECK(s_indexed_kinds
.find(kind
) == s_indexed_kinds
.end())
4781 << "Expected a kind for a non-indexed operator.";
4782 return Op(this, kind
);
4783 CVC4_API_TRY_CATCH_END
4786 Op
Solver::mkOp(Kind kind
, const std::string
& arg
) const
4788 CVC4_API_TRY_CATCH_BEGIN
;
4789 CVC4_API_KIND_CHECK_EXPECTED((kind
== RECORD_UPDATE
) || (kind
== DIVISIBLE
),
4791 << "RECORD_UPDATE or DIVISIBLE";
4793 if (kind
== RECORD_UPDATE
)
4797 *mkValHelper
<CVC4::RecordUpdate
>(CVC4::RecordUpdate(arg
)).d_node
);
4801 /* CLN and GMP handle this case differently, CLN interprets it as 0, GMP
4802 * throws an std::invalid_argument exception. For consistency, we treat it
4804 CVC4_API_ARG_CHECK_EXPECTED(arg
!= ".", arg
)
4805 << "a string representing an integer, real or rational value.";
4808 *mkValHelper
<CVC4::Divisible
>(CVC4::Divisible(CVC4::Integer(arg
)))
4813 CVC4_API_TRY_CATCH_END
;
4816 Op
Solver::mkOp(Kind kind
, uint32_t arg
) const
4818 CVC4_API_TRY_CATCH_BEGIN
;
4819 CVC4_API_KIND_CHECK(kind
);
4827 *mkValHelper
<CVC4::Divisible
>(CVC4::Divisible(arg
)).d_node
);
4829 case BITVECTOR_REPEAT
:
4832 *mkValHelper
<CVC4::BitVectorRepeat
>(CVC4::BitVectorRepeat(arg
))
4835 case BITVECTOR_ZERO_EXTEND
:
4838 *mkValHelper
<CVC4::BitVectorZeroExtend
>(
4839 CVC4::BitVectorZeroExtend(arg
))
4842 case BITVECTOR_SIGN_EXTEND
:
4845 *mkValHelper
<CVC4::BitVectorSignExtend
>(
4846 CVC4::BitVectorSignExtend(arg
))
4849 case BITVECTOR_ROTATE_LEFT
:
4852 *mkValHelper
<CVC4::BitVectorRotateLeft
>(
4853 CVC4::BitVectorRotateLeft(arg
))
4856 case BITVECTOR_ROTATE_RIGHT
:
4859 *mkValHelper
<CVC4::BitVectorRotateRight
>(
4860 CVC4::BitVectorRotateRight(arg
))
4863 case INT_TO_BITVECTOR
:
4867 *mkValHelper
<CVC4::IntToBitVector
>(CVC4::IntToBitVector(arg
)).d_node
);
4871 Op(this, kind
, *mkValHelper
<CVC4::IntAnd
>(CVC4::IntAnd(arg
)).d_node
);
4873 case FLOATINGPOINT_TO_UBV
:
4877 *mkValHelper
<CVC4::FloatingPointToUBV
>(CVC4::FloatingPointToUBV(arg
))
4880 case FLOATINGPOINT_TO_SBV
:
4884 *mkValHelper
<CVC4::FloatingPointToSBV
>(CVC4::FloatingPointToSBV(arg
))
4890 *mkValHelper
<CVC4::TupleUpdate
>(CVC4::TupleUpdate(arg
)).d_node
);
4896 *mkValHelper
<CVC4::RegExpRepeat
>(CVC4::RegExpRepeat(arg
)).d_node
);
4899 CVC4_API_KIND_CHECK_EXPECTED(false, kind
)
4900 << "operator kind with uint32_t argument";
4902 Assert(!res
.isNull());
4905 CVC4_API_TRY_CATCH_END
;
4908 Op
Solver::mkOp(Kind kind
, uint32_t arg1
, uint32_t arg2
) const
4910 CVC4_API_TRY_CATCH_BEGIN
;
4911 CVC4_API_KIND_CHECK(kind
);
4916 case BITVECTOR_EXTRACT
:
4919 *mkValHelper
<CVC4::BitVectorExtract
>(
4920 CVC4::BitVectorExtract(arg1
, arg2
))
4923 case FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
:
4926 *mkValHelper
<CVC4::FloatingPointToFPIEEEBitVector
>(
4927 CVC4::FloatingPointToFPIEEEBitVector(arg1
, arg2
))
4930 case FLOATINGPOINT_TO_FP_FLOATINGPOINT
:
4933 *mkValHelper
<CVC4::FloatingPointToFPFloatingPoint
>(
4934 CVC4::FloatingPointToFPFloatingPoint(arg1
, arg2
))
4937 case FLOATINGPOINT_TO_FP_REAL
:
4940 *mkValHelper
<CVC4::FloatingPointToFPReal
>(
4941 CVC4::FloatingPointToFPReal(arg1
, arg2
))
4944 case FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
:
4947 *mkValHelper
<CVC4::FloatingPointToFPSignedBitVector
>(
4948 CVC4::FloatingPointToFPSignedBitVector(arg1
, arg2
))
4951 case FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
:
4954 *mkValHelper
<CVC4::FloatingPointToFPUnsignedBitVector
>(
4955 CVC4::FloatingPointToFPUnsignedBitVector(arg1
, arg2
))
4958 case FLOATINGPOINT_TO_FP_GENERIC
:
4961 *mkValHelper
<CVC4::FloatingPointToFPGeneric
>(
4962 CVC4::FloatingPointToFPGeneric(arg1
, arg2
))
4969 *mkValHelper
<CVC4::RegExpLoop
>(CVC4::RegExpLoop(arg1
, arg2
)).d_node
);
4972 CVC4_API_KIND_CHECK_EXPECTED(false, kind
)
4973 << "operator kind with two uint32_t arguments";
4975 Assert(!res
.isNull());
4978 CVC4_API_TRY_CATCH_END
;
4981 Op
Solver::mkOp(Kind kind
, const std::vector
<uint32_t>& args
) const
4983 CVC4_API_TRY_CATCH_BEGIN
;
4984 CVC4_API_KIND_CHECK(kind
);
4993 *mkValHelper
<CVC4::TupleProjectOp
>(CVC4::TupleProjectOp(args
))
4999 std::string message
= "operator kind with " + std::to_string(args
.size())
5000 + " uint32_t arguments";
5001 CVC4_API_KIND_CHECK_EXPECTED(false, kind
) << message
;
5004 Assert(!res
.isNull());
5007 CVC4_API_TRY_CATCH_END
;
5010 /* Non-SMT-LIB commands */
5011 /* -------------------------------------------------------------------------- */
5013 Term
Solver::simplify(const Term
& term
)
5015 CVC4_API_TRY_CATCH_BEGIN
;
5016 NodeManagerScope
scope(getNodeManager());
5017 CVC4_API_ARG_CHECK_NOT_NULL(term
);
5018 CVC4_API_SOLVER_CHECK_TERM(term
);
5020 return Term(this, d_smtEngine
->simplify(*term
.d_node
));
5022 CVC4_API_TRY_CATCH_END
;
5025 Result
Solver::checkEntailed(const Term
& term
) const
5027 CVC4_API_TRY_CATCH_BEGIN
;
5028 NodeManagerScope
scope(getNodeManager());
5029 CVC4_API_CHECK(!d_smtEngine
->isQueryMade()
5030 || d_smtEngine
->getOptions()[options::incrementalSolving
])
5031 << "Cannot make multiple queries unless incremental solving is enabled "
5032 "(try --incremental)";
5033 CVC4_API_ARG_CHECK_NOT_NULL(term
);
5034 CVC4_API_SOLVER_CHECK_TERM(term
);
5036 CVC4::Result r
= d_smtEngine
->checkEntailed(*term
.d_node
);
5039 CVC4_API_TRY_CATCH_END
;
5042 Result
Solver::checkEntailed(const std::vector
<Term
>& terms
) const
5044 CVC4_API_TRY_CATCH_BEGIN
;
5045 NodeManagerScope
scope(getNodeManager());
5046 CVC4_API_CHECK(!d_smtEngine
->isQueryMade()
5047 || d_smtEngine
->getOptions()[options::incrementalSolving
])
5048 << "Cannot make multiple queries unless incremental solving is enabled "
5049 "(try --incremental)";
5050 for (const Term
& term
: terms
)
5052 CVC4_API_SOLVER_CHECK_TERM(term
);
5053 CVC4_API_ARG_CHECK_NOT_NULL(term
);
5056 std::vector
<Node
> exprs
= Term::termVectorToNodes(terms
);
5057 CVC4::Result r
= d_smtEngine
->checkEntailed(exprs
);
5060 CVC4_API_TRY_CATCH_END
;
5063 /* SMT-LIB commands */
5064 /* -------------------------------------------------------------------------- */
5069 void Solver::assertFormula(const Term
& term
) const
5071 CVC4_API_TRY_CATCH_BEGIN
;
5072 CVC4_API_SOLVER_CHECK_TERM(term
);
5073 CVC4_API_ARG_CHECK_NOT_NULL(term
);
5074 d_smtEngine
->assertFormula(*term
.d_node
);
5076 CVC4_API_TRY_CATCH_END
;
5082 Result
Solver::checkSat(void) const
5084 CVC4_API_TRY_CATCH_BEGIN
;
5085 NodeManagerScope
scope(getNodeManager());
5086 CVC4_API_CHECK(!d_smtEngine
->isQueryMade()
5087 || d_smtEngine
->getOptions()[options::incrementalSolving
])
5088 << "Cannot make multiple queries unless incremental solving is enabled "
5089 "(try --incremental)";
5090 CVC4::Result r
= d_smtEngine
->checkSat();
5093 CVC4_API_TRY_CATCH_END
;
5097 * ( check-sat-assuming ( <prop_literal> ) )
5099 Result
Solver::checkSatAssuming(const Term
& assumption
) const
5101 CVC4_API_TRY_CATCH_BEGIN
;
5102 NodeManagerScope
scope(getNodeManager());
5103 CVC4_API_CHECK(!d_smtEngine
->isQueryMade()
5104 || d_smtEngine
->getOptions()[options::incrementalSolving
])
5105 << "Cannot make multiple queries unless incremental solving is enabled "
5106 "(try --incremental)";
5107 CVC4_API_SOLVER_CHECK_TERM(assumption
);
5108 CVC4::Result r
= d_smtEngine
->checkSat(*assumption
.d_node
);
5111 CVC4_API_TRY_CATCH_END
;
5115 * ( check-sat-assuming ( <prop_literal>* ) )
5117 Result
Solver::checkSatAssuming(const std::vector
<Term
>& assumptions
) const
5119 CVC4_API_TRY_CATCH_BEGIN
;
5120 NodeManagerScope
scope(getNodeManager());
5121 CVC4_API_CHECK(!d_smtEngine
->isQueryMade() || assumptions
.size() == 0
5122 || d_smtEngine
->getOptions()[options::incrementalSolving
])
5123 << "Cannot make multiple queries unless incremental solving is enabled "
5124 "(try --incremental)";
5125 for (const Term
& term
: assumptions
)
5127 CVC4_API_SOLVER_CHECK_TERM(term
);
5128 CVC4_API_ARG_CHECK_NOT_NULL(term
);
5130 std::vector
<Node
> eassumptions
= Term::termVectorToNodes(assumptions
);
5131 CVC4::Result r
= d_smtEngine
->checkSat(eassumptions
);
5134 CVC4_API_TRY_CATCH_END
;
5138 * ( declare-datatype <symbol> <datatype_decl> )
5140 Sort
Solver::declareDatatype(
5141 const std::string
& symbol
,
5142 const std::vector
<DatatypeConstructorDecl
>& ctors
) const
5144 CVC4_API_TRY_CATCH_BEGIN
;
5145 CVC4_API_ARG_CHECK_EXPECTED(ctors
.size() > 0, ctors
)
5146 << "a datatype declaration with at least one constructor";
5147 DatatypeDecl
dtdecl(this, symbol
);
5148 for (size_t i
= 0, size
= ctors
.size(); i
< size
; i
++)
5150 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(this == ctors
[i
].d_solver
,
5151 "datatype constructor declaration",
5154 << "datatype constructor declaration associated to this solver object";
5155 dtdecl
.addConstructor(ctors
[i
]);
5157 return Sort(this, getNodeManager()->mkDatatypeType(*dtdecl
.d_dtype
));
5159 CVC4_API_TRY_CATCH_END
;
5163 * ( declare-fun <symbol> ( <sort>* ) <sort> )
5165 Term
Solver::declareFun(const std::string
& symbol
,
5166 const std::vector
<Sort
>& sorts
,
5167 const Sort
& sort
) const
5169 CVC4_API_TRY_CATCH_BEGIN
;
5170 for (size_t i
= 0, size
= sorts
.size(); i
< size
; ++i
)
5172 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5173 this == sorts
[i
].d_solver
, "parameter sort", sorts
[i
], i
)
5174 << "parameter sort associated to this solver object";
5175 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5176 sorts
[i
].isFirstClass(), "parameter sort", sorts
[i
], i
)
5177 << "first-class sort as parameter sort for function sort";
5179 CVC4_API_ARG_CHECK_EXPECTED(sort
.isFirstClass(), sort
)
5180 << "first-class sort as function codomain sort";
5181 CVC4_API_SOLVER_CHECK_SORT(sort
);
5182 Assert(!sort
.isFunction()); /* A function sort is not first-class. */
5183 TypeNode type
= *sort
.d_type
;
5186 std::vector
<TypeNode
> types
= Sort::sortVectorToTypeNodes(sorts
);
5187 type
= getNodeManager()->mkFunctionType(types
, type
);
5189 return Term(this, d_nodeMgr
->mkVar(symbol
, type
));
5191 CVC4_API_TRY_CATCH_END
;
5195 * ( declare-sort <symbol> <numeral> )
5197 Sort
Solver::declareSort(const std::string
& symbol
, uint32_t arity
) const
5199 CVC4_API_TRY_CATCH_BEGIN
;
5202 return Sort(this, getNodeManager()->mkSort(symbol
));
5204 return Sort(this, getNodeManager()->mkSortConstructor(symbol
, arity
));
5206 CVC4_API_TRY_CATCH_END
;
5210 * ( define-fun <function_def> )
5212 Term
Solver::defineFun(const std::string
& symbol
,
5213 const std::vector
<Term
>& bound_vars
,
5218 CVC4_API_TRY_CATCH_BEGIN
;
5219 CVC4_API_ARG_CHECK_EXPECTED(sort
.isFirstClass(), sort
)
5220 << "first-class sort as codomain sort for function sort";
5221 std::vector
<TypeNode
> domain_types
;
5222 for (size_t i
= 0, size
= bound_vars
.size(); i
< size
; ++i
)
5224 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5225 this == bound_vars
[i
].d_solver
, "bound variable", bound_vars
[i
], i
)
5226 << "bound variable associated to this solver object";
5227 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5228 bound_vars
[i
].d_node
->getKind() == CVC4::Kind::BOUND_VARIABLE
,
5232 << "a bound variable";
5233 CVC4::TypeNode t
= bound_vars
[i
].d_node
->getType();
5234 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5235 t
.isFirstClass(), "sort of parameter", bound_vars
[i
], i
)
5236 << "first-class sort of parameter of defined function";
5237 domain_types
.push_back(t
);
5239 CVC4_API_SOLVER_CHECK_SORT(sort
);
5240 CVC4_API_SOLVER_CHECK_TERM(term
);
5241 CVC4_API_CHECK(sort
== term
.getSort())
5242 << "Invalid sort of function body '" << term
<< "', expected '" << sort
5244 NodeManager
* nm
= getNodeManager();
5245 TypeNode type
= *sort
.d_type
;
5246 if (!domain_types
.empty())
5248 type
= nm
->mkFunctionType(domain_types
, type
);
5250 Node fun
= d_nodeMgr
->mkVar(symbol
, type
);
5251 std::vector
<Node
> ebound_vars
= Term::termVectorToNodes(bound_vars
);
5252 d_smtEngine
->defineFunction(fun
, ebound_vars
, *term
.d_node
, global
);
5253 return Term(this, fun
);
5255 CVC4_API_TRY_CATCH_END
;
5258 Term
Solver::defineFun(const Term
& fun
,
5259 const std::vector
<Term
>& bound_vars
,
5263 CVC4_API_TRY_CATCH_BEGIN
;
5265 if (fun
.getSort().isFunction())
5267 std::vector
<Sort
> domain_sorts
= fun
.getSort().getFunctionDomainSorts();
5268 size_t size
= bound_vars
.size();
5269 CVC4_API_ARG_SIZE_CHECK_EXPECTED(size
== domain_sorts
.size(), bound_vars
)
5270 << "'" << domain_sorts
.size() << "'";
5271 for (size_t i
= 0; i
< size
; ++i
)
5273 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5274 this == bound_vars
[i
].d_solver
, "bound variable", bound_vars
[i
], i
)
5275 << "bound variable associated to this solver object";
5276 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5277 bound_vars
[i
].d_node
->getKind() == CVC4::Kind::BOUND_VARIABLE
,
5281 << "a bound variable";
5282 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5283 domain_sorts
[i
] == bound_vars
[i
].getSort(),
5284 "sort of parameter",
5287 << "'" << domain_sorts
[i
] << "'";
5289 Sort codomain
= fun
.getSort().getFunctionCodomainSort();
5290 CVC4_API_CHECK(codomain
== term
.getSort())
5291 << "Invalid sort of function body '" << term
<< "', expected '"
5296 CVC4_API_ARG_CHECK_EXPECTED(bound_vars
.size() == 0, fun
)
5297 << "function or nullary symbol";
5300 CVC4_API_SOLVER_CHECK_TERM(term
);
5302 std::vector
<Node
> ebound_vars
= Term::termVectorToNodes(bound_vars
);
5303 d_smtEngine
->defineFunction(*fun
.d_node
, ebound_vars
, *term
.d_node
, global
);
5306 CVC4_API_TRY_CATCH_END
;
5310 * ( define-fun-rec <function_def> )
5312 Term
Solver::defineFunRec(const std::string
& symbol
,
5313 const std::vector
<Term
>& bound_vars
,
5318 NodeManagerScope
scope(getNodeManager());
5319 CVC4_API_TRY_CATCH_BEGIN
;
5321 CVC4_API_CHECK(d_smtEngine
->getUserLogicInfo().isQuantified())
5322 << "recursive function definitions require a logic with quantifiers";
5324 d_smtEngine
->getUserLogicInfo().isTheoryEnabled(theory::THEORY_UF
))
5325 << "recursive function definitions require a logic with uninterpreted "
5328 CVC4_API_ARG_CHECK_EXPECTED(sort
.isFirstClass(), sort
)
5329 << "first-class sort as function codomain sort";
5330 Assert(!sort
.isFunction()); /* A function sort is not first-class. */
5331 std::vector
<TypeNode
> domain_types
;
5332 for (size_t i
= 0, size
= bound_vars
.size(); i
< size
; ++i
)
5334 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5335 this == bound_vars
[i
].d_solver
, "bound variable", bound_vars
[i
], i
)
5336 << "bound variable associated to this solver object";
5337 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5338 bound_vars
[i
].d_node
->getKind() == CVC4::Kind::BOUND_VARIABLE
,
5342 << "a bound variable";
5343 CVC4::TypeNode t
= bound_vars
[i
].d_node
->getType();
5344 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5345 t
.isFirstClass(), "sort of parameter", bound_vars
[i
], i
)
5346 << "first-class sort of parameter of defined function";
5347 domain_types
.push_back(t
);
5349 CVC4_API_SOLVER_CHECK_SORT(sort
);
5350 CVC4_API_CHECK(sort
== term
.getSort())
5351 << "Invalid sort of function body '" << term
<< "', expected '" << sort
5353 CVC4_API_SOLVER_CHECK_TERM(term
);
5354 NodeManager
* nm
= getNodeManager();
5355 TypeNode type
= *sort
.d_type
;
5356 if (!domain_types
.empty())
5358 type
= nm
->mkFunctionType(domain_types
, type
);
5360 Node fun
= d_nodeMgr
->mkVar(symbol
, type
);
5361 std::vector
<Node
> ebound_vars
= Term::termVectorToNodes(bound_vars
);
5362 d_smtEngine
->defineFunctionRec(fun
, ebound_vars
, *term
.d_node
, global
);
5363 return Term(this, fun
);
5365 CVC4_API_TRY_CATCH_END
;
5368 Term
Solver::defineFunRec(const Term
& fun
,
5369 const std::vector
<Term
>& bound_vars
,
5373 NodeManagerScope
scope(getNodeManager());
5374 CVC4_API_TRY_CATCH_BEGIN
;
5376 CVC4_API_CHECK(d_smtEngine
->getUserLogicInfo().isQuantified())
5377 << "recursive function definitions require a logic with quantifiers";
5379 d_smtEngine
->getUserLogicInfo().isTheoryEnabled(theory::THEORY_UF
))
5380 << "recursive function definitions require a logic with uninterpreted "
5383 CVC4_API_SOLVER_CHECK_TERM(fun
);
5384 if (fun
.getSort().isFunction())
5386 std::vector
<Sort
> domain_sorts
= fun
.getSort().getFunctionDomainSorts();
5387 size_t size
= bound_vars
.size();
5388 CVC4_API_ARG_SIZE_CHECK_EXPECTED(size
== domain_sorts
.size(), bound_vars
)
5389 << "'" << domain_sorts
.size() << "'";
5390 for (size_t i
= 0; i
< size
; ++i
)
5392 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5393 this == bound_vars
[i
].d_solver
, "bound variable", bound_vars
[i
], i
)
5394 << "bound variable associated to this solver object";
5395 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5396 bound_vars
[i
].d_node
->getKind() == CVC4::Kind::BOUND_VARIABLE
,
5400 << "a bound variable";
5401 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5402 domain_sorts
[i
] == bound_vars
[i
].getSort(),
5403 "sort of parameter",
5406 << "'" << domain_sorts
[i
] << "'";
5408 Sort codomain
= fun
.getSort().getFunctionCodomainSort();
5409 CVC4_API_CHECK(codomain
== term
.getSort())
5410 << "Invalid sort of function body '" << term
<< "', expected '"
5415 CVC4_API_ARG_CHECK_EXPECTED(bound_vars
.size() == 0, fun
)
5416 << "function or nullary symbol";
5419 CVC4_API_SOLVER_CHECK_TERM(term
);
5420 std::vector
<Node
> ebound_vars
= Term::termVectorToNodes(bound_vars
);
5421 d_smtEngine
->defineFunctionRec(
5422 *fun
.d_node
, ebound_vars
, *term
.d_node
, global
);
5425 CVC4_API_TRY_CATCH_END
;
5429 * ( define-funs-rec ( <function_decl>^{n+1} ) ( <term>^{n+1} ) )
5431 void Solver::defineFunsRec(const std::vector
<Term
>& funs
,
5432 const std::vector
<std::vector
<Term
>>& bound_vars
,
5433 const std::vector
<Term
>& terms
,
5436 NodeManagerScope
scope(getNodeManager());
5437 CVC4_API_TRY_CATCH_BEGIN
;
5439 CVC4_API_CHECK(d_smtEngine
->getUserLogicInfo().isQuantified())
5440 << "recursive function definitions require a logic with quantifiers";
5442 d_smtEngine
->getUserLogicInfo().isTheoryEnabled(theory::THEORY_UF
))
5443 << "recursive function definitions require a logic with uninterpreted "
5446 size_t funs_size
= funs
.size();
5447 CVC4_API_ARG_SIZE_CHECK_EXPECTED(funs_size
== bound_vars
.size(), bound_vars
)
5448 << "'" << funs_size
<< "'";
5449 for (size_t j
= 0; j
< funs_size
; ++j
)
5451 const Term
& fun
= funs
[j
];
5452 const std::vector
<Term
>& bvars
= bound_vars
[j
];
5453 const Term
& term
= terms
[j
];
5455 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5456 this == fun
.d_solver
, "function", fun
, j
)
5457 << "function associated to this solver object";
5458 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(this == term
.d_solver
, "term", term
, j
)
5459 << "term associated to this solver object";
5461 if (fun
.getSort().isFunction())
5463 std::vector
<Sort
> domain_sorts
= fun
.getSort().getFunctionDomainSorts();
5464 size_t size
= bvars
.size();
5465 CVC4_API_ARG_SIZE_CHECK_EXPECTED(size
== domain_sorts
.size(), bvars
)
5466 << "'" << domain_sorts
.size() << "'";
5467 for (size_t i
= 0; i
< size
; ++i
)
5469 for (size_t k
= 0, nbvars
= bvars
.size(); k
< nbvars
; ++k
)
5471 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5472 this == bvars
[k
].d_solver
, "bound variable", bvars
[k
], k
)
5473 << "bound variable associated to this solver object";
5474 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5475 bvars
[k
].d_node
->getKind() == CVC4::Kind::BOUND_VARIABLE
,
5479 << "a bound variable";
5481 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5482 domain_sorts
[i
] == bvars
[i
].getSort(),
5483 "sort of parameter",
5486 << "'" << domain_sorts
[i
] << "' in parameter bound_vars[" << j
5489 Sort codomain
= fun
.getSort().getFunctionCodomainSort();
5490 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5491 codomain
== term
.getSort(), "sort of function body", term
, j
)
5492 << "'" << codomain
<< "'";
5496 CVC4_API_ARG_CHECK_EXPECTED(bvars
.size() == 0, fun
)
5497 << "function or nullary symbol";
5500 std::vector
<Node
> efuns
= Term::termVectorToNodes(funs
);
5501 std::vector
<std::vector
<Node
>> ebound_vars
;
5502 for (const auto& v
: bound_vars
)
5504 ebound_vars
.push_back(Term::termVectorToNodes(v
));
5506 std::vector
<Node
> nodes
= Term::termVectorToNodes(terms
);
5507 d_smtEngine
->defineFunctionsRec(efuns
, ebound_vars
, nodes
, global
);
5509 CVC4_API_TRY_CATCH_END
;
5513 * ( echo <std::string> )
5515 void Solver::echo(std::ostream
& out
, const std::string
& str
) const
5521 * ( get-assertions )
5523 std::vector
<Term
> Solver::getAssertions(void) const
5525 CVC4_API_TRY_CATCH_BEGIN
;
5526 std::vector
<Node
> assertions
= d_smtEngine
->getAssertions();
5528 * return std::vector<Term>(assertions.begin(), assertions.end());
5529 * here since constructor is private */
5530 std::vector
<Term
> res
;
5531 for (const Node
& e
: assertions
)
5533 res
.push_back(Term(this, e
));
5537 CVC4_API_TRY_CATCH_END
;
5541 * ( get-info <info_flag> )
5543 std::string
Solver::getInfo(const std::string
& flag
) const
5545 CVC4_API_TRY_CATCH_BEGIN
;
5546 CVC4_API_RECOVERABLE_CHECK(d_smtEngine
->isValidGetInfoFlag(flag
))
5547 << "Unrecognized flag for getInfo.";
5549 return d_smtEngine
->getInfo(flag
).toString();
5551 CVC4_API_TRY_CATCH_END
;
5555 * ( get-option <keyword> )
5557 std::string
Solver::getOption(const std::string
& option
) const
5559 CVC4_API_TRY_CATCH_BEGIN
;
5560 SExpr res
= d_smtEngine
->getOption(option
);
5561 return res
.toString();
5563 CVC4_API_TRY_CATCH_END
;
5567 * ( get-unsat-assumptions )
5569 std::vector
<Term
> Solver::getUnsatAssumptions(void) const
5571 CVC4_API_TRY_CATCH_BEGIN
;
5572 NodeManagerScope
scope(getNodeManager());
5573 CVC4_API_CHECK(d_smtEngine
->getOptions()[options::incrementalSolving
])
5574 << "Cannot get unsat assumptions unless incremental solving is enabled "
5575 "(try --incremental)";
5576 CVC4_API_CHECK(d_smtEngine
->getOptions()[options::unsatAssumptions
])
5577 << "Cannot get unsat assumptions unless explicitly enabled "
5578 "(try --produce-unsat-assumptions)";
5579 CVC4_API_CHECK(d_smtEngine
->getSmtMode() == SmtMode::UNSAT
)
5580 << "Cannot get unsat assumptions unless in unsat mode.";
5582 std::vector
<Node
> uassumptions
= d_smtEngine
->getUnsatAssumptions();
5584 * return std::vector<Term>(uassumptions.begin(), uassumptions.end());
5585 * here since constructor is private */
5586 std::vector
<Term
> res
;
5587 for (const Node
& n
: uassumptions
)
5589 res
.push_back(Term(this, n
));
5593 CVC4_API_TRY_CATCH_END
;
5597 * ( get-unsat-core )
5599 std::vector
<Term
> Solver::getUnsatCore(void) const
5601 CVC4_API_TRY_CATCH_BEGIN
;
5602 NodeManagerScope
scope(getNodeManager());
5603 CVC4_API_CHECK(d_smtEngine
->getOptions()[options::unsatCores
])
5604 << "Cannot get unsat core unless explicitly enabled "
5605 "(try --produce-unsat-cores)";
5606 CVC4_API_RECOVERABLE_CHECK(d_smtEngine
->getSmtMode() == SmtMode::UNSAT
)
5607 << "Cannot get unsat core unless in unsat mode.";
5608 UnsatCore core
= d_smtEngine
->getUnsatCore();
5610 * return std::vector<Term>(core.begin(), core.end());
5611 * here since constructor is private */
5612 std::vector
<Term
> res
;
5613 for (const Node
& e
: core
)
5615 res
.push_back(Term(this, e
));
5619 CVC4_API_TRY_CATCH_END
;
5623 * ( get-value ( <term> ) )
5625 Term
Solver::getValue(const Term
& term
) const
5627 CVC4_API_TRY_CATCH_BEGIN
;
5628 CVC4_API_SOLVER_CHECK_TERM(term
);
5629 return getValueHelper(term
);
5631 CVC4_API_TRY_CATCH_END
;
5635 * ( get-value ( <term>+ ) )
5637 std::vector
<Term
> Solver::getValue(const std::vector
<Term
>& terms
) const
5639 CVC4_API_TRY_CATCH_BEGIN
;
5640 NodeManagerScope
scope(getNodeManager());
5641 CVC4_API_RECOVERABLE_CHECK(d_smtEngine
->getOptions()[options::produceModels
])
5642 << "Cannot get value unless model generation is enabled "
5643 "(try --produce-models)";
5644 CVC4_API_RECOVERABLE_CHECK(d_smtEngine
->isSmtModeSat())
5645 << "Cannot get value unless after a SAT or unknown response.";
5646 std::vector
<Term
> res
;
5647 for (size_t i
= 0, n
= terms
.size(); i
< n
; ++i
)
5649 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5650 this == terms
[i
].d_solver
, "term", terms
[i
], i
)
5651 << "term associated to this solver object";
5652 /* Can not use emplace_back here since constructor is private. */
5653 res
.push_back(getValueHelper(terms
[i
]));
5657 CVC4_API_TRY_CATCH_END
;
5660 Term
Solver::getQuantifierElimination(const Term
& q
) const
5662 CVC4_API_TRY_CATCH_BEGIN
;
5663 CVC4_API_ARG_CHECK_NOT_NULL(q
);
5664 CVC4_API_SOLVER_CHECK_TERM(q
);
5665 NodeManagerScope
scope(getNodeManager());
5667 d_smtEngine
->getQuantifierElimination(q
.getNode(), true, true));
5669 CVC4_API_TRY_CATCH_END
;
5672 Term
Solver::getQuantifierEliminationDisjunct(const Term
& q
) const
5674 CVC4_API_TRY_CATCH_BEGIN
;
5675 CVC4_API_ARG_CHECK_NOT_NULL(q
);
5676 CVC4_API_SOLVER_CHECK_TERM(q
);
5677 NodeManagerScope
scope(getNodeManager());
5679 this, d_smtEngine
->getQuantifierElimination(q
.getNode(), false, true));
5681 CVC4_API_TRY_CATCH_END
;
5684 void Solver::declareSeparationHeap(const Sort
& locSort
,
5685 const Sort
& dataSort
) const
5687 CVC4_API_TRY_CATCH_BEGIN
;
5688 CVC4_API_SOLVER_CHECK_SORT(locSort
);
5689 CVC4_API_SOLVER_CHECK_SORT(dataSort
);
5691 d_smtEngine
->getLogicInfo().isTheoryEnabled(theory::THEORY_SEP
))
5692 << "Cannot obtain separation logic expressions if not using the "
5693 "separation logic theory.";
5694 d_smtEngine
->declareSepHeap(locSort
.getTypeNode(), dataSort
.getTypeNode());
5696 CVC4_API_TRY_CATCH_END
;
5699 Term
Solver::getSeparationHeap() const
5701 NodeManagerScope
scope(getNodeManager());
5702 CVC4_API_TRY_CATCH_BEGIN
;
5704 d_smtEngine
->getLogicInfo().isTheoryEnabled(theory::THEORY_SEP
))
5705 << "Cannot obtain separation logic expressions if not using the "
5706 "separation logic theory.";
5707 CVC4_API_CHECK(d_smtEngine
->getOptions()[options::produceModels
])
5708 << "Cannot get separation heap term unless model generation is enabled "
5709 "(try --produce-models)";
5710 CVC4_API_RECOVERABLE_CHECK(d_smtEngine
->isSmtModeSat())
5711 << "Can only get separtion heap term after sat or unknown response.";
5712 return Term(this, d_smtEngine
->getSepHeapExpr());
5714 CVC4_API_TRY_CATCH_END
;
5717 Term
Solver::getSeparationNilTerm() const
5719 NodeManagerScope
scope(getNodeManager());
5720 CVC4_API_TRY_CATCH_BEGIN
;
5722 d_smtEngine
->getLogicInfo().isTheoryEnabled(theory::THEORY_SEP
))
5723 << "Cannot obtain separation logic expressions if not using the "
5724 "separation logic theory.";
5725 CVC4_API_CHECK(d_smtEngine
->getOptions()[options::produceModels
])
5726 << "Cannot get separation nil term unless model generation is enabled "
5727 "(try --produce-models)";
5728 CVC4_API_RECOVERABLE_CHECK(d_smtEngine
->isSmtModeSat())
5729 << "Can only get separtion nil term after sat or unknown response.";
5730 return Term(this, d_smtEngine
->getSepNilExpr());
5732 CVC4_API_TRY_CATCH_END
;
5738 void Solver::pop(uint32_t nscopes
) const
5740 NodeManagerScope
scope(getNodeManager());
5741 CVC4_API_TRY_CATCH_BEGIN
;
5742 CVC4_API_CHECK(d_smtEngine
->getOptions()[options::incrementalSolving
])
5743 << "Cannot pop when not solving incrementally (use --incremental)";
5744 CVC4_API_CHECK(nscopes
<= d_smtEngine
->getNumUserLevels())
5745 << "Cannot pop beyond first pushed context";
5747 for (uint32_t n
= 0; n
< nscopes
; ++n
)
5752 CVC4_API_TRY_CATCH_END
;
5755 bool Solver::getInterpolant(const Term
& conj
, Term
& output
) const
5757 NodeManagerScope
scope(getNodeManager());
5758 CVC4_API_TRY_CATCH_BEGIN
;
5759 CVC4_API_SOLVER_CHECK_TERM(conj
);
5761 bool success
= d_smtEngine
->getInterpol(*conj
.d_node
, result
);
5764 output
= Term(this, result
);
5768 CVC4_API_TRY_CATCH_END
;
5771 bool Solver::getInterpolant(const Term
& conj
, Grammar
& g
, Term
& output
) const
5773 NodeManagerScope
scope(getNodeManager());
5774 CVC4_API_TRY_CATCH_BEGIN
;
5775 CVC4_API_SOLVER_CHECK_TERM(conj
);
5778 d_smtEngine
->getInterpol(*conj
.d_node
, *g
.resolve().d_type
, result
);
5781 output
= Term(this, result
);
5785 CVC4_API_TRY_CATCH_END
;
5788 bool Solver::getAbduct(const Term
& conj
, Term
& output
) const
5790 NodeManagerScope
scope(getNodeManager());
5791 CVC4_API_TRY_CATCH_BEGIN
;
5792 CVC4_API_SOLVER_CHECK_TERM(conj
);
5794 bool success
= d_smtEngine
->getAbduct(*conj
.d_node
, result
);
5797 output
= Term(this, result
);
5801 CVC4_API_TRY_CATCH_END
;
5804 bool Solver::getAbduct(const Term
& conj
, Grammar
& g
, Term
& output
) const
5806 NodeManagerScope
scope(getNodeManager());
5807 CVC4_API_TRY_CATCH_BEGIN
;
5808 CVC4_API_SOLVER_CHECK_TERM(conj
);
5811 d_smtEngine
->getAbduct(*conj
.d_node
, *g
.resolve().d_type
, result
);
5814 output
= Term(this, result
);
5818 CVC4_API_TRY_CATCH_END
;
5821 void Solver::blockModel() const
5823 CVC4_API_TRY_CATCH_BEGIN
;
5824 NodeManagerScope
scope(getNodeManager());
5825 CVC4_API_CHECK(d_smtEngine
->getOptions()[options::produceModels
])
5826 << "Cannot get value unless model generation is enabled "
5827 "(try --produce-models)";
5828 CVC4_API_RECOVERABLE_CHECK(d_smtEngine
->isSmtModeSat())
5829 << "Can only block model after sat or unknown response.";
5830 d_smtEngine
->blockModel();
5832 CVC4_API_TRY_CATCH_END
;
5835 void Solver::blockModelValues(const std::vector
<Term
>& terms
) const
5837 CVC4_API_TRY_CATCH_BEGIN
;
5838 CVC4_API_CHECK(d_smtEngine
->getOptions()[options::produceModels
])
5839 << "Cannot get value unless model generation is enabled "
5840 "(try --produce-models)";
5841 CVC4_API_RECOVERABLE_CHECK(d_smtEngine
->isSmtModeSat())
5842 << "Can only block model values after sat or unknown response.";
5843 CVC4_API_ARG_SIZE_CHECK_EXPECTED(!terms
.empty(), terms
)
5844 << "a non-empty set of terms";
5845 for (size_t i
= 0, tsize
= terms
.size(); i
< tsize
; ++i
)
5847 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5848 !terms
[i
].isNull(), "term", terms
[i
], i
)
5849 << "a non-null term";
5850 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5851 this == terms
[i
].d_solver
, "term", terms
[i
], i
)
5852 << "a term associated to this solver object";
5854 NodeManagerScope
scope(getNodeManager());
5855 d_smtEngine
->blockModelValues(Term::termVectorToNodes(terms
));
5857 CVC4_API_TRY_CATCH_END
;
5860 void Solver::printInstantiations(std::ostream
& out
) const
5862 CVC4_API_TRY_CATCH_BEGIN
;
5863 NodeManagerScope
scope(getNodeManager());
5864 d_smtEngine
->printInstantiations(out
);
5866 CVC4_API_TRY_CATCH_END
;
5870 * ( push <numeral> )
5872 void Solver::push(uint32_t nscopes
) const
5874 CVC4_API_TRY_CATCH_BEGIN
;
5875 NodeManagerScope
scope(getNodeManager());
5876 CVC4_API_CHECK(d_smtEngine
->getOptions()[options::incrementalSolving
])
5877 << "Cannot push when not solving incrementally (use --incremental)";
5879 for (uint32_t n
= 0; n
< nscopes
; ++n
)
5881 d_smtEngine
->push();
5884 CVC4_API_TRY_CATCH_END
;
5888 * ( reset-assertions )
5890 void Solver::resetAssertions(void) const
5892 CVC4_API_TRY_CATCH_BEGIN
;
5893 d_smtEngine
->resetAssertions();
5895 CVC4_API_TRY_CATCH_END
;
5899 * ( set-info <attribute> )
5901 void Solver::setInfo(const std::string
& keyword
, const std::string
& value
) const
5903 CVC4_API_TRY_CATCH_BEGIN
;
5904 CVC4_API_RECOVERABLE_ARG_CHECK_EXPECTED(
5905 keyword
== "source" || keyword
== "category" || keyword
== "difficulty"
5906 || keyword
== "filename" || keyword
== "license" || keyword
== "name"
5907 || keyword
== "notes" || keyword
== "smt-lib-version"
5908 || keyword
== "status",
5910 << "'source', 'category', 'difficulty', 'filename', 'license', 'name', "
5911 "'notes', 'smt-lib-version' or 'status'";
5912 CVC4_API_RECOVERABLE_ARG_CHECK_EXPECTED(
5913 keyword
!= "smt-lib-version" || value
== "2" || value
== "2.0"
5914 || value
== "2.5" || value
== "2.6",
5916 << "'2.0', '2.5', '2.6'";
5917 CVC4_API_ARG_CHECK_EXPECTED(keyword
!= "status" || value
== "sat"
5918 || value
== "unsat" || value
== "unknown",
5920 << "'sat', 'unsat' or 'unknown'";
5922 d_smtEngine
->setInfo(keyword
, value
);
5924 CVC4_API_TRY_CATCH_END
;
5928 * ( set-logic <symbol> )
5930 void Solver::setLogic(const std::string
& logic
) const
5932 CVC4_API_TRY_CATCH_BEGIN
;
5933 CVC4_API_CHECK(!d_smtEngine
->isFullyInited())
5934 << "Invalid call to 'setLogic', solver is already fully initialized";
5935 CVC4::LogicInfo
logic_info(logic
);
5936 d_smtEngine
->setLogic(logic_info
);
5938 CVC4_API_TRY_CATCH_END
;
5942 * ( set-option <option> )
5944 void Solver::setOption(const std::string
& option
,
5945 const std::string
& value
) const
5947 CVC4_API_TRY_CATCH_BEGIN
;
5948 CVC4_API_CHECK(!d_smtEngine
->isFullyInited())
5949 << "Invalid call to 'setOption', solver is already fully initialized";
5950 d_smtEngine
->setOption(option
, value
);
5952 CVC4_API_TRY_CATCH_END
;
5955 Term
Solver::mkSygusVar(const Sort
& sort
, const std::string
& symbol
) const
5957 CVC4_API_TRY_CATCH_BEGIN
;
5958 CVC4_API_ARG_CHECK_NOT_NULL(sort
);
5959 CVC4_API_SOLVER_CHECK_SORT(sort
);
5961 Node res
= getNodeManager()->mkBoundVar(symbol
, *sort
.d_type
);
5962 (void)res
.getType(true); /* kick off type checking */
5964 d_smtEngine
->declareSygusVar(res
);
5966 return Term(this, res
);
5968 CVC4_API_TRY_CATCH_END
;
5971 Grammar
Solver::mkSygusGrammar(const std::vector
<Term
>& boundVars
,
5972 const std::vector
<Term
>& ntSymbols
) const
5974 CVC4_API_TRY_CATCH_BEGIN
;
5975 CVC4_API_ARG_SIZE_CHECK_EXPECTED(!ntSymbols
.empty(), ntSymbols
)
5976 << "a non-empty vector";
5978 for (size_t i
= 0, n
= boundVars
.size(); i
< n
; ++i
)
5980 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5981 this == boundVars
[i
].d_solver
, "bound variable", boundVars
[i
], i
)
5982 << "bound variable associated to this solver object";
5983 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5984 !boundVars
[i
].isNull(), "bound variable", boundVars
[i
], i
)
5985 << "a non-null term";
5986 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5987 boundVars
[i
].d_node
->getKind() == CVC4::Kind::BOUND_VARIABLE
,
5991 << "a bound variable";
5994 for (size_t i
= 0, n
= ntSymbols
.size(); i
< n
; ++i
)
5996 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
5997 this == ntSymbols
[i
].d_solver
, "non-terminal", ntSymbols
[i
], i
)
5998 << "term associated to this solver object";
5999 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
6000 !ntSymbols
[i
].isNull(), "non-terminal", ntSymbols
[i
], i
)
6001 << "a non-null term";
6002 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
6003 ntSymbols
[i
].d_node
->getKind() == CVC4::Kind::BOUND_VARIABLE
,
6007 << "a bound variable";
6010 return Grammar(this, boundVars
, ntSymbols
);
6012 CVC4_API_TRY_CATCH_END
;
6015 Term
Solver::synthFun(const std::string
& symbol
,
6016 const std::vector
<Term
>& boundVars
,
6017 const Sort
& sort
) const
6019 CVC4_API_TRY_CATCH_BEGIN
;
6020 return synthFunHelper(symbol
, boundVars
, sort
);
6022 CVC4_API_TRY_CATCH_END
;
6025 Term
Solver::synthFun(const std::string
& symbol
,
6026 const std::vector
<Term
>& boundVars
,
6030 CVC4_API_TRY_CATCH_BEGIN
;
6031 return synthFunHelper(symbol
, boundVars
, sort
, false, &g
);
6033 CVC4_API_TRY_CATCH_END
;
6036 Term
Solver::synthInv(const std::string
& symbol
,
6037 const std::vector
<Term
>& boundVars
) const
6039 CVC4_API_TRY_CATCH_BEGIN
;
6040 return synthFunHelper(
6041 symbol
, boundVars
, Sort(this, getNodeManager()->booleanType()), true);
6043 CVC4_API_TRY_CATCH_END
;
6046 Term
Solver::synthInv(const std::string
& symbol
,
6047 const std::vector
<Term
>& boundVars
,
6050 CVC4_API_TRY_CATCH_BEGIN
;
6051 return synthFunHelper(
6052 symbol
, boundVars
, Sort(this, getNodeManager()->booleanType()), true, &g
);
6054 CVC4_API_TRY_CATCH_END
;
6057 void Solver::addSygusConstraint(const Term
& term
) const
6059 NodeManagerScope
scope(getNodeManager());
6060 CVC4_API_TRY_CATCH_BEGIN
;
6061 CVC4_API_ARG_CHECK_NOT_NULL(term
);
6062 CVC4_API_SOLVER_CHECK_TERM(term
);
6063 CVC4_API_ARG_CHECK_EXPECTED(
6064 term
.d_node
->getType() == getNodeManager()->booleanType(), term
)
6067 d_smtEngine
->assertSygusConstraint(*term
.d_node
);
6069 CVC4_API_TRY_CATCH_END
;
6072 void Solver::addSygusInvConstraint(Term inv
,
6077 CVC4_API_TRY_CATCH_BEGIN
;
6078 CVC4_API_ARG_CHECK_NOT_NULL(inv
);
6079 CVC4_API_SOLVER_CHECK_TERM(inv
);
6080 CVC4_API_ARG_CHECK_NOT_NULL(pre
);
6081 CVC4_API_SOLVER_CHECK_TERM(pre
);
6082 CVC4_API_ARG_CHECK_NOT_NULL(trans
);
6083 CVC4_API_SOLVER_CHECK_TERM(trans
);
6084 CVC4_API_ARG_CHECK_NOT_NULL(post
);
6085 CVC4_API_SOLVER_CHECK_TERM(post
);
6087 CVC4_API_ARG_CHECK_EXPECTED(inv
.d_node
->getType().isFunction(), inv
)
6090 TypeNode invType
= inv
.d_node
->getType();
6092 CVC4_API_ARG_CHECK_EXPECTED(invType
.getRangeType().isBoolean(), inv
)
6095 CVC4_API_CHECK(pre
.d_node
->getType() == invType
)
6096 << "Expected inv and pre to have the same sort";
6098 CVC4_API_CHECK(post
.d_node
->getType() == invType
)
6099 << "Expected inv and post to have the same sort";
6101 const std::vector
<TypeNode
>& invArgTypes
= invType
.getArgTypes();
6103 std::vector
<TypeNode
> expectedTypes
;
6104 expectedTypes
.reserve(2 * invArgTypes
.size() + 1);
6106 for (size_t i
= 0, n
= invArgTypes
.size(); i
< 2 * n
; i
+= 2)
6108 expectedTypes
.push_back(invArgTypes
[i
% n
]);
6109 expectedTypes
.push_back(invArgTypes
[(i
+ 1) % n
]);
6112 expectedTypes
.push_back(invType
.getRangeType());
6113 TypeNode expectedTransType
= getNodeManager()->mkFunctionType(expectedTypes
);
6115 CVC4_API_CHECK(trans
.d_node
->getType() == expectedTransType
)
6116 << "Expected trans's sort to be " << invType
;
6118 d_smtEngine
->assertSygusInvConstraint(
6119 *inv
.d_node
, *pre
.d_node
, *trans
.d_node
, *post
.d_node
);
6121 CVC4_API_TRY_CATCH_END
;
6124 Result
Solver::checkSynth() const
6126 CVC4_API_TRY_CATCH_BEGIN
;
6127 return d_smtEngine
->checkSynth();
6129 CVC4_API_TRY_CATCH_END
;
6132 Term
Solver::getSynthSolution(Term term
) const
6134 CVC4_API_TRY_CATCH_BEGIN
;
6135 CVC4_API_ARG_CHECK_NOT_NULL(term
);
6136 CVC4_API_SOLVER_CHECK_TERM(term
);
6138 std::map
<CVC4::Node
, CVC4::Node
> map
;
6139 CVC4_API_CHECK(d_smtEngine
->getSynthSolutions(map
))
6140 << "The solver is not in a state immediately preceded by a "
6141 "successful call to checkSynth";
6143 std::map
<CVC4::Node
, CVC4::Node
>::const_iterator it
= map
.find(*term
.d_node
);
6145 CVC4_API_CHECK(it
!= map
.cend()) << "Synth solution not found for given term";
6147 return Term(this, it
->second
);
6149 CVC4_API_TRY_CATCH_END
;
6152 std::vector
<Term
> Solver::getSynthSolutions(
6153 const std::vector
<Term
>& terms
) const
6155 CVC4_API_TRY_CATCH_BEGIN
;
6156 CVC4_API_ARG_SIZE_CHECK_EXPECTED(!terms
.empty(), terms
) << "non-empty vector";
6158 for (size_t i
= 0, n
= terms
.size(); i
< n
; ++i
)
6160 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
6161 this == terms
[i
].d_solver
, "parameter term", terms
[i
], i
)
6162 << "parameter term associated to this solver object";
6163 CVC4_API_ARG_AT_INDEX_CHECK_EXPECTED(
6164 !terms
[i
].isNull(), "parameter term", terms
[i
], i
)
6168 std::map
<CVC4::Node
, CVC4::Node
> map
;
6169 CVC4_API_CHECK(d_smtEngine
->getSynthSolutions(map
))
6170 << "The solver is not in a state immediately preceded by a "
6171 "successful call to checkSynth";
6173 std::vector
<Term
> synthSolution
;
6174 synthSolution
.reserve(terms
.size());
6176 for (size_t i
= 0, n
= terms
.size(); i
< n
; ++i
)
6178 std::map
<CVC4::Node
, CVC4::Node
>::const_iterator it
=
6179 map
.find(*terms
[i
].d_node
);
6181 CVC4_API_CHECK(it
!= map
.cend())
6182 << "Synth solution not found for term at index " << i
;
6184 synthSolution
.push_back(Term(this, it
->second
));
6187 return synthSolution
;
6189 CVC4_API_TRY_CATCH_END
;
6192 void Solver::printSynthSolution(std::ostream
& out
) const
6194 CVC4_API_TRY_CATCH_BEGIN
;
6195 d_smtEngine
->printSynthSolution(out
);
6197 CVC4_API_TRY_CATCH_END
;
6201 * !!! This is only temporarily available until the parser is fully migrated to
6204 SmtEngine
* Solver::getSmtEngine(void) const { return d_smtEngine
.get(); }
6207 * !!! This is only temporarily available until the parser is fully migrated to
6210 Options
& Solver::getOptions(void) { return d_smtEngine
->getOptions(); }