Makes SyGuS parsing more robust in invariant problems (#2509)
[cvc5.git] / src / parser / smt2 / smt2.cpp
1 /********************* */
2 /*! \file smt2.cpp
3 ** \verbatim
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-2018 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
11 **
12 ** \brief Definitions of SMT2 constants.
13 **
14 ** Definitions of SMT2 constants.
15 **/
16 #include "parser/smt2/smt2.h"
17
18 #include "api/cvc4cpp.h"
19 #include "expr/type.h"
20 #include "options/options.h"
21 #include "parser/antlr_input.h"
22 #include "parser/parser.h"
23 #include "parser/smt1/smt1.h"
24 #include "parser/smt2/smt2_input.h"
25 #include "printer/sygus_print_callback.h"
26 #include "smt/command.h"
27 #include "util/bitvector.h"
28
29 #include <algorithm>
30
31 // ANTLR defines these, which is really bad!
32 #undef true
33 #undef false
34
35 namespace CVC4 {
36 namespace parser {
37
38 Smt2::Smt2(api::Solver* solver, Input* input, bool strictMode, bool parseOnly)
39 : Parser(solver, input, strictMode, parseOnly), d_logicSet(false)
40 {
41 if (!strictModeEnabled())
42 {
43 addTheory(Smt2::THEORY_CORE);
44 }
45 }
46
47 void Smt2::addArithmeticOperators() {
48 Parser::addOperator(kind::PLUS);
49 Parser::addOperator(kind::MINUS);
50 Parser::addOperator(kind::UMINUS);
51 Parser::addOperator(kind::MULT);
52 Parser::addOperator(kind::LT);
53 Parser::addOperator(kind::LEQ);
54 Parser::addOperator(kind::GT);
55 Parser::addOperator(kind::GEQ);
56
57 // NOTE: this operator is non-standard
58 addOperator(kind::POW, "^");
59 }
60
61 void Smt2::addTranscendentalOperators()
62 {
63 addOperator(kind::EXPONENTIAL, "exp");
64 addOperator(kind::SINE, "sin");
65 addOperator(kind::COSINE, "cos");
66 addOperator(kind::TANGENT, "tan");
67 addOperator(kind::COSECANT, "csc");
68 addOperator(kind::SECANT, "sec");
69 addOperator(kind::COTANGENT, "cot");
70 addOperator(kind::ARCSINE, "arcsin");
71 addOperator(kind::ARCCOSINE, "arccos");
72 addOperator(kind::ARCTANGENT, "arctan");
73 addOperator(kind::ARCCOSECANT, "arccsc");
74 addOperator(kind::ARCSECANT, "arcsec");
75 addOperator(kind::ARCCOTANGENT, "arccot");
76 addOperator(kind::SQRT, "sqrt");
77 }
78
79 void Smt2::addBitvectorOperators() {
80 addOperator(kind::BITVECTOR_CONCAT, "concat");
81 addOperator(kind::BITVECTOR_NOT, "bvnot");
82 addOperator(kind::BITVECTOR_AND, "bvand");
83 addOperator(kind::BITVECTOR_OR, "bvor");
84 addOperator(kind::BITVECTOR_NEG, "bvneg");
85 addOperator(kind::BITVECTOR_PLUS, "bvadd");
86 addOperator(kind::BITVECTOR_MULT, "bvmul");
87 addOperator(kind::BITVECTOR_UDIV, "bvudiv");
88 addOperator(kind::BITVECTOR_UREM, "bvurem");
89 addOperator(kind::BITVECTOR_SHL, "bvshl");
90 addOperator(kind::BITVECTOR_LSHR, "bvlshr");
91 addOperator(kind::BITVECTOR_ULT, "bvult");
92 addOperator(kind::BITVECTOR_NAND, "bvnand");
93 addOperator(kind::BITVECTOR_NOR, "bvnor");
94 addOperator(kind::BITVECTOR_XOR, "bvxor");
95 addOperator(kind::BITVECTOR_XNOR, "bvxnor");
96 addOperator(kind::BITVECTOR_COMP, "bvcomp");
97 addOperator(kind::BITVECTOR_SUB, "bvsub");
98 addOperator(kind::BITVECTOR_SDIV, "bvsdiv");
99 addOperator(kind::BITVECTOR_SREM, "bvsrem");
100 addOperator(kind::BITVECTOR_SMOD, "bvsmod");
101 addOperator(kind::BITVECTOR_ASHR, "bvashr");
102 addOperator(kind::BITVECTOR_ULE, "bvule");
103 addOperator(kind::BITVECTOR_UGT, "bvugt");
104 addOperator(kind::BITVECTOR_UGE, "bvuge");
105 addOperator(kind::BITVECTOR_SLT, "bvslt");
106 addOperator(kind::BITVECTOR_SLE, "bvsle");
107 addOperator(kind::BITVECTOR_SGT, "bvsgt");
108 addOperator(kind::BITVECTOR_SGE, "bvsge");
109 addOperator(kind::BITVECTOR_REDOR, "bvredor");
110 addOperator(kind::BITVECTOR_REDAND, "bvredand");
111
112 Parser::addOperator(kind::BITVECTOR_BITOF);
113 Parser::addOperator(kind::BITVECTOR_EXTRACT);
114 Parser::addOperator(kind::BITVECTOR_REPEAT);
115 Parser::addOperator(kind::BITVECTOR_ZERO_EXTEND);
116 Parser::addOperator(kind::BITVECTOR_SIGN_EXTEND);
117 Parser::addOperator(kind::BITVECTOR_ROTATE_LEFT);
118 Parser::addOperator(kind::BITVECTOR_ROTATE_RIGHT);
119
120 Parser::addOperator(kind::INT_TO_BITVECTOR);
121 Parser::addOperator(kind::BITVECTOR_TO_NAT);
122 }
123
124 void Smt2::addStringOperators() {
125 addOperator(kind::STRING_CONCAT, "str.++");
126 addOperator(kind::STRING_LENGTH, "str.len");
127 addOperator(kind::STRING_SUBSTR, "str.substr" );
128 addOperator(kind::STRING_STRCTN, "str.contains" );
129 addOperator(kind::STRING_CHARAT, "str.at" );
130 addOperator(kind::STRING_STRIDOF, "str.indexof" );
131 addOperator(kind::STRING_STRREPL, "str.replace" );
132 addOperator(kind::STRING_PREFIX, "str.prefixof" );
133 addOperator(kind::STRING_SUFFIX, "str.suffixof" );
134 // at the moment, we only use this syntax for smt2.6.1
135 if (getLanguage() == language::input::LANG_SMTLIB_V2_6_1)
136 {
137 addOperator(kind::STRING_ITOS, "str.from-int");
138 addOperator(kind::STRING_STOI, "str.to-int");
139 addOperator(kind::STRING_IN_REGEXP, "str.in-re");
140 addOperator(kind::STRING_TO_REGEXP, "str.to-re");
141 }
142 else
143 {
144 addOperator(kind::STRING_ITOS, "int.to.str");
145 addOperator(kind::STRING_STOI, "str.to.int");
146 addOperator(kind::STRING_IN_REGEXP, "str.in.re");
147 addOperator(kind::STRING_TO_REGEXP, "str.to.re");
148 }
149
150 addOperator(kind::REGEXP_CONCAT, "re.++");
151 addOperator(kind::REGEXP_UNION, "re.union");
152 addOperator(kind::REGEXP_INTER, "re.inter");
153 addOperator(kind::REGEXP_STAR, "re.*");
154 addOperator(kind::REGEXP_PLUS, "re.+");
155 addOperator(kind::REGEXP_OPT, "re.opt");
156 addOperator(kind::REGEXP_RANGE, "re.range");
157 addOperator(kind::REGEXP_LOOP, "re.loop");
158 addOperator(kind::STRING_CODE, "str.code");
159 addOperator(kind::STRING_LT, "str.<");
160 addOperator(kind::STRING_LEQ, "str.<=");
161 }
162
163 void Smt2::addFloatingPointOperators() {
164 addOperator(kind::FLOATINGPOINT_FP, "fp");
165 addOperator(kind::FLOATINGPOINT_EQ, "fp.eq");
166 addOperator(kind::FLOATINGPOINT_ABS, "fp.abs");
167 addOperator(kind::FLOATINGPOINT_NEG, "fp.neg");
168 addOperator(kind::FLOATINGPOINT_PLUS, "fp.add");
169 addOperator(kind::FLOATINGPOINT_SUB, "fp.sub");
170 addOperator(kind::FLOATINGPOINT_MULT, "fp.mul");
171 addOperator(kind::FLOATINGPOINT_DIV, "fp.div");
172 addOperator(kind::FLOATINGPOINT_FMA, "fp.fma");
173 addOperator(kind::FLOATINGPOINT_SQRT, "fp.sqrt");
174 addOperator(kind::FLOATINGPOINT_REM, "fp.rem");
175 addOperator(kind::FLOATINGPOINT_RTI, "fp.roundToIntegral");
176 addOperator(kind::FLOATINGPOINT_MIN, "fp.min");
177 addOperator(kind::FLOATINGPOINT_MAX, "fp.max");
178 addOperator(kind::FLOATINGPOINT_LEQ, "fp.leq");
179 addOperator(kind::FLOATINGPOINT_LT, "fp.lt");
180 addOperator(kind::FLOATINGPOINT_GEQ, "fp.geq");
181 addOperator(kind::FLOATINGPOINT_GT, "fp.gt");
182 addOperator(kind::FLOATINGPOINT_ISN, "fp.isNormal");
183 addOperator(kind::FLOATINGPOINT_ISSN, "fp.isSubnormal");
184 addOperator(kind::FLOATINGPOINT_ISZ, "fp.isZero");
185 addOperator(kind::FLOATINGPOINT_ISINF, "fp.isInfinite");
186 addOperator(kind::FLOATINGPOINT_ISNAN, "fp.isNaN");
187 addOperator(kind::FLOATINGPOINT_ISNEG, "fp.isNegative");
188 addOperator(kind::FLOATINGPOINT_ISPOS, "fp.isPositive");
189 addOperator(kind::FLOATINGPOINT_TO_REAL, "fp.to_real");
190
191 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR);
192 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT);
193 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_REAL);
194 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR);
195 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR);
196 Parser::addOperator(kind::FLOATINGPOINT_TO_UBV);
197 Parser::addOperator(kind::FLOATINGPOINT_TO_SBV);
198 }
199
200 void Smt2::addSepOperators() {
201 addOperator(kind::SEP_STAR, "sep");
202 addOperator(kind::SEP_PTO, "pto");
203 addOperator(kind::SEP_WAND, "wand");
204 addOperator(kind::SEP_EMP, "emp");
205 Parser::addOperator(kind::SEP_STAR);
206 Parser::addOperator(kind::SEP_PTO);
207 Parser::addOperator(kind::SEP_WAND);
208 Parser::addOperator(kind::SEP_EMP);
209 }
210
211 void Smt2::addTheory(Theory theory) {
212 switch(theory) {
213 case THEORY_ARRAYS:
214 addOperator(kind::SELECT, "select");
215 addOperator(kind::STORE, "store");
216 break;
217
218 case THEORY_BITVECTORS:
219 addBitvectorOperators();
220 break;
221
222 case THEORY_CORE:
223 defineType("Bool", getExprManager()->booleanType());
224 defineVar("true", getExprManager()->mkConst(true));
225 defineVar("false", getExprManager()->mkConst(false));
226 Parser::addOperator(kind::AND);
227 Parser::addOperator(kind::DISTINCT);
228 Parser::addOperator(kind::EQUAL);
229 Parser::addOperator(kind::IMPLIES);
230 Parser::addOperator(kind::ITE);
231 Parser::addOperator(kind::NOT);
232 Parser::addOperator(kind::OR);
233 Parser::addOperator(kind::XOR);
234 break;
235
236 case THEORY_REALS_INTS:
237 defineType("Real", getExprManager()->realType());
238 Parser::addOperator(kind::DIVISION);
239 addOperator(kind::TO_INTEGER, "to_int");
240 addOperator(kind::IS_INTEGER, "is_int");
241 addOperator(kind::TO_REAL, "to_real");
242 // falling through on purpose, to add Ints part of Reals_Ints
243 case THEORY_INTS:
244 defineType("Int", getExprManager()->integerType());
245 addArithmeticOperators();
246 addOperator(kind::INTS_DIVISION, "div");
247 addOperator(kind::INTS_MODULUS, "mod");
248 addOperator(kind::ABS, "abs");
249 Parser::addOperator(kind::DIVISIBLE);
250 break;
251
252 case THEORY_REALS:
253 defineType("Real", getExprManager()->realType());
254 addArithmeticOperators();
255 Parser::addOperator(kind::DIVISION);
256 break;
257
258 case THEORY_TRANSCENDENTALS: addTranscendentalOperators(); break;
259
260 case THEORY_QUANTIFIERS:
261 break;
262
263 case THEORY_SETS:
264 addOperator(kind::UNION, "union");
265 addOperator(kind::INTERSECTION, "intersection");
266 addOperator(kind::SETMINUS, "setminus");
267 addOperator(kind::SUBSET, "subset");
268 addOperator(kind::MEMBER, "member");
269 addOperator(kind::SINGLETON, "singleton");
270 addOperator(kind::INSERT, "insert");
271 addOperator(kind::CARD, "card");
272 addOperator(kind::COMPLEMENT, "complement");
273 addOperator(kind::JOIN, "join");
274 addOperator(kind::PRODUCT, "product");
275 addOperator(kind::TRANSPOSE, "transpose");
276 addOperator(kind::TCLOSURE, "tclosure");
277 break;
278
279 case THEORY_DATATYPES:
280 {
281 const std::vector<Type> types;
282 defineType("Tuple", getExprManager()->mkTupleType(types));
283 Parser::addOperator(kind::APPLY_CONSTRUCTOR);
284 Parser::addOperator(kind::APPLY_TESTER);
285 Parser::addOperator(kind::APPLY_SELECTOR);
286 Parser::addOperator(kind::APPLY_SELECTOR_TOTAL);
287 break;
288 }
289
290 case THEORY_STRINGS:
291 defineType("String", getExprManager()->stringType());
292 defineType("RegLan", getExprManager()->regExpType());
293 defineType("Int", getExprManager()->integerType());
294 addStringOperators();
295 break;
296
297 case THEORY_UF:
298 Parser::addOperator(kind::APPLY_UF);
299 break;
300
301 case THEORY_FP:
302 defineType("RoundingMode", getExprManager()->roundingModeType());
303 defineType("Float16", getExprManager()->mkFloatingPointType(5, 11));
304 defineType("Float32", getExprManager()->mkFloatingPointType(8, 24));
305 defineType("Float64", getExprManager()->mkFloatingPointType(11, 53));
306 defineType("Float128", getExprManager()->mkFloatingPointType(15, 113));
307 addFloatingPointOperators();
308 break;
309
310 case THEORY_SEP:
311 addSepOperators();
312 break;
313
314 default:
315 std::stringstream ss;
316 ss << "internal error: unsupported theory " << theory;
317 throw ParserException(ss.str());
318 }
319 }
320
321 void Smt2::addOperator(Kind kind, const std::string& name) {
322 Debug("parser") << "Smt2::addOperator( " << kind << ", " << name << " )"
323 << std::endl;
324 Parser::addOperator(kind);
325 operatorKindMap[name] = kind;
326 }
327
328 Kind Smt2::getOperatorKind(const std::string& name) const {
329 // precondition: isOperatorEnabled(name)
330 return operatorKindMap.find(name)->second;
331 }
332
333 bool Smt2::isOperatorEnabled(const std::string& name) const {
334 return operatorKindMap.find(name) != operatorKindMap.end();
335 }
336
337 bool Smt2::isTheoryEnabled(Theory theory) const {
338 switch(theory) {
339 case THEORY_ARRAYS:
340 return d_logic.isTheoryEnabled(theory::THEORY_ARRAYS);
341 case THEORY_BITVECTORS:
342 return d_logic.isTheoryEnabled(theory::THEORY_BV);
343 case THEORY_CORE:
344 return true;
345 case THEORY_DATATYPES:
346 return d_logic.isTheoryEnabled(theory::THEORY_DATATYPES);
347 case THEORY_INTS:
348 return d_logic.isTheoryEnabled(theory::THEORY_ARITH) &&
349 d_logic.areIntegersUsed() && ( !d_logic.areRealsUsed() );
350 case THEORY_REALS:
351 return d_logic.isTheoryEnabled(theory::THEORY_ARITH) &&
352 ( !d_logic.areIntegersUsed() ) && d_logic.areRealsUsed();
353 case THEORY_REALS_INTS:
354 return d_logic.isTheoryEnabled(theory::THEORY_ARITH) &&
355 d_logic.areIntegersUsed() && d_logic.areRealsUsed();
356 case THEORY_QUANTIFIERS:
357 return d_logic.isQuantified();
358 case THEORY_SETS:
359 return d_logic.isTheoryEnabled(theory::THEORY_SETS);
360 case THEORY_STRINGS:
361 return d_logic.isTheoryEnabled(theory::THEORY_STRINGS);
362 case THEORY_UF:
363 return d_logic.isTheoryEnabled(theory::THEORY_UF);
364 case THEORY_FP:
365 return d_logic.isTheoryEnabled(theory::THEORY_FP);
366 case THEORY_SEP:
367 return d_logic.isTheoryEnabled(theory::THEORY_SEP);
368 default:
369 std::stringstream ss;
370 ss << "internal error: unsupported theory " << theory;
371 throw ParserException(ss.str());
372 }
373 }
374
375 bool Smt2::logicIsSet() {
376 return d_logicSet;
377 }
378
379 Expr Smt2::getExpressionForNameAndType(const std::string& name, Type t) {
380 if(sygus() && name[0]=='-' &&
381 name.find_first_not_of("0123456789", 1) == std::string::npos) {
382 //allow unary minus in sygus
383 return getExprManager()->mkConst(Rational(name));
384 }else if(isAbstractValue(name)) {
385 return mkAbstractValue(name);
386 }else{
387 return Parser::getExpressionForNameAndType(name, t);
388 }
389 }
390
391 Expr Smt2::mkDefineFunRec(
392 const std::string& fname,
393 const std::vector<std::pair<std::string, Type> >& sortedVarNames,
394 Type t,
395 std::vector<Expr>& flattenVars)
396 {
397 std::vector<Type> sorts;
398 for (const std::pair<std::string, CVC4::Type>& svn : sortedVarNames)
399 {
400 sorts.push_back(svn.second);
401 }
402
403 // make the flattened function type, add bound variables
404 // to flattenVars if the defined function was given a function return type.
405 Type ft = mkFlatFunctionType(sorts, t, flattenVars);
406
407 // allow overloading
408 return mkVar(fname, ft, ExprManager::VAR_FLAG_NONE, true);
409 }
410
411 void Smt2::pushDefineFunRecScope(
412 const std::vector<std::pair<std::string, Type> >& sortedVarNames,
413 Expr func,
414 const std::vector<Expr>& flattenVars,
415 std::vector<Expr>& bvs,
416 bool bindingLevel)
417 {
418 pushScope(bindingLevel);
419
420 // bound variables are those that are explicitly named in the preamble
421 // of the define-fun(s)-rec command, we define them here
422 for (const std::pair<std::string, CVC4::Type>& svn : sortedVarNames)
423 {
424 Expr v = mkBoundVar(svn.first, svn.second);
425 bvs.push_back(v);
426 }
427
428 bvs.insert(bvs.end(), flattenVars.begin(), flattenVars.end());
429 }
430
431 void Smt2::reset() {
432 d_logicSet = false;
433 d_logic = LogicInfo();
434 operatorKindMap.clear();
435 d_lastNamedTerm = std::pair<Expr, std::string>();
436 this->Parser::reset();
437
438 if( !strictModeEnabled() ) {
439 addTheory(Smt2::THEORY_CORE);
440 }
441 }
442
443 void Smt2::resetAssertions() {
444 // Remove all declarations except the ones at level 0.
445 while (this->scopeLevel() > 0) {
446 this->popScope();
447 }
448 }
449
450 void Smt2::setLogic(std::string name) {
451
452 if(sygus()) {
453 // non-smt2-standard sygus logic names go here (http://sygus.seas.upenn.edu/files/sygus.pdf Section 3.2)
454 if(name == "Arrays") {
455 name = "A";
456 }else if(name == "Reals") {
457 name = "LRA";
458 }
459 }
460
461 d_logicSet = true;
462 if(logicIsForced()) {
463 d_logic = getForcedLogic();
464 } else {
465 d_logic = name;
466 }
467
468 // if sygus is enabled, we must enable UF, datatypes, integer arithmetic and
469 // higher-order
470 if(sygus()) {
471 if (!d_logic.isQuantified())
472 {
473 warning("Logics in sygus are assumed to contain quantifiers.");
474 warning("Omit QF_ from the logic to avoid this warning.");
475 }
476 // get unlocked copy, modify, copy and relock
477 LogicInfo log(d_logic.getUnlockedCopy());
478 log.enableQuantifiers();
479 log.enableTheory(theory::THEORY_UF);
480 log.enableTheory(theory::THEORY_DATATYPES);
481 log.enableIntegers();
482 log.enableHigherOrder();
483 d_logic = log;
484 d_logic.lock();
485 }
486
487 // Core theory belongs to every logic
488 addTheory(THEORY_CORE);
489
490 if(d_logic.isTheoryEnabled(theory::THEORY_UF)) {
491 addTheory(THEORY_UF);
492 }
493
494 if(d_logic.isTheoryEnabled(theory::THEORY_ARITH)) {
495 if(d_logic.areIntegersUsed()) {
496 if(d_logic.areRealsUsed()) {
497 addTheory(THEORY_REALS_INTS);
498 } else {
499 addTheory(THEORY_INTS);
500 }
501 } else if(d_logic.areRealsUsed()) {
502 addTheory(THEORY_REALS);
503 }
504
505 if (d_logic.areTranscendentalsUsed())
506 {
507 addTheory(THEORY_TRANSCENDENTALS);
508 }
509 }
510
511 if(d_logic.isTheoryEnabled(theory::THEORY_ARRAYS)) {
512 addTheory(THEORY_ARRAYS);
513 }
514
515 if(d_logic.isTheoryEnabled(theory::THEORY_BV)) {
516 addTheory(THEORY_BITVECTORS);
517 }
518
519 if(d_logic.isTheoryEnabled(theory::THEORY_DATATYPES)) {
520 addTheory(THEORY_DATATYPES);
521 }
522
523 if(d_logic.isTheoryEnabled(theory::THEORY_SETS)) {
524 addTheory(THEORY_SETS);
525 }
526
527 if(d_logic.isTheoryEnabled(theory::THEORY_STRINGS)) {
528 addTheory(THEORY_STRINGS);
529 }
530
531 if(d_logic.isQuantified()) {
532 addTheory(THEORY_QUANTIFIERS);
533 }
534
535 if (d_logic.isTheoryEnabled(theory::THEORY_FP)) {
536 addTheory(THEORY_FP);
537 }
538
539 if (d_logic.isTheoryEnabled(theory::THEORY_SEP)) {
540 addTheory(THEORY_SEP);
541 }
542
543 }/* Smt2::setLogic() */
544
545 void Smt2::setInfo(const std::string& flag, const SExpr& sexpr) {
546 // TODO: ???
547 }
548
549 void Smt2::setOption(const std::string& flag, const SExpr& sexpr) {
550 // TODO: ???
551 }
552
553 void Smt2::checkThatLogicIsSet() {
554 if( ! logicIsSet() ) {
555 if(strictModeEnabled()) {
556 parseError("set-logic must appear before this point.");
557 } else {
558 warning("No set-logic command was given before this point.");
559 warning("CVC4 will make all theories available.");
560 warning("Consider setting a stricter logic for (likely) better performance.");
561 warning("To suppress this warning in the future use (set-logic ALL).");
562
563 setLogic("ALL");
564
565 Command* c = new SetBenchmarkLogicCommand("ALL");
566 c->setMuted(true);
567 preemptCommand(c);
568 }
569 }
570 }
571
572 /* The include are managed in the lexer but called in the parser */
573 // Inspired by http://www.antlr3.org/api/C/interop.html
574
575 static bool newInputStream(const std::string& filename, pANTLR3_LEXER lexer) {
576 Debug("parser") << "Including " << filename << std::endl;
577 // Create a new input stream and take advantage of built in stream stacking
578 // in C target runtime.
579 //
580 pANTLR3_INPUT_STREAM in;
581 #ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
582 in = antlr3AsciiFileStreamNew((pANTLR3_UINT8) filename.c_str());
583 #else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
584 in = antlr3FileStreamNew((pANTLR3_UINT8) filename.c_str(), ANTLR3_ENC_8BIT);
585 #endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
586 if( in == NULL ) {
587 Debug("parser") << "Can't open " << filename << std::endl;
588 return false;
589 }
590 // Same thing as the predefined PUSHSTREAM(in);
591 lexer->pushCharStream(lexer, in);
592 // restart it
593 //lexer->rec->state->tokenStartCharIndex = -10;
594 //lexer->emit(lexer);
595
596 // Note that the input stream is not closed when it EOFs, I don't bother
597 // to do it here, but it is up to you to track streams created like this
598 // and destroy them when the whole parse session is complete. Remember that you
599 // don't want to do this until all tokens have been manipulated all the way through
600 // your tree parsers etc as the token does not store the text it just refers
601 // back to the input stream and trying to get the text for it will abort if you
602 // close the input stream too early.
603
604 //TODO what said before
605 return true;
606 }
607
608 void Smt2::includeFile(const std::string& filename) {
609 // security for online version
610 if(!canIncludeFile()) {
611 parseError("include-file feature was disabled for this run.");
612 }
613
614 // Get the lexer
615 AntlrInput* ai = static_cast<AntlrInput*>(getInput());
616 pANTLR3_LEXER lexer = ai->getAntlr3Lexer();
617 // get the name of the current stream "Does it work inside an include?"
618 const std::string inputName = ai->getInputStreamName();
619
620 // Find the directory of the current input file
621 std::string path;
622 size_t pos = inputName.rfind('/');
623 if(pos != std::string::npos) {
624 path = std::string(inputName, 0, pos + 1);
625 }
626 path.append(filename);
627 if(!newInputStream(path, lexer)) {
628 parseError("Couldn't open include file `" + path + "'");
629 }
630 }
631
632 void Smt2::mkSygusVar(const std::string& name, const Type& type, bool isPrimed)
633 {
634 if (!isPrimed)
635 {
636 d_sygusVars.push_back(mkBoundVar(name, type));
637 }
638 #ifdef CVC4_ASSERTIONS
639 else
640 {
641 d_sygusVarPrimed.push_back(mkBoundVar(name, type));
642 }
643 #endif
644 }
645
646 void Smt2::mkSygusConstantsForType( const Type& type, std::vector<CVC4::Expr>& ops ) {
647 if( type.isInteger() ){
648 ops.push_back(getExprManager()->mkConst(Rational(0)));
649 ops.push_back(getExprManager()->mkConst(Rational(1)));
650 }else if( type.isBitVector() ){
651 unsigned sz = ((BitVectorType)type).getSize();
652 BitVector bval0(sz, (unsigned int)0);
653 ops.push_back( getExprManager()->mkConst(bval0) );
654 BitVector bval1(sz, (unsigned int)1);
655 ops.push_back( getExprManager()->mkConst(bval1) );
656 }else if( type.isBoolean() ){
657 ops.push_back(getExprManager()->mkConst(true));
658 ops.push_back(getExprManager()->mkConst(false));
659 }
660 //TODO : others?
661 }
662
663 // 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)
664 // This method may also add new elements pairwise into datatypes/sorts/ops/cnames/cargs in the case of non-flat gterms.
665 void Smt2::processSygusGTerm( CVC4::SygusGTerm& sgt, int index,
666 std::vector< CVC4::Datatype >& datatypes,
667 std::vector< CVC4::Type>& sorts,
668 std::vector< std::vector<CVC4::Expr> >& ops,
669 std::vector< std::vector<std::string> >& cnames,
670 std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
671 std::vector< bool >& allow_const,
672 std::vector< std::vector< std::string > >& unresolved_gterm_sym,
673 std::vector<CVC4::Expr>& sygus_vars,
674 std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin, std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr,
675 CVC4::Type& ret, bool isNested ){
676 if( sgt.d_gterm_type==SygusGTerm::gterm_op || sgt.d_gterm_type==SygusGTerm::gterm_let ){
677 Debug("parser-sygus") << "Add " << sgt.d_expr << " to datatype " << index
678 << ", isLet = "
679 << (sgt.d_gterm_type == SygusGTerm::gterm_let)
680 << std::endl;
681 Kind oldKind;
682 Kind newKind = kind::UNDEFINED_KIND;
683 //convert to UMINUS if one child of MINUS
684 if( sgt.d_children.size()==1 && sgt.d_expr==getExprManager()->operatorOf(kind::MINUS) ){
685 oldKind = kind::MINUS;
686 newKind = kind::UMINUS;
687 }
688 if( newKind!=kind::UNDEFINED_KIND ){
689 Expr newExpr = getExprManager()->operatorOf(newKind);
690 Debug("parser-sygus") << "Replace " << sgt.d_expr << " with " << newExpr << std::endl;
691 sgt.d_expr = newExpr;
692 std::string oldName = kind::kindToString(oldKind);
693 std::string newName = kind::kindToString(newKind);
694 size_t pos = 0;
695 if((pos = sgt.d_name.find(oldName, pos)) != std::string::npos){
696 sgt.d_name.replace(pos, oldName.length(), newName);
697 }
698 }
699 ops[index].push_back( sgt.d_expr );
700 cnames[index].push_back( sgt.d_name );
701 cargs[index].push_back( std::vector< CVC4::Type >() );
702 for( unsigned i=0; i<sgt.d_children.size(); i++ ){
703 std::stringstream ss;
704 ss << datatypes[index].getName() << "_" << ops[index].size() << "_arg_" << i;
705 std::string sub_dname = ss.str();
706 //add datatype for child
707 Type null_type;
708 pushSygusDatatypeDef( null_type, sub_dname, datatypes, sorts, ops, cnames, cargs, allow_const, unresolved_gterm_sym );
709 int sub_dt_index = datatypes.size()-1;
710 //process child
711 Type sub_ret;
712 processSygusGTerm( sgt.d_children[i], sub_dt_index, datatypes, sorts, ops, cnames, cargs, allow_const, unresolved_gterm_sym,
713 sygus_vars, sygus_to_builtin, sygus_to_builtin_expr, sub_ret, true );
714 //process the nested gterm (either pop the last datatype, or flatten the argument)
715 Type tt = processSygusNestedGTerm( sub_dt_index, sub_dname, datatypes, sorts, ops, cnames, cargs, allow_const, unresolved_gterm_sym,
716 sygus_to_builtin, sygus_to_builtin_expr, sub_ret );
717 cargs[index].back().push_back(tt);
718 }
719 //if let, must create operator
720 if( sgt.d_gterm_type==SygusGTerm::gterm_let ){
721 processSygusLetConstructor( sgt.d_let_vars, index, datatypes, sorts, ops, cnames, cargs,
722 sygus_vars, sygus_to_builtin, sygus_to_builtin_expr );
723 }
724 }else if( sgt.d_gterm_type==SygusGTerm::gterm_constant ){
725 if( sgt.getNumChildren()!=0 ){
726 parseError("Bad syntax for Sygus Constant.");
727 }
728 std::vector< Expr > consts;
729 mkSygusConstantsForType( sgt.d_type, consts );
730 Debug("parser-sygus") << "...made " << consts.size() << " constants." << std::endl;
731 for( unsigned i=0; i<consts.size(); i++ ){
732 std::stringstream ss;
733 ss << consts[i];
734 Debug("parser-sygus") << "...add for constant " << ss.str() << std::endl;
735 ops[index].push_back( consts[i] );
736 cnames[index].push_back( ss.str() );
737 cargs[index].push_back( std::vector< CVC4::Type >() );
738 }
739 allow_const[index] = true;
740 }else if( sgt.d_gterm_type==SygusGTerm::gterm_variable || sgt.d_gterm_type==SygusGTerm::gterm_input_variable ){
741 if( sgt.getNumChildren()!=0 ){
742 parseError("Bad syntax for Sygus Variable.");
743 }
744 Debug("parser-sygus") << "...process " << sygus_vars.size() << " variables." << std::endl;
745 for( unsigned i=0; i<sygus_vars.size(); i++ ){
746 if( sygus_vars[i].getType()==sgt.d_type ){
747 std::stringstream ss;
748 ss << sygus_vars[i];
749 Debug("parser-sygus") << "...add for variable " << ss.str() << std::endl;
750 ops[index].push_back( sygus_vars[i] );
751 cnames[index].push_back( ss.str() );
752 cargs[index].push_back( std::vector< CVC4::Type >() );
753 }
754 }
755 }else if( sgt.d_gterm_type==SygusGTerm::gterm_nested_sort ){
756 ret = sgt.d_type;
757 }else if( sgt.d_gterm_type==SygusGTerm::gterm_unresolved ){
758 if( isNested ){
759 if( isUnresolvedType(sgt.d_name) ){
760 ret = getSort(sgt.d_name);
761 }else{
762 //nested, unresolved symbol...fail
763 std::stringstream ss;
764 ss << "Cannot handle nested unresolved symbol " << sgt.d_name << std::endl;
765 parseError(ss.str());
766 }
767 }else{
768 //will resolve when adding constructors
769 unresolved_gterm_sym[index].push_back(sgt.d_name);
770 }
771 }else if( sgt.d_gterm_type==SygusGTerm::gterm_ignore ){
772
773 }
774 }
775
776 bool Smt2::pushSygusDatatypeDef( Type t, std::string& dname,
777 std::vector< CVC4::Datatype >& datatypes,
778 std::vector< CVC4::Type>& sorts,
779 std::vector< std::vector<CVC4::Expr> >& ops,
780 std::vector< std::vector<std::string> >& cnames,
781 std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
782 std::vector< bool >& allow_const,
783 std::vector< std::vector< std::string > >& unresolved_gterm_sym ){
784 sorts.push_back(t);
785 datatypes.push_back(Datatype(dname));
786 ops.push_back(std::vector<Expr>());
787 cnames.push_back(std::vector<std::string>());
788 cargs.push_back(std::vector<std::vector<CVC4::Type> >());
789 allow_const.push_back(false);
790 unresolved_gterm_sym.push_back(std::vector< std::string >());
791 return true;
792 }
793
794 bool Smt2::popSygusDatatypeDef( std::vector< CVC4::Datatype >& datatypes,
795 std::vector< CVC4::Type>& sorts,
796 std::vector< std::vector<CVC4::Expr> >& ops,
797 std::vector< std::vector<std::string> >& cnames,
798 std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
799 std::vector< bool >& allow_const,
800 std::vector< std::vector< std::string > >& unresolved_gterm_sym ){
801 sorts.pop_back();
802 datatypes.pop_back();
803 ops.pop_back();
804 cnames.pop_back();
805 cargs.pop_back();
806 allow_const.pop_back();
807 unresolved_gterm_sym.pop_back();
808 return true;
809 }
810
811 Type Smt2::processSygusNestedGTerm( int sub_dt_index, std::string& sub_dname, std::vector< CVC4::Datatype >& datatypes,
812 std::vector< CVC4::Type>& sorts,
813 std::vector< std::vector<CVC4::Expr> >& ops,
814 std::vector< std::vector<std::string> >& cnames,
815 std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
816 std::vector< bool >& allow_const,
817 std::vector< std::vector< std::string > >& unresolved_gterm_sym,
818 std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin,
819 std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr, Type sub_ret ) {
820 Type t = sub_ret;
821 Debug("parser-sygus") << "Argument is ";
822 if( t.isNull() ){
823 //then, it is the datatype we constructed, which should have a single constructor
824 t = mkUnresolvedType(sub_dname);
825 Debug("parser-sygus") << "inline flattening of (auxiliary, local) datatype " << t << std::endl;
826 Debug("parser-sygus") << ": to compute type, construct ground term witnessing the grammar, #cons=" << cargs[sub_dt_index].size() << std::endl;
827 if( cargs[sub_dt_index].empty() ){
828 parseError(std::string("Internal error : datatype for nested gterm does not have a constructor."));
829 }
830 Expr sop = ops[sub_dt_index][0];
831 Type curr_t;
832 if( sop.getKind() != kind::BUILTIN && ( sop.isConst() || cargs[sub_dt_index][0].empty() ) ){
833 curr_t = sop.getType();
834 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;
835 // only cache if it is a singleton datatype (has unique expr)
836 if (ops[sub_dt_index].size() == 1)
837 {
838 sygus_to_builtin_expr[t] = sop;
839 // store that term sop has dedicated sygus type t
840 if (d_sygus_bound_var_type.find(sop) == d_sygus_bound_var_type.end())
841 {
842 d_sygus_bound_var_type[sop] = t;
843 }
844 }
845 }else{
846 std::vector< Expr > children;
847 if( sop.getKind() != kind::BUILTIN ){
848 children.push_back( sop );
849 }
850 for( unsigned i=0; i<cargs[sub_dt_index][0].size(); i++ ){
851 std::map< CVC4::Type, CVC4::Expr >::iterator it = sygus_to_builtin_expr.find( cargs[sub_dt_index][0][i] );
852 if( it==sygus_to_builtin_expr.end() ){
853 if( sygus_to_builtin.find( cargs[sub_dt_index][0][i] )==sygus_to_builtin.end() ){
854 std::stringstream ss;
855 ss << "Missing builtin type for type " << cargs[sub_dt_index][0][i] << "!" << std::endl;
856 ss << "Builtin types are currently : " << std::endl;
857 for( std::map< CVC4::Type, CVC4::Type >::iterator itb = sygus_to_builtin.begin(); itb != sygus_to_builtin.end(); ++itb ){
858 ss << " " << itb->first << " -> " << itb->second << std::endl;
859 }
860 parseError(ss.str());
861 }
862 Type bt = sygus_to_builtin[cargs[sub_dt_index][0][i]];
863 Debug("parser-sygus") << ": child " << i << " introduce type elem for " << cargs[sub_dt_index][0][i] << " " << bt << std::endl;
864 std::stringstream ss;
865 ss << t << "_x_" << i;
866 Expr bv = mkBoundVar(ss.str(), bt);
867 children.push_back( bv );
868 d_sygus_bound_var_type[bv] = cargs[sub_dt_index][0][i];
869 }else{
870 Debug("parser-sygus") << ": child " << i << " existing sygus to builtin expr : " << it->second << std::endl;
871 children.push_back( it->second );
872 }
873 }
874 Kind sk = sop.getKind() != kind::BUILTIN ? kind::APPLY : getExprManager()->operatorToKind(sop);
875 Debug("parser-sygus") << ": operator " << sop << " with " << sop.getKind() << " " << sk << std::endl;
876 Expr e = getExprManager()->mkExpr( sk, children );
877 Debug("parser-sygus") << ": constructed " << e << ", which has type " << e.getType() << std::endl;
878 curr_t = e.getType();
879 sygus_to_builtin_expr[t] = e;
880 }
881 sorts[sub_dt_index] = curr_t;
882 sygus_to_builtin[t] = curr_t;
883 }else{
884 Debug("parser-sygus") << "simple argument " << t << std::endl;
885 Debug("parser-sygus") << "...removing " << datatypes.back().getName() << std::endl;
886 //otherwise, datatype was unecessary
887 //pop argument datatype definition
888 popSygusDatatypeDef( datatypes, sorts, ops, cnames, cargs, allow_const, unresolved_gterm_sym );
889 }
890 return t;
891 }
892
893 void Smt2::processSygusLetConstructor( std::vector< CVC4::Expr >& let_vars,
894 int index,
895 std::vector< CVC4::Datatype >& datatypes,
896 std::vector< CVC4::Type>& sorts,
897 std::vector< std::vector<CVC4::Expr> >& ops,
898 std::vector< std::vector<std::string> >& cnames,
899 std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
900 std::vector<CVC4::Expr>& sygus_vars,
901 std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin,
902 std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr ) {
903 std::vector< CVC4::Expr > let_define_args;
904 Expr let_body;
905 int dindex = cargs[index].size()-1;
906 Debug("parser-sygus") << "Process let constructor for datatype " << datatypes[index].getName() << ", #subtypes = " << cargs[index][dindex].size() << std::endl;
907 for( unsigned i=0; i<cargs[index][dindex].size(); i++ ){
908 Debug("parser-sygus") << " " << i << " : " << cargs[index][dindex][i] << std::endl;
909 if( i+1==cargs[index][dindex].size() ){
910 std::map< CVC4::Type, CVC4::Expr >::iterator it = sygus_to_builtin_expr.find( cargs[index][dindex][i] );
911 if( it!=sygus_to_builtin_expr.end() ){
912 let_body = it->second;
913 }else{
914 std::stringstream ss;
915 ss << datatypes[index].getName() << "_body";
916 let_body = mkBoundVar(ss.str(), sygus_to_builtin[cargs[index][dindex][i]]);
917 d_sygus_bound_var_type[let_body] = cargs[index][dindex][i];
918 }
919 }
920 }
921 Debug("parser-sygus") << std::endl;
922 Debug("parser-sygus") << "Body is " << let_body << std::endl;
923 Debug("parser-sygus") << "# let vars = " << let_vars.size() << std::endl;
924 for( unsigned i=0; i<let_vars.size(); i++ ){
925 Debug("parser-sygus") << " let var " << i << " : " << let_vars[i] << " " << let_vars[i].getType() << std::endl;
926 let_define_args.push_back( let_vars[i] );
927 }
928 /*
929 Debug("parser-sygus") << "index = " << index << ", start index = " << start_index << ", #Current datatypes = " << datatypes.size() << std::endl;
930 for( unsigned i=start_index; i<datatypes.size(); i++ ){
931 Debug("parser-sygus") << " datatype " << i << " : " << datatypes[i].getName() << ", #cons = " << cargs[i].size() << std::endl;
932 if( !cargs[i].empty() ){
933 Debug("parser-sygus") << " operator 0 is " << ops[i][0] << std::endl;
934 Debug("parser-sygus") << " cons 0 has " << cargs[i][0].size() << " sub fields." << std::endl;
935 for( unsigned j=0; j<cargs[i][0].size(); j++ ){
936 Type bt = sygus_to_builtin[cargs[i][0][j]];
937 Debug("parser-sygus") << " cons 0, selector " << j << " : " << cargs[i][0][j] << " " << bt << std::endl;
938 }
939 }
940 }
941 */
942 //last argument is the return, pop
943 cargs[index][dindex].pop_back();
944 collectSygusLetArgs( let_body, cargs[index][dindex], let_define_args );
945
946 Debug("parser-sygus") << "Make define-fun with "
947 << cargs[index][dindex].size()
948 << " operator arguments and " << let_define_args.size()
949 << " provided arguments..." << std::endl;
950 if (cargs[index][dindex].size() != let_define_args.size())
951 {
952 std::stringstream ss;
953 ss << "Wrong number of let body terms." << std::endl;
954 parseError(ss.str());
955 }
956 std::vector<CVC4::Type> fsorts;
957 for( unsigned i=0; i<cargs[index][dindex].size(); i++ ){
958 Debug("parser-sygus") << " " << i << " : " << let_define_args[i] << " " << let_define_args[i].getType() << " " << cargs[index][dindex][i] << std::endl;
959 fsorts.push_back(let_define_args[i].getType());
960 }
961
962 Type ft = getExprManager()->mkFunctionType(fsorts, let_body.getType());
963 std::stringstream ss;
964 ss << datatypes[index].getName() << "_let";
965 Expr let_func = mkFunction(ss.str(), ft, ExprManager::VAR_FLAG_DEFINED);
966 d_sygus_defined_funs.push_back( let_func );
967 preemptCommand( new DefineFunctionCommand(ss.str(), let_func, let_define_args, let_body) );
968
969 ops[index].pop_back();
970 ops[index].push_back( let_func );
971 cnames[index].pop_back();
972 cnames[index].push_back(ss.str());
973
974 //mark function as let constructor
975 d_sygus_let_func_to_vars[let_func].insert( d_sygus_let_func_to_vars[let_func].end(), let_define_args.begin(), let_define_args.end() );
976 d_sygus_let_func_to_body[let_func] = let_body;
977 d_sygus_let_func_to_num_input_vars[let_func] = let_vars.size();
978 }
979
980
981 void Smt2::collectSygusLetArgs( CVC4::Expr e, std::vector< CVC4::Type >& sygusArgs, std::vector< CVC4::Expr >& builtinArgs ) {
982 if( e.getKind()==kind::BOUND_VARIABLE ){
983 if( std::find( builtinArgs.begin(), builtinArgs.end(), e )==builtinArgs.end() ){
984 builtinArgs.push_back( e );
985 sygusArgs.push_back( d_sygus_bound_var_type[e] );
986 if( d_sygus_bound_var_type[e].isNull() ){
987 std::stringstream ss;
988 ss << "While constructing body of let gterm, can't map " << e << " to sygus type." << std::endl;
989 parseError(ss.str());
990 }
991 }
992 }else{
993 for( unsigned i=0; i<e.getNumChildren(); i++ ){
994 collectSygusLetArgs( e[i], sygusArgs, builtinArgs );
995 }
996 }
997 }
998
999 void Smt2::setSygusStartIndex( std::string& fun, int startIndex,
1000 std::vector< CVC4::Datatype >& datatypes,
1001 std::vector< CVC4::Type>& sorts,
1002 std::vector< std::vector<CVC4::Expr> >& ops ) {
1003 if( startIndex>0 ){
1004 CVC4::Datatype tmp_dt = datatypes[0];
1005 Type tmp_sort = sorts[0];
1006 std::vector< Expr > tmp_ops;
1007 tmp_ops.insert( tmp_ops.end(), ops[0].begin(), ops[0].end() );
1008 datatypes[0] = datatypes[startIndex];
1009 sorts[0] = sorts[startIndex];
1010 ops[0].clear();
1011 ops[0].insert( ops[0].end(), ops[startIndex].begin(), ops[startIndex].end() );
1012 datatypes[startIndex] = tmp_dt;
1013 sorts[startIndex] = tmp_sort;
1014 ops[startIndex].clear();
1015 ops[startIndex].insert( ops[startIndex].begin(), tmp_ops.begin(), tmp_ops.end() );
1016 }else if( startIndex<0 ){
1017 std::stringstream ss;
1018 ss << "warning: no symbol named Start for synth-fun " << fun << std::endl;
1019 warning(ss.str());
1020 }
1021 }
1022
1023 void Smt2::mkSygusDatatype( CVC4::Datatype& dt, std::vector<CVC4::Expr>& ops,
1024 std::vector<std::string>& cnames, std::vector< std::vector< CVC4::Type > >& cargs,
1025 std::vector<std::string>& unresolved_gterm_sym,
1026 std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin ) {
1027 Debug("parser-sygus") << "Making sygus datatype " << dt.getName() << std::endl;
1028 Debug("parser-sygus") << " add constructors..." << std::endl;
1029
1030 Debug("parser-sygus") << "SMT2 sygus parser : Making constructors for sygus datatype " << dt.getName() << std::endl;
1031 Debug("parser-sygus") << " add constructors..." << std::endl;
1032 // size of cnames changes, this loop must check size
1033 for (unsigned i = 0; i < cnames.size(); i++)
1034 {
1035 bool is_dup = false;
1036 bool is_dup_op = false;
1037 for (unsigned j = 0; j < i; j++)
1038 {
1039 if( ops[i]==ops[j] ){
1040 is_dup_op = true;
1041 if( cargs[i].size()==cargs[j].size() ){
1042 is_dup = true;
1043 for( unsigned k=0; k<cargs[i].size(); k++ ){
1044 if( cargs[i][k]!=cargs[j][k] ){
1045 is_dup = false;
1046 break;
1047 }
1048 }
1049 }
1050 if( is_dup ){
1051 break;
1052 }
1053 }
1054 }
1055 Debug("parser-sygus") << "SYGUS CONS " << i << " : ";
1056 if( is_dup ){
1057 Debug("parser-sygus") << "--> Duplicate gterm : " << ops[i] << std::endl;
1058 ops.erase( ops.begin() + i, ops.begin() + i + 1 );
1059 cnames.erase( cnames.begin() + i, cnames.begin() + i + 1 );
1060 cargs.erase( cargs.begin() + i, cargs.begin() + i + 1 );
1061 i--;
1062 }
1063 else
1064 {
1065 std::shared_ptr<SygusPrintCallback> spc;
1066 if (is_dup_op)
1067 {
1068 Debug("parser-sygus") << "--> Duplicate gterm operator : " << ops[i]
1069 << std::endl;
1070 // make into define-fun
1071 std::vector<Type> ltypes;
1072 for (unsigned j = 0, size = cargs[i].size(); j < size; j++)
1073 {
1074 ltypes.push_back(sygus_to_builtin[cargs[i][j]]);
1075 }
1076 std::vector<Expr> largs;
1077 Expr lbvl = makeSygusBoundVarList(dt, i, ltypes, largs);
1078
1079 // make the let_body
1080 std::vector<Expr> children;
1081 if (ops[i].getKind() != kind::BUILTIN)
1082 {
1083 children.push_back(ops[i]);
1084 }
1085 children.insert(children.end(), largs.begin(), largs.end());
1086 Kind sk = ops[i].getKind() != kind::BUILTIN
1087 ? kind::APPLY
1088 : getExprManager()->operatorToKind(ops[i]);
1089 Expr body = getExprManager()->mkExpr(sk, children);
1090 // replace by lambda
1091 ops[i] = getExprManager()->mkExpr(kind::LAMBDA, lbvl, body);
1092 Debug("parser-sygus") << " ...replace op : " << ops[i] << std::endl;
1093 // callback prints as the expression
1094 spc = std::make_shared<printer::SygusExprPrintCallback>(body, largs);
1095 }
1096 else
1097 {
1098 std::map<Expr, Expr>::iterator it =
1099 d_sygus_let_func_to_body.find(ops[i]);
1100 if (it != d_sygus_let_func_to_body.end())
1101 {
1102 Debug("parser-sygus") << "--> Let expression " << ops[i] << std::endl;
1103 Expr let_body = it->second;
1104 std::vector<Expr> let_args = d_sygus_let_func_to_vars[ops[i]];
1105 unsigned let_num_input_args =
1106 d_sygus_let_func_to_num_input_vars[ops[i]];
1107 // the operator is just the body for the arguments
1108 std::vector<Type> ltypes;
1109 for (unsigned j = 0, size = let_args.size(); j < size; j++)
1110 {
1111 ltypes.push_back(let_args[j].getType());
1112 }
1113 std::vector<Expr> largs;
1114 Expr lbvl = makeSygusBoundVarList(dt, i, ltypes, largs);
1115 Expr sbody = let_body.substitute(let_args, largs);
1116 ops[i] = getExprManager()->mkExpr(kind::LAMBDA, lbvl, sbody);
1117 Debug("parser-sygus") << " ...replace op : " << ops[i] << std::endl;
1118 // callback prints as a let expression
1119 spc = std::make_shared<printer::SygusLetExprPrintCallback>(
1120 let_body, let_args, let_num_input_args);
1121 }
1122 else if (ops[i].getType().isBitVector() && ops[i].isConst())
1123 {
1124 Debug("parser-sygus") << "--> Bit-vector constant " << ops[i] << " ("
1125 << cnames[i] << ")" << std::endl;
1126 // Since there are multiple output formats for bit-vectors and
1127 // we are required by sygus standards to print in the exact input
1128 // format given by the user, we use a print callback to custom print
1129 // the given name.
1130 spc = std::make_shared<printer::SygusNamedPrintCallback>(cnames[i]);
1131 }
1132 else if (isDefinedFunction(ops[i]))
1133 {
1134 Debug("parser-sygus") << "--> Defined function " << ops[i]
1135 << std::endl;
1136 // turn f into (lammbda (x) (f x))
1137 // in a degenerate case, ops[i] may be a defined constant,
1138 // in which case we do not replace by a lambda.
1139 if (ops[i].getType().isFunction())
1140 {
1141 std::vector<Type> ftypes =
1142 static_cast<FunctionType>(ops[i].getType()).getArgTypes();
1143 std::vector<Expr> largs;
1144 Expr lbvl = makeSygusBoundVarList(dt, i, ftypes, largs);
1145 largs.insert(largs.begin(), ops[i]);
1146 Expr body = getExprManager()->mkExpr(kind::APPLY, largs);
1147 ops[i] = getExprManager()->mkExpr(kind::LAMBDA, lbvl, body);
1148 Debug("parser-sygus") << " ...replace op : " << ops[i]
1149 << std::endl;
1150 }
1151 else
1152 {
1153 ops[i] = getExprManager()->mkExpr(kind::APPLY, ops[i]);
1154 Debug("parser-sygus") << " ...replace op : " << ops[i]
1155 << std::endl;
1156 }
1157 // keep a callback to say it should be printed with the defined name
1158 spc = std::make_shared<printer::SygusNamedPrintCallback>(cnames[i]);
1159 }
1160 else
1161 {
1162 Debug("parser-sygus") << "--> Default case " << ops[i] << std::endl;
1163 }
1164 }
1165 // must rename to avoid duplication
1166 std::stringstream ss;
1167 ss << dt.getName() << "_" << i << "_" << cnames[i];
1168 cnames[i] = ss.str();
1169 Debug("parser-sygus") << " construct the datatype " << cnames[i] << "..."
1170 << std::endl;
1171 // add the sygus constructor
1172 dt.addSygusConstructor(ops[i], cnames[i], cargs[i], spc);
1173 Debug("parser-sygus") << " finished constructing the datatype"
1174 << std::endl;
1175 }
1176 }
1177
1178 Debug("parser-sygus") << " add constructors for unresolved symbols..." << std::endl;
1179 if( !unresolved_gterm_sym.empty() ){
1180 std::vector< Type > types;
1181 Debug("parser-sygus") << "...resolve " << unresolved_gterm_sym.size() << " symbols..." << std::endl;
1182 for( unsigned i=0; i<unresolved_gterm_sym.size(); i++ ){
1183 Debug("parser-sygus") << " resolve : " << unresolved_gterm_sym[i] << std::endl;
1184 if( isUnresolvedType(unresolved_gterm_sym[i]) ){
1185 Debug("parser-sygus") << " it is an unresolved type." << std::endl;
1186 Type t = getSort(unresolved_gterm_sym[i]);
1187 if( std::find( types.begin(), types.end(), t )==types.end() ){
1188 types.push_back( t );
1189 //identity element
1190 Type bt = dt.getSygusType();
1191 Debug("parser-sygus") << ": make identity function for " << bt << ", argument type " << t << std::endl;
1192
1193 std::stringstream ss;
1194 ss << t << "_x";
1195 Expr var = mkBoundVar(ss.str(), bt);
1196 std::vector<Expr> lchildren;
1197 lchildren.push_back(
1198 getExprManager()->mkExpr(kind::BOUND_VAR_LIST, var));
1199 lchildren.push_back(var);
1200 Expr id_op = getExprManager()->mkExpr(kind::LAMBDA, lchildren);
1201
1202 // empty sygus callback (should not be printed)
1203 std::shared_ptr<SygusPrintCallback> sepc =
1204 std::make_shared<printer::SygusEmptyPrintCallback>();
1205
1206 //make the sygus argument list
1207 std::vector< Type > id_carg;
1208 id_carg.push_back( t );
1209 dt.addSygusConstructor(id_op, unresolved_gterm_sym[i], id_carg, sepc);
1210
1211 //add to operators
1212 ops.push_back( id_op );
1213 }
1214 }else{
1215 Debug("parser-sygus") << " ignore. (likely a free let variable)" << std::endl;
1216 }
1217 }
1218 }
1219 }
1220
1221 Expr Smt2::makeSygusBoundVarList(Datatype& dt,
1222 unsigned i,
1223 const std::vector<Type>& ltypes,
1224 std::vector<Expr>& lvars)
1225 {
1226 for (unsigned j = 0, size = ltypes.size(); j < size; j++)
1227 {
1228 std::stringstream ss;
1229 ss << dt.getName() << "_x_" << i << "_" << j;
1230 Expr v = mkBoundVar(ss.str(), ltypes[j]);
1231 lvars.push_back(v);
1232 }
1233 return getExprManager()->mkExpr(kind::BOUND_VAR_LIST, lvars);
1234 }
1235
1236 const void Smt2::getSygusInvVars(FunctionType t,
1237 std::vector<Expr>& vars,
1238 std::vector<Expr>& primed_vars)
1239 {
1240 std::vector<Type> argTypes = t.getArgTypes();
1241 ExprManager* em = getExprManager();
1242 for (const Type& ti : argTypes)
1243 {
1244 vars.push_back(em->mkBoundVar(ti));
1245 d_sygusVars.push_back(vars.back());
1246 std::stringstream ss;
1247 ss << vars.back() << "'";
1248 primed_vars.push_back(em->mkBoundVar(ss.str(), ti));
1249 d_sygusVars.push_back(primed_vars.back());
1250 #ifdef CVC4_ASSERTIONS
1251 bool find_new_declared_var = false;
1252 for (const Expr& e : d_sygusVarPrimed)
1253 {
1254 if (e.getType() == ti)
1255 {
1256 d_sygusVarPrimed.erase(
1257 std::find(d_sygusVarPrimed.begin(), d_sygusVarPrimed.end(), e));
1258 find_new_declared_var = true;
1259 break;
1260 }
1261 }
1262 if (!find_new_declared_var)
1263 {
1264 ss.str("");
1265 ss << "warning: decleared primed variables do not match invariant's "
1266 "type\n";
1267 warning(ss.str());
1268 }
1269 #endif
1270 }
1271 }
1272
1273 const void Smt2::addSygusFunSymbol( Type t, Expr synth_fun ){
1274 // When constructing the synthesis conjecture, we quantify on the
1275 // (higher-order) bound variable synth_fun.
1276 d_sygusFunSymbols.push_back(synth_fun);
1277
1278 // Variable "sfproxy" carries the type, which may be a SyGuS datatype
1279 // that corresponds to syntactic restrictions.
1280 Expr sym = mkBoundVar("sfproxy", t);
1281 std::vector< Expr > attr_value;
1282 attr_value.push_back(sym);
1283 Command* cattr =
1284 new SetUserAttributeCommand("sygus-synth-grammar", synth_fun, attr_value);
1285 cattr->setMuted(true);
1286 preemptCommand(cattr);
1287 }
1288
1289 InputLanguage Smt2::getLanguage() const
1290 {
1291 ExprManager* em = getExprManager();
1292 return em->getOptions().getInputLanguage();
1293 }
1294
1295 }/* CVC4::parser namespace */
1296 }/* CVC4 namespace */