1 /******************************************************************************
2 * Top contributors (to current version):
3 * Andrew Reynolds, Andres Noetzli, Morgan Deters
5 * This file is part of the cvc5 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.
11 * ****************************************************************************
13 * Definitions of SMT2 constants.
15 #include "parser/smt2/smt2.h"
19 #include "base/check.h"
20 #include "parser/antlr_input.h"
21 #include "parser/parser.h"
22 #include "parser/smt2/smt2_input.h"
24 // ANTLR defines these, which is really bad!
27 // ANTLR pulls in arpa/nameser_compat.h which defines this (again, bad!)
33 Smt2::Smt2(cvc5::Solver
* solver
,
37 : Parser(solver
, sm
, strictMode
, parseOnly
),
45 void Smt2::addArithmeticOperators() {
46 addOperator(cvc5::ADD
, "+");
47 addOperator(cvc5::SUB
, "-");
48 // cvc5::SUB is converted to cvc5::NEG if there is only a single operand
49 Parser::addOperator(cvc5::NEG
);
50 addOperator(cvc5::MULT
, "*");
51 addOperator(cvc5::LT
, "<");
52 addOperator(cvc5::LEQ
, "<=");
53 addOperator(cvc5::GT
, ">");
54 addOperator(cvc5::GEQ
, ">=");
56 if (!strictModeEnabled())
58 // NOTE: this operator is non-standard
59 addOperator(cvc5::POW
, "^");
63 void Smt2::addTranscendentalOperators()
65 addOperator(cvc5::EXPONENTIAL
, "exp");
66 addOperator(cvc5::SINE
, "sin");
67 addOperator(cvc5::COSINE
, "cos");
68 addOperator(cvc5::TANGENT
, "tan");
69 addOperator(cvc5::COSECANT
, "csc");
70 addOperator(cvc5::SECANT
, "sec");
71 addOperator(cvc5::COTANGENT
, "cot");
72 addOperator(cvc5::ARCSINE
, "arcsin");
73 addOperator(cvc5::ARCCOSINE
, "arccos");
74 addOperator(cvc5::ARCTANGENT
, "arctan");
75 addOperator(cvc5::ARCCOSECANT
, "arccsc");
76 addOperator(cvc5::ARCSECANT
, "arcsec");
77 addOperator(cvc5::ARCCOTANGENT
, "arccot");
78 addOperator(cvc5::SQRT
, "sqrt");
81 void Smt2::addQuantifiersOperators()
85 void Smt2::addBitvectorOperators() {
86 addOperator(cvc5::BITVECTOR_CONCAT
, "concat");
87 addOperator(cvc5::BITVECTOR_NOT
, "bvnot");
88 addOperator(cvc5::BITVECTOR_AND
, "bvand");
89 addOperator(cvc5::BITVECTOR_OR
, "bvor");
90 addOperator(cvc5::BITVECTOR_NEG
, "bvneg");
91 addOperator(cvc5::BITVECTOR_ADD
, "bvadd");
92 addOperator(cvc5::BITVECTOR_MULT
, "bvmul");
93 addOperator(cvc5::BITVECTOR_UDIV
, "bvudiv");
94 addOperator(cvc5::BITVECTOR_UREM
, "bvurem");
95 addOperator(cvc5::BITVECTOR_SHL
, "bvshl");
96 addOperator(cvc5::BITVECTOR_LSHR
, "bvlshr");
97 addOperator(cvc5::BITVECTOR_ULT
, "bvult");
98 addOperator(cvc5::BITVECTOR_NAND
, "bvnand");
99 addOperator(cvc5::BITVECTOR_NOR
, "bvnor");
100 addOperator(cvc5::BITVECTOR_XOR
, "bvxor");
101 addOperator(cvc5::BITVECTOR_XNOR
, "bvxnor");
102 addOperator(cvc5::BITVECTOR_COMP
, "bvcomp");
103 addOperator(cvc5::BITVECTOR_SUB
, "bvsub");
104 addOperator(cvc5::BITVECTOR_SDIV
, "bvsdiv");
105 addOperator(cvc5::BITVECTOR_SREM
, "bvsrem");
106 addOperator(cvc5::BITVECTOR_SMOD
, "bvsmod");
107 addOperator(cvc5::BITVECTOR_ASHR
, "bvashr");
108 addOperator(cvc5::BITVECTOR_ULE
, "bvule");
109 addOperator(cvc5::BITVECTOR_UGT
, "bvugt");
110 addOperator(cvc5::BITVECTOR_UGE
, "bvuge");
111 addOperator(cvc5::BITVECTOR_SLT
, "bvslt");
112 addOperator(cvc5::BITVECTOR_SLE
, "bvsle");
113 addOperator(cvc5::BITVECTOR_SGT
, "bvsgt");
114 addOperator(cvc5::BITVECTOR_SGE
, "bvsge");
115 addOperator(cvc5::BITVECTOR_REDOR
, "bvredor");
116 addOperator(cvc5::BITVECTOR_REDAND
, "bvredand");
118 addIndexedOperator(cvc5::BITVECTOR_EXTRACT
, "extract");
119 addIndexedOperator(cvc5::BITVECTOR_REPEAT
, "repeat");
120 addIndexedOperator(cvc5::BITVECTOR_ZERO_EXTEND
, "zero_extend");
121 addIndexedOperator(cvc5::BITVECTOR_SIGN_EXTEND
, "sign_extend");
122 addIndexedOperator(cvc5::BITVECTOR_ROTATE_LEFT
, "rotate_left");
123 addIndexedOperator(cvc5::BITVECTOR_ROTATE_RIGHT
, "rotate_right");
126 void Smt2::addDatatypesOperators()
128 Parser::addOperator(cvc5::APPLY_CONSTRUCTOR
);
129 Parser::addOperator(cvc5::APPLY_TESTER
);
130 Parser::addOperator(cvc5::APPLY_SELECTOR
);
132 if (!strictModeEnabled())
134 Parser::addOperator(cvc5::APPLY_UPDATER
);
135 // Notice that tuple operators, we use the generic APPLY_SELECTOR and
136 // APPLY_UPDATER kinds. These are processed based on the context
137 // in which they are parsed, e.g. when parsing identifiers.
138 addIndexedOperator(cvc5::APPLY_SELECTOR
, "tuple.select");
139 addIndexedOperator(cvc5::APPLY_UPDATER
, "tuple.update");
143 void Smt2::addStringOperators() {
144 defineVar("re.all", getSolver()->mkRegexpAll());
145 addOperator(cvc5::STRING_CONCAT
, "str.++");
146 addOperator(cvc5::STRING_LENGTH
, "str.len");
147 addOperator(cvc5::STRING_SUBSTR
, "str.substr");
148 addOperator(cvc5::STRING_CONTAINS
, "str.contains");
149 addOperator(cvc5::STRING_CHARAT
, "str.at");
150 addOperator(cvc5::STRING_INDEXOF
, "str.indexof");
151 addOperator(cvc5::STRING_REPLACE
, "str.replace");
152 addOperator(cvc5::STRING_PREFIX
, "str.prefixof");
153 addOperator(cvc5::STRING_SUFFIX
, "str.suffixof");
154 addOperator(cvc5::STRING_FROM_CODE
, "str.from_code");
155 addOperator(cvc5::STRING_IS_DIGIT
, "str.is_digit");
156 addOperator(cvc5::STRING_REPLACE_RE
, "str.replace_re");
157 addOperator(cvc5::STRING_REPLACE_RE_ALL
, "str.replace_re_all");
158 if (!strictModeEnabled())
160 addOperator(cvc5::STRING_INDEXOF_RE
, "str.indexof_re");
161 addOperator(cvc5::STRING_UPDATE
, "str.update");
162 addOperator(cvc5::STRING_TO_LOWER
, "str.to_lower");
163 addOperator(cvc5::STRING_TO_UPPER
, "str.to_upper");
164 addOperator(cvc5::STRING_REV
, "str.rev");
166 addOperator(cvc5::SEQ_CONCAT
, "seq.++");
167 addOperator(cvc5::SEQ_LENGTH
, "seq.len");
168 addOperator(cvc5::SEQ_EXTRACT
, "seq.extract");
169 addOperator(cvc5::SEQ_UPDATE
, "seq.update");
170 addOperator(cvc5::SEQ_AT
, "seq.at");
171 addOperator(cvc5::SEQ_CONTAINS
, "seq.contains");
172 addOperator(cvc5::SEQ_INDEXOF
, "seq.indexof");
173 addOperator(cvc5::SEQ_REPLACE
, "seq.replace");
174 addOperator(cvc5::SEQ_PREFIX
, "seq.prefixof");
175 addOperator(cvc5::SEQ_SUFFIX
, "seq.suffixof");
176 addOperator(cvc5::SEQ_REV
, "seq.rev");
177 addOperator(cvc5::SEQ_REPLACE_ALL
, "seq.replace_all");
178 addOperator(cvc5::SEQ_UNIT
, "seq.unit");
179 addOperator(cvc5::SEQ_NTH
, "seq.nth");
181 addOperator(cvc5::STRING_FROM_INT
, "str.from_int");
182 addOperator(cvc5::STRING_TO_INT
, "str.to_int");
183 addOperator(cvc5::STRING_IN_REGEXP
, "str.in_re");
184 addOperator(cvc5::STRING_TO_REGEXP
, "str.to_re");
185 addOperator(cvc5::STRING_TO_CODE
, "str.to_code");
186 addOperator(cvc5::STRING_REPLACE_ALL
, "str.replace_all");
188 addOperator(cvc5::REGEXP_CONCAT
, "re.++");
189 addOperator(cvc5::REGEXP_UNION
, "re.union");
190 addOperator(cvc5::REGEXP_INTER
, "re.inter");
191 addOperator(cvc5::REGEXP_STAR
, "re.*");
192 addOperator(cvc5::REGEXP_PLUS
, "re.+");
193 addOperator(cvc5::REGEXP_OPT
, "re.opt");
194 addIndexedOperator(cvc5::REGEXP_REPEAT
, "re.^");
195 addIndexedOperator(cvc5::REGEXP_LOOP
, "re.loop");
196 addOperator(cvc5::REGEXP_RANGE
, "re.range");
197 addOperator(cvc5::REGEXP_COMPLEMENT
, "re.comp");
198 addOperator(cvc5::REGEXP_DIFF
, "re.diff");
199 addOperator(cvc5::STRING_LT
, "str.<");
200 addOperator(cvc5::STRING_LEQ
, "str.<=");
203 void Smt2::addFloatingPointOperators() {
204 addOperator(cvc5::FLOATINGPOINT_FP
, "fp");
205 addOperator(cvc5::FLOATINGPOINT_EQ
, "fp.eq");
206 addOperator(cvc5::FLOATINGPOINT_ABS
, "fp.abs");
207 addOperator(cvc5::FLOATINGPOINT_NEG
, "fp.neg");
208 addOperator(cvc5::FLOATINGPOINT_ADD
, "fp.add");
209 addOperator(cvc5::FLOATINGPOINT_SUB
, "fp.sub");
210 addOperator(cvc5::FLOATINGPOINT_MULT
, "fp.mul");
211 addOperator(cvc5::FLOATINGPOINT_DIV
, "fp.div");
212 addOperator(cvc5::FLOATINGPOINT_FMA
, "fp.fma");
213 addOperator(cvc5::FLOATINGPOINT_SQRT
, "fp.sqrt");
214 addOperator(cvc5::FLOATINGPOINT_REM
, "fp.rem");
215 addOperator(cvc5::FLOATINGPOINT_RTI
, "fp.roundToIntegral");
216 addOperator(cvc5::FLOATINGPOINT_MIN
, "fp.min");
217 addOperator(cvc5::FLOATINGPOINT_MAX
, "fp.max");
218 addOperator(cvc5::FLOATINGPOINT_LEQ
, "fp.leq");
219 addOperator(cvc5::FLOATINGPOINT_LT
, "fp.lt");
220 addOperator(cvc5::FLOATINGPOINT_GEQ
, "fp.geq");
221 addOperator(cvc5::FLOATINGPOINT_GT
, "fp.gt");
222 addOperator(cvc5::FLOATINGPOINT_IS_NORMAL
, "fp.isNormal");
223 addOperator(cvc5::FLOATINGPOINT_IS_SUBNORMAL
, "fp.isSubnormal");
224 addOperator(cvc5::FLOATINGPOINT_IS_ZERO
, "fp.isZero");
225 addOperator(cvc5::FLOATINGPOINT_IS_INF
, "fp.isInfinite");
226 addOperator(cvc5::FLOATINGPOINT_IS_NAN
, "fp.isNaN");
227 addOperator(cvc5::FLOATINGPOINT_IS_NEG
, "fp.isNegative");
228 addOperator(cvc5::FLOATINGPOINT_IS_POS
, "fp.isPositive");
229 addOperator(cvc5::FLOATINGPOINT_TO_REAL
, "fp.to_real");
231 addIndexedOperator(cvc5::UNDEFINED_KIND
, "to_fp");
232 addIndexedOperator(cvc5::FLOATINGPOINT_TO_FP_FROM_UBV
, "to_fp_unsigned");
233 addIndexedOperator(cvc5::FLOATINGPOINT_TO_UBV
, "fp.to_ubv");
234 addIndexedOperator(cvc5::FLOATINGPOINT_TO_SBV
, "fp.to_sbv");
236 if (!strictModeEnabled())
238 addIndexedOperator(cvc5::FLOATINGPOINT_TO_FP_FROM_IEEE_BV
, "to_fp_bv");
239 addIndexedOperator(cvc5::FLOATINGPOINT_TO_FP_FROM_FP
, "to_fp_fp");
240 addIndexedOperator(cvc5::FLOATINGPOINT_TO_FP_FROM_REAL
, "to_fp_real");
241 addIndexedOperator(cvc5::FLOATINGPOINT_TO_FP_FROM_SBV
, "to_fp_signed");
245 void Smt2::addSepOperators() {
246 defineVar("sep.emp", d_solver
->mkSepEmp());
247 // the Boolean sort is a placeholder here since we don't have type info
248 // without type annotation
249 defineVar("sep.nil", d_solver
->mkSepNil(d_solver
->getBooleanSort()));
250 addOperator(cvc5::SEP_STAR
, "sep");
251 addOperator(cvc5::SEP_PTO
, "pto");
252 addOperator(cvc5::SEP_WAND
, "wand");
253 Parser::addOperator(cvc5::SEP_STAR
);
254 Parser::addOperator(cvc5::SEP_PTO
);
255 Parser::addOperator(cvc5::SEP_WAND
);
258 void Smt2::addCoreSymbols()
260 defineType("Bool", d_solver
->getBooleanSort(), true);
261 defineVar("true", d_solver
->mkTrue(), true);
262 defineVar("false", d_solver
->mkFalse(), true);
263 addOperator(cvc5::AND
, "and");
264 addOperator(cvc5::DISTINCT
, "distinct");
265 addOperator(cvc5::EQUAL
, "=");
266 addOperator(cvc5::IMPLIES
, "=>");
267 addOperator(cvc5::ITE
, "ite");
268 addOperator(cvc5::NOT
, "not");
269 addOperator(cvc5::OR
, "or");
270 addOperator(cvc5::XOR
, "xor");
273 void Smt2::addOperator(cvc5::Kind kind
, const std::string
& name
)
275 Trace("parser") << "Smt2::addOperator( " << kind
<< ", " << name
<< " )"
277 Parser::addOperator(kind
);
278 d_operatorKindMap
[name
] = kind
;
281 void Smt2::addIndexedOperator(cvc5::Kind tKind
, const std::string
& name
)
283 Parser::addOperator(tKind
);
284 d_indexedOpKindMap
[name
] = tKind
;
287 bool Smt2::isIndexedOperatorEnabled(const std::string
& name
) const
289 return d_indexedOpKindMap
.find(name
) != d_indexedOpKindMap
.end();
292 cvc5::Kind
Smt2::getOperatorKind(const std::string
& name
) const
294 // precondition: isOperatorEnabled(name)
295 return d_operatorKindMap
.find(name
)->second
;
298 bool Smt2::isOperatorEnabled(const std::string
& name
) const {
299 return d_operatorKindMap
.find(name
) != d_operatorKindMap
.end();
302 modes::BlockModelsMode
Smt2::getBlockModelsMode(const std::string
& mode
)
304 if (mode
== "literals")
306 return modes::BlockModelsMode::LITERALS
;
308 else if (mode
== "values")
310 return modes::BlockModelsMode::VALUES
;
312 parseError(std::string("Unknown block models mode `") + mode
+ "'");
313 return modes::BlockModelsMode::LITERALS
;
316 bool Smt2::isTheoryEnabled(internal::theory::TheoryId theory
) const
318 return d_logic
.isTheoryEnabled(theory
);
321 bool Smt2::isHoEnabled() const { return d_logic
.isHigherOrder(); }
323 bool Smt2::hasCardinalityConstraints() const { return d_logic
.hasCardinalityConstraints(); }
325 bool Smt2::logicIsSet() {
329 bool Smt2::getTesterName(cvc5::Term cons
, std::string
& name
)
331 if ((v2_6() || sygus()) && strictModeEnabled())
333 // 2.6 or above uses indexed tester symbols, if we are in strict mode,
334 // we do not automatically define is-cons for constructor cons.
337 std::stringstream ss
;
343 cvc5::Term
Smt2::mkIndexedConstant(const std::string
& name
,
344 const std::vector
<uint32_t>& numerals
)
346 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_FP
))
350 return d_solver
->mkFloatingPointPosInf(numerals
[0], numerals
[1]);
352 else if (name
== "-oo")
354 return d_solver
->mkFloatingPointNegInf(numerals
[0], numerals
[1]);
356 else if (name
== "NaN")
358 return d_solver
->mkFloatingPointNaN(numerals
[0], numerals
[1]);
360 else if (name
== "+zero")
362 return d_solver
->mkFloatingPointPosZero(numerals
[0], numerals
[1]);
364 else if (name
== "-zero")
366 return d_solver
->mkFloatingPointNegZero(numerals
[0], numerals
[1]);
370 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_BV
)
371 && name
.find("bv") == 0)
373 std::string bvStr
= name
.substr(2);
374 return d_solver
->mkBitVector(numerals
[0], bvStr
, 10);
377 // NOTE: Theory parametric constants go here
379 parseError(std::string("Unknown indexed literal `") + name
+ "'");
383 cvc5::Kind
Smt2::getIndexedOpKind(const std::string
& name
)
385 const auto& kIt
= d_indexedOpKindMap
.find(name
);
386 if (kIt
!= d_indexedOpKindMap
.end())
388 return (*kIt
).second
;
390 parseError(std::string("Unknown indexed function `") + name
+ "'");
391 return cvc5::UNDEFINED_KIND
;
394 cvc5::Term
Smt2::bindDefineFunRec(
395 const std::string
& fname
,
396 const std::vector
<std::pair
<std::string
, cvc5::Sort
>>& sortedVarNames
,
398 std::vector
<cvc5::Term
>& flattenVars
)
400 std::vector
<cvc5::Sort
> sorts
;
401 for (const std::pair
<std::string
, cvc5::Sort
>& svn
: sortedVarNames
)
403 sorts
.push_back(svn
.second
);
406 // make the flattened function type, add bound variables
407 // to flattenVars if the defined function was given a function return type.
408 cvc5::Sort ft
= mkFlatFunctionType(sorts
, t
, flattenVars
);
411 return bindVar(fname
, ft
, true);
414 void Smt2::pushDefineFunRecScope(
415 const std::vector
<std::pair
<std::string
, cvc5::Sort
>>& sortedVarNames
,
417 const std::vector
<cvc5::Term
>& flattenVars
,
418 std::vector
<cvc5::Term
>& bvs
)
422 // bound variables are those that are explicitly named in the preamble
423 // of the define-fun(s)-rec command, we define them here
424 for (const std::pair
<std::string
, cvc5::Sort
>& svn
: sortedVarNames
)
426 cvc5::Term v
= bindBoundVar(svn
.first
, svn
.second
);
430 bvs
.insert(bvs
.end(), flattenVars
.begin(), flattenVars
.end());
435 d_seenSetLogic
= false;
436 d_logic
= internal::LogicInfo();
437 d_operatorKindMap
.clear();
438 d_lastNamedTerm
= std::pair
<cvc5::Term
, std::string
>();
441 std::unique_ptr
<Command
> Smt2::invConstraint(
442 const std::vector
<std::string
>& names
)
444 checkThatLogicIsSet();
445 Trace("parser-sygus") << "Sygus : define sygus funs..." << std::endl
;
446 Trace("parser-sygus") << "Sygus : read inv-constraint..." << std::endl
;
448 if (names
.size() != 4)
451 "Bad syntax for inv-constraint: expected 4 "
455 std::vector
<cvc5::Term
> terms
;
456 for (const std::string
& name
: names
)
458 if (!isDeclared(name
))
460 std::stringstream ss
;
461 ss
<< "Function " << name
<< " in inv-constraint is not defined.";
462 parseError(ss
.str());
465 terms
.push_back(getVariable(name
));
468 return std::unique_ptr
<Command
>(new SygusInvConstraintCommand(terms
));
471 Command
* Smt2::setLogic(std::string name
, bool fromCommand
)
477 parseError("Only one set-logic is allowed.");
479 d_seenSetLogic
= true;
483 // If the logic is forced, we ignore all set-logic requests from commands.
484 return new EmptyCommand();
491 // if sygus is enabled, we must enable UF, datatypes, and integer arithmetic
493 if (!d_logic
.isQuantified())
495 warning("Logics in sygus are assumed to contain quantifiers.");
496 warning("Omit QF_ from the logic to avoid this warning.");
500 // Core theory belongs to every logic
503 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_UF
))
505 Parser::addOperator(cvc5::APPLY_UF
);
508 if (d_logic
.isHigherOrder())
510 addOperator(cvc5::HO_APPLY
, "@");
513 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_ARITH
))
515 if(d_logic
.areIntegersUsed()) {
516 defineType("Int", d_solver
->getIntegerSort(), true);
517 addArithmeticOperators();
518 if (!strictModeEnabled() || !d_logic
.isLinear())
520 addOperator(cvc5::INTS_DIVISION
, "div");
521 addOperator(cvc5::INTS_MODULUS
, "mod");
522 addOperator(cvc5::ABS
, "abs");
524 addIndexedOperator(cvc5::DIVISIBLE
, "divisible");
527 if (d_logic
.areRealsUsed())
529 defineType("Real", d_solver
->getRealSort(), true);
530 addArithmeticOperators();
531 addOperator(cvc5::DIVISION
, "/");
532 if (!strictModeEnabled())
534 addOperator(cvc5::ABS
, "abs");
538 if (d_logic
.areIntegersUsed() && d_logic
.areRealsUsed())
540 addOperator(cvc5::TO_INTEGER
, "to_int");
541 addOperator(cvc5::IS_INTEGER
, "is_int");
542 addOperator(cvc5::TO_REAL
, "to_real");
545 if (d_logic
.areTranscendentalsUsed())
547 defineVar("real.pi", d_solver
->mkPi());
548 addTranscendentalOperators();
550 if (!strictModeEnabled())
552 // integer version of AND
553 addIndexedOperator(cvc5::IAND
, "iand");
555 addOperator(cvc5::POW2
, "int.pow2");
559 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_ARRAYS
))
561 addOperator(cvc5::SELECT
, "select");
562 addOperator(cvc5::STORE
, "store");
563 addOperator(cvc5::EQ_RANGE
, "eqrange");
566 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_BV
))
568 addBitvectorOperators();
570 if (!strictModeEnabled()
571 && d_logic
.isTheoryEnabled(internal::theory::THEORY_ARITH
)
572 && d_logic
.areIntegersUsed())
574 // Conversions between bit-vectors and integers
575 addOperator(cvc5::BITVECTOR_TO_NAT
, "bv2nat");
576 addIndexedOperator(cvc5::INT_TO_BITVECTOR
, "int2bv");
580 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_DATATYPES
))
582 const std::vector
<cvc5::Sort
> types
;
583 defineType("Tuple", d_solver
->mkTupleSort(types
), true);
584 addDatatypesOperators();
587 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_SETS
))
589 defineVar("set.empty", d_solver
->mkEmptySet(d_solver
->getNullSort()));
590 // the Boolean sort is a placeholder here since we don't have type info
591 // without type annotation
592 defineVar("set.universe",
593 d_solver
->mkUniverseSet(d_solver
->getBooleanSort()));
595 addOperator(cvc5::SET_UNION
, "set.union");
596 addOperator(cvc5::SET_INTER
, "set.inter");
597 addOperator(cvc5::SET_MINUS
, "set.minus");
598 addOperator(cvc5::SET_SUBSET
, "set.subset");
599 addOperator(cvc5::SET_MEMBER
, "set.member");
600 addOperator(cvc5::SET_SINGLETON
, "set.singleton");
601 addOperator(cvc5::SET_INSERT
, "set.insert");
602 addOperator(cvc5::SET_CARD
, "set.card");
603 addOperator(cvc5::SET_COMPLEMENT
, "set.complement");
604 addOperator(cvc5::SET_CHOOSE
, "set.choose");
605 addOperator(cvc5::SET_IS_SINGLETON
, "set.is_singleton");
606 addOperator(cvc5::SET_MAP
, "set.map");
607 addOperator(cvc5::RELATION_JOIN
, "rel.join");
608 addOperator(cvc5::RELATION_PRODUCT
, "rel.product");
609 addOperator(cvc5::RELATION_TRANSPOSE
, "rel.transpose");
610 addOperator(cvc5::RELATION_TCLOSURE
, "rel.tclosure");
611 addOperator(cvc5::RELATION_JOIN_IMAGE
, "rel.join_image");
612 addOperator(cvc5::RELATION_IDEN
, "rel.iden");
615 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_BAGS
))
617 defineVar("bag.empty", d_solver
->mkEmptyBag(d_solver
->getNullSort()));
618 addOperator(cvc5::BAG_UNION_MAX
, "bag.union_max");
619 addOperator(cvc5::BAG_UNION_DISJOINT
, "bag.union_disjoint");
620 addOperator(cvc5::BAG_INTER_MIN
, "bag.inter_min");
621 addOperator(cvc5::BAG_DIFFERENCE_SUBTRACT
, "bag.difference_subtract");
622 addOperator(cvc5::BAG_DIFFERENCE_REMOVE
, "bag.difference_remove");
623 addOperator(cvc5::BAG_SUBBAG
, "bag.subbag");
624 addOperator(cvc5::BAG_COUNT
, "bag.count");
625 addOperator(cvc5::BAG_MEMBER
, "bag.member");
626 addOperator(cvc5::BAG_DUPLICATE_REMOVAL
, "bag.duplicate_removal");
627 addOperator(cvc5::BAG_MAKE
, "bag");
628 addOperator(cvc5::BAG_CARD
, "bag.card");
629 addOperator(cvc5::BAG_CHOOSE
, "bag.choose");
630 addOperator(cvc5::BAG_IS_SINGLETON
, "bag.is_singleton");
631 addOperator(cvc5::BAG_FROM_SET
, "bag.from_set");
632 addOperator(cvc5::BAG_TO_SET
, "bag.to_set");
633 addOperator(cvc5::BAG_MAP
, "bag.map");
634 addOperator(cvc5::BAG_FILTER
, "bag.filter");
635 addOperator(cvc5::BAG_FOLD
, "bag.fold");
636 addOperator(cvc5::TABLE_PRODUCT
, "table.product");
638 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_STRINGS
))
640 defineType("String", d_solver
->getStringSort(), true);
641 defineType("RegLan", d_solver
->getRegExpSort(), true);
642 defineType("Int", d_solver
->getIntegerSort(), true);
644 defineVar("re.none", d_solver
->mkRegexpNone());
645 defineVar("re.allchar", d_solver
->mkRegexpAllchar());
647 // Boolean is a placeholder
648 defineVar("seq.empty",
649 d_solver
->mkEmptySequence(d_solver
->getBooleanSort()));
651 addStringOperators();
654 if(d_logic
.isQuantified()) {
655 addQuantifiersOperators();
658 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_FP
))
660 defineType("RoundingMode", d_solver
->getRoundingModeSort(), true);
661 defineType("Float16", d_solver
->mkFloatingPointSort(5, 11), true);
662 defineType("Float32", d_solver
->mkFloatingPointSort(8, 24), true);
663 defineType("Float64", d_solver
->mkFloatingPointSort(11, 53), true);
664 defineType("Float128", d_solver
->mkFloatingPointSort(15, 113), true);
667 d_solver
->mkRoundingMode(cvc5::ROUND_NEAREST_TIES_TO_EVEN
));
668 defineVar("roundNearestTiesToEven",
669 d_solver
->mkRoundingMode(cvc5::ROUND_NEAREST_TIES_TO_EVEN
));
671 d_solver
->mkRoundingMode(cvc5::ROUND_NEAREST_TIES_TO_AWAY
));
672 defineVar("roundNearestTiesToAway",
673 d_solver
->mkRoundingMode(cvc5::ROUND_NEAREST_TIES_TO_AWAY
));
674 defineVar("RTP", d_solver
->mkRoundingMode(cvc5::ROUND_TOWARD_POSITIVE
));
675 defineVar("roundTowardPositive",
676 d_solver
->mkRoundingMode(cvc5::ROUND_TOWARD_POSITIVE
));
677 defineVar("RTN", d_solver
->mkRoundingMode(cvc5::ROUND_TOWARD_NEGATIVE
));
678 defineVar("roundTowardNegative",
679 d_solver
->mkRoundingMode(cvc5::ROUND_TOWARD_NEGATIVE
));
680 defineVar("RTZ", d_solver
->mkRoundingMode(cvc5::ROUND_TOWARD_ZERO
));
681 defineVar("roundTowardZero",
682 d_solver
->mkRoundingMode(cvc5::ROUND_TOWARD_ZERO
));
684 addFloatingPointOperators();
687 if (d_logic
.isTheoryEnabled(internal::theory::THEORY_SEP
))
692 // builtin symbols of the logic are declared at context level zero, hence
693 // we push the outermost scope here
696 std::string logic
= sygus() ? d_logic
.getLogicString() : name
;
699 // If not from a command, just set the logic directly. Notice this is
700 // important since we do not want to enqueue a set-logic command and
701 // fully initialize the underlying SolverEngine in the meantime before the
702 // command has a chance to execute, which would lead to an error.
703 d_solver
->setLogic(logic
);
706 Command
* cmd
= new SetBenchmarkLogicCommand(logic
);
708 } /* Smt2::setLogic() */
710 cvc5::Grammar
* Smt2::mkGrammar(const std::vector
<cvc5::Term
>& boundVars
,
711 const std::vector
<cvc5::Term
>& ntSymbols
)
713 d_allocGrammars
.emplace_back(
714 new cvc5::Grammar(d_solver
->mkSygusGrammar(boundVars
, ntSymbols
)));
715 return d_allocGrammars
.back().get();
718 bool Smt2::sygus() const
720 return d_solver
->getOption("input-language") == "LANG_SYGUS_V2";
723 void Smt2::checkThatLogicIsSet()
727 if (strictModeEnabled())
729 parseError("set-logic must appear before this point.");
733 // the calls to setLogic below set the logic on the solver directly
736 setLogic(getForcedLogic(), false);
740 warning("No set-logic command was given before this point.");
741 warning("cvc5 will make all theories available.");
743 "Consider setting a stricter logic for (likely) better "
745 warning("To suppress this warning in the future use (set-logic ALL).");
747 setLogic("ALL", false);
753 void Smt2::checkLogicAllowsFreeSorts()
755 if (!d_logic
.isTheoryEnabled(internal::theory::THEORY_UF
)
756 && !d_logic
.isTheoryEnabled(internal::theory::THEORY_ARRAYS
)
757 && !d_logic
.isTheoryEnabled(internal::theory::THEORY_DATATYPES
)
758 && !d_logic
.isTheoryEnabled(internal::theory::THEORY_SETS
)
759 && !d_logic
.isTheoryEnabled(internal::theory::THEORY_BAGS
))
761 parseErrorLogic("Free sort symbols not allowed in ");
765 void Smt2::checkLogicAllowsFunctions()
767 if (!d_logic
.isTheoryEnabled(internal::theory::THEORY_UF
) && !isHoEnabled())
770 "Functions (of non-zero arity) cannot "
771 "be declared in logic "
772 + d_logic
.getLogicString()
773 + ". Try including UF or adding the prefix HO_.");
777 /* The include are managed in the lexer but called in the parser */
778 // Inspired by http://www.antlr3.org/api/C/interop.html
780 static bool newInputStream(const std::string
& filename
, pANTLR3_LEXER lexer
) {
781 Trace("parser") << "Including " << filename
<< std::endl
;
782 // Create a new input stream and take advantage of built in stream stacking
783 // in C target runtime.
785 pANTLR3_INPUT_STREAM in
;
786 #ifdef CVC5_ANTLR3_OLD_INPUT_STREAM
787 in
= antlr3AsciiFileStreamNew((pANTLR3_UINT8
) filename
.c_str());
788 #else /* CVC5_ANTLR3_OLD_INPUT_STREAM */
789 in
= antlr3FileStreamNew((pANTLR3_UINT8
) filename
.c_str(), ANTLR3_ENC_8BIT
);
790 #endif /* CVC5_ANTLR3_OLD_INPUT_STREAM */
792 Trace("parser") << "Can't open " << filename
<< std::endl
;
795 // Same thing as the predefined PUSHSTREAM(in);
796 lexer
->pushCharStream(lexer
, in
);
798 //lexer->rec->state->tokenStartCharIndex = -10;
799 //lexer->emit(lexer);
801 // Note that the input stream is not closed when it EOFs, I don't bother
802 // to do it here, but it is up to you to track streams created like this
803 // and destroy them when the whole parse session is complete. Remember that you
804 // don't want to do this until all tokens have been manipulated all the way through
805 // your tree parsers etc as the token does not store the text it just refers
806 // back to the input stream and trying to get the text for it will abort if you
807 // close the input stream too early.
809 //TODO what said before
813 void Smt2::includeFile(const std::string
& filename
) {
814 // security for online version
815 if(!canIncludeFile()) {
816 parseError("include-file feature was disabled for this run.");
820 AntlrInput
* ai
= static_cast<AntlrInput
*>(getInput());
821 pANTLR3_LEXER lexer
= ai
->getAntlr3Lexer();
822 // get the name of the current stream "Does it work inside an include?"
823 const std::string inputName
= ai
->getInputStreamName();
825 // Find the directory of the current input file
827 size_t pos
= inputName
.rfind('/');
828 if(pos
!= std::string::npos
) {
829 path
= std::string(inputName
, 0, pos
+ 1);
831 path
.append(filename
);
832 if(!newInputStream(path
, lexer
)) {
833 parseError("Couldn't open include file `" + path
+ "'");
836 bool Smt2::isAbstractValue(const std::string
& name
)
838 return name
.length() >= 2 && name
[0] == '@' && name
[1] != '0'
839 && name
.find_first_not_of("0123456789", 1) == std::string::npos
;
842 void Smt2::parseOpApplyTypeAscription(ParseOp
& p
, cvc5::Sort type
)
844 Trace("parser") << "parseOpApplyTypeAscription : " << p
<< " " << type
846 // (as const (Array T1 T2))
847 if (p
.d_kind
== cvc5::CONST_ARRAY
)
851 std::stringstream ss
;
852 ss
<< "expected array constant term, but cast is not of array type"
854 << "cast type: " << type
;
855 parseError(ss
.str());
860 if (p
.d_expr
.isNull())
862 Trace("parser-overloading")
863 << "Getting variable expression with name " << p
.d_name
<< " and type "
864 << type
<< std::endl
;
865 // get the variable expression for the type
866 if (isDeclared(p
.d_name
, SYM_VARIABLE
))
868 p
.d_expr
= getExpressionForNameAndType(p
.d_name
, type
);
869 p
.d_name
= std::string("");
871 if (p
.d_expr
.isNull())
873 std::stringstream ss
;
874 ss
<< "Could not resolve expression with name " << p
.d_name
875 << " and type " << type
<< std::endl
;
876 parseError(ss
.str());
879 Trace("parser-qid") << "Resolve ascription " << type
<< " on " << p
.d_expr
;
880 Trace("parser-qid") << " " << p
.d_expr
.getKind() << " " << p
.d_expr
.getSort();
881 Trace("parser-qid") << std::endl
;
882 // otherwise, we process the type ascription
883 p
.d_expr
= applyTypeAscription(p
.d_expr
, type
);
886 cvc5::Term
Smt2::parseOpToExpr(ParseOp
& p
)
888 Trace("parser") << "parseOpToExpr: " << p
<< std::endl
;
890 if (p
.d_kind
!= cvc5::NULL_TERM
|| !p
.d_type
.isNull())
893 "Bad syntax for qualified identifier operator in term position.");
895 else if (!p
.d_expr
.isNull())
899 else if (!isDeclared(p
.d_name
, SYM_VARIABLE
))
901 std::stringstream ss
;
902 ss
<< "Symbol " << p
.d_name
<< " is not declared.";
903 parseError(ss
.str());
907 expr
= getExpressionForName(p
.d_name
);
909 Assert(!expr
.isNull());
913 cvc5::Term
Smt2::applyParseOp(ParseOp
& p
, std::vector
<cvc5::Term
>& args
)
915 bool isBuiltinOperator
= false;
916 // the builtin kind of the overall return expression
917 cvc5::Kind kind
= cvc5::NULL_TERM
;
918 // First phase: process the operator
919 if (TraceIsOn("parser"))
921 Trace("parser") << "applyParseOp: " << p
<< " to:" << std::endl
;
922 for (std::vector
<cvc5::Term
>::iterator i
= args
.begin(); i
!= args
.end();
925 Trace("parser") << "++ " << *i
<< std::endl
;
929 if (p
.d_kind
== cvc5::UNDEFINED_KIND
&& isIndexedOperatorEnabled(p
.d_name
))
931 // Resolve indexed symbols that cannot be resolved without knowing the type
932 // of the arguments. This is currently limited to `to_fp`.
933 Assert(p
.d_name
== "to_fp");
934 size_t nchildren
= args
.size();
937 kind
= cvc5::FLOATINGPOINT_TO_FP_FROM_IEEE_BV
;
938 op
= d_solver
->mkOp(kind
, p
.d_indices
);
940 else if (nchildren
> 2)
942 std::stringstream ss
;
943 ss
<< "Wrong number of arguments for indexed operator to_fp, expected "
946 parseError(ss
.str());
948 else if (!args
[0].getSort().isRoundingMode())
950 std::stringstream ss
;
951 ss
<< "Expected a rounding mode as the first argument, got "
952 << args
[0].getSort();
953 parseError(ss
.str());
957 cvc5::Sort t
= args
[1].getSort();
959 if (t
.isFloatingPoint())
961 kind
= cvc5::FLOATINGPOINT_TO_FP_FROM_FP
;
962 op
= d_solver
->mkOp(kind
, p
.d_indices
);
964 else if (t
.isInteger() || t
.isReal())
966 kind
= cvc5::FLOATINGPOINT_TO_FP_FROM_REAL
;
967 op
= d_solver
->mkOp(kind
, p
.d_indices
);
971 kind
= cvc5::FLOATINGPOINT_TO_FP_FROM_SBV
;
972 op
= d_solver
->mkOp(kind
, p
.d_indices
);
976 else if (p
.d_kind
!= cvc5::NULL_TERM
)
978 // It is a special case, e.g. tuple.select or array constant specification.
979 // We have to wait until the arguments are parsed to resolve it.
981 else if (!p
.d_expr
.isNull())
983 // An explicit operator, e.g. an apply function
984 cvc5::Kind fkind
= getKindForFunction(p
.d_expr
);
985 if (fkind
!= cvc5::UNDEFINED_KIND
)
987 // Some operators may require a specific kind.
988 // Testers are handled differently than other indexed operators,
989 // since they require a kind.
991 Trace("parser") << "Got function kind " << kind
<< " for expression "
994 args
.insert(args
.begin(), p
.d_expr
);
996 else if (!p
.d_op
.isNull())
998 // it was given an operator
1003 isBuiltinOperator
= isOperatorEnabled(p
.d_name
);
1004 if (isBuiltinOperator
)
1006 // a builtin operator, convert to kind
1007 kind
= getOperatorKind(p
.d_name
);
1008 Trace("parser") << "Got builtin kind " << kind
<< " for name"
1013 // A non-built-in function application, get the expression
1014 checkDeclaration(p
.d_name
, CHECK_DECLARED
, SYM_VARIABLE
);
1015 cvc5::Term v
= getVariable(p
.d_name
);
1018 checkFunctionLike(v
);
1019 kind
= getKindForFunction(v
);
1020 args
.insert(args
.begin(), v
);
1024 // Overloaded symbol?
1025 // Could not find the expression. It may be an overloaded symbol,
1026 // in which case we may find it after knowing the types of its
1028 std::vector
<cvc5::Sort
> argTypes
;
1029 for (std::vector
<cvc5::Term
>::iterator i
= args
.begin();
1033 argTypes
.push_back((*i
).getSort());
1035 cvc5::Term fop
= getOverloadedFunctionForTypes(p
.d_name
, argTypes
);
1038 checkFunctionLike(fop
);
1039 kind
= getKindForFunction(fop
);
1040 args
.insert(args
.begin(), fop
);
1045 "Cannot find unambiguous overloaded function for argument "
1051 // handle special cases
1052 if (p
.d_kind
== cvc5::CONST_ARRAY
&& !p
.d_type
.isNull())
1054 if (args
.size() != 1)
1056 parseError("Too many arguments to array constant.");
1058 cvc5::Term constVal
= args
[0];
1060 if (p
.d_type
.getArrayElementSort() != constVal
.getSort())
1062 std::stringstream ss
;
1063 ss
<< "type mismatch inside array constant term:" << std::endl
1064 << "array type: " << p
.d_type
<< std::endl
1065 << "expected const type: " << p
.d_type
.getArrayElementSort()
1067 << "computed const type: " << constVal
.getSort();
1068 parseError(ss
.str());
1070 cvc5::Term ret
= d_solver
->mkConstArray(p
.d_type
, constVal
);
1071 Trace("parser") << "applyParseOp: return store all " << ret
<< std::endl
;
1074 else if ((p
.d_kind
== cvc5::APPLY_SELECTOR
|| p
.d_kind
== cvc5::APPLY_UPDATER
)
1075 && !p
.d_expr
.isNull())
1077 // tuple selector case
1078 if (!p
.d_expr
.isUInt64Value())
1081 "index of tuple select or update is larger than size of uint64_t");
1083 uint64_t n
= p
.d_expr
.getUInt64Value();
1084 if (args
.size() != (p
.d_kind
== cvc5::APPLY_SELECTOR
? 1 : 2))
1086 parseError("wrong number of arguments for tuple select or update");
1088 cvc5::Sort t
= args
[0].getSort();
1091 parseError("tuple select or update applied to non-tuple");
1093 size_t length
= t
.getTupleLength();
1096 std::stringstream ss
;
1097 ss
<< "tuple is of length " << length
<< "; cannot access index " << n
;
1098 parseError(ss
.str());
1100 const cvc5::Datatype
& dt
= t
.getDatatype();
1102 if (p
.d_kind
== cvc5::APPLY_SELECTOR
)
1105 d_solver
->mkTerm(cvc5::APPLY_SELECTOR
, {dt
[0][n
].getTerm(), args
[0]});
1109 ret
= d_solver
->mkTerm(cvc5::APPLY_UPDATER
,
1110 {dt
[0][n
].getUpdaterTerm(), args
[0], args
[1]});
1112 Trace("parser") << "applyParseOp: return selector " << ret
<< std::endl
;
1115 else if (p
.d_kind
== cvc5::TUPLE_PROJECT
)
1117 cvc5::Term ret
= d_solver
->mkTerm(p
.d_op
, args
);
1118 Trace("parser") << "applyParseOp: return projection " << ret
<< std::endl
;
1121 else if (p
.d_kind
!= cvc5::NULL_TERM
)
1123 // it should not have an expression or type specified at this point
1124 if (!p
.d_expr
.isNull() || !p
.d_type
.isNull())
1126 std::stringstream ss
;
1127 ss
<< "Could not process parsed qualified identifier kind " << p
.d_kind
;
1128 parseError(ss
.str());
1130 // otherwise it is a simple application
1133 else if (isBuiltinOperator
)
1135 if (!isHoEnabled() && (kind
== cvc5::EQUAL
|| kind
== cvc5::DISTINCT
))
1137 // need hol if these operators are applied over function args
1138 for (std::vector
<cvc5::Term
>::iterator i
= args
.begin(); i
!= args
.end();
1141 if ((*i
).getSort().isFunction())
1144 "Cannot apply equality to functions unless logic is prefixed by "
1149 if (!strictModeEnabled() && (kind
== cvc5::AND
|| kind
== cvc5::OR
)
1150 && args
.size() == 1)
1152 // Unary AND/OR can be replaced with the argument.
1153 Trace("parser") << "applyParseOp: return unary " << args
[0] << std::endl
;
1156 else if (kind
== cvc5::SUB
&& args
.size() == 1)
1158 if (isConstInt(args
[0]) && args
[0].getRealOrIntegerValueSign() > 0)
1160 // (- n) denotes a negative value
1161 std::stringstream suminus
;
1162 suminus
<< "-" << args
[0].getIntegerValue();
1163 cvc5::Term ret
= d_solver
->mkInteger(suminus
.str());
1164 Trace("parser") << "applyParseOp: return negative constant " << ret
1168 cvc5::Term ret
= d_solver
->mkTerm(cvc5::NEG
, {args
[0]});
1169 Trace("parser") << "applyParseOp: return uminus " << ret
<< std::endl
;
1172 else if (kind
== cvc5::DIVISION
&& args
.size() == 2 && isConstInt(args
[0])
1173 && isConstInt(args
[1]) && args
[1].getRealOrIntegerValueSign() > 0)
1175 // (/ m n) or (/ (- m) n) denote values in reals
1176 std::stringstream sdiv
;
1177 sdiv
<< args
[0].getIntegerValue() << "/" << args
[1].getIntegerValue();
1178 cvc5::Term ret
= d_solver
->mkReal(sdiv
.str());
1179 Trace("parser") << "applyParseOp: return rational constant " << ret
1183 if (kind
== cvc5::SET_SINGLETON
&& args
.size() == 1)
1185 cvc5::Term ret
= d_solver
->mkTerm(cvc5::SET_SINGLETON
, {args
[0]});
1186 Trace("parser") << "applyParseOp: return set.singleton " << ret
1190 else if (kind
== cvc5::CARDINALITY_CONSTRAINT
)
1192 if (args
.size() != 2)
1194 parseError("Incorrect arguments for cardinality constraint");
1196 cvc5::Sort sort
= args
[0].getSort();
1197 if (!sort
.isUninterpretedSort())
1199 parseError("Expected uninterpreted sort for cardinality constraint");
1201 uint64_t ubound
= args
[1].getUInt32Value();
1202 cvc5::Term ret
= d_solver
->mkCardinalityConstraint(sort
, ubound
);
1205 cvc5::Term ret
= d_solver
->mkTerm(kind
, args
);
1206 Trace("parser") << "applyParseOp: return default builtin " << ret
1211 if (args
.size() >= 2)
1213 // may be partially applied function, in this case we use HO_APPLY
1214 cvc5::Sort argt
= args
[0].getSort();
1215 if (argt
.isFunction())
1217 unsigned arity
= argt
.getFunctionArity();
1218 if (args
.size() - 1 < arity
)
1223 "Cannot partially apply functions unless logic is prefixed by "
1226 Trace("parser") << "Partial application of " << args
[0];
1227 Trace("parser") << " : #argTypes = " << arity
;
1228 Trace("parser") << ", #args = " << args
.size() - 1 << std::endl
;
1229 cvc5::Term ret
= d_solver
->mkTerm(cvc5::HO_APPLY
, args
);
1230 Trace("parser") << "applyParseOp: return curry higher order " << ret
1232 // must curry the partial application
1239 cvc5::Term ret
= d_solver
->mkTerm(op
, args
);
1240 Trace("parser") << "applyParseOp: return op : " << ret
<< std::endl
;
1243 if (kind
== cvc5::NULL_TERM
)
1245 // should never happen in the new API
1246 parseError("do not know how to process parse op");
1248 Trace("parser") << "Try default term construction for kind " << kind
1249 << " #args = " << args
.size() << "..." << std::endl
;
1250 cvc5::Term ret
= d_solver
->mkTerm(kind
, args
);
1251 Trace("parser") << "applyParseOp: return : " << ret
<< std::endl
;
1255 void Smt2::notifyNamedExpression(cvc5::Term
& expr
, std::string name
)
1257 checkUserSymbol(name
);
1258 // remember the expression name in the symbol manager
1259 if (getSymbolManager()->setExpressionName(expr
, name
, false)
1260 == NamingResult::ERROR_IN_BINDER
)
1263 "Cannot name a term in a binder (e.g., quantifiers, definitions)");
1265 // define the variable
1266 defineVar(name
, expr
);
1267 // set the last named term, which ensures that we catch when assertions are
1269 setLastNamedTerm(expr
, name
);
1272 cvc5::Term
Smt2::mkAnd(const std::vector
<cvc5::Term
>& es
) const
1276 return d_solver
->mkTrue();
1278 else if (es
.size() == 1)
1282 return d_solver
->mkTerm(cvc5::AND
, es
);
1285 bool Smt2::isConstInt(const cvc5::Term
& t
)
1287 cvc5::Kind k
= t
.getKind();
1288 // !!! Note when arithmetic subtyping is eliminated, this will update to
1290 return k
== cvc5::CONST_RATIONAL
&& t
.getSort().isInteger();
1293 } // namespace parser