Refactoring Options Handler & Library Cycle Breaking
[cvc5.git] / src / parser / smt2 / smt2.cpp
1 /********************* */
2 /*! \file smt2.cpp
3 ** \verbatim
4 ** Original author: Christopher L. Conway
5 ** Major contributors: Kshitij Bansal, Morgan Deters
6 ** Minor contributors (to current version): Andrew Reynolds, Clark Barrett, Tianyi Liang
7 ** This file is part of the CVC4 project.
8 ** Copyright (c) 2009-2014 New York University and The University of Iowa
9 ** See the file COPYING in the top-level source directory for licensing
10 ** 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 "smt_util/command.h"
24 #include "util/bitvector.h"
25
26 // ANTLR defines these, which is really bad!
27 #undef true
28 #undef false
29
30 namespace CVC4 {
31 namespace parser {
32
33 Smt2::Smt2(ExprManager* exprManager, Input* input, bool strictMode, bool parseOnly) :
34 Parser(exprManager,input,strictMode,parseOnly),
35 d_logicSet(false),
36 d_nextSygusFun(0) {
37 d_unsatCoreNames.push(std::map<Expr, std::string>());
38 if( !strictModeEnabled() ) {
39 addTheory(Smt2::THEORY_CORE);
40 }
41 }
42
43 void Smt2::addArithmeticOperators() {
44 Parser::addOperator(kind::PLUS);
45 Parser::addOperator(kind::MINUS);
46 Parser::addOperator(kind::UMINUS);
47 Parser::addOperator(kind::MULT);
48 Parser::addOperator(kind::LT);
49 Parser::addOperator(kind::LEQ);
50 Parser::addOperator(kind::GT);
51 Parser::addOperator(kind::GEQ);
52 }
53
54 void Smt2::addBitvectorOperators() {
55 addOperator(kind::BITVECTOR_CONCAT, "concat");
56 addOperator(kind::BITVECTOR_NOT, "bvnot");
57 addOperator(kind::BITVECTOR_AND, "bvand");
58 addOperator(kind::BITVECTOR_OR, "bvor");
59 addOperator(kind::BITVECTOR_NEG, "bvneg");
60 addOperator(kind::BITVECTOR_PLUS, "bvadd");
61 addOperator(kind::BITVECTOR_MULT, "bvmul");
62 addOperator(kind::BITVECTOR_UDIV, "bvudiv");
63 addOperator(kind::BITVECTOR_UREM, "bvurem");
64 addOperator(kind::BITVECTOR_SHL, "bvshl");
65 addOperator(kind::BITVECTOR_LSHR, "bvlshr");
66 addOperator(kind::BITVECTOR_ULT, "bvult");
67 addOperator(kind::BITVECTOR_NAND, "bvnand");
68 addOperator(kind::BITVECTOR_NOR, "bvnor");
69 addOperator(kind::BITVECTOR_XOR, "bvxor");
70 addOperator(kind::BITVECTOR_XNOR, "bvxnor");
71 addOperator(kind::BITVECTOR_COMP, "bvcomp");
72 addOperator(kind::BITVECTOR_SUB, "bvsub");
73 addOperator(kind::BITVECTOR_SDIV, "bvsdiv");
74 addOperator(kind::BITVECTOR_SREM, "bvsrem");
75 addOperator(kind::BITVECTOR_SMOD, "bvsmod");
76 addOperator(kind::BITVECTOR_ASHR, "bvashr");
77 addOperator(kind::BITVECTOR_ULE, "bvule");
78 addOperator(kind::BITVECTOR_UGT, "bvugt");
79 addOperator(kind::BITVECTOR_UGE, "bvuge");
80 addOperator(kind::BITVECTOR_SLT, "bvslt");
81 addOperator(kind::BITVECTOR_SLE, "bvsle");
82 addOperator(kind::BITVECTOR_SGT, "bvsgt");
83 addOperator(kind::BITVECTOR_SGE, "bvsge");
84 addOperator(kind::BITVECTOR_REDOR, "bvredor");
85 addOperator(kind::BITVECTOR_REDAND, "bvredand");
86
87 Parser::addOperator(kind::BITVECTOR_BITOF);
88 Parser::addOperator(kind::BITVECTOR_EXTRACT);
89 Parser::addOperator(kind::BITVECTOR_REPEAT);
90 Parser::addOperator(kind::BITVECTOR_ZERO_EXTEND);
91 Parser::addOperator(kind::BITVECTOR_SIGN_EXTEND);
92 Parser::addOperator(kind::BITVECTOR_ROTATE_LEFT);
93 Parser::addOperator(kind::BITVECTOR_ROTATE_RIGHT);
94
95 Parser::addOperator(kind::INT_TO_BITVECTOR);
96 Parser::addOperator(kind::BITVECTOR_TO_NAT);
97 }
98
99 void Smt2::addStringOperators() {
100 addOperator(kind::STRING_CONCAT, "str.++");
101 addOperator(kind::STRING_LENGTH, "str.len");
102 addOperator(kind::STRING_SUBSTR, "str.substr" );
103 addOperator(kind::STRING_STRCTN, "str.contains" );
104 addOperator(kind::STRING_CHARAT, "str.at" );
105 addOperator(kind::STRING_STRIDOF, "str.indexof" );
106 addOperator(kind::STRING_STRREPL, "str.replace" );
107 addOperator(kind::STRING_PREFIX, "str.prefixof" );
108 addOperator(kind::STRING_SUFFIX, "str.suffixof" );
109 addOperator(kind::STRING_ITOS, "int.to.str" );
110 addOperator(kind::STRING_STOI, "str.to.int" );
111 addOperator(kind::STRING_U16TOS, "u16.to.str" );
112 addOperator(kind::STRING_STOU16, "str.to.u16" );
113 addOperator(kind::STRING_U32TOS, "u32.to.str" );
114 addOperator(kind::STRING_STOU32, "str.to.u32" );
115 addOperator(kind::STRING_IN_REGEXP, "str.in.re");
116 addOperator(kind::STRING_TO_REGEXP, "str.to.re");
117 addOperator(kind::REGEXP_CONCAT, "re.++");
118 addOperator(kind::REGEXP_UNION, "re.union");
119 addOperator(kind::REGEXP_INTER, "re.inter");
120 addOperator(kind::REGEXP_STAR, "re.*");
121 addOperator(kind::REGEXP_PLUS, "re.+");
122 addOperator(kind::REGEXP_OPT, "re.opt");
123 addOperator(kind::REGEXP_RANGE, "re.range");
124 addOperator(kind::REGEXP_LOOP, "re.loop");
125 }
126
127 void Smt2::addFloatingPointOperators() {
128 addOperator(kind::FLOATINGPOINT_FP, "fp");
129 addOperator(kind::FLOATINGPOINT_EQ, "fp.eq");
130 addOperator(kind::FLOATINGPOINT_ABS, "fp.abs");
131 addOperator(kind::FLOATINGPOINT_NEG, "fp.neg");
132 addOperator(kind::FLOATINGPOINT_PLUS, "fp.add");
133 addOperator(kind::FLOATINGPOINT_SUB, "fp.sub");
134 addOperator(kind::FLOATINGPOINT_MULT, "fp.mul");
135 addOperator(kind::FLOATINGPOINT_DIV, "fp.div");
136 addOperator(kind::FLOATINGPOINT_FMA, "fp.fma");
137 addOperator(kind::FLOATINGPOINT_SQRT, "fp.sqrt");
138 addOperator(kind::FLOATINGPOINT_REM, "fp.rem");
139 addOperator(kind::FLOATINGPOINT_RTI, "fp.roundToIntegral");
140 addOperator(kind::FLOATINGPOINT_MIN, "fp.min");
141 addOperator(kind::FLOATINGPOINT_MAX, "fp.max");
142 addOperator(kind::FLOATINGPOINT_LEQ, "fp.leq");
143 addOperator(kind::FLOATINGPOINT_LT, "fp.lt");
144 addOperator(kind::FLOATINGPOINT_GEQ, "fp.geq");
145 addOperator(kind::FLOATINGPOINT_GT, "fp.gt");
146 addOperator(kind::FLOATINGPOINT_ISN, "fp.isNormal");
147 addOperator(kind::FLOATINGPOINT_ISSN, "fp.isSubnormal");
148 addOperator(kind::FLOATINGPOINT_ISZ, "fp.isZero");
149 addOperator(kind::FLOATINGPOINT_ISINF, "fp.isInfinite");
150 addOperator(kind::FLOATINGPOINT_ISNAN, "fp.isNaN");
151 addOperator(kind::FLOATINGPOINT_ISNEG, "fp.isNegative");
152 addOperator(kind::FLOATINGPOINT_ISPOS, "fp.isPositive");
153 addOperator(kind::FLOATINGPOINT_TO_REAL, "fp.to_real");
154
155 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_IEEE_BITVECTOR);
156 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_FLOATINGPOINT);
157 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_REAL);
158 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_SIGNED_BITVECTOR);
159 Parser::addOperator(kind::FLOATINGPOINT_TO_FP_UNSIGNED_BITVECTOR);
160 Parser::addOperator(kind::FLOATINGPOINT_TO_UBV);
161 Parser::addOperator(kind::FLOATINGPOINT_TO_SBV);
162 }
163
164
165 void Smt2::addTheory(Theory theory) {
166 switch(theory) {
167 case THEORY_ARRAYS:
168 addOperator(kind::SELECT, "select");
169 addOperator(kind::STORE, "store");
170 break;
171
172 case THEORY_BITVECTORS:
173 addBitvectorOperators();
174 break;
175
176 case THEORY_CORE:
177 defineType("Bool", getExprManager()->booleanType());
178 defineVar("true", getExprManager()->mkConst(true));
179 defineVar("false", getExprManager()->mkConst(false));
180 Parser::addOperator(kind::AND);
181 Parser::addOperator(kind::DISTINCT);
182 Parser::addOperator(kind::EQUAL);
183 Parser::addOperator(kind::IFF);
184 Parser::addOperator(kind::IMPLIES);
185 Parser::addOperator(kind::ITE);
186 Parser::addOperator(kind::NOT);
187 Parser::addOperator(kind::OR);
188 Parser::addOperator(kind::XOR);
189 break;
190
191 case THEORY_REALS_INTS:
192 defineType("Real", getExprManager()->realType());
193 Parser::addOperator(kind::DIVISION);
194 addOperator(kind::TO_INTEGER, "to_int");
195 addOperator(kind::IS_INTEGER, "is_int");
196 addOperator(kind::TO_REAL, "to_real");
197 // falling through on purpose, to add Ints part of Reals_Ints
198 case THEORY_INTS:
199 defineType("Int", getExprManager()->integerType());
200 addArithmeticOperators();
201 addOperator(kind::INTS_DIVISION, "div");
202 addOperator(kind::INTS_MODULUS, "mod");
203 addOperator(kind::ABS, "abs");
204 Parser::addOperator(kind::DIVISIBLE);
205 break;
206
207 case THEORY_REALS:
208 defineType("Real", getExprManager()->realType());
209 addArithmeticOperators();
210 Parser::addOperator(kind::DIVISION);
211 break;
212
213 case THEORY_QUANTIFIERS:
214 break;
215
216 case THEORY_SETS:
217 addOperator(kind::UNION, "union");
218 addOperator(kind::INTERSECTION, "intersection");
219 addOperator(kind::SETMINUS, "setminus");
220 addOperator(kind::SUBSET, "subset");
221 addOperator(kind::MEMBER, "member");
222 addOperator(kind::SINGLETON, "singleton");
223 addOperator(kind::INSERT, "insert");
224 break;
225
226 case THEORY_DATATYPES:
227 Parser::addOperator(kind::APPLY_CONSTRUCTOR);
228 Parser::addOperator(kind::APPLY_TESTER);
229 Parser::addOperator(kind::APPLY_SELECTOR);
230 Parser::addOperator(kind::APPLY_SELECTOR_TOTAL);
231 break;
232
233 case THEORY_STRINGS:
234 defineType("String", getExprManager()->stringType());
235 defineType("Int", getExprManager()->integerType());
236 addStringOperators();
237 break;
238
239 case THEORY_UF:
240 Parser::addOperator(kind::APPLY_UF);
241 break;
242
243 case THEORY_FP:
244 defineType("RoundingMode", getExprManager()->roundingModeType());
245 defineType("Float16", getExprManager()->mkFloatingPointType(5, 11));
246 defineType("Float32", getExprManager()->mkFloatingPointType(8, 24));
247 defineType("Float64", getExprManager()->mkFloatingPointType(11, 53));
248 defineType("Float128", getExprManager()->mkFloatingPointType(15, 113));
249 addFloatingPointOperators();
250 break;
251
252 default:
253 std::stringstream ss;
254 ss << "internal error: unsupported theory " << theory;
255 throw ParserException(ss.str());
256 }
257 }
258
259 void Smt2::addOperator(Kind kind, const std::string& name) {
260 Debug("parser") << "Smt2::addOperator( " << kind << ", " << name << " )"
261 << std::endl;
262 Parser::addOperator(kind);
263 operatorKindMap[name] = kind;
264 }
265
266 Kind Smt2::getOperatorKind(const std::string& name) const {
267 // precondition: isOperatorEnabled(name)
268 return operatorKindMap.find(name)->second;
269 }
270
271 bool Smt2::isOperatorEnabled(const std::string& name) const {
272 return operatorKindMap.find(name) != operatorKindMap.end();
273 }
274
275 bool Smt2::isTheoryEnabled(Theory theory) const {
276 switch(theory) {
277 case THEORY_ARRAYS:
278 return d_logic.isTheoryEnabled(theory::THEORY_ARRAY);
279 case THEORY_BITVECTORS:
280 return d_logic.isTheoryEnabled(theory::THEORY_BV);
281 case THEORY_CORE:
282 return true;
283 case THEORY_DATATYPES:
284 return d_logic.isTheoryEnabled(theory::THEORY_DATATYPES);
285 case THEORY_INTS:
286 return d_logic.isTheoryEnabled(theory::THEORY_ARITH) &&
287 d_logic.areIntegersUsed() && ( !d_logic.areRealsUsed() );
288 case THEORY_REALS:
289 return d_logic.isTheoryEnabled(theory::THEORY_ARITH) &&
290 ( !d_logic.areIntegersUsed() ) && d_logic.areRealsUsed();
291 case THEORY_REALS_INTS:
292 return d_logic.isTheoryEnabled(theory::THEORY_ARITH) &&
293 d_logic.areIntegersUsed() && d_logic.areRealsUsed();
294 case THEORY_QUANTIFIERS:
295 return d_logic.isQuantified();
296 case THEORY_SETS:
297 return d_logic.isTheoryEnabled(theory::THEORY_SETS);
298 case THEORY_STRINGS:
299 return d_logic.isTheoryEnabled(theory::THEORY_STRINGS);
300 case THEORY_UF:
301 return d_logic.isTheoryEnabled(theory::THEORY_UF);
302 case THEORY_FP:
303 return d_logic.isTheoryEnabled(theory::THEORY_FP);
304 default:
305 std::stringstream ss;
306 ss << "internal error: unsupported theory " << theory;
307 throw ParserException(ss.str());
308 }
309 }
310
311 bool Smt2::logicIsSet() {
312 return d_logicSet;
313 }
314
315 void Smt2::reset() {
316 d_logicSet = false;
317 d_logic = LogicInfo();
318 operatorKindMap.clear();
319 d_lastNamedTerm = std::pair<Expr, std::string>();
320 d_unsatCoreNames = std::stack< std::map<Expr, std::string> >();
321 this->Parser::reset();
322
323 d_unsatCoreNames.push(std::map<Expr, std::string>());
324 if( !strictModeEnabled() ) {
325 addTheory(Smt2::THEORY_CORE);
326 }
327 }
328
329 void Smt2::resetAssertions() {
330 this->Parser::reset();
331 }
332
333 void Smt2::setLogic(std::string name) {
334 if(sygus()) {
335 if(name == "Arrays") {
336 name = "AUF";
337 } else if(name == "Reals") {
338 name = "UFLRA";
339 } else if(name == "LIA") {
340 name = "UFLIA";
341 } else if(name == "LRA") {
342 name = "UFLRA";
343 } else if(name == "LIRA") {
344 name = "UFLIRA";
345 } else if(name == "BV") {
346 name = "UFBV";
347 } else if(name == "ALL_SUPPORTED") {
348 //no change
349 } else {
350 std::stringstream ss;
351 ss << "Unknown SyGuS background logic `" << name << "'";
352 parseError(ss.str());
353 }
354 }
355
356 d_logicSet = true;
357 if(logicIsForced()) {
358 d_logic = getForcedLogic();
359 } else {
360 d_logic = name;
361 }
362
363 // Core theory belongs to every logic
364 addTheory(THEORY_CORE);
365
366 if(d_logic.isTheoryEnabled(theory::THEORY_UF)) {
367 addTheory(THEORY_UF);
368 }
369
370 if(d_logic.isTheoryEnabled(theory::THEORY_ARITH)) {
371 if(d_logic.areIntegersUsed()) {
372 if(d_logic.areRealsUsed()) {
373 addTheory(THEORY_REALS_INTS);
374 } else {
375 addTheory(THEORY_INTS);
376 }
377 } else if(d_logic.areRealsUsed()) {
378 addTheory(THEORY_REALS);
379 }
380 }
381
382 if(d_logic.isTheoryEnabled(theory::THEORY_ARRAY)) {
383 addTheory(THEORY_ARRAYS);
384 }
385
386 if(d_logic.isTheoryEnabled(theory::THEORY_BV)) {
387 addTheory(THEORY_BITVECTORS);
388 }
389
390 if(d_logic.isTheoryEnabled(theory::THEORY_DATATYPES)) {
391 addTheory(THEORY_DATATYPES);
392 }
393
394 if(d_logic.isTheoryEnabled(theory::THEORY_SETS)) {
395 addTheory(THEORY_SETS);
396 }
397
398 if(d_logic.isTheoryEnabled(theory::THEORY_STRINGS)) {
399 addTheory(THEORY_STRINGS);
400 }
401
402 if(d_logic.isQuantified()) {
403 addTheory(THEORY_QUANTIFIERS);
404 }
405
406 if (d_logic.isTheoryEnabled(theory::THEORY_FP)) {
407 addTheory(THEORY_FP);
408 }
409
410 }/* Smt2::setLogic() */
411
412 void Smt2::setInfo(const std::string& flag, const SExpr& sexpr) {
413 // TODO: ???
414 }
415
416 void Smt2::setOption(const std::string& flag, const SExpr& sexpr) {
417 // TODO: ???
418 }
419
420 void Smt2::checkThatLogicIsSet() {
421 if( ! logicIsSet() ) {
422 if(strictModeEnabled()) {
423 parseError("set-logic must appear before this point.");
424 } else {
425 if(sygus()) {
426 setLogic("LIA");
427 } else {
428 warning("No set-logic command was given before this point.");
429 warning("CVC4 will assume the non-standard ALL_SUPPORTED logic.");
430 warning("Consider setting a stricter logic for (likely) better performance.");
431 warning("To suppress this warning in the future use (set-logic ALL_SUPPORTED).");
432
433 setLogic("ALL_SUPPORTED");
434 }
435
436 Command* c = new SetBenchmarkLogicCommand("ALL_SUPPORTED");
437 c->setMuted(true);
438 preemptCommand(c);
439 }
440 }
441 }
442
443 /* The include are managed in the lexer but called in the parser */
444 // Inspired by http://www.antlr3.org/api/C/interop.html
445
446 static bool newInputStream(const std::string& filename, pANTLR3_LEXER lexer) {
447 Debug("parser") << "Including " << filename << std::endl;
448 // Create a new input stream and take advantage of built in stream stacking
449 // in C target runtime.
450 //
451 pANTLR3_INPUT_STREAM in;
452 #ifdef CVC4_ANTLR3_OLD_INPUT_STREAM
453 in = antlr3AsciiFileStreamNew((pANTLR3_UINT8) filename.c_str());
454 #else /* CVC4_ANTLR3_OLD_INPUT_STREAM */
455 in = antlr3FileStreamNew((pANTLR3_UINT8) filename.c_str(), ANTLR3_ENC_8BIT);
456 #endif /* CVC4_ANTLR3_OLD_INPUT_STREAM */
457 if( in == NULL ) {
458 Debug("parser") << "Can't open " << filename << std::endl;
459 return false;
460 }
461 // Same thing as the predefined PUSHSTREAM(in);
462 lexer->pushCharStream(lexer, in);
463 // restart it
464 //lexer->rec->state->tokenStartCharIndex = -10;
465 //lexer->emit(lexer);
466
467 // Note that the input stream is not closed when it EOFs, I don't bother
468 // to do it here, but it is up to you to track streams created like this
469 // and destroy them when the whole parse session is complete. Remember that you
470 // don't want to do this until all tokens have been manipulated all the way through
471 // your tree parsers etc as the token does not store the text it just refers
472 // back to the input stream and trying to get the text for it will abort if you
473 // close the input stream too early.
474
475 //TODO what said before
476 return true;
477 }
478
479 void Smt2::includeFile(const std::string& filename) {
480 // security for online version
481 if(!canIncludeFile()) {
482 parseError("include-file feature was disabled for this run.");
483 }
484
485 // Get the lexer
486 AntlrInput* ai = static_cast<AntlrInput*>(getInput());
487 pANTLR3_LEXER lexer = ai->getAntlr3Lexer();
488 // get the name of the current stream "Does it work inside an include?"
489 const std::string inputName = ai->getInputStreamName();
490
491 // Find the directory of the current input file
492 std::string path;
493 size_t pos = inputName.rfind('/');
494 if(pos != std::string::npos) {
495 path = std::string(inputName, 0, pos + 1);
496 }
497 path.append(filename);
498 if(!newInputStream(path, lexer)) {
499 parseError("Couldn't open include file `" + path + "'");
500 }
501 }
502
503 Expr Smt2::mkSygusVar(const std::string& name, const Type& type, bool isPrimed) {
504 Expr e = mkBoundVar(name, type);
505 d_sygusVars.push_back(e);
506 d_sygusVarPrimed[e] = false;
507 if( isPrimed ){
508 std::stringstream ss;
509 ss << name << "'";
510 Expr ep = mkBoundVar(ss.str(), type);
511 d_sygusVars.push_back(ep);
512 d_sygusVarPrimed[ep] = true;
513 }
514 return e;
515 }
516
517 void collectSygusGrammarTypesFor( Type range, std::vector< Type >& types, std::map< Type, std::vector< DatatypeConstructorArg > >& sels ){
518 if( !range.isBoolean() ){
519 if( std::find( types.begin(), types.end(), range )==types.end() ){
520 Debug("parser-sygus") << "...will make grammar for " << range << std::endl;
521 types.push_back( range );
522 if( range.isDatatype() ){
523 const Datatype& dt = ((DatatypeType)range).getDatatype();
524 for( unsigned i=0; i<dt.getNumConstructors(); i++ ){
525 for( unsigned j=0; j<dt[i].getNumArgs(); j++ ){
526 Type crange = ((SelectorType)dt[i][j].getType()).getRangeType();
527 sels[crange].push_back( dt[i][j] );
528 collectSygusGrammarTypesFor( crange, types, sels );
529 }
530 }
531 }
532 }
533 }
534 }
535
536 void Smt2::mkSygusDefaultGrammar( const Type& range, Expr& bvl, const std::string& fun, std::vector<CVC4::Datatype>& datatypes,
537 std::vector<Type>& sorts, std::vector< std::vector<Expr> >& ops, std::vector<Expr> sygus_vars, int& startIndex ) {
538
539 //if( !range.isBoolean() && !range.isInteger() && !range.isBitVector() && !range.isDatatype() ){
540 // parseError("No default grammar for type.");
541 //}
542 startIndex = -1;
543 Debug("parser-sygus") << "Construct default grammar for " << fun << " " << range << std::endl;
544 std::map< CVC4::Type, CVC4::Type > sygus_to_builtin;
545
546 std::vector< Type > types;
547 std::map< Type, std::vector< DatatypeConstructorArg > > sels;
548 //types for each of the variables
549 for( unsigned i=0; i<sygus_vars.size(); i++ ){
550 collectSygusGrammarTypesFor( sygus_vars[i].getType(), types, sels );
551 }
552 //types connected to range
553 collectSygusGrammarTypesFor( range, types, sels );
554
555 //name of boolean sort
556 std::stringstream ssb;
557 ssb << fun << "_Bool";
558 std::string dbname = ssb.str();
559 Type unres_bt = mkUnresolvedType(ssb.str());
560
561 std::vector< Type > unres_types;
562 std::map< Type, Type > type_to_unres;
563 for( unsigned i=0; i<types.size(); i++ ){
564 std::stringstream ss;
565 ss << fun << "_" << types[i];
566 std::string dname = ss.str();
567 datatypes.push_back(Datatype(dname));
568 ops.push_back(std::vector<Expr>());
569 //make unresolved type
570 Type unres_t = mkUnresolvedType(dname);
571 unres_types.push_back(unres_t);
572 type_to_unres[types[i]] = unres_t;
573 sygus_to_builtin[unres_t] = types[i];
574 }
575 for( unsigned i=0; i<types.size(); i++ ){
576 Debug("parser-sygus") << "Make grammar for " << types[i] << " " << unres_types[i] << std::endl;
577 std::vector<std::string> cnames;
578 std::vector<std::vector<CVC4::Type> > cargs;
579 std::vector<std::string> unresolved_gterm_sym;
580 Type unres_t = unres_types[i];
581 //add variables
582 for( unsigned j=0; j<sygus_vars.size(); j++ ){
583 if( sygus_vars[j].getType()==types[i] ){
584 std::stringstream ss;
585 ss << sygus_vars[j];
586 Debug("parser-sygus") << "...add for variable " << ss.str() << std::endl;
587 ops[i].push_back( sygus_vars[j] );
588 cnames.push_back( ss.str() );
589 cargs.push_back( std::vector< CVC4::Type >() );
590 }
591 }
592 //add constants
593 std::vector< Expr > consts;
594 mkSygusConstantsForType( types[i], consts );
595 for( unsigned j=0; j<consts.size(); j++ ){
596 std::stringstream ss;
597 ss << consts[j];
598 Debug("parser-sygus") << "...add for constant " << ss.str() << std::endl;
599 ops[i].push_back( consts[j] );
600 cnames.push_back( ss.str() );
601 cargs.push_back( std::vector< CVC4::Type >() );
602 }
603 //ITE
604 CVC4::Kind k = kind::ITE;
605 Debug("parser-sygus") << "...add for " << k << std::endl;
606 ops[i].push_back(getExprManager()->operatorOf(k));
607 cnames.push_back( kind::kindToString(k) );
608 cargs.push_back( std::vector< CVC4::Type >() );
609 cargs.back().push_back(unres_bt);
610 cargs.back().push_back(unres_t);
611 cargs.back().push_back(unres_t);
612
613 if( types[i].isInteger() ){
614 for( unsigned j=0; j<2; j++ ){
615 CVC4::Kind k = j==0 ? kind::PLUS : kind::MINUS;
616 Debug("parser-sygus") << "...add for " << k << std::endl;
617 ops[i].push_back(getExprManager()->operatorOf(k));
618 cnames.push_back(kind::kindToString(k));
619 cargs.push_back( std::vector< CVC4::Type >() );
620 cargs.back().push_back(unres_t);
621 cargs.back().push_back(unres_t);
622 }
623 }else if( types[i].isDatatype() ){
624 Debug("parser-sygus") << "...add for constructors" << std::endl;
625 const Datatype& dt = ((DatatypeType)types[i]).getDatatype();
626 for( unsigned k=0; k<dt.getNumConstructors(); k++ ){
627 Debug("parser-sygus") << "...for " << dt[k].getName() << std::endl;
628 ops[i].push_back( dt[k].getConstructor() );
629 cnames.push_back( dt[k].getName() );
630 cargs.push_back( std::vector< CVC4::Type >() );
631 for( unsigned j=0; j<dt[k].getNumArgs(); j++ ){
632 Type crange = ((SelectorType)dt[k][j].getType()).getRangeType();
633 //Assert( type_to_unres.find(crange)!=type_to_unres.end() );
634 cargs.back().push_back( type_to_unres[crange] );
635 }
636 }
637 }else{
638 std::stringstream sserr;
639 sserr << "No implementation for default Sygus grammar of type " << types[i] << std::endl;
640 warning(sserr.str());
641 }
642 //add for all selectors to this type
643 if( !sels[types[i]].empty() ){
644 Debug("parser-sygus") << "...add for selectors" << std::endl;
645 for( unsigned j=0; j<sels[types[i]].size(); j++ ){
646 Debug("parser-sygus") << "...for " << sels[types[i]][j].getName() << std::endl;
647 Type arg_type = ((SelectorType)sels[types[i]][j].getType()).getDomain();
648 ops[i].push_back( sels[types[i]][j].getSelector() );
649 cnames.push_back( sels[types[i]][j].getName() );
650 cargs.push_back( std::vector< CVC4::Type >() );
651 //Assert( type_to_unres.find(arg_type)!=type_to_unres.end() );
652 cargs.back().push_back( type_to_unres[arg_type] );
653 }
654 }
655 Debug("parser-sygus") << "...make datatype " << datatypes.back() << std::endl;
656 datatypes[i].setSygus( types[i], bvl, true, true );
657 mkSygusDatatype( datatypes[i], ops[i], cnames, cargs, unresolved_gterm_sym, sygus_to_builtin );
658 sorts.push_back( types[i] );
659 //set start index if applicable
660 if( types[i]==range ){
661 startIndex = i;
662 }
663 }
664
665 //make Boolean type
666 Type btype = getExprManager()->booleanType();
667 datatypes.push_back(Datatype(dbname));
668 ops.push_back(std::vector<Expr>());
669 std::vector<std::string> cnames;
670 std::vector<std::vector<CVC4::Type> > cargs;
671 std::vector<std::string> unresolved_gterm_sym;
672 Debug("parser-sygus") << "Make grammar for " << btype << " " << datatypes.back() << std::endl;
673 //add variables
674 for( unsigned i=0; i<sygus_vars.size(); i++ ){
675 if( sygus_vars[i].getType().isBoolean() ){
676 std::stringstream ss;
677 ss << sygus_vars[i];
678 Debug("parser-sygus") << "...add for variable " << ss.str() << std::endl;
679 ops.back().push_back( sygus_vars[i] );
680 cnames.push_back( ss.str() );
681 cargs.push_back( std::vector< CVC4::Type >() );
682 }
683 }
684 //add constants if no variables and no connected types
685 if( ops.back().empty() && types.empty() ){
686 std::vector< Expr > consts;
687 mkSygusConstantsForType( btype, consts );
688 for( unsigned j=0; j<consts.size(); j++ ){
689 std::stringstream ss;
690 ss << consts[j];
691 Debug("parser-sygus") << "...add for constant " << ss.str() << std::endl;
692 ops.back().push_back( consts[j] );
693 cnames.push_back( ss.str() );
694 cargs.push_back( std::vector< CVC4::Type >() );
695 }
696 }
697 //add operators
698 for( unsigned i=0; i<3; i++ ){
699 CVC4::Kind k = i==0 ? kind::NOT : ( i==1 ? kind::AND : kind::OR );
700 Debug("parser-sygus") << "...add for " << k << std::endl;
701 ops.back().push_back(getExprManager()->operatorOf(k));
702 cnames.push_back(kind::kindToString(k));
703 cargs.push_back( std::vector< CVC4::Type >() );
704 if( k==kind::NOT ){
705 cargs.back().push_back(unres_bt);
706 }else if( k==kind::AND || k==kind::OR ){
707 cargs.back().push_back(unres_bt);
708 cargs.back().push_back(unres_bt);
709 }
710 }
711 //add predicates for types
712 for( unsigned i=0; i<types.size(); i++ ){
713 Debug("parser-sygus") << "...add predicates for " << types[i] << std::endl;
714 //add equality per type
715 CVC4::Kind k = kind::EQUAL;
716 Debug("parser-sygus") << "...add for " << k << std::endl;
717 ops.back().push_back(getExprManager()->operatorOf(k));
718 std::stringstream ss;
719 ss << kind::kindToString(k) << "_" << types[i];
720 cnames.push_back(ss.str());
721 cargs.push_back( std::vector< CVC4::Type >() );
722 cargs.back().push_back(unres_types[i]);
723 cargs.back().push_back(unres_types[i]);
724 //type specific predicates
725 if( types[i].isInteger() ){
726 CVC4::Kind k = kind::LEQ;
727 Debug("parser-sygus") << "...add for " << k << std::endl;
728 ops.back().push_back(getExprManager()->operatorOf(k));
729 cnames.push_back(kind::kindToString(k));
730 cargs.push_back( std::vector< CVC4::Type >() );
731 cargs.back().push_back(unres_types[i]);
732 cargs.back().push_back(unres_types[i]);
733 }else if( types[i].isDatatype() ){
734 //add for testers
735 Debug("parser-sygus") << "...add for testers" << std::endl;
736 const Datatype& dt = ((DatatypeType)types[i]).getDatatype();
737 for( unsigned k=0; k<dt.getNumConstructors(); k++ ){
738 Debug("parser-sygus") << "...for " << dt[k].getTesterName() << std::endl;
739 ops.back().push_back(dt[k].getTester());
740 cnames.push_back(dt[k].getTesterName());
741 cargs.push_back( std::vector< CVC4::Type >() );
742 cargs.back().push_back(unres_types[i]);
743 }
744 }
745 }
746 if( range==btype ){
747 startIndex = sorts.size();
748 }
749 Debug("parser-sygus") << "...make datatype " << datatypes.back() << std::endl;
750 datatypes.back().setSygus( btype, bvl, true, true );
751 mkSygusDatatype( datatypes.back(), ops.back(), cnames, cargs, unresolved_gterm_sym, sygus_to_builtin );
752 sorts.push_back( btype );
753
754 Debug("parser-sygus") << "...finished make default grammar for " << fun << " " << range << std::endl;
755 }
756
757 void Smt2::mkSygusConstantsForType( const Type& type, std::vector<CVC4::Expr>& ops ) {
758 if( type.isInteger() ){
759 ops.push_back(getExprManager()->mkConst(Rational(0)));
760 ops.push_back(getExprManager()->mkConst(Rational(1)));
761 }else if( type.isBitVector() ){
762 unsigned sz = ((BitVectorType)type).getSize();
763 BitVector bval0(sz, (unsigned int)0);
764 ops.push_back( getExprManager()->mkConst(bval0) );
765 BitVector bval1(sz, (unsigned int)1);
766 ops.push_back( getExprManager()->mkConst(bval1) );
767 }else if( type.isBoolean() ){
768 ops.push_back(getExprManager()->mkConst(true));
769 ops.push_back(getExprManager()->mkConst(false));
770 }
771 //TODO : others?
772 }
773
774 // 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)
775 // This method may also add new elements pairwise into datatypes/sorts/ops/cnames/cargs in the case of non-flat gterms.
776 void Smt2::processSygusGTerm( CVC4::SygusGTerm& sgt, int index,
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 std::vector<CVC4::Expr>& sygus_vars,
785 std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin, std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr,
786 CVC4::Type& ret, bool isNested ){
787 if( sgt.d_gterm_type==SygusGTerm::gterm_op || sgt.d_gterm_type==SygusGTerm::gterm_let ){
788 Debug("parser-sygus") << "Add " << sgt.d_expr << " to datatype " << index << std::endl;
789 Kind oldKind;
790 Kind newKind = kind::UNDEFINED_KIND;
791 //convert to UMINUS if one child of MINUS
792 if( sgt.d_children.size()==1 && sgt.d_expr==getExprManager()->operatorOf(kind::MINUS) ){
793 oldKind = kind::MINUS;
794 newKind = kind::UMINUS;
795 }
796 //convert to IFF if boolean EQUAL
797 if( sgt.d_expr==getExprManager()->operatorOf(kind::EQUAL) ){
798 Type ctn = sgt.d_children[0].d_type;
799 std::map< CVC4::Type, CVC4::Type >::iterator it = sygus_to_builtin.find( ctn );
800 if( it != sygus_to_builtin.end() && it->second.isBoolean() ){
801 oldKind = kind::EQUAL;
802 newKind = kind::IFF;
803 }
804 }
805 if( newKind!=kind::UNDEFINED_KIND ){
806 Expr newExpr = getExprManager()->operatorOf(newKind);
807 Debug("parser-sygus") << "Replace " << sgt.d_expr << " with " << newExpr << std::endl;
808 sgt.d_expr = newExpr;
809 std::string oldName = kind::kindToString(oldKind);
810 std::string newName = kind::kindToString(newKind);
811 size_t pos = 0;
812 if((pos = sgt.d_name.find(oldName, pos)) != std::string::npos){
813 sgt.d_name.replace(pos, oldName.length(), newName);
814 }
815 }
816 ops[index].push_back( sgt.d_expr );
817 cnames[index].push_back( sgt.d_name );
818 cargs[index].push_back( std::vector< CVC4::Type >() );
819 for( unsigned i=0; i<sgt.d_children.size(); i++ ){
820 std::stringstream ss;
821 ss << datatypes[index].getName() << "_" << ops[index].size() << "_arg_" << i;
822 std::string sub_dname = ss.str();
823 //add datatype for child
824 Type null_type;
825 pushSygusDatatypeDef( null_type, sub_dname, datatypes, sorts, ops, cnames, cargs, allow_const, unresolved_gterm_sym );
826 int sub_dt_index = datatypes.size()-1;
827 //process child
828 Type sub_ret;
829 processSygusGTerm( sgt.d_children[i], sub_dt_index, datatypes, sorts, ops, cnames, cargs, allow_const, unresolved_gterm_sym,
830 sygus_vars, sygus_to_builtin, sygus_to_builtin_expr, sub_ret, true );
831 //process the nested gterm (either pop the last datatype, or flatten the argument)
832 Type tt = processSygusNestedGTerm( sub_dt_index, sub_dname, datatypes, sorts, ops, cnames, cargs, allow_const, unresolved_gterm_sym,
833 sygus_to_builtin, sygus_to_builtin_expr, sub_ret );
834 cargs[index].back().push_back(tt);
835 }
836 //if let, must create operator
837 if( sgt.d_gterm_type==SygusGTerm::gterm_let ){
838 processSygusLetConstructor( sgt.d_let_vars, index, datatypes, sorts, ops, cnames, cargs,
839 sygus_vars, sygus_to_builtin, sygus_to_builtin_expr );
840 }
841 }else if( sgt.d_gterm_type==SygusGTerm::gterm_constant ){
842 if( sgt.getNumChildren()!=0 ){
843 parseError("Bad syntax for Sygus Constant.");
844 }
845 std::vector< Expr > consts;
846 mkSygusConstantsForType( sgt.d_type, consts );
847 Debug("parser-sygus") << "...made " << consts.size() << " constants." << std::endl;
848 for( unsigned i=0; i<consts.size(); i++ ){
849 std::stringstream ss;
850 ss << consts[i];
851 Debug("parser-sygus") << "...add for constant " << ss.str() << std::endl;
852 ops[index].push_back( consts[i] );
853 cnames[index].push_back( ss.str() );
854 cargs[index].push_back( std::vector< CVC4::Type >() );
855 }
856 allow_const[index] = true;
857 }else if( sgt.d_gterm_type==SygusGTerm::gterm_variable || sgt.d_gterm_type==SygusGTerm::gterm_input_variable ){
858 if( sgt.getNumChildren()!=0 ){
859 parseError("Bad syntax for Sygus Variable.");
860 }
861 Debug("parser-sygus") << "...process " << sygus_vars.size() << " variables." << std::endl;
862 for( unsigned i=0; i<sygus_vars.size(); i++ ){
863 if( sygus_vars[i].getType()==sgt.d_type ){
864 std::stringstream ss;
865 ss << sygus_vars[i];
866 Debug("parser-sygus") << "...add for variable " << ss.str() << std::endl;
867 ops[index].push_back( sygus_vars[i] );
868 cnames[index].push_back( ss.str() );
869 cargs[index].push_back( std::vector< CVC4::Type >() );
870 }
871 }
872 }else if( sgt.d_gterm_type==SygusGTerm::gterm_nested_sort ){
873 ret = sgt.d_type;
874 }else if( sgt.d_gterm_type==SygusGTerm::gterm_unresolved ){
875 if( isNested ){
876 if( isUnresolvedType(sgt.d_name) ){
877 ret = getSort(sgt.d_name);
878 }else{
879 //nested, unresolved symbol...fail
880 std::stringstream ss;
881 ss << "Cannot handle nested unresolved symbol " << sgt.d_name << std::endl;
882 parseError(ss.str());
883 }
884 }else{
885 //will resolve when adding constructors
886 unresolved_gterm_sym[index].push_back(sgt.d_name);
887 }
888 }else if( sgt.d_gterm_type==SygusGTerm::gterm_ignore ){
889
890 }
891 }
892
893 bool Smt2::pushSygusDatatypeDef( Type t, std::string& dname,
894 std::vector< CVC4::Datatype >& datatypes,
895 std::vector< CVC4::Type>& sorts,
896 std::vector< std::vector<CVC4::Expr> >& ops,
897 std::vector< std::vector<std::string> >& cnames,
898 std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
899 std::vector< bool >& allow_const,
900 std::vector< std::vector< std::string > >& unresolved_gterm_sym ){
901 sorts.push_back(t);
902 datatypes.push_back(Datatype(dname));
903 ops.push_back(std::vector<Expr>());
904 cnames.push_back(std::vector<std::string>());
905 cargs.push_back(std::vector<std::vector<CVC4::Type> >());
906 allow_const.push_back(false);
907 unresolved_gterm_sym.push_back(std::vector< std::string >());
908 return true;
909 }
910
911 bool Smt2::popSygusDatatypeDef( std::vector< CVC4::Datatype >& datatypes,
912 std::vector< CVC4::Type>& sorts,
913 std::vector< std::vector<CVC4::Expr> >& ops,
914 std::vector< std::vector<std::string> >& cnames,
915 std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
916 std::vector< bool >& allow_const,
917 std::vector< std::vector< std::string > >& unresolved_gterm_sym ){
918 sorts.pop_back();
919 datatypes.pop_back();
920 ops.pop_back();
921 cnames.pop_back();
922 cargs.pop_back();
923 allow_const.pop_back();
924 unresolved_gterm_sym.pop_back();
925 return true;
926 }
927
928 Type Smt2::processSygusNestedGTerm( int sub_dt_index, std::string& sub_dname, std::vector< CVC4::Datatype >& datatypes,
929 std::vector< CVC4::Type>& sorts,
930 std::vector< std::vector<CVC4::Expr> >& ops,
931 std::vector< std::vector<std::string> >& cnames,
932 std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
933 std::vector< bool >& allow_const,
934 std::vector< std::vector< std::string > >& unresolved_gterm_sym,
935 std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin,
936 std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr, Type sub_ret ) {
937 Type t = sub_ret;
938 Debug("parser-sygus") << "Argument is ";
939 if( t.isNull() ){
940 //then, it is the datatype we constructed, which should have a single constructor
941 t = mkUnresolvedType(sub_dname);
942 Debug("parser-sygus") << "inline flattening of (auxiliary, local) datatype " << t << std::endl;
943 Debug("parser-sygus") << ": to compute type, construct ground term witnessing the grammar, #cons=" << cargs[sub_dt_index].size() << std::endl;
944 if( cargs[sub_dt_index].empty() ){
945 parseError(std::string("Internal error : datatype for nested gterm does not have a constructor."));
946 }
947 Expr sop = ops[sub_dt_index][0];
948 Type curr_t;
949 if( sop.getKind() != kind::BUILTIN && ( sop.isConst() || cargs[sub_dt_index][0].empty() ) ){
950 curr_t = sop.getType();
951 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;
952 sygus_to_builtin_expr[t] = sop;
953 //store that term sop has dedicated sygus type t
954 if( d_sygus_bound_var_type.find( sop )==d_sygus_bound_var_type.end() ){
955 d_sygus_bound_var_type[sop] = t;
956 }
957 }else{
958 std::vector< Expr > children;
959 if( sop.getKind() != kind::BUILTIN ){
960 children.push_back( sop );
961 }
962 for( unsigned i=0; i<cargs[sub_dt_index][0].size(); i++ ){
963 std::map< CVC4::Type, CVC4::Expr >::iterator it = sygus_to_builtin_expr.find( cargs[sub_dt_index][0][i] );
964 if( it==sygus_to_builtin_expr.end() ){
965 if( sygus_to_builtin.find( cargs[sub_dt_index][0][i] )==sygus_to_builtin.end() ){
966 std::stringstream ss;
967 ss << "Missing builtin type for type " << cargs[sub_dt_index][0][i] << "!" << std::endl;
968 ss << "Builtin types are currently : " << std::endl;
969 for( std::map< CVC4::Type, CVC4::Type >::iterator itb = sygus_to_builtin.begin(); itb != sygus_to_builtin.end(); ++itb ){
970 ss << " " << itb->first << " -> " << itb->second << std::endl;
971 }
972 parseError(ss.str());
973 }
974 Type bt = sygus_to_builtin[cargs[sub_dt_index][0][i]];
975 Debug("parser-sygus") << ": child " << i << " introduce type elem for " << cargs[sub_dt_index][0][i] << " " << bt << std::endl;
976 std::stringstream ss;
977 ss << t << "_x_" << i;
978 Expr bv = mkBoundVar(ss.str(), bt);
979 children.push_back( bv );
980 d_sygus_bound_var_type[bv] = cargs[sub_dt_index][0][i];
981 }else{
982 Debug("parser-sygus") << ": child " << i << " existing sygus to builtin expr : " << it->second << std::endl;
983 children.push_back( it->second );
984 }
985 }
986 Kind sk = sop.getKind() != kind::BUILTIN ? kind::APPLY : getExprManager()->operatorToKind(sop);
987 Debug("parser-sygus") << ": operator " << sop << " with " << sop.getKind() << " " << sk << std::endl;
988 Expr e = getExprManager()->mkExpr( sk, children );
989 Debug("parser-sygus") << ": constructed " << e << ", which has type " << e.getType() << std::endl;
990 curr_t = e.getType();
991 sygus_to_builtin_expr[t] = e;
992 }
993 sorts[sub_dt_index] = curr_t;
994 sygus_to_builtin[t] = curr_t;
995 }else{
996 Debug("parser-sygus") << "simple argument " << t << std::endl;
997 Debug("parser-sygus") << "...removing " << datatypes.back().getName() << std::endl;
998 //otherwise, datatype was unecessary
999 //pop argument datatype definition
1000 popSygusDatatypeDef( datatypes, sorts, ops, cnames, cargs, allow_const, unresolved_gterm_sym );
1001 }
1002 return t;
1003 }
1004
1005 void Smt2::processSygusLetConstructor( std::vector< CVC4::Expr >& let_vars,
1006 int index,
1007 std::vector< CVC4::Datatype >& datatypes,
1008 std::vector< CVC4::Type>& sorts,
1009 std::vector< std::vector<CVC4::Expr> >& ops,
1010 std::vector< std::vector<std::string> >& cnames,
1011 std::vector< std::vector< std::vector< CVC4::Type > > >& cargs,
1012 std::vector<CVC4::Expr>& sygus_vars,
1013 std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin,
1014 std::map< CVC4::Type, CVC4::Expr >& sygus_to_builtin_expr ) {
1015 std::vector< CVC4::Expr > let_define_args;
1016 Expr let_body;
1017 int dindex = cargs[index].size()-1;
1018 Debug("parser-sygus") << "Process let constructor for datatype " << datatypes[index].getName() << ", #subtypes = " << cargs[index][dindex].size() << std::endl;
1019 for( unsigned i=0; i<cargs[index][dindex].size(); i++ ){
1020 Debug("parser-sygus") << " " << i << " : " << cargs[index][dindex][i] << std::endl;
1021 if( i+1==cargs[index][dindex].size() ){
1022 std::map< CVC4::Type, CVC4::Expr >::iterator it = sygus_to_builtin_expr.find( cargs[index][dindex][i] );
1023 if( it!=sygus_to_builtin_expr.end() ){
1024 let_body = it->second;
1025 }else{
1026 std::stringstream ss;
1027 ss << datatypes[index].getName() << "_body";
1028 let_body = mkBoundVar(ss.str(), sygus_to_builtin[cargs[index][dindex][i]]);
1029 d_sygus_bound_var_type[let_body] = cargs[index][dindex][i];
1030 }
1031 }
1032 }
1033 Debug("parser-sygus") << std::endl;
1034 Debug("parser-sygus") << "Body is " << let_body << std::endl;
1035 Debug("parser-sygus") << "# let vars = " << let_vars.size() << std::endl;
1036 for( unsigned i=0; i<let_vars.size(); i++ ){
1037 Debug("parser-sygus") << " let var " << i << " : " << let_vars[i] << " " << let_vars[i].getType() << std::endl;
1038 let_define_args.push_back( let_vars[i] );
1039 }
1040 /*
1041 Debug("parser-sygus") << "index = " << index << ", start index = " << start_index << ", #Current datatypes = " << datatypes.size() << std::endl;
1042 for( unsigned i=start_index; i<datatypes.size(); i++ ){
1043 Debug("parser-sygus") << " datatype " << i << " : " << datatypes[i].getName() << ", #cons = " << cargs[i].size() << std::endl;
1044 if( !cargs[i].empty() ){
1045 Debug("parser-sygus") << " operator 0 is " << ops[i][0] << std::endl;
1046 Debug("parser-sygus") << " cons 0 has " << cargs[i][0].size() << " sub fields." << std::endl;
1047 for( unsigned j=0; j<cargs[i][0].size(); j++ ){
1048 Type bt = sygus_to_builtin[cargs[i][0][j]];
1049 Debug("parser-sygus") << " cons 0, selector " << j << " : " << cargs[i][0][j] << " " << bt << std::endl;
1050 }
1051 }
1052 }
1053 */
1054 //last argument is the return, pop
1055 cargs[index][dindex].pop_back();
1056 collectSygusLetArgs( let_body, cargs[index][dindex], let_define_args );
1057
1058 Debug("parser-sygus") << "Make define-fun with " << cargs[index][dindex].size() << " arguments..." << std::endl;
1059 std::vector<CVC4::Type> fsorts;
1060 for( unsigned i=0; i<cargs[index][dindex].size(); i++ ){
1061 Debug("parser-sygus") << " " << i << " : " << let_define_args[i] << " " << let_define_args[i].getType() << " " << cargs[index][dindex][i] << std::endl;
1062 fsorts.push_back(let_define_args[i].getType());
1063 }
1064
1065 Type ft = getExprManager()->mkFunctionType(fsorts, let_body.getType());
1066 std::stringstream ss;
1067 ss << datatypes[index].getName() << "_let";
1068 Expr let_func = mkFunction(ss.str(), ft, ExprManager::VAR_FLAG_DEFINED);
1069 d_sygus_defined_funs.push_back( let_func );
1070 preemptCommand( new DefineFunctionCommand(ss.str(), let_func, let_define_args, let_body) );
1071
1072 ops[index].pop_back();
1073 ops[index].push_back( let_func );
1074 cnames[index].pop_back();
1075 cnames[index].push_back(ss.str());
1076
1077 //mark function as let constructor
1078 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() );
1079 d_sygus_let_func_to_body[let_func] = let_body;
1080 d_sygus_let_func_to_num_input_vars[let_func] = let_vars.size();
1081 }
1082
1083
1084 void Smt2::collectSygusLetArgs( CVC4::Expr e, std::vector< CVC4::Type >& sygusArgs, std::vector< CVC4::Expr >& builtinArgs ) {
1085 if( e.getKind()==kind::BOUND_VARIABLE ){
1086 if( std::find( builtinArgs.begin(), builtinArgs.end(), e )==builtinArgs.end() ){
1087 builtinArgs.push_back( e );
1088 sygusArgs.push_back( d_sygus_bound_var_type[e] );
1089 if( d_sygus_bound_var_type[e].isNull() ){
1090 std::stringstream ss;
1091 ss << "While constructing body of let gterm, can't map " << e << " to sygus type." << std::endl;
1092 parseError(ss.str());
1093 }
1094 }
1095 }else{
1096 for( unsigned i=0; i<e.getNumChildren(); i++ ){
1097 collectSygusLetArgs( e[i], sygusArgs, builtinArgs );
1098 }
1099 }
1100 }
1101
1102 void Smt2::setSygusStartIndex( std::string& fun, int startIndex,
1103 std::vector< CVC4::Datatype >& datatypes,
1104 std::vector< CVC4::Type>& sorts,
1105 std::vector< std::vector<CVC4::Expr> >& ops ) {
1106 if( startIndex>0 ){
1107 CVC4::Datatype tmp_dt = datatypes[0];
1108 Type tmp_sort = sorts[0];
1109 std::vector< Expr > tmp_ops;
1110 tmp_ops.insert( tmp_ops.end(), ops[0].begin(), ops[0].end() );
1111 datatypes[0] = datatypes[startIndex];
1112 sorts[0] = sorts[startIndex];
1113 ops[0].clear();
1114 ops[0].insert( ops[0].end(), ops[startIndex].begin(), ops[startIndex].end() );
1115 datatypes[startIndex] = tmp_dt;
1116 sorts[startIndex] = tmp_sort;
1117 ops[startIndex].clear();
1118 ops[startIndex].insert( ops[startIndex].begin(), tmp_ops.begin(), tmp_ops.end() );
1119 }else if( startIndex<0 ){
1120 std::stringstream ss;
1121 ss << "warning: no symbol named Start for synth-fun " << fun << std::endl;
1122 warning(ss.str());
1123 }
1124 }
1125
1126 void Smt2::defineSygusFuns() {
1127 // only define each one once
1128 while(d_nextSygusFun < d_sygusFuns.size()) {
1129 std::pair<std::string, Expr> p = d_sygusFuns[d_nextSygusFun];
1130 std::string fun = p.first;
1131 Debug("parser-sygus") << "Sygus : define fun " << fun << std::endl;
1132 Expr eval = p.second;
1133 FunctionType evalType = eval.getType();
1134 std::vector<Type> argTypes = evalType.getArgTypes();
1135 Type rangeType = evalType.getRangeType();
1136 Debug("parser-sygus") << "...eval type : " << evalType << ", #args=" << argTypes.size() << std::endl;
1137
1138 // first make the function type
1139 std::vector<Expr> sygusVars;
1140 std::vector<Type> funType;
1141 for(size_t j = 1; j < argTypes.size(); ++j) {
1142 funType.push_back(argTypes[j]);
1143 std::stringstream ss;
1144 ss << fun << "_v_" << j;
1145 sygusVars.push_back(getExprManager()->mkBoundVar(ss.str(), argTypes[j]));
1146 }
1147 Type funt;
1148 if( !funType.empty() ){
1149 funt = getExprManager()->mkFunctionType(funType, rangeType);
1150 Debug("parser-sygus") << "...eval function type : " << funt << std::endl;
1151
1152 // copy the bound vars
1153 /*
1154 std::vector<Expr> sygusVars;
1155 //std::vector<Type> types;
1156 for(size_t i = 0; i < d_sygusVars.size(); ++i) {
1157 std::stringstream ss;
1158 ss << d_sygusVars[i];
1159 Type type = d_sygusVars[i].getType();
1160 sygusVars.push_back(getExprManager()->mkBoundVar(ss.str(), type));
1161 //types.push_back(type);
1162 }
1163 Debug("parser-sygus") << "...made vars, #vars=" << sygusVars.size() << std::endl;
1164 */
1165
1166 //Type t = getExprManager()->mkFunctionType(types, rangeType);
1167 //Debug("parser-sygus") << "...function type : " << t << std::endl;
1168 }else{
1169 funt = rangeType;
1170 }
1171 Expr lambda = mkFunction(fun, funt, ExprManager::VAR_FLAG_DEFINED);
1172 Debug("parser-sygus") << "...made function : " << lambda << std::endl;
1173 std::vector<Expr> applyv;
1174 Expr funbv = getExprManager()->mkBoundVar(std::string("f") + fun, argTypes[0]);
1175 d_sygusFunSymbols.push_back(funbv);
1176 applyv.push_back(eval);
1177 applyv.push_back(funbv);
1178 for(size_t i = 0; i < sygusVars.size(); ++i) {
1179 applyv.push_back(sygusVars[i]);
1180 }
1181 Expr apply = getExprManager()->mkExpr(kind::APPLY_UF, applyv);
1182 Debug("parser-sygus") << "...made apply " << apply << std::endl;
1183 Debug("parser-sygus") << "--> Define " << fun << " as " << lambda << " " << apply << std::endl;
1184 Command* cmd = new DefineFunctionCommand(fun, lambda, sygusVars, apply);
1185 preemptCommand(cmd);
1186
1187 ++d_nextSygusFun;
1188 }
1189 }
1190
1191 void Smt2::mkSygusDatatype( CVC4::Datatype& dt, std::vector<CVC4::Expr>& ops,
1192 std::vector<std::string>& cnames, std::vector< std::vector< CVC4::Type > >& cargs,
1193 std::vector<std::string>& unresolved_gterm_sym,
1194 std::map< CVC4::Type, CVC4::Type >& sygus_to_builtin ) {
1195 Debug("parser-sygus") << "Making sygus datatype " << dt.getName() << std::endl;
1196 Debug("parser-sygus") << " add constructors..." << std::endl;
1197 for( int i=0; i<(int)cnames.size(); i++ ){
1198 bool is_dup = false;
1199 bool is_dup_op = false;
1200 Expr let_body;
1201 std::vector< Expr > let_args;
1202 unsigned let_num_input_args = 0;
1203 for( int j=0; j<i; j++ ){
1204 if( ops[i]==ops[j] ){
1205 is_dup_op = true;
1206 if( cargs[i].size()==cargs[j].size() ){
1207 is_dup = true;
1208 for( unsigned k=0; k<cargs[i].size(); k++ ){
1209 if( cargs[i][k]!=cargs[j][k] ){
1210 is_dup = false;
1211 break;
1212 }
1213 }
1214 }
1215 if( is_dup ){
1216 break;
1217 }
1218 }
1219 }
1220 if( is_dup ){
1221 Debug("parser-sygus") << "--> Duplicate gterm : " << ops[i] << " at " << i << std::endl;
1222 ops.erase( ops.begin() + i, ops.begin() + i + 1 );
1223 cnames.erase( cnames.begin() + i, cnames.begin() + i + 1 );
1224 cargs.erase( cargs.begin() + i, cargs.begin() + i + 1 );
1225 i--;
1226 }else if( is_dup_op ){
1227 Debug("parser-sygus") << "--> Duplicate gterm operator : " << ops[i] << " at " << i << std::endl;
1228 //make into define-fun
1229 std::vector<CVC4::Type> fsorts;
1230 for( unsigned j=0; j<cargs[i].size(); j++ ){
1231 Type bt = sygus_to_builtin[cargs[i][j]];
1232 std::stringstream ss;
1233 ss << dt.getName() << "_x_" << i << "_" << j;
1234 Expr v = mkBoundVar(ss.str(), bt);
1235 let_args.push_back( v );
1236 fsorts.push_back( bt );
1237 Debug("parser-sygus") << ": var " << i << " " << v << " with type " << bt << " from " << cargs[i][j] << std::endl;
1238 }
1239 //make the let_body
1240 std::vector< Expr > children;
1241 if( ops[i].getKind() != kind::BUILTIN ){
1242 children.push_back( ops[i] );
1243 }
1244 children.insert( children.end(), let_args.begin(), let_args.end() );
1245 Kind sk = ops[i].getKind() != kind::BUILTIN ? kind::APPLY : getExprManager()->operatorToKind(ops[i]);
1246 Debug("parser-sygus") << ": replace " << ops[i] << " " << ops[i].getKind() << " " << sk << std::endl;
1247 let_body = getExprManager()->mkExpr( sk, children );
1248 Debug("parser-sygus") << ": new body of function is " << let_body << std::endl;
1249
1250 Type ft = getExprManager()->mkFunctionType(fsorts, let_body.getType());
1251 Debug("parser-sygus") << ": function type is " << ft << std::endl;
1252 std::stringstream ss;
1253 ss << dt.getName() << "_df_" << i;
1254 //replace operator and name
1255 ops[i] = mkFunction(ss.str(), ft, ExprManager::VAR_FLAG_DEFINED);
1256 cnames[i] = ss.str();
1257 d_sygus_defined_funs.push_back( ops[i] );
1258 preemptCommand( new DefineFunctionCommand(ss.str(), ops[i], let_args, let_body) );
1259 addSygusDatatypeConstructor( dt, ops[i], cnames[i], cargs[i], let_body, let_args, 0 );
1260 }else{
1261 std::map< CVC4::Expr, CVC4::Expr >::iterator it = d_sygus_let_func_to_body.find( ops[i] );
1262 if( it!=d_sygus_let_func_to_body.end() ){
1263 let_body = it->second;
1264 let_args.insert( let_args.end(), d_sygus_let_func_to_vars[ops[i]].begin(), d_sygus_let_func_to_vars[ops[i]].end() );
1265 let_num_input_args = d_sygus_let_func_to_num_input_vars[ops[i]];
1266 }
1267 addSygusDatatypeConstructor( dt, ops[i], cnames[i], cargs[i], let_body, let_args, let_num_input_args );
1268 }
1269 }
1270 Debug("parser-sygus") << " add constructors for unresolved symbols..." << std::endl;
1271 if( !unresolved_gterm_sym.empty() ){
1272 std::vector< Type > types;
1273 Debug("parser-sygus") << "...resolve " << unresolved_gterm_sym.size() << " symbols..." << std::endl;
1274 for( unsigned i=0; i<unresolved_gterm_sym.size(); i++ ){
1275 Debug("parser-sygus") << " resolve : " << unresolved_gterm_sym[i] << std::endl;
1276 if( isUnresolvedType(unresolved_gterm_sym[i]) ){
1277 Debug("parser-sygus") << " it is an unresolved type." << std::endl;
1278 Type t = getSort(unresolved_gterm_sym[i]);
1279 if( std::find( types.begin(), types.end(), t )==types.end() ){
1280 types.push_back( t );
1281 //identity element
1282 Type bt = dt.getSygusType();
1283 Debug("parser-sygus") << ": make identity function for " << bt << ", argument type " << t << std::endl;
1284 std::stringstream ss;
1285 ss << t << "_x_id";
1286 Expr let_body = mkBoundVar(ss.str(), bt);
1287 std::vector< Expr > let_args;
1288 let_args.push_back( let_body );
1289 //make the identity function
1290 Type ft = getExprManager()->mkFunctionType(bt, bt);
1291 std::stringstream ssid;
1292 ssid << unresolved_gterm_sym[i] << "_id";
1293 Expr id_op = mkFunction(ss.str(), ft, ExprManager::VAR_FLAG_DEFINED);
1294 d_sygus_defined_funs.push_back( id_op );
1295 preemptCommand( new DefineFunctionCommand(ssid.str(), id_op, let_args, let_body) );
1296 //make the sygus argument list
1297 std::vector< Type > id_carg;
1298 id_carg.push_back( t );
1299 addSygusDatatypeConstructor( dt, id_op, unresolved_gterm_sym[i], id_carg, let_body, let_args, 0 );
1300 //add to operators
1301 ops.push_back( id_op );
1302 }
1303 }else{
1304 Debug("parser-sygus") << " ignore. (likely a free let variable)" << std::endl;
1305 }
1306 }
1307 }
1308
1309 }
1310
1311 void Smt2::addSygusDatatypeConstructor( CVC4::Datatype& dt, CVC4::Expr op, std::string& cname, std::vector< CVC4::Type >& cargs,
1312 CVC4::Expr& let_body, std::vector< CVC4::Expr >& let_args, unsigned let_num_input_args ) {
1313 Debug("parser-sygus") << "--> Add constructor " << cname << " to " << dt.getName() << std::endl;
1314 if( !let_body.isNull() ){
1315 Debug("parser-sygus") << " let body = " << let_body << ", args = " << let_args.size() << "," << let_num_input_args << std::endl;
1316 //TODO : remove arguments not occurring in body
1317 //if this is a self identity function, ignore
1318 if( let_args.size()==0 && let_args[0]==let_body ){
1319 Debug("parser-sygus") << " identity function " << cargs[0] << " to " << dt.getName() << std::endl;
1320 //TODO
1321 }
1322 }
1323 std::string name = dt.getName() + "_" + cname;
1324 std::string testerId("is-");
1325 testerId.append(name);
1326 checkDeclaration(name, CHECK_UNDECLARED, SYM_VARIABLE);
1327 checkDeclaration(testerId, CHECK_UNDECLARED, SYM_VARIABLE);
1328 CVC4::DatatypeConstructor c(name, testerId );
1329 c.setSygus( op, let_body, let_args, let_num_input_args );
1330 for( unsigned j=0; j<cargs.size(); j++ ){
1331 Debug("parser-sygus-debug") << " arg " << j << " : " << cargs[j] << std::endl;
1332 std::stringstream sname;
1333 sname << name << "_" << j;
1334 c.addArg(sname.str(), cargs[j]);
1335 }
1336 dt.addConstructor(c);
1337 }
1338
1339
1340 // i is index in datatypes/ops
1341 // j is index is datatype
1342 Expr Smt2::getSygusAssertion( std::vector<DatatypeType>& datatypeTypes, std::vector< std::vector<Expr> >& ops,
1343 std::map<DatatypeType, Expr>& evals, std::vector<Expr>& terms,
1344 Expr eval, const Datatype& dt, size_t i, size_t j ) {
1345 const DatatypeConstructor& ctor = dt[j];
1346 Debug("parser-sygus") << "Sygus : process constructor " << j << " : " << dt[j] << std::endl;
1347 std::vector<Expr> bvs, extraArgs;
1348 for(size_t k = 0; k < ctor.getNumArgs(); ++k) {
1349 std::string vname = "v_" + ctor[k].getName();
1350 Expr bv = getExprManager()->mkBoundVar(vname, SelectorType(ctor[k].getType()).getRangeType());
1351 bvs.push_back(bv);
1352 extraArgs.push_back(bv);
1353 }
1354 if( !terms[0].isNull() ){
1355 bvs.insert(bvs.end(), terms[0].begin(), terms[0].end());
1356 }
1357 Expr bvl;
1358 if( !bvs.empty() ){
1359 bvl = getExprManager()->mkExpr(kind::BOUND_VAR_LIST, bvs);
1360 }
1361 Debug("parser-sygus") << "...made bv list " << bvl << std::endl;
1362 std::vector<Expr> patv;
1363 patv.push_back(eval);
1364 std::vector<Expr> applyv;
1365 applyv.push_back(ctor.getConstructor());
1366 applyv.insert(applyv.end(), extraArgs.begin(), extraArgs.end());
1367 for(size_t k = 0; k < applyv.size(); ++k) {
1368 }
1369 Expr cpatv = getExprManager()->mkExpr(kind::APPLY_CONSTRUCTOR, applyv);
1370 Debug("parser-sygus") << "...made eval ctor apply " << cpatv << std::endl;
1371 patv.push_back(cpatv);
1372 if( !terms[0].isNull() ){
1373 patv.insert(patv.end(), terms[0].begin(), terms[0].end());
1374 }
1375 Expr evalApply = getExprManager()->mkExpr(kind::APPLY_UF, patv);
1376 Debug("parser-sygus") << "...made eval apply " << evalApply << std::endl;
1377 std::vector<Expr> builtApply;
1378 for(size_t k = 0; k < extraArgs.size(); ++k) {
1379 std::vector<Expr> patvb;
1380 patvb.push_back(evals[DatatypeType(extraArgs[k].getType())]);
1381 patvb.push_back(extraArgs[k]);
1382 if( !terms[0].isNull() ){
1383 patvb.insert(patvb.end(), terms[0].begin(), terms[0].end());
1384 }
1385 Debug("parser-sygus-debug") << "...add to built apply " << evals[DatatypeType(extraArgs[k].getType())] << " " << extraArgs[k] << " " << extraArgs[k].getType() << std::endl;
1386 builtApply.push_back(getExprManager()->mkExpr(kind::APPLY_UF, patvb));
1387 Debug("parser-sygus-debug") << "...added " << builtApply.back() << std::endl;
1388 }
1389 for(size_t k = 0; k < builtApply.size(); ++k) {
1390 }
1391 Expr builtTerm;
1392 Debug("parser-sygus") << "...operator is : " << ops[i][j] << ", type = " << ops[i][j].getType() << ", kind = " << ops[i][j].getKind() << ", is defined = " << isDefinedFunction( ops[i][j] ) << std::endl;
1393 if( ops[i][j].getKind() != kind::BUILTIN ){
1394 Kind ok = kind::UNDEFINED_KIND;
1395 if( isDefinedFunction( ops[i][j] ) || std::find( d_sygus_defined_funs.begin(), d_sygus_defined_funs.end(), ops[i][j] )!=d_sygus_defined_funs.end() ){
1396 ok = kind::APPLY;
1397 }else{
1398 Type t = ops[i][j].getType();
1399 if( t.isConstructor() ){
1400 ok = kind::APPLY_CONSTRUCTOR;
1401 }else if( t.isSelector() ){
1402 ok = kind::APPLY_SELECTOR;
1403 }else if( t.isTester() ){
1404 ok = kind::APPLY_TESTER;
1405 }else{
1406 ok = getExprManager()->operatorToKind( ops[i][j] );
1407 }
1408 }
1409 Debug("parser-sygus") << "...processed operator kind : " << ok << std::endl;
1410 if( ok!=kind::UNDEFINED_KIND ){
1411 builtTerm = getExprManager()->mkExpr(ok, ops[i][j], builtApply);
1412 }else{
1413 builtTerm = ops[i][j];
1414 }
1415 }else{
1416 if( !builtApply.empty() ){
1417 builtTerm = getExprManager()->mkExpr(ops[i][j], builtApply);
1418 }else{
1419 builtTerm = ops[i][j];
1420 }
1421 }
1422 Debug("parser-sygus") << "...made built term " << builtTerm << std::endl;
1423 Expr assertion = getExprManager()->mkExpr(evalApply.getType().isBoolean() ? kind::IFF : kind::EQUAL, evalApply, builtTerm);
1424 if( !bvl.isNull() ){
1425 Expr pattern = getExprManager()->mkExpr(kind::INST_PATTERN, evalApply);
1426 pattern = getExprManager()->mkExpr(kind::INST_PATTERN_LIST, pattern);
1427 assertion = getExprManager()->mkExpr(kind::FORALL, bvl, assertion, pattern);
1428 }
1429 Debug("parser-sygus") << "...made assertion " << assertion << std::endl;
1430
1431 //linearize multiplication if possible
1432 if( builtTerm.getKind()==kind::MULT ){
1433 for(size_t k = 0; k < ctor.getNumArgs(); ++k) {
1434 Type at = SelectorType(ctor[k].getType()).getRangeType();
1435 if( at.isDatatype() ){
1436 DatatypeType atd = (DatatypeType)SelectorType(ctor[k].getType()).getRangeType();
1437 Debug("parser-sygus") << "Argument " << k << " " << atd << std::endl;
1438 std::vector<DatatypeType>::iterator itd = std::find( datatypeTypes.begin(), datatypeTypes.end(), atd );
1439 if( itd!=datatypeTypes.end() ){
1440 Debug("parser-sygus2") << "Exists in datatypeTypes." << std::endl;
1441 unsigned index = itd-datatypeTypes.begin();
1442 Debug("parser-sygus2") << "index = " << index << std::endl;
1443 bool isConst = true;
1444 for( unsigned cc = 0; cc < ops[index].size(); cc++ ){
1445 Debug("parser-sygus2") << "ops[" << cc << "]=" << ops[index][cc] << std::endl;
1446 if( ops[index][cc].getKind() != kind::CONST_RATIONAL ){
1447 isConst = false;
1448 break;
1449 }
1450 }
1451 if( isConst ){
1452 Debug("parser-sygus") << "Linearize multiplication " << ctor << " based on argument " << k << std::endl;
1453 const Datatype & atdd = atd.getDatatype();
1454 std::vector<Expr> assertions;
1455 std::vector<Expr> nbvs;
1456 for( unsigned a=0; a<bvl.getNumChildren(); a++ ){
1457 if( a!=k ){
1458 nbvs.push_back( bvl[a] );
1459 }
1460 }
1461 Expr nbvl = getExprManager()->mkExpr( kind::BOUND_VAR_LIST, nbvs );
1462 for( unsigned cc = 0; cc < ops[index].size(); cc++ ){
1463 //Make new assertion based on partially instantiating existing
1464 applyv[k+1] = getExprManager()->mkExpr(kind::APPLY_CONSTRUCTOR, atdd[cc].getConstructor());
1465 Debug("parser-sygus") << "applyv " << applyv[k+1] << std::endl;
1466 cpatv = getExprManager()->mkExpr(kind::APPLY_CONSTRUCTOR, applyv);
1467 Debug("parser-sygus") << "cpatv " << cpatv << std::endl;
1468 patv[1] = cpatv;
1469 evalApply = getExprManager()->mkExpr(kind::APPLY_UF, patv);
1470 Debug("parser-sygus") << "evalApply " << evalApply << std::endl;
1471 builtApply[k] = ops[index][cc];
1472 Debug("parser-sygus") << "builtApply " << builtApply[k] << std::endl;
1473 builtTerm = getExprManager()->mkExpr(ops[i][j], builtApply);
1474 Debug("parser-sygus") << "builtTerm " << builtTerm << std::endl;
1475 Expr eassertion = getExprManager()->mkExpr(evalApply.getType().isBoolean() ? kind::IFF : kind::EQUAL, evalApply, builtTerm);
1476 Expr epattern = getExprManager()->mkExpr(kind::INST_PATTERN, evalApply);
1477 epattern = getExprManager()->mkExpr(kind::INST_PATTERN_LIST, epattern);
1478 eassertion = getExprManager()->mkExpr(kind::FORALL, nbvl, eassertion, epattern);
1479 assertions.push_back( eassertion );
1480 }
1481 assertion = assertions.size()==1 ? assertions[0] : getExprManager()->mkExpr( kind::AND, assertions );
1482 Debug("parser-sygus") << "...(linearized) assertion is: " << assertion << std::endl;
1483 }
1484 }
1485 }
1486 }
1487 }
1488 return assertion;
1489 }
1490
1491 const void Smt2::getSygusPrimedVars( std::vector<Expr>& vars, bool isPrimed ) {
1492 for( unsigned i=0; i<d_sygusVars.size(); i++ ){
1493 Expr v = d_sygusVars[i];
1494 std::map< Expr, bool >::iterator it = d_sygusVarPrimed.find( v );
1495 if( it!=d_sygusVarPrimed.end() ){
1496 if( it->second==isPrimed ){
1497 vars.push_back( v );
1498 }
1499 }else{
1500 //should never happen
1501 }
1502 }
1503 }
1504
1505 }/* CVC4::parser namespace */
1506 }/* CVC4 namespace */