1 /********************* */
4 ** Top contributors (to current version):
5 ** Andrew Reynolds, Kshitij Bansal, Morgan Deters
6 ** This file is part of the CVC4 project.
7 ** Copyright (c) 2009-2019 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 Definitions of SMT2 constants.
14 ** Definitions of SMT2 constants.
16 #include "parser/smt2/smt2.h"
20 #include "base/check.h"
21 #include "expr/type.h"
22 #include "options/options.h"
23 #include "parser/antlr_input.h"
24 #include "parser/parser.h"
25 #include "parser/smt2/smt2_input.h"
26 #include "printer/sygus_print_callback.h"
27 #include "util/bitvector.h"
29 // ANTLR defines these, which is really bad!
36 Smt2::Smt2(api::Solver
* solver
, Input
* input
, bool strictMode
, bool parseOnly
)
37 : Parser(solver
, input
, strictMode
, parseOnly
),
41 if (!strictModeEnabled())
43 addTheory(Smt2::THEORY_CORE
);
47 void Smt2::addArithmeticOperators() {
48 addOperator(kind::PLUS
, "+");
49 addOperator(kind::MINUS
, "-");
50 // kind::MINUS is converted to kind::UMINUS if there is only a single operand
51 Parser::addOperator(kind::UMINUS
);
52 addOperator(kind::MULT
, "*");
53 addOperator(kind::LT
, "<");
54 addOperator(kind::LEQ
, "<=");
55 addOperator(kind::GT
, ">");
56 addOperator(kind::GEQ
, ">=");
58 if (!strictModeEnabled())
60 // NOTE: this operator is non-standard
61 addOperator(kind::POW
, "^");
65 void Smt2::addTranscendentalOperators()
67 addOperator(kind::EXPONENTIAL
, "exp");
68 addOperator(kind::SINE
, "sin");
69 addOperator(kind::COSINE
, "cos");
70 addOperator(kind::TANGENT
, "tan");
71 addOperator(kind::COSECANT
, "csc");
72 addOperator(kind::SECANT
, "sec");
73 addOperator(kind::COTANGENT
, "cot");
74 addOperator(kind::ARCSINE
, "arcsin");
75 addOperator(kind::ARCCOSINE
, "arccos");
76 addOperator(kind::ARCTANGENT
, "arctan");
77 addOperator(kind::ARCCOSECANT
, "arccsc");
78 addOperator(kind::ARCSECANT
, "arcsec");
79 addOperator(kind::ARCCOTANGENT
, "arccot");
80 addOperator(kind::SQRT
, "sqrt");
83 void Smt2::addQuantifiersOperators()
85 if (!strictModeEnabled())
87 addOperator(kind::INST_CLOSURE
, "inst-closure");
91 void Smt2::addBitvectorOperators() {
92 addOperator(kind::BITVECTOR_CONCAT
, "concat");
93 addOperator(kind::BITVECTOR_NOT
, "bvnot");
94 addOperator(kind::BITVECTOR_AND
, "bvand");
95 addOperator(kind::BITVECTOR_OR
, "bvor");
96 addOperator(kind::BITVECTOR_NEG
, "bvneg");
97 addOperator(kind::BITVECTOR_PLUS
, "bvadd");
98 addOperator(kind::BITVECTOR_MULT
, "bvmul");
99 addOperator(kind::BITVECTOR_UDIV
, "bvudiv");
100 addOperator(kind::BITVECTOR_UREM
, "bvurem");
101 addOperator(kind::BITVECTOR_SHL
, "bvshl");
102 addOperator(kind::BITVECTOR_LSHR
, "bvlshr");
103 addOperator(kind::BITVECTOR_ULT
, "bvult");
104 addOperator(kind::BITVECTOR_NAND
, "bvnand");
105 addOperator(kind::BITVECTOR_NOR
, "bvnor");
106 addOperator(kind::BITVECTOR_XOR
, "bvxor");
107 addOperator(kind::BITVECTOR_XNOR
, "bvxnor");
108 addOperator(kind::BITVECTOR_COMP
, "bvcomp");
109 addOperator(kind::BITVECTOR_SUB
, "bvsub");
110 addOperator(kind::BITVECTOR_SDIV
, "bvsdiv");
111 addOperator(kind::BITVECTOR_SREM
, "bvsrem");
112 addOperator(kind::BITVECTOR_SMOD
, "bvsmod");
113 addOperator(kind::BITVECTOR_ASHR
, "bvashr");
114 addOperator(kind::BITVECTOR_ULE
, "bvule");
115 addOperator(kind::BITVECTOR_UGT
, "bvugt");
116 addOperator(kind::BITVECTOR_UGE
, "bvuge");
117 addOperator(kind::BITVECTOR_SLT
, "bvslt");
118 addOperator(kind::BITVECTOR_SLE
, "bvsle");
119 addOperator(kind::BITVECTOR_SGT
, "bvsgt");
120 addOperator(kind::BITVECTOR_SGE
, "bvsge");
121 addOperator(kind::BITVECTOR_REDOR
, "bvredor");
122 addOperator(kind::BITVECTOR_REDAND
, "bvredand");
123 addOperator(kind::BITVECTOR_TO_NAT
, "bv2nat");
126 kind::BITVECTOR_EXTRACT
, api::BITVECTOR_EXTRACT
, "extract");
127 addIndexedOperator(kind::BITVECTOR_REPEAT
, api::BITVECTOR_REPEAT
, "repeat");
129 kind::BITVECTOR_ZERO_EXTEND
, api::BITVECTOR_ZERO_EXTEND
, "zero_extend");
131 kind::BITVECTOR_SIGN_EXTEND
, api::BITVECTOR_SIGN_EXTEND
, "sign_extend");
133 kind::BITVECTOR_ROTATE_LEFT
, api::BITVECTOR_ROTATE_LEFT
, "rotate_left");
134 addIndexedOperator(kind::BITVECTOR_ROTATE_RIGHT
,
135 api::BITVECTOR_ROTATE_RIGHT
,
137 addIndexedOperator(kind::INT_TO_BITVECTOR
, api::INT_TO_BITVECTOR
, "int2bv");
140 void Smt2::addDatatypesOperators()
142 Parser::addOperator(kind::APPLY_CONSTRUCTOR
);
143 Parser::addOperator(kind::APPLY_TESTER
);
144 Parser::addOperator(kind::APPLY_SELECTOR
);
145 Parser::addOperator(kind::APPLY_SELECTOR_TOTAL
);
147 if (!strictModeEnabled())
149 addOperator(kind::DT_SIZE
, "dt.size");
153 void Smt2::addStringOperators() {
156 ->mkTerm(api::REGEXP_STAR
, getSolver()->mkRegexpSigma())
159 addOperator(kind::STRING_CONCAT
, "str.++");
160 addOperator(kind::STRING_LENGTH
, "str.len");
161 addOperator(kind::STRING_SUBSTR
, "str.substr" );
162 addOperator(kind::STRING_STRCTN
, "str.contains" );
163 addOperator(kind::STRING_CHARAT
, "str.at" );
164 addOperator(kind::STRING_STRIDOF
, "str.indexof" );
165 addOperator(kind::STRING_STRREPL
, "str.replace" );
166 if (!strictModeEnabled())
168 addOperator(kind::STRING_TOLOWER
, "str.tolower");
169 addOperator(kind::STRING_TOUPPER
, "str.toupper");
170 addOperator(kind::STRING_REV
, "str.rev");
172 addOperator(kind::STRING_PREFIX
, "str.prefixof" );
173 addOperator(kind::STRING_SUFFIX
, "str.suffixof" );
174 addOperator(kind::STRING_FROM_CODE
, "str.from_code");
175 addOperator(kind::STRING_IS_DIGIT
, "str.is_digit" );
177 // at the moment, we only use this syntax for smt2.6.1
178 if (getLanguage() == language::input::LANG_SMTLIB_V2_6_1
179 || getLanguage() == language::input::LANG_SYGUS_V2
)
181 addOperator(kind::STRING_ITOS
, "str.from_int");
182 addOperator(kind::STRING_STOI
, "str.to_int");
183 addOperator(kind::STRING_IN_REGEXP
, "str.in_re");
184 addOperator(kind::STRING_TO_REGEXP
, "str.to_re");
185 addOperator(kind::STRING_TO_CODE
, "str.to_code");
186 addOperator(kind::STRING_STRREPLALL
, "str.replace_all");
190 addOperator(kind::STRING_ITOS
, "int.to.str");
191 addOperator(kind::STRING_STOI
, "str.to.int");
192 addOperator(kind::STRING_IN_REGEXP
, "str.in.re");
193 addOperator(kind::STRING_TO_REGEXP
, "str.to.re");
194 addOperator(kind::STRING_TO_CODE
, "str.code");
195 addOperator(kind::STRING_STRREPLALL
, "str.replaceall");
198 addOperator(kind::REGEXP_CONCAT
, "re.++");
199 addOperator(kind::REGEXP_UNION
, "re.union");
200 addOperator(kind::REGEXP_INTER
, "re.inter");
201 addOperator(kind::REGEXP_STAR
, "re.*");
202 addOperator(kind::REGEXP_PLUS
, "re.+");
203 addOperator(kind::REGEXP_OPT
, "re.opt");
204 addOperator(kind::REGEXP_RANGE
, "re.range");
205 addOperator(kind::REGEXP_LOOP
, "re.loop");
206 addOperator(kind::REGEXP_COMPLEMENT
, "re.comp");
207 addOperator(kind::REGEXP_DIFF
, "re.diff");
208 addOperator(kind::STRING_LT
, "str.<");
209 addOperator(kind::STRING_LEQ
, "str.<=");
212 void Smt2::addFloatingPointOperators() {
213 addOperator(kind::FLOATINGPOINT_FP
, "fp");
214 addOperator(kind::FLOATINGPOINT_EQ
, "fp.eq");
215 addOperator(kind::FLOATINGPOINT_ABS
, "fp.abs");
216 addOperator(kind::FLOATINGPOINT_NEG
, "fp.neg");
217 addOperator(kind::FLOATINGPOINT_PLUS
, "fp.add");
218 addOperator(kind::FLOATINGPOINT_SUB
, "fp.sub");
219 addOperator(kind::FLOATINGPOINT_MULT
, "fp.mul");
220 addOperator(kind::FLOATINGPOINT_DIV
, "fp.div");
221 addOperator(kind::FLOATINGPOINT_FMA
, "fp.fma");
222 addOperator(kind::FLOATINGPOINT_SQRT
, "fp.sqrt");
223 addOperator(kind::FLOATINGPOINT_REM
, "fp.rem");
224 addOperator(kind::FLOATINGPOINT_RTI
, "fp.roundToIntegral");
225 addOperator(kind::FLOATINGPOINT_MIN
, "fp.min");
226 addOperator(kind::FLOATINGPOINT_MAX
, "fp.max");
227 addOperator(kind::FLOATINGPOINT_LEQ
, "fp.leq");
228 addOperator(kind::FLOATINGPOINT_LT
, "fp.lt");
229 addOperator(kind::FLOATINGPOINT_GEQ
, "fp.geq");
230 addOperator(kind::FLOATINGPOINT_GT
, "fp.gt");
231 addOperator(kind::FLOATINGPOINT_ISN
, "fp.isNormal");
232 addOperator(kind::FLOATINGPOINT_ISSN
, "fp.isSubnormal");
233 addOperator(kind::FLOATINGPOINT_ISZ
, "fp.isZero");
234 addOperator(kind::FLOATINGPOINT_ISINF
, "fp.isInfinite");
235 addOperator(kind::FLOATINGPOINT_ISNAN
, "fp.isNaN");
236 addOperator(kind::FLOATINGPOINT_ISNEG
, "fp.isNegative");
237 addOperator(kind::FLOATINGPOINT_ISPOS
, "fp.isPositive");
238 addOperator(kind::FLOATINGPOINT_TO_REAL
, "fp.to_real");
240 addIndexedOperator(kind::FLOATINGPOINT_TO_FP_GENERIC
,
241 api::FLOATINGPOINT_TO_FP_GENERIC
,
243 addIndexedOperator(kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
,
244 api::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR
,
247 kind::FLOATINGPOINT_TO_UBV
, api::FLOATINGPOINT_TO_UBV
, "fp.to_ubv");
249 kind::FLOATINGPOINT_TO_SBV
, api::FLOATINGPOINT_TO_SBV
, "fp.to_sbv");
251 if (!strictModeEnabled())
253 addIndexedOperator(kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
,
254 api::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR
,
256 addIndexedOperator(kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT
,
257 api::FLOATINGPOINT_TO_FP_FLOATINGPOINT
,
259 addIndexedOperator(kind::FLOATINGPOINT_TO_FP_REAL
,
260 api::FLOATINGPOINT_TO_FP_REAL
,
262 addIndexedOperator(kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
,
263 api::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR
,
268 void Smt2::addSepOperators() {
269 addOperator(kind::SEP_STAR
, "sep");
270 addOperator(kind::SEP_PTO
, "pto");
271 addOperator(kind::SEP_WAND
, "wand");
272 addOperator(kind::SEP_EMP
, "emp");
273 Parser::addOperator(kind::SEP_STAR
);
274 Parser::addOperator(kind::SEP_PTO
);
275 Parser::addOperator(kind::SEP_WAND
);
276 Parser::addOperator(kind::SEP_EMP
);
279 void Smt2::addTheory(Theory theory
) {
282 addOperator(kind::SELECT
, "select");
283 addOperator(kind::STORE
, "store");
286 case THEORY_BITVECTORS
:
287 addBitvectorOperators();
291 defineType("Bool", getExprManager()->booleanType());
292 defineVar("true", getExprManager()->mkConst(true));
293 defineVar("false", getExprManager()->mkConst(false));
294 addOperator(kind::AND
, "and");
295 addOperator(kind::DISTINCT
, "distinct");
296 addOperator(kind::EQUAL
, "=");
297 addOperator(kind::IMPLIES
, "=>");
298 addOperator(kind::ITE
, "ite");
299 addOperator(kind::NOT
, "not");
300 addOperator(kind::OR
, "or");
301 addOperator(kind::XOR
, "xor");
304 case THEORY_REALS_INTS
:
305 defineType("Real", getExprManager()->realType());
306 addOperator(kind::DIVISION
, "/");
307 addOperator(kind::TO_INTEGER
, "to_int");
308 addOperator(kind::IS_INTEGER
, "is_int");
309 addOperator(kind::TO_REAL
, "to_real");
310 // falling through on purpose, to add Ints part of Reals_Ints
313 defineType("Int", getExprManager()->integerType());
314 addArithmeticOperators();
315 addOperator(kind::INTS_DIVISION
, "div");
316 addOperator(kind::INTS_MODULUS
, "mod");
317 addOperator(kind::ABS
, "abs");
318 addIndexedOperator(kind::DIVISIBLE
, api::DIVISIBLE
, "divisible");
322 defineType("Real", getExprManager()->realType());
323 addArithmeticOperators();
324 addOperator(kind::DIVISION
, "/");
325 if (!strictModeEnabled())
327 addOperator(kind::ABS
, "abs");
331 case THEORY_TRANSCENDENTALS
:
333 getExprManager()->mkNullaryOperator(getExprManager()->realType(),
335 addTranscendentalOperators();
338 case THEORY_QUANTIFIERS
: addQuantifiersOperators(); break;
341 defineVar("emptyset",
342 d_solver
->mkEmptySet(d_solver
->getNullSort()).getExpr());
343 // the Boolean sort is a placeholder here since we don't have type info
344 // without type annotation
346 d_solver
->mkUniverseSet(d_solver
->getBooleanSort()).getExpr());
348 addOperator(kind::UNION
, "union");
349 addOperator(kind::INTERSECTION
, "intersection");
350 addOperator(kind::SETMINUS
, "setminus");
351 addOperator(kind::SUBSET
, "subset");
352 addOperator(kind::MEMBER
, "member");
353 addOperator(kind::SINGLETON
, "singleton");
354 addOperator(kind::INSERT
, "insert");
355 addOperator(kind::CARD
, "card");
356 addOperator(kind::COMPLEMENT
, "complement");
357 addOperator(kind::JOIN
, "join");
358 addOperator(kind::PRODUCT
, "product");
359 addOperator(kind::TRANSPOSE
, "transpose");
360 addOperator(kind::TCLOSURE
, "tclosure");
363 case THEORY_DATATYPES
:
365 const std::vector
<Type
> types
;
366 defineType("Tuple", getExprManager()->mkTupleType(types
));
367 addDatatypesOperators();
372 defineType("String", getExprManager()->stringType());
373 defineType("RegLan", getExprManager()->regExpType());
374 defineType("Int", getExprManager()->integerType());
376 if (getLanguage() == language::input::LANG_SMTLIB_V2_6_1
)
378 defineVar("re.none", d_solver
->mkRegexpEmpty().getExpr());
382 defineVar("re.nostr", d_solver
->mkRegexpEmpty().getExpr());
384 defineVar("re.allchar", d_solver
->mkRegexpSigma().getExpr());
386 addStringOperators();
390 Parser::addOperator(kind::APPLY_UF
);
392 if (!strictModeEnabled() && d_logic
.hasCardinalityConstraints())
394 addOperator(kind::CARDINALITY_CONSTRAINT
, "fmf.card");
395 addOperator(kind::CARDINALITY_VALUE
, "fmf.card.val");
400 defineType("RoundingMode", getExprManager()->roundingModeType());
401 defineType("Float16", getExprManager()->mkFloatingPointType(5, 11));
402 defineType("Float32", getExprManager()->mkFloatingPointType(8, 24));
403 defineType("Float64", getExprManager()->mkFloatingPointType(11, 53));
404 defineType("Float128", getExprManager()->mkFloatingPointType(15, 113));
408 d_solver
->mkRoundingMode(api::ROUND_NEAREST_TIES_TO_EVEN
).getExpr());
410 "roundNearestTiesToEven",
411 d_solver
->mkRoundingMode(api::ROUND_NEAREST_TIES_TO_EVEN
).getExpr());
414 d_solver
->mkRoundingMode(api::ROUND_NEAREST_TIES_TO_AWAY
).getExpr());
416 "roundNearestTiesToAway",
417 d_solver
->mkRoundingMode(api::ROUND_NEAREST_TIES_TO_AWAY
).getExpr());
419 d_solver
->mkRoundingMode(api::ROUND_TOWARD_POSITIVE
).getExpr());
420 defineVar("roundTowardPositive",
421 d_solver
->mkRoundingMode(api::ROUND_TOWARD_POSITIVE
).getExpr());
423 d_solver
->mkRoundingMode(api::ROUND_TOWARD_NEGATIVE
).getExpr());
424 defineVar("roundTowardNegative",
425 d_solver
->mkRoundingMode(api::ROUND_TOWARD_NEGATIVE
).getExpr());
427 d_solver
->mkRoundingMode(api::ROUND_TOWARD_ZERO
).getExpr());
428 defineVar("roundTowardZero",
429 d_solver
->mkRoundingMode(api::ROUND_TOWARD_ZERO
).getExpr());
431 addFloatingPointOperators();
435 // the Boolean sort is a placeholder here since we don't have type info
436 // without type annotation
438 d_solver
->mkSepNil(d_solver
->getBooleanSort()).getExpr());
444 std::stringstream ss
;
445 ss
<< "internal error: unsupported theory " << theory
;
446 throw ParserException(ss
.str());
450 void Smt2::addOperator(Kind kind
, const std::string
& name
) {
451 Debug("parser") << "Smt2::addOperator( " << kind
<< ", " << name
<< " )"
453 Parser::addOperator(kind
);
454 operatorKindMap
[name
] = kind
;
457 void Smt2::addIndexedOperator(Kind tKind
,
459 const std::string
& name
)
461 Parser::addOperator(tKind
);
462 d_indexedOpKindMap
[name
] = opKind
;
465 Kind
Smt2::getOperatorKind(const std::string
& name
) const {
466 // precondition: isOperatorEnabled(name)
467 return operatorKindMap
.find(name
)->second
;
470 bool Smt2::isOperatorEnabled(const std::string
& name
) const {
471 return operatorKindMap
.find(name
) != operatorKindMap
.end();
474 bool Smt2::isTheoryEnabled(Theory theory
) const {
477 return d_logic
.isTheoryEnabled(theory::THEORY_ARRAYS
);
478 case THEORY_BITVECTORS
:
479 return d_logic
.isTheoryEnabled(theory::THEORY_BV
);
482 case THEORY_DATATYPES
:
483 return d_logic
.isTheoryEnabled(theory::THEORY_DATATYPES
);
485 return d_logic
.isTheoryEnabled(theory::THEORY_ARITH
) &&
486 d_logic
.areIntegersUsed() && ( !d_logic
.areRealsUsed() );
488 return d_logic
.isTheoryEnabled(theory::THEORY_ARITH
) &&
489 ( !d_logic
.areIntegersUsed() ) && d_logic
.areRealsUsed();
490 case THEORY_REALS_INTS
:
491 return d_logic
.isTheoryEnabled(theory::THEORY_ARITH
) &&
492 d_logic
.areIntegersUsed() && d_logic
.areRealsUsed();
493 case THEORY_QUANTIFIERS
:
494 return d_logic
.isQuantified();
496 return d_logic
.isTheoryEnabled(theory::THEORY_SETS
);
498 return d_logic
.isTheoryEnabled(theory::THEORY_STRINGS
);
500 return d_logic
.isTheoryEnabled(theory::THEORY_UF
);
502 return d_logic
.isTheoryEnabled(theory::THEORY_FP
);
504 return d_logic
.isTheoryEnabled(theory::THEORY_SEP
);
506 std::stringstream ss
;
507 ss
<< "internal error: unsupported theory " << theory
;
508 throw ParserException(ss
.str());
512 bool Smt2::logicIsSet() {
516 Expr
Smt2::getExpressionForNameAndType(const std::string
& name
, Type t
) {
517 if (isAbstractValue(name
))
519 return mkAbstractValue(name
);
521 return Parser::getExpressionForNameAndType(name
, t
);
524 api::Term
Smt2::mkIndexedConstant(const std::string
& name
,
525 const std::vector
<uint64_t>& numerals
)
527 if (isTheoryEnabled(THEORY_FP
))
531 return d_solver
->mkPosInf(numerals
[0], numerals
[1]);
533 else if (name
== "-oo")
535 return d_solver
->mkNegInf(numerals
[0], numerals
[1]);
537 else if (name
== "NaN")
539 return d_solver
->mkNaN(numerals
[0], numerals
[1]);
541 else if (name
== "+zero")
543 return d_solver
->mkPosZero(numerals
[0], numerals
[1]);
545 else if (name
== "-zero")
547 return d_solver
->mkNegZero(numerals
[0], numerals
[1]);
551 if (isTheoryEnabled(THEORY_BITVECTORS
) && name
.find("bv") == 0)
553 std::string bvStr
= name
.substr(2);
554 return d_solver
->mkBitVector(numerals
[0], bvStr
, 10);
557 // NOTE: Theory parametric constants go here
559 parseError(std::string("Unknown indexed literal `") + name
+ "'");
563 api::Op
Smt2::mkIndexedOp(const std::string
& name
,
564 const std::vector
<uint64_t>& numerals
)
566 const auto& kIt
= d_indexedOpKindMap
.find(name
);
567 if (kIt
!= d_indexedOpKindMap
.end())
569 api::Kind k
= (*kIt
).second
;
570 if (numerals
.size() == 1)
572 return d_solver
->mkOp(k
, numerals
[0]);
574 else if (numerals
.size() == 2)
576 return d_solver
->mkOp(k
, numerals
[0], numerals
[1]);
580 parseError(std::string("Unknown indexed function `") + name
+ "'");
584 Expr
Smt2::mkDefineFunRec(
585 const std::string
& fname
,
586 const std::vector
<std::pair
<std::string
, Type
> >& sortedVarNames
,
588 std::vector
<Expr
>& flattenVars
)
590 std::vector
<Type
> sorts
;
591 for (const std::pair
<std::string
, CVC4::Type
>& svn
: sortedVarNames
)
593 sorts
.push_back(svn
.second
);
596 // make the flattened function type, add bound variables
597 // to flattenVars if the defined function was given a function return type.
598 Type ft
= mkFlatFunctionType(sorts
, t
, flattenVars
);
601 return mkVar(fname
, ft
, ExprManager::VAR_FLAG_NONE
, true);
604 void Smt2::pushDefineFunRecScope(
605 const std::vector
<std::pair
<std::string
, Type
> >& sortedVarNames
,
607 const std::vector
<Expr
>& flattenVars
,
608 std::vector
<Expr
>& bvs
,
611 pushScope(bindingLevel
);
613 // bound variables are those that are explicitly named in the preamble
614 // of the define-fun(s)-rec command, we define them here
615 for (const std::pair
<std::string
, CVC4::Type
>& svn
: sortedVarNames
)
617 Expr v
= mkBoundVar(svn
.first
, svn
.second
);
621 bvs
.insert(bvs
.end(), flattenVars
.begin(), flattenVars
.end());
626 d_seenSetLogic
= false;
627 d_logic
= LogicInfo();
628 operatorKindMap
.clear();
629 d_lastNamedTerm
= std::pair
<Expr
, std::string
>();
630 this->Parser::reset();
632 if( !strictModeEnabled() ) {
633 addTheory(Smt2::THEORY_CORE
);
637 void Smt2::resetAssertions() {
638 // Remove all declarations except the ones at level 0.
639 while (this->scopeLevel() > 0) {
644 Smt2::SynthFunFactory::SynthFunFactory(
646 const std::string
& fun
,
649 std::vector
<std::pair
<std::string
, CVC4::Type
>>& sortedVarNames
)
650 : d_smt2(smt2
), d_fun(fun
), d_isInv(isInv
)
654 smt2
->parseError("Must supply return type for synth-fun.");
656 if (range
.isFunction())
658 smt2
->parseError("Cannot use synth-fun with function return type.");
660 std::vector
<Type
> varSorts
;
661 for (const std::pair
<std::string
, CVC4::Type
>& p
: sortedVarNames
)
663 varSorts
.push_back(p
.second
);
665 Debug("parser-sygus") << "Define synth fun : " << fun
<< std::endl
;
668 ? d_smt2
->getExprManager()->mkFunctionType(varSorts
, range
)
671 // we do not allow overloading for synth fun
672 d_synthFun
= d_smt2
->mkBoundVar(fun
, synthFunType
);
673 // set the sygus type to be range by default, which is overwritten below
674 // if a grammar is provided
677 d_smt2
->pushScope(true);
678 d_sygusVars
= d_smt2
->mkBoundVars(sortedVarNames
);
681 Smt2::SynthFunFactory::~SynthFunFactory() { d_smt2
->popScope(); }
683 std::unique_ptr
<Command
> Smt2::SynthFunFactory::mkCommand(Type grammar
)
685 Debug("parser-sygus") << "...read synth fun " << d_fun
<< std::endl
;
686 return std::unique_ptr
<Command
>(
687 new SynthFunCommand(d_fun
,
689 grammar
.isNull() ? d_sygusType
: grammar
,
694 std::unique_ptr
<Command
> Smt2::invConstraint(
695 const std::vector
<std::string
>& names
)
697 checkThatLogicIsSet();
698 Debug("parser-sygus") << "Sygus : define sygus funs..." << std::endl
;
699 Debug("parser-sygus") << "Sygus : read inv-constraint..." << std::endl
;
701 if (names
.size() != 4)
704 "Bad syntax for inv-constraint: expected 4 "
708 std::vector
<Expr
> terms
;
709 for (const std::string
& name
: names
)
711 if (!isDeclared(name
))
713 std::stringstream ss
;
714 ss
<< "Function " << name
<< " in inv-constraint is not defined.";
715 parseError(ss
.str());
718 terms
.push_back(getVariable(name
));
721 return std::unique_ptr
<Command
>(new SygusInvConstraintCommand(terms
));
724 Command
* Smt2::setLogic(std::string name
, bool fromCommand
)
730 parseError("Only one set-logic is allowed.");
732 d_seenSetLogic
= true;
736 // If the logic is forced, we ignore all set-logic requests from commands.
737 return new EmptyCommand();
743 // non-smt2-standard sygus logic names go here (http://sygus.seas.upenn.edu/files/sygus.pdf Section 3.2)
744 if(name
== "Arrays") {
746 }else if(name
== "Reals") {
754 // if sygus is enabled, we must enable UF, datatypes, integer arithmetic and
757 if (!d_logic
.isQuantified())
759 warning("Logics in sygus are assumed to contain quantifiers.");
760 warning("Omit QF_ from the logic to avoid this warning.");
764 // Core theory belongs to every logic
765 addTheory(THEORY_CORE
);
767 if(d_logic
.isTheoryEnabled(theory::THEORY_UF
)) {
768 addTheory(THEORY_UF
);
771 if(d_logic
.isTheoryEnabled(theory::THEORY_ARITH
)) {
772 if(d_logic
.areIntegersUsed()) {
773 if(d_logic
.areRealsUsed()) {
774 addTheory(THEORY_REALS_INTS
);
776 addTheory(THEORY_INTS
);
778 } else if(d_logic
.areRealsUsed()) {
779 addTheory(THEORY_REALS
);
782 if (d_logic
.areTranscendentalsUsed())
784 addTheory(THEORY_TRANSCENDENTALS
);
788 if(d_logic
.isTheoryEnabled(theory::THEORY_ARRAYS
)) {
789 addTheory(THEORY_ARRAYS
);
792 if(d_logic
.isTheoryEnabled(theory::THEORY_BV
)) {
793 addTheory(THEORY_BITVECTORS
);
796 if(d_logic
.isTheoryEnabled(theory::THEORY_DATATYPES
)) {
797 addTheory(THEORY_DATATYPES
);
800 if(d_logic
.isTheoryEnabled(theory::THEORY_SETS
)) {
801 addTheory(THEORY_SETS
);
804 if(d_logic
.isTheoryEnabled(theory::THEORY_STRINGS
)) {
805 addTheory(THEORY_STRINGS
);
808 if(d_logic
.isQuantified()) {
809 addTheory(THEORY_QUANTIFIERS
);
812 if (d_logic
.isTheoryEnabled(theory::THEORY_FP
)) {
813 addTheory(THEORY_FP
);
816 if (d_logic
.isTheoryEnabled(theory::THEORY_SEP
)) {
817 addTheory(THEORY_SEP
);
821 new SetBenchmarkLogicCommand(sygus() ? d_logic
.getLogicString() : name
);
822 cmd
->setMuted(!fromCommand
);
824 } /* Smt2::setLogic() */
826 bool Smt2::sygus() const
828 InputLanguage ilang
= getLanguage();
829 return ilang
== language::input::LANG_SYGUS
830 || ilang
== language::input::LANG_SYGUS_V2
;
832 bool Smt2::sygus_v1() const
834 return getLanguage() == language::input::LANG_SYGUS
;
837 void Smt2::setInfo(const std::string
& flag
, const SExpr
& sexpr
) {
841 void Smt2::setOption(const std::string
& flag
, const SExpr
& sexpr
) {
845 void Smt2::checkThatLogicIsSet()
849 if (strictModeEnabled())
851 parseError("set-logic must appear before this point.");
855 Command
* cmd
= nullptr;
858 cmd
= setLogic(getForcedLogic(), false);
862 warning("No set-logic command was given before this point.");
863 warning("CVC4 will make all theories available.");
865 "Consider setting a stricter logic for (likely) better "
867 warning("To suppress this warning in the future use (set-logic ALL).");
869 cmd
= setLogic("ALL", false);
876 /* The include are managed in the lexer but called in the parser */
877 // Inspired by http://www.antlr3.org/api/C/interop.html
879 static bool newInputStream(const std::string
& filename
, pANTLR3_LEXER lexer
) {
880 Debug("parser") << "Including " << filename
<< std::endl
;
881 // Create a new input stream and take advantage of built in stream stacking
882 // in C target runtime.
884 pANTLR3_INPUT_STREAM in
;
885 #ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
886 in
= antlr3AsciiFileStreamNew((pANTLR3_UINT8
) filename
.c_str());
887 #else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
888 in
= antlr3FileStreamNew((pANTLR3_UINT8
) filename
.c_str(), ANTLR3_ENC_8BIT
);
889 #endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
891 Debug("parser") << "Can't open " << filename
<< std::endl
;
894 // Same thing as the predefined PUSHSTREAM(in);
895 lexer
->pushCharStream(lexer
, in
);
897 //lexer->rec->state->tokenStartCharIndex = -10;
898 //lexer->emit(lexer);
900 // Note that the input stream is not closed when it EOFs, I don't bother
901 // to do it here, but it is up to you to track streams created like this
902 // and destroy them when the whole parse session is complete. Remember that you
903 // don't want to do this until all tokens have been manipulated all the way through
904 // your tree parsers etc as the token does not store the text it just refers
905 // back to the input stream and trying to get the text for it will abort if you
906 // close the input stream too early.
908 //TODO what said before
912 void Smt2::includeFile(const std::string
& filename
) {
913 // security for online version
914 if(!canIncludeFile()) {
915 parseError("include-file feature was disabled for this run.");
919 AntlrInput
* ai
= static_cast<AntlrInput
*>(getInput());
920 pANTLR3_LEXER lexer
= ai
->getAntlr3Lexer();
921 // get the name of the current stream "Does it work inside an include?"
922 const std::string inputName
= ai
->getInputStreamName();
924 // Find the directory of the current input file
926 size_t pos
= inputName
.rfind('/');
927 if(pos
!= std::string::npos
) {
928 path
= std::string(inputName
, 0, pos
+ 1);
930 path
.append(filename
);
931 if(!newInputStream(path
, lexer
)) {
932 parseError("Couldn't open include file `" + path
+ "'");
936 bool Smt2::isAbstractValue(const std::string
& name
)
938 return name
.length() >= 2 && name
[0] == '@' && name
[1] != '0'
939 && name
.find_first_not_of("0123456789", 1) == std::string::npos
;
942 Expr
Smt2::mkAbstractValue(const std::string
& name
)
944 assert(isAbstractValue(name
));
946 return getExprManager()->mkConst(AbstractValue(Integer(name
.substr(1))));
949 void Smt2::mkSygusConstantsForType( const Type
& type
, std::vector
<CVC4::Expr
>& ops
) {
950 if( type
.isInteger() ){
951 ops
.push_back(getExprManager()->mkConst(Rational(0)));
952 ops
.push_back(getExprManager()->mkConst(Rational(1)));
953 }else if( type
.isBitVector() ){
954 unsigned sz
= ((BitVectorType
)type
).getSize();
955 BitVector
bval0(sz
, (unsigned int)0);
956 ops
.push_back( getExprManager()->mkConst(bval0
) );
957 BitVector
bval1(sz
, (unsigned int)1);
958 ops
.push_back( getExprManager()->mkConst(bval1
) );
959 }else if( type
.isBoolean() ){
960 ops
.push_back(getExprManager()->mkConst(true));
961 ops
.push_back(getExprManager()->mkConst(false));
966 // This method adds N operators to ops[index], N names to cnames[index] and N type argument vectors to cargs[index] (where typically N=1)
967 // This method may also add new elements pairwise into datatypes/sorts/ops/cnames/cargs in the case of non-flat gterms.
968 void Smt2::processSygusGTerm(
969 CVC4::SygusGTerm
& sgt
,
971 std::vector
<CVC4::Datatype
>& datatypes
,
972 std::vector
<CVC4::Type
>& sorts
,
973 std::vector
<std::vector
<ParseOp
>>& ops
,
974 std::vector
<std::vector
<std::string
>>& cnames
,
975 std::vector
<std::vector
<std::vector
<CVC4::Type
>>>& cargs
,
976 std::vector
<bool>& allow_const
,
977 std::vector
<std::vector
<std::string
>>& unresolved_gterm_sym
,
978 const std::vector
<CVC4::Expr
>& sygus_vars
,
979 std::map
<CVC4::Type
, CVC4::Type
>& sygus_to_builtin
,
980 std::map
<CVC4::Type
, CVC4::Expr
>& sygus_to_builtin_expr
,
984 if (sgt
.d_gterm_type
== SygusGTerm::gterm_op
)
986 Debug("parser-sygus") << "Add " << sgt
.d_op
<< " to datatype "
987 << index
<< std::endl
;
989 Kind newKind
= kind::UNDEFINED_KIND
;
990 //convert to UMINUS if one child of MINUS
991 if (sgt
.d_children
.size() == 1 && sgt
.d_op
.d_kind
== kind::MINUS
)
993 oldKind
= kind::MINUS
;
994 newKind
= kind::UMINUS
;
996 if( newKind
!=kind::UNDEFINED_KIND
){
997 Debug("parser-sygus")
998 << "Replace " << sgt
.d_op
.d_kind
<< " with " << newKind
<< std::endl
;
999 sgt
.d_op
.d_kind
= newKind
;
1000 std::string oldName
= kind::kindToString(oldKind
);
1001 std::string newName
= kind::kindToString(newKind
);
1003 if((pos
= sgt
.d_name
.find(oldName
, pos
)) != std::string::npos
){
1004 sgt
.d_name
.replace(pos
, oldName
.length(), newName
);
1007 ops
[index
].push_back(sgt
.d_op
);
1008 cnames
[index
].push_back( sgt
.d_name
);
1009 cargs
[index
].push_back( std::vector
< CVC4::Type
>() );
1010 for( unsigned i
=0; i
<sgt
.d_children
.size(); i
++ ){
1011 std::stringstream ss
;
1012 ss
<< datatypes
[index
].getName() << "_" << ops
[index
].size() << "_arg_" << i
;
1013 std::string sub_dname
= ss
.str();
1014 //add datatype for child
1016 pushSygusDatatypeDef( null_type
, sub_dname
, datatypes
, sorts
, ops
, cnames
, cargs
, allow_const
, unresolved_gterm_sym
);
1017 int sub_dt_index
= datatypes
.size()-1;
1020 processSygusGTerm( sgt
.d_children
[i
], sub_dt_index
, datatypes
, sorts
, ops
, cnames
, cargs
, allow_const
, unresolved_gterm_sym
,
1021 sygus_vars
, sygus_to_builtin
, sygus_to_builtin_expr
, sub_ret
, true );
1022 //process the nested gterm (either pop the last datatype, or flatten the argument)
1023 Type tt
= processSygusNestedGTerm( sub_dt_index
, sub_dname
, datatypes
, sorts
, ops
, cnames
, cargs
, allow_const
, unresolved_gterm_sym
,
1024 sygus_to_builtin
, sygus_to_builtin_expr
, sub_ret
);
1025 cargs
[index
].back().push_back(tt
);
1028 else if (sgt
.d_gterm_type
== SygusGTerm::gterm_constant
)
1030 if( sgt
.getNumChildren()!=0 ){
1031 parseError("Bad syntax for Sygus Constant.");
1033 std::vector
< Expr
> consts
;
1034 mkSygusConstantsForType( sgt
.d_type
, consts
);
1035 Debug("parser-sygus") << "...made " << consts
.size() << " constants." << std::endl
;
1036 for( unsigned i
=0; i
<consts
.size(); i
++ ){
1037 std::stringstream ss
;
1039 Debug("parser-sygus") << "...add for constant " << ss
.str() << std::endl
;
1041 constOp
.d_expr
= consts
[i
];
1042 ops
[index
].push_back(constOp
);
1043 cnames
[index
].push_back( ss
.str() );
1044 cargs
[index
].push_back( std::vector
< CVC4::Type
>() );
1046 allow_const
[index
] = true;
1048 else if (sgt
.d_gterm_type
== SygusGTerm::gterm_variable
1049 || sgt
.d_gterm_type
== SygusGTerm::gterm_input_variable
)
1051 if( sgt
.getNumChildren()!=0 ){
1052 parseError("Bad syntax for Sygus Variable.");
1054 Debug("parser-sygus") << "...process " << sygus_vars
.size() << " variables." << std::endl
;
1055 for( unsigned i
=0; i
<sygus_vars
.size(); i
++ ){
1056 if( sygus_vars
[i
].getType()==sgt
.d_type
){
1057 std::stringstream ss
;
1058 ss
<< sygus_vars
[i
];
1059 Debug("parser-sygus") << "...add for variable " << ss
.str() << std::endl
;
1061 varOp
.d_expr
= sygus_vars
[i
];
1062 ops
[index
].push_back(varOp
);
1063 cnames
[index
].push_back( ss
.str() );
1064 cargs
[index
].push_back( std::vector
< CVC4::Type
>() );
1068 else if (sgt
.d_gterm_type
== SygusGTerm::gterm_nested_sort
)
1072 else if (sgt
.d_gterm_type
== SygusGTerm::gterm_unresolved
)
1075 if( isUnresolvedType(sgt
.d_name
) ){
1076 ret
= getSort(sgt
.d_name
);
1078 //nested, unresolved symbol...fail
1079 std::stringstream ss
;
1080 ss
<< "Cannot handle nested unresolved symbol " << sgt
.d_name
<< std::endl
;
1081 parseError(ss
.str());
1084 //will resolve when adding constructors
1085 unresolved_gterm_sym
[index
].push_back(sgt
.d_name
);
1088 else if (sgt
.d_gterm_type
== SygusGTerm::gterm_ignore
)
1094 bool Smt2::pushSygusDatatypeDef(
1097 std::vector
<CVC4::Datatype
>& datatypes
,
1098 std::vector
<CVC4::Type
>& sorts
,
1099 std::vector
<std::vector
<ParseOp
>>& ops
,
1100 std::vector
<std::vector
<std::string
>>& cnames
,
1101 std::vector
<std::vector
<std::vector
<CVC4::Type
>>>& cargs
,
1102 std::vector
<bool>& allow_const
,
1103 std::vector
<std::vector
<std::string
>>& unresolved_gterm_sym
)
1106 datatypes
.push_back(Datatype(getExprManager(), dname
));
1107 ops
.push_back(std::vector
<ParseOp
>());
1108 cnames
.push_back(std::vector
<std::string
>());
1109 cargs
.push_back(std::vector
<std::vector
<CVC4::Type
> >());
1110 allow_const
.push_back(false);
1111 unresolved_gterm_sym
.push_back(std::vector
< std::string
>());
1115 bool Smt2::popSygusDatatypeDef(
1116 std::vector
<CVC4::Datatype
>& datatypes
,
1117 std::vector
<CVC4::Type
>& sorts
,
1118 std::vector
<std::vector
<ParseOp
>>& ops
,
1119 std::vector
<std::vector
<std::string
>>& cnames
,
1120 std::vector
<std::vector
<std::vector
<CVC4::Type
>>>& cargs
,
1121 std::vector
<bool>& allow_const
,
1122 std::vector
<std::vector
<std::string
>>& unresolved_gterm_sym
)
1125 datatypes
.pop_back();
1129 allow_const
.pop_back();
1130 unresolved_gterm_sym
.pop_back();
1134 Type
Smt2::processSygusNestedGTerm(
1136 std::string
& sub_dname
,
1137 std::vector
<CVC4::Datatype
>& datatypes
,
1138 std::vector
<CVC4::Type
>& sorts
,
1139 std::vector
<std::vector
<ParseOp
>>& ops
,
1140 std::vector
<std::vector
<std::string
>>& cnames
,
1141 std::vector
<std::vector
<std::vector
<CVC4::Type
>>>& cargs
,
1142 std::vector
<bool>& allow_const
,
1143 std::vector
<std::vector
<std::string
>>& unresolved_gterm_sym
,
1144 std::map
<CVC4::Type
, CVC4::Type
>& sygus_to_builtin
,
1145 std::map
<CVC4::Type
, CVC4::Expr
>& sygus_to_builtin_expr
,
1149 Debug("parser-sygus") << "Argument is ";
1151 //then, it is the datatype we constructed, which should have a single constructor
1152 t
= mkUnresolvedType(sub_dname
);
1153 Debug("parser-sygus") << "inline flattening of (auxiliary, local) datatype " << t
<< std::endl
;
1154 Debug("parser-sygus") << ": to compute type, construct ground term witnessing the grammar, #cons=" << cargs
[sub_dt_index
].size() << std::endl
;
1155 if( cargs
[sub_dt_index
].empty() ){
1156 parseError(std::string("Internal error : datatype for nested gterm does not have a constructor."));
1158 ParseOp op
= ops
[sub_dt_index
][0];
1160 if (!op
.d_expr
.isNull()
1161 && (op
.d_expr
.isConst() || cargs
[sub_dt_index
][0].empty()))
1163 Expr sop
= op
.d_expr
;
1164 curr_t
= sop
.getType();
1165 Debug("parser-sygus") << ": it is constant/0-arg cons " << sop
<< " with type " << sop
.getType() << ", debug=" << sop
.isConst() << " " << cargs
[sub_dt_index
][0].size() << std::endl
;
1166 // only cache if it is a singleton datatype (has unique expr)
1167 if (ops
[sub_dt_index
].size() == 1)
1169 sygus_to_builtin_expr
[t
] = sop
;
1170 // store that term sop has dedicated sygus type t
1171 if (d_sygus_bound_var_type
.find(sop
) == d_sygus_bound_var_type
.end())
1173 d_sygus_bound_var_type
[sop
] = t
;
1179 std::vector
< Expr
> children
;
1180 for( unsigned i
=0; i
<cargs
[sub_dt_index
][0].size(); i
++ ){
1181 std::map
< CVC4::Type
, CVC4::Expr
>::iterator it
= sygus_to_builtin_expr
.find( cargs
[sub_dt_index
][0][i
] );
1182 if( it
==sygus_to_builtin_expr
.end() ){
1183 if( sygus_to_builtin
.find( cargs
[sub_dt_index
][0][i
] )==sygus_to_builtin
.end() ){
1184 std::stringstream ss
;
1185 ss
<< "Missing builtin type for type " << cargs
[sub_dt_index
][0][i
] << "!" << std::endl
;
1186 ss
<< "Builtin types are currently : " << std::endl
;
1187 for( std::map
< CVC4::Type
, CVC4::Type
>::iterator itb
= sygus_to_builtin
.begin(); itb
!= sygus_to_builtin
.end(); ++itb
){
1188 ss
<< " " << itb
->first
<< " -> " << itb
->second
<< std::endl
;
1190 parseError(ss
.str());
1192 Type bt
= sygus_to_builtin
[cargs
[sub_dt_index
][0][i
]];
1193 Debug("parser-sygus") << ": child " << i
<< " introduce type elem for " << cargs
[sub_dt_index
][0][i
] << " " << bt
<< std::endl
;
1194 std::stringstream ss
;
1195 ss
<< t
<< "_x_" << i
;
1196 Expr bv
= mkBoundVar(ss
.str(), bt
);
1197 children
.push_back( bv
);
1198 d_sygus_bound_var_type
[bv
] = cargs
[sub_dt_index
][0][i
];
1200 Debug("parser-sygus") << ": child " << i
<< " existing sygus to builtin expr : " << it
->second
<< std::endl
;
1201 children
.push_back( it
->second
);
1204 Expr e
= applyParseOp(op
, children
);
1205 Debug("parser-sygus") << ": constructed " << e
<< ", which has type " << e
.getType() << std::endl
;
1206 curr_t
= e
.getType();
1207 sygus_to_builtin_expr
[t
] = e
;
1209 sorts
[sub_dt_index
] = curr_t
;
1210 sygus_to_builtin
[t
] = curr_t
;
1212 Debug("parser-sygus") << "simple argument " << t
<< std::endl
;
1213 Debug("parser-sygus") << "...removing " << datatypes
.back().getName() << std::endl
;
1214 //otherwise, datatype was unecessary
1215 //pop argument datatype definition
1216 popSygusDatatypeDef( datatypes
, sorts
, ops
, cnames
, cargs
, allow_const
, unresolved_gterm_sym
);
1221 void Smt2::setSygusStartIndex(const std::string
& fun
,
1223 std::vector
<CVC4::Datatype
>& datatypes
,
1224 std::vector
<CVC4::Type
>& sorts
,
1225 std::vector
<std::vector
<ParseOp
>>& ops
)
1228 CVC4::Datatype tmp_dt
= datatypes
[0];
1229 Type tmp_sort
= sorts
[0];
1230 std::vector
<ParseOp
> tmp_ops
;
1231 tmp_ops
.insert( tmp_ops
.end(), ops
[0].begin(), ops
[0].end() );
1232 datatypes
[0] = datatypes
[startIndex
];
1233 sorts
[0] = sorts
[startIndex
];
1235 ops
[0].insert( ops
[0].end(), ops
[startIndex
].begin(), ops
[startIndex
].end() );
1236 datatypes
[startIndex
] = tmp_dt
;
1237 sorts
[startIndex
] = tmp_sort
;
1238 ops
[startIndex
].clear();
1239 ops
[startIndex
].insert( ops
[startIndex
].begin(), tmp_ops
.begin(), tmp_ops
.end() );
1240 }else if( startIndex
<0 ){
1241 std::stringstream ss
;
1242 ss
<< "warning: no symbol named Start for synth-fun " << fun
<< std::endl
;
1247 void Smt2::mkSygusDatatype(CVC4::Datatype
& dt
,
1248 std::vector
<ParseOp
>& ops
,
1249 std::vector
<std::string
>& cnames
,
1250 std::vector
<std::vector
<CVC4::Type
>>& cargs
,
1251 std::vector
<std::string
>& unresolved_gterm_sym
,
1252 std::map
<CVC4::Type
, CVC4::Type
>& sygus_to_builtin
)
1254 Debug("parser-sygus") << "Making sygus datatype " << dt
.getName() << std::endl
;
1255 Debug("parser-sygus") << " add constructors..." << std::endl
;
1257 Debug("parser-sygus") << "SMT2 sygus parser : Making constructors for sygus datatype " << dt
.getName() << std::endl
;
1258 Debug("parser-sygus") << " add constructors..." << std::endl
;
1259 // size of cnames changes, this loop must check size
1260 for (unsigned i
= 0; i
< cnames
.size(); i
++)
1262 bool is_dup
= false;
1263 bool is_dup_op
= false;
1264 for (unsigned j
= 0; j
< i
; j
++)
1266 if( ops
[i
]==ops
[j
] ){
1268 if( cargs
[i
].size()==cargs
[j
].size() ){
1270 for( unsigned k
=0; k
<cargs
[i
].size(); k
++ ){
1271 if( cargs
[i
][k
]!=cargs
[j
][k
] ){
1282 Debug("parser-sygus") << "SYGUS CONS " << i
<< " : ";
1284 Debug("parser-sygus") << "--> Duplicate gterm : " << ops
[i
] << std::endl
;
1285 ops
.erase( ops
.begin() + i
, ops
.begin() + i
+ 1 );
1286 cnames
.erase( cnames
.begin() + i
, cnames
.begin() + i
+ 1 );
1287 cargs
.erase( cargs
.begin() + i
, cargs
.begin() + i
+ 1 );
1292 std::shared_ptr
<SygusPrintCallback
> spc
;
1295 Debug("parser-sygus") << "--> Duplicate gterm operator : " << ops
[i
]
1297 // make into define-fun
1298 std::vector
<Type
> ltypes
;
1299 for (unsigned j
= 0, size
= cargs
[i
].size(); j
< size
; j
++)
1301 ltypes
.push_back(sygus_to_builtin
[cargs
[i
][j
]]);
1303 std::vector
<Expr
> largs
;
1304 Expr lbvl
= makeSygusBoundVarList(dt
, i
, ltypes
, largs
);
1306 // make the let_body
1307 Expr body
= applyParseOp(ops
[i
], largs
);
1308 // replace by lambda
1310 pLam
.d_expr
= getExprManager()->mkExpr(kind::LAMBDA
, lbvl
, body
);
1312 Debug("parser-sygus") << " ...replace op : " << ops
[i
] << std::endl
;
1313 // callback prints as the expression
1314 spc
= std::make_shared
<printer::SygusExprPrintCallback
>(body
, largs
);
1318 Expr sop
= ops
[i
].d_expr
;
1319 if (!sop
.isNull() && sop
.getType().isBitVector() && sop
.isConst())
1321 Debug("parser-sygus") << "--> Bit-vector constant " << sop
<< " ("
1322 << cnames
[i
] << ")" << std::endl
;
1323 // Since there are multiple output formats for bit-vectors and
1324 // we are required by sygus standards to print in the exact input
1325 // format given by the user, we use a print callback to custom print
1327 spc
= std::make_shared
<printer::SygusNamedPrintCallback
>(cnames
[i
]);
1329 else if (!sop
.isNull() && sop
.getKind() == kind::VARIABLE
)
1331 Debug("parser-sygus") << "--> Defined function " << ops
[i
]
1333 // turn f into (lammbda (x) (f x))
1334 // in a degenerate case, ops[i] may be a defined constant,
1335 // in which case we do not replace by a lambda.
1336 if (sop
.getType().isFunction())
1338 std::vector
<Type
> ftypes
=
1339 static_cast<FunctionType
>(sop
.getType()).getArgTypes();
1340 std::vector
<Expr
> largs
;
1341 Expr lbvl
= makeSygusBoundVarList(dt
, i
, ftypes
, largs
);
1342 largs
.insert(largs
.begin(), sop
);
1343 Expr body
= getExprManager()->mkExpr(kind::APPLY_UF
, largs
);
1344 ops
[i
].d_expr
= getExprManager()->mkExpr(kind::LAMBDA
, lbvl
, body
);
1345 Debug("parser-sygus") << " ...replace op : " << ops
[i
]
1350 Debug("parser-sygus") << " ...replace op : " << ops
[i
]
1353 // keep a callback to say it should be printed with the defined name
1354 spc
= std::make_shared
<printer::SygusNamedPrintCallback
>(cnames
[i
]);
1358 Debug("parser-sygus") << "--> Default case " << ops
[i
] << std::endl
;
1361 // must rename to avoid duplication
1362 std::stringstream ss
;
1363 ss
<< dt
.getName() << "_" << i
<< "_" << cnames
[i
];
1364 cnames
[i
] = ss
.str();
1365 Debug("parser-sygus") << " construct the datatype " << cnames
[i
] << "..."
1367 // Add the sygus constructor, either using the expression operator of
1368 // ops[i], or the kind.
1369 if (!ops
[i
].d_expr
.isNull())
1371 dt
.addSygusConstructor(ops
[i
].d_expr
, cnames
[i
], cargs
[i
], spc
);
1373 else if (ops
[i
].d_kind
!= kind::NULL_EXPR
)
1375 dt
.addSygusConstructor(ops
[i
].d_kind
, cnames
[i
], cargs
[i
], spc
);
1379 std::stringstream ss
;
1380 ss
<< "unexpected parse operator for sygus constructor" << ops
[i
];
1381 parseError(ss
.str());
1383 Debug("parser-sygus") << " finished constructing the datatype"
1388 Debug("parser-sygus") << " add constructors for unresolved symbols..." << std::endl
;
1389 if( !unresolved_gterm_sym
.empty() ){
1390 std::vector
< Type
> types
;
1391 Debug("parser-sygus") << "...resolve " << unresolved_gterm_sym
.size() << " symbols..." << std::endl
;
1392 for( unsigned i
=0; i
<unresolved_gterm_sym
.size(); i
++ ){
1393 Debug("parser-sygus") << " resolve : " << unresolved_gterm_sym
[i
] << std::endl
;
1394 if( isUnresolvedType(unresolved_gterm_sym
[i
]) ){
1395 Debug("parser-sygus") << " it is an unresolved type." << std::endl
;
1396 Type t
= getSort(unresolved_gterm_sym
[i
]);
1397 if( std::find( types
.begin(), types
.end(), t
)==types
.end() ){
1398 types
.push_back( t
);
1400 Type bt
= dt
.getSygusType();
1401 Debug("parser-sygus") << ": make identity function for " << bt
<< ", argument type " << t
<< std::endl
;
1403 std::stringstream ss
;
1405 Expr var
= mkBoundVar(ss
.str(), bt
);
1406 std::vector
<Expr
> lchildren
;
1407 lchildren
.push_back(
1408 getExprManager()->mkExpr(kind::BOUND_VAR_LIST
, var
));
1409 lchildren
.push_back(var
);
1410 Expr id_op
= getExprManager()->mkExpr(kind::LAMBDA
, lchildren
);
1412 // empty sygus callback (should not be printed)
1413 std::shared_ptr
<SygusPrintCallback
> sepc
=
1414 std::make_shared
<printer::SygusEmptyPrintCallback
>();
1416 //make the sygus argument list
1417 std::vector
< Type
> id_carg
;
1418 id_carg
.push_back( t
);
1419 dt
.addSygusConstructor(id_op
, unresolved_gterm_sym
[i
], id_carg
, sepc
);
1423 idOp
.d_expr
= id_op
;
1424 ops
.push_back(idOp
);
1427 std::stringstream ss
;
1428 ss
<< "Unhandled sygus constructor " << unresolved_gterm_sym
[i
];
1429 throw ParserException(ss
.str());
1435 Expr
Smt2::makeSygusBoundVarList(Datatype
& dt
,
1437 const std::vector
<Type
>& ltypes
,
1438 std::vector
<Expr
>& lvars
)
1440 for (unsigned j
= 0, size
= ltypes
.size(); j
< size
; j
++)
1442 std::stringstream ss
;
1443 ss
<< dt
.getName() << "_x_" << i
<< "_" << j
;
1444 Expr v
= mkBoundVar(ss
.str(), ltypes
[j
]);
1447 return getExprManager()->mkExpr(kind::BOUND_VAR_LIST
, lvars
);
1450 void Smt2::addSygusConstructorTerm(Datatype
& dt
,
1452 std::map
<Expr
, Type
>& ntsToUnres
) const
1454 Trace("parser-sygus2") << "Add sygus cons term " << term
<< std::endl
;
1455 // Ensure that we do type checking here to catch sygus constructors with
1456 // malformed builtin operators. The argument "true" to getType here forces
1457 // a recursive well-typedness check.
1459 // purify each occurrence of a non-terminal symbol in term, replace by
1460 // free variables. These become arguments to constructors. Notice we must do
1461 // a tree traversal in this function, since unique paths to the same term
1462 // should be treated as distinct terms.
1463 // Notice that let expressions are forbidden in the input syntax of term, so
1464 // this does not lead to exponential behavior with respect to input size.
1465 std::vector
<api::Term
> args
;
1466 std::vector
<api::Sort
> cargs
;
1467 api::Term op
= purifySygusGTerm(api::Term(term
), ntsToUnres
, args
, cargs
);
1468 std::stringstream ssCName
;
1469 ssCName
<< op
.getKind();
1470 Trace("parser-sygus2") << "Purified operator " << op
1471 << ", #args/cargs=" << args
.size() << "/"
1472 << cargs
.size() << std::endl
;
1473 std::shared_ptr
<SygusPrintCallback
> spc
;
1474 // callback prints as the expression
1475 spc
= std::make_shared
<printer::SygusExprPrintCallback
>(
1476 op
.getExpr(), api::termVectorToExprs(args
));
1479 api::Term lbvl
= d_solver
->mkTerm(api::BOUND_VAR_LIST
, args
);
1480 // its operator is a lambda
1481 op
= d_solver
->mkTerm(api::LAMBDA
, lbvl
, op
);
1483 Trace("parser-sygus2") << "addSygusConstructor: operator " << op
1485 dt
.addSygusConstructor(
1486 op
.getExpr(), ssCName
.str(), api::sortVectorToTypes(cargs
), spc
);
1489 api::Term
Smt2::purifySygusGTerm(api::Term term
,
1490 std::map
<Expr
, Type
>& ntsToUnres
,
1491 std::vector
<api::Term
>& args
,
1492 std::vector
<api::Sort
>& cargs
) const
1494 Trace("parser-sygus2-debug")
1495 << "purifySygusGTerm: " << term
1496 << " #nchild=" << term
.getExpr().getNumChildren() << std::endl
;
1497 std::map
<Expr
, Type
>::iterator itn
= ntsToUnres
.find(term
.getExpr());
1498 if (itn
!= ntsToUnres
.end())
1500 api::Term ret
= d_solver
->mkVar(term
.getSort());
1501 Trace("parser-sygus2-debug")
1502 << "...unresolved non-terminal, intro " << ret
<< std::endl
;
1503 args
.push_back(ret
.getExpr());
1504 cargs
.push_back(itn
->second
);
1507 std::vector
<api::Term
> pchildren
;
1508 bool childChanged
= false;
1509 for (unsigned i
= 0, nchild
= term
.getNumChildren(); i
< nchild
; i
++)
1511 Trace("parser-sygus2-debug")
1512 << "......purify child " << i
<< " : " << term
[i
] << std::endl
;
1513 api::Term ptermc
= purifySygusGTerm(term
[i
], ntsToUnres
, args
, cargs
);
1514 pchildren
.push_back(ptermc
);
1515 childChanged
= childChanged
|| ptermc
!= term
[i
];
1519 Trace("parser-sygus2-debug") << "...no child changed" << std::endl
;
1522 api::Term nret
= d_solver
->mkTerm(term
.getOp(), pchildren
);
1523 Trace("parser-sygus2-debug")
1524 << "...child changed, return " << nret
<< std::endl
;
1528 void Smt2::addSygusConstructorVariables(Datatype
& dt
,
1529 const std::vector
<Expr
>& sygusVars
,
1532 // each variable of appropriate type becomes a sygus constructor in dt.
1533 for (unsigned i
= 0, size
= sygusVars
.size(); i
< size
; i
++)
1535 Expr v
= sygusVars
[i
];
1536 if (v
.getType() == type
)
1538 std::stringstream ss
;
1540 std::vector
<CVC4::Type
> cargs
;
1541 dt
.addSygusConstructor(v
, ss
.str(), cargs
);
1546 InputLanguage
Smt2::getLanguage() const
1548 ExprManager
* em
= getExprManager();
1549 return em
->getOptions().getInputLanguage();
1552 void Smt2::parseOpApplyTypeAscription(ParseOp
& p
, Type type
)
1554 Debug("parser") << "parseOpApplyTypeAscription : " << p
<< " " << type
1556 // (as const (Array T1 T2))
1557 if (p
.d_kind
== kind::STORE_ALL
)
1559 if (!type
.isArray())
1561 std::stringstream ss
;
1562 ss
<< "expected array constant term, but cast is not of array type"
1564 << "cast type: " << type
;
1565 parseError(ss
.str());
1570 if (p
.d_expr
.isNull())
1572 Trace("parser-overloading")
1573 << "Getting variable expression with name " << p
.d_name
<< " and type "
1574 << type
<< std::endl
;
1575 // get the variable expression for the type
1576 if (isDeclared(p
.d_name
, SYM_VARIABLE
))
1578 p
.d_expr
= getExpressionForNameAndType(p
.d_name
, type
);
1580 if (p
.d_expr
.isNull())
1582 std::stringstream ss
;
1583 ss
<< "Could not resolve expression with name " << p
.d_name
1584 << " and type " << type
<< std::endl
;
1585 parseError(ss
.str());
1588 Trace("parser-qid") << "Resolve ascription " << type
<< " on " << p
.d_expr
;
1589 Trace("parser-qid") << " " << p
.d_expr
.getKind() << " " << p
.d_expr
.getType();
1590 Trace("parser-qid") << std::endl
;
1591 // otherwise, we process the type ascription
1593 applyTypeAscription(api::Term(p
.d_expr
), api::Sort(type
)).getExpr();
1596 Expr
Smt2::parseOpToExpr(ParseOp
& p
)
1599 if (p
.d_kind
!= kind::NULL_EXPR
|| !p
.d_type
.isNull())
1602 "Bad syntax for qualified identifier operator in term position.");
1604 else if (!p
.d_expr
.isNull())
1608 else if (!isDeclared(p
.d_name
, SYM_VARIABLE
))
1610 if (sygus_v1() && p
.d_name
[0] == '-'
1611 && p
.d_name
.find_first_not_of("0123456789", 1) == std::string::npos
)
1613 // allow unary minus in sygus version 1
1614 expr
= getExprManager()->mkConst(Rational(p
.d_name
));
1618 std::stringstream ss
;
1619 ss
<< "Symbol " << p
.d_name
<< " is not declared.";
1620 parseError(ss
.str());
1625 expr
= getExpressionForName(p
.d_name
);
1627 assert(!expr
.isNull());
1631 Expr
Smt2::applyParseOp(ParseOp
& p
, std::vector
<Expr
>& args
)
1633 bool isBuiltinOperator
= false;
1634 // the builtin kind of the overall return expression
1635 Kind kind
= kind::NULL_EXPR
;
1636 // First phase: process the operator
1637 if (Debug
.isOn("parser"))
1639 Debug("parser") << "applyParseOp: " << p
<< " to:" << std::endl
;
1640 for (std::vector
<Expr
>::iterator i
= args
.begin(); i
!= args
.end(); ++i
)
1642 Debug("parser") << "++ " << *i
<< std::endl
;
1646 if (p
.d_kind
!= kind::NULL_EXPR
)
1648 // It is a special case, e.g. tupSel or array constant specification.
1649 // We have to wait until the arguments are parsed to resolve it.
1651 else if (!p
.d_expr
.isNull())
1653 // An explicit operator, e.g. an indexed symbol.
1654 args
.insert(args
.begin(), p
.d_expr
);
1655 Kind fkind
= getKindForFunction(p
.d_expr
);
1656 if (fkind
!= kind::UNDEFINED_KIND
)
1658 // Some operators may require a specific kind.
1659 // Testers are handled differently than other indexed operators,
1660 // since they require a kind.
1664 else if (!p
.d_op
.isNull())
1666 // it was given an operator
1671 isBuiltinOperator
= isOperatorEnabled(p
.d_name
);
1672 if (isBuiltinOperator
)
1674 // a builtin operator, convert to kind
1675 kind
= getOperatorKind(p
.d_name
);
1679 // A non-built-in function application, get the expression
1680 checkDeclaration(p
.d_name
, CHECK_DECLARED
, SYM_VARIABLE
);
1681 Expr v
= getVariable(p
.d_name
);
1684 checkFunctionLike(v
);
1685 kind
= getKindForFunction(v
);
1686 args
.insert(args
.begin(), v
);
1690 // Overloaded symbol?
1691 // Could not find the expression. It may be an overloaded symbol,
1692 // in which case we may find it after knowing the types of its
1694 std::vector
<Type
> argTypes
;
1695 for (std::vector
<Expr
>::iterator i
= args
.begin(); i
!= args
.end(); ++i
)
1697 argTypes
.push_back((*i
).getType());
1699 Expr op
= getOverloadedFunctionForTypes(p
.d_name
, argTypes
);
1702 checkFunctionLike(op
);
1703 kind
= getKindForFunction(op
);
1704 args
.insert(args
.begin(), op
);
1709 "Cannot find unambiguous overloaded function for argument "
1715 // Second phase: apply the arguments to the parse op
1716 ExprManager
* em
= getExprManager();
1717 // handle special cases
1718 if (p
.d_kind
== kind::STORE_ALL
&& !p
.d_type
.isNull())
1720 if (args
.size() != 1)
1722 parseError("Too many arguments to array constant.");
1724 Expr constVal
= args
[0];
1725 if (!constVal
.isConst())
1727 // To parse array constants taking reals whose values are specified by
1728 // rationals, e.g. ((as const (Array Int Real)) (/ 1 3)), we must handle
1729 // the fact that (/ 1 3) is the division of constants 1 and 3, and not
1730 // the resulting constant rational value. Thus, we must construct the
1731 // resulting rational here. This also is applied for integral real values
1732 // like 5.0 which are converted to (/ 5 1) to distinguish them from
1733 // integer constants. We must ensure numerator and denominator are
1734 // constant and the denominator is non-zero.
1735 if (constVal
.getKind() == kind::DIVISION
&& constVal
[0].isConst()
1736 && constVal
[1].isConst()
1737 && !constVal
[1].getConst
<Rational
>().isZero())
1739 constVal
= em
->mkConst(constVal
[0].getConst
<Rational
>()
1740 / constVal
[1].getConst
<Rational
>());
1742 if (!constVal
.isConst())
1744 std::stringstream ss
;
1745 ss
<< "expected constant term inside array constant, but found "
1746 << "nonconstant term:" << std::endl
1747 << "the term: " << constVal
;
1748 parseError(ss
.str());
1751 ArrayType aqtype
= static_cast<ArrayType
>(p
.d_type
);
1752 if (!aqtype
.getConstituentType().isComparableTo(constVal
.getType()))
1754 std::stringstream ss
;
1755 ss
<< "type mismatch inside array constant term:" << std::endl
1756 << "array type: " << p
.d_type
<< std::endl
1757 << "expected const type: " << aqtype
.getConstituentType() << std::endl
1758 << "computed const type: " << constVal
.getType();
1759 parseError(ss
.str());
1761 return em
->mkConst(ArrayStoreAll(p
.d_type
, constVal
));
1763 else if (p
.d_kind
== kind::APPLY_SELECTOR
&& !p
.d_expr
.isNull())
1765 // tuple selector case
1766 Integer x
= p
.d_expr
.getConst
<Rational
>().getNumerator();
1767 if (!x
.fitsUnsignedInt())
1769 parseError("index of tupSel is larger than size of unsigned int");
1771 unsigned int n
= x
.toUnsignedInt();
1772 if (args
.size() > 1)
1774 parseError("tupSel applied to more than one tuple argument");
1776 Type t
= args
[0].getType();
1779 parseError("tupSel applied to non-tuple");
1781 size_t length
= ((DatatypeType
)t
).getTupleLength();
1784 std::stringstream ss
;
1785 ss
<< "tuple is of length " << length
<< "; cannot access index " << n
;
1786 parseError(ss
.str());
1788 const Datatype
& dt
= ((DatatypeType
)t
).getDatatype();
1789 return em
->mkExpr(kind::APPLY_SELECTOR
, dt
[0][n
].getSelector(), args
);
1791 else if (p
.d_kind
!= kind::NULL_EXPR
)
1793 // it should not have an expression or type specified at this point
1794 if (!p
.d_expr
.isNull() || !p
.d_type
.isNull())
1796 std::stringstream ss
;
1797 ss
<< "Could not process parsed qualified identifier kind " << p
.d_kind
;
1798 parseError(ss
.str());
1800 // otherwise it is a simple application
1803 else if (isBuiltinOperator
)
1805 if (!em
->getOptions().getUfHo()
1806 && (kind
== kind::EQUAL
|| kind
== kind::DISTINCT
))
1808 // need --uf-ho if these operators are applied over function args
1809 for (std::vector
<Expr
>::iterator i
= args
.begin(); i
!= args
.end(); ++i
)
1811 if ((*i
).getType().isFunction())
1814 "Cannot apply equalty to functions unless --uf-ho is set.");
1818 if (!strictModeEnabled() && (kind
== kind::AND
|| kind
== kind::OR
)
1819 && args
.size() == 1)
1821 // Unary AND/OR can be replaced with the argument.
1824 else if (kind
== kind::MINUS
&& args
.size() == 1)
1826 return em
->mkExpr(kind::UMINUS
, args
[0]);
1829 d_solver
->mkTerm(intToExtKind(kind
), api::exprVectorToTerms(args
));
1830 Debug("parser") << "applyParseOp: return default builtin " << ret
1832 return ret
.getExpr();
1835 if (args
.size() >= 2)
1837 // may be partially applied function, in this case we use HO_APPLY
1838 Type argt
= args
[0].getType();
1839 if (argt
.isFunction())
1841 unsigned arity
= static_cast<FunctionType
>(argt
).getArity();
1842 if (args
.size() - 1 < arity
)
1844 if (!em
->getOptions().getUfHo())
1846 parseError("Cannot partially apply functions unless --uf-ho is set.");
1848 Debug("parser") << "Partial application of " << args
[0];
1849 Debug("parser") << " : #argTypes = " << arity
;
1850 Debug("parser") << ", #args = " << args
.size() - 1 << std::endl
;
1851 // must curry the partial application
1852 return em
->mkLeftAssociative(kind::HO_APPLY
, args
);
1858 api::Term ret
= d_solver
->mkTerm(op
, api::exprVectorToTerms(args
));
1859 Debug("parser") << "applyParseOp: return op : " << ret
<< std::endl
;
1860 return ret
.getExpr();
1862 if (kind
== kind::NULL_EXPR
)
1864 std::vector
<Expr
> eargs(args
.begin() + 1, args
.end());
1865 return em
->mkExpr(args
[0], eargs
);
1867 return em
->mkExpr(kind
, args
);
1870 Expr
Smt2::setNamedAttribute(Expr
& expr
, const SExpr
& sexpr
)
1872 if (!sexpr
.isKeyword())
1874 parseError("improperly formed :named annotation");
1876 std::string name
= sexpr
.getValue();
1877 checkUserSymbol(name
);
1878 // ensure expr is a closed subterm
1879 if (expr
.hasFreeVariable())
1881 std::stringstream ss
;
1882 ss
<< ":named annotations can only name terms that are closed";
1883 parseError(ss
.str());
1885 // check that sexpr is a fresh function symbol, and reserve it
1886 reserveSymbolAtAssertionLevel(name
);
1888 Expr func
= mkVar(name
, expr
.getType(), ExprManager::VAR_FLAG_DEFINED
);
1889 // remember the last term to have been given a :named attribute
1890 setLastNamedTerm(expr
, name
);
1894 Expr
Smt2::mkAnd(const std::vector
<Expr
>& es
)
1896 ExprManager
* em
= getExprManager();
1900 return em
->mkConst(true);
1902 else if (es
.size() == 1)
1908 return em
->mkExpr(kind::AND
, es
);
1912 } // namespace parser
1913 }/* CVC4 namespace */