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