00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "translator.h"
00024 #include "expr.h"
00025 #include "theory_core.h"
00026 #include "theory_uf.h"
00027 #include "theory_arith.h"
00028 #include "theory_bitvector.h"
00029 #include "theory_array.h"
00030 #include "theory_quant.h"
00031 #include "theory_records.h"
00032 #include "theory_simulate.h"
00033 #include "theory_datatype.h"
00034 #include "theory_datatype_lazy.h"
00035 #include "smtlib_exception.h"
00036 #include "command_line_flags.h"
00037
00038
00039 using namespace std;
00040 using namespace CVC3;
00041
00042
00043 string Translator::fileToSMTLIBIdentifier(const string& filename)
00044 {
00045 string tmpName;
00046 string::size_type pos = filename.rfind("/");
00047 if (pos == string::npos) {
00048 tmpName = filename;
00049 }
00050 else {
00051 tmpName = filename.substr(pos+1);
00052 }
00053 char c = tmpName[0];
00054 string res;
00055 if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) {
00056 res = "B_";
00057 }
00058 for (unsigned i = 0; i < tmpName.length(); ++i) {
00059 c = tmpName[i];
00060 if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
00061 (c < '0' || c > '9') && (c != '.' && c != '_')) {
00062 c = '_';
00063 }
00064 res += c;
00065 }
00066 return res;
00067 }
00068
00069
00070 Expr Translator::preprocessRec(const Expr& e, ExprMap<Expr>& cache)
00071 {
00072 ExprMap<Expr>::iterator i(cache.find(e));
00073 if(i != cache.end()) {
00074 return (*i).second;
00075 }
00076
00077 if (e.isClosure()) {
00078 Expr newBody = preprocessRec(e.getBody(), cache);
00079 Expr e2(e);
00080 if (newBody != e.getBody()) {
00081 e2 = d_em->newClosureExpr(e.getKind(), e.getVars(), newBody);
00082 }
00083 d_theoryCore->theoryOf(e2)->setUsed();
00084 cache[e] = e2;
00085 return e2;
00086 }
00087
00088 Expr e2(e);
00089 vector<Expr> children;
00090 bool diff = false;
00091
00092 for(int k = 0; k < e.arity(); ++k) {
00093
00094 Expr child = preprocessRec(e[k], cache);
00095 if (child != e[k]) diff = true;
00096 children.push_back(child);
00097 }
00098 if (diff) {
00099 e2 = Expr(e.getOp(), children);
00100 }
00101
00102 Rational r;
00103 switch (e2.getKind()) {
00104 case RATIONAL_EXPR:
00105 if (d_convertToBV) {
00106 Rational r = e2.getRational();
00107 if (!r.isInteger()) {
00108 FatalAssert(false, "Cannot convert non-integer constant to BV");
00109 }
00110 Rational limit = pow(d_convertToBV-1, 2);
00111 if (r >= limit) {
00112 FatalAssert(false, "Cannot convert to BV: integer too big");
00113 }
00114 else if (r < -limit) {
00115 FatalAssert(false, "Cannot convert to BV: integer too small");
00116 }
00117 e2 = d_theoryBitvector->signed_newBVConstExpr(r, d_convertToBV);
00118 break;
00119 }
00120
00121 case READ:
00122 if (!d_unknown && d_theoryCore->getFlags()["convert2array"].getBool()) {
00123 if (e2[1].getKind() != UCONST) break;
00124 map<string, Type>::iterator i = d_arrayConvertMap->find(e2[1].getName());
00125 if (i == d_arrayConvertMap->end()) {
00126 (*d_arrayConvertMap)[e2[1].getName()] = *d_indexType;
00127 }
00128 else {
00129 if ((*i).second != (*d_indexType)) {
00130 d_unknown = true;
00131 }
00132 }
00133 }
00134 break;
00135
00136 case WRITE:
00137 if (!d_unknown && d_theoryCore->getFlags()["convert2array"].getBool()) {
00138 map<string, Type>::iterator i;
00139 if (e2[1].getKind() == UCONST) {
00140 i = d_arrayConvertMap->find(e2[1].getName());
00141 if (i == d_arrayConvertMap->end()) {
00142 (*d_arrayConvertMap)[e2[1].getName()] = *d_indexType;
00143 }
00144 else {
00145 if ((*i).second != (*d_indexType)) {
00146 d_unknown = true;
00147 break;
00148 }
00149 }
00150 }
00151 if (e2[2].getKind() != UCONST) break;
00152 i = d_arrayConvertMap->find(e2[2].getName());
00153 if (i == d_arrayConvertMap->end()) {
00154 (*d_arrayConvertMap)[e2[2].getName()] = *d_elementType;
00155 }
00156 else {
00157 if ((*i).second != (*d_elementType)) {
00158 d_unknown = true;
00159 }
00160 }
00161 }
00162 break;
00163
00164 case APPLY:
00165
00166 if (e2.getOpKind() == LAMBDA) {
00167 Expr lambda(e2.getOpExpr());
00168 Expr body(lambda.getBody());
00169 const vector<Expr>& vars = lambda.getVars();
00170 FatalAssert(vars.size() == (size_t)e2.arity(),
00171 "wrong number of arguments applied to lambda\n");
00172 body = body.substExpr(vars, e2.getKids());
00173 e2 = preprocessRec(body, cache);
00174 }
00175 break;
00176
00177 case EQ:
00178 if (d_theoryArith->getBaseType(e2[0]) != d_theoryArith->realType())
00179 break;
00180 if (d_theoryCore->getFlags()["convert2array"].getBool() &&
00181 ((e2[0].getKind() == UCONST && d_arrayConvertMap->find(e2[0].getName()) == d_arrayConvertMap->end()) ||
00182 (e2[1].getKind() == UCONST && d_arrayConvertMap->find(e2[1].getName()) == d_arrayConvertMap->end()))) {
00183 d_equalities.push_back(e2);
00184 }
00185 goto arith_rewrites;
00186
00187 case UMINUS:
00188 if (d_convertToBV) {
00189 e2 = Expr(BVUMINUS, e2[0]);
00190 break;
00191 }
00192 if (d_theoryArith->isSyntacticRational(e2, r)) {
00193 e2 = preprocessRec(d_em->newRatExpr(r), cache);
00194 break;
00195 }
00196 goto arith_rewrites;
00197
00198 case DIVIDE:
00199 if (d_convertToBV) {
00200 FatalAssert(false, "Conversion of DIVIDE to BV not implemented yet");
00201 break;
00202 }
00203 if (d_theoryArith->isSyntacticRational(e2, r)) {
00204 e2 = preprocessRec(d_em->newRatExpr(r), cache);
00205 break;
00206 }
00207 else if (d_convertArith && e2[1].isRational()) {
00208 r = e2[1].getRational();
00209 if (r != 0) {
00210 e2 = d_em->newRatExpr(1/r) * e2[0];
00211 e2 = preprocessRec(e2, cache);
00212 break;
00213 }
00214 }
00215 goto arith_rewrites;
00216
00217 case MINUS:
00218 if (d_convertToBV) {
00219 e2 = Expr(BVSUB, e2[0], e2[1]);
00220 break;
00221 }
00222 if (d_convertArith) {
00223 if (e2[0].isRational() && e2[1].isRational()) {
00224 e2 = d_em->newRatExpr(e2[0].getRational() - e2[1].getRational());
00225 break;
00226 }
00227 }
00228 goto arith_rewrites;
00229
00230 case PLUS:
00231 if (d_convertToBV) {
00232 e2 = Expr(Expr(BVPLUS, d_em->newRatExpr(d_convertToBV)).mkOp(), e2.getKids());
00233 break;
00234 }
00235 if (d_convertArith) {
00236
00237 vector<Expr> terms;
00238 bool changed = false;
00239 int numConst = 0;
00240 r = 0;
00241 Expr::iterator i = e2.begin(), iend = e2.end();
00242 for(; i!=iend; ++i) {
00243 if ((*i).getKind() == PLUS) {
00244 changed = true;
00245 Expr::iterator i2 = (*i).begin(), i2end = (*i).end();
00246 for (; i2 != i2end; ++i2) {
00247 if ((*i2).isRational()) {
00248 r += (*i2).getRational();
00249 numConst++;
00250 }
00251 else terms.push_back(*i2);
00252 }
00253 }
00254 else {
00255 if ((*i).isRational()) {
00256 r += (*i).getRational();
00257 numConst++;
00258 if (numConst > 1) changed = true;
00259 }
00260 else terms.push_back(*i);
00261 }
00262 }
00263 if (terms.size() == 0) {
00264 e2 = preprocessRec(d_em->newRatExpr(r), cache);
00265 break;
00266 }
00267 else if (terms.size() == 1) {
00268 if (r == 0) {
00269 e2 = terms[0];
00270 break;
00271 }
00272 else if (r < 0) {
00273 e2 = preprocessRec(Expr(MINUS, terms[0], d_em->newRatExpr(-r)), cache);
00274 break;
00275 }
00276 }
00277 if (changed) {
00278 if (r != 0) terms.push_back(d_em->newRatExpr(r));
00279 e2 = preprocessRec(Expr(PLUS, terms), cache);
00280 break;
00281 }
00282 }
00283 goto arith_rewrites;
00284
00285 case MULT:
00286 if (d_convertToBV) {
00287 e2 = Expr(Expr(BVMULT, d_em->newRatExpr(d_convertToBV)).mkOp(), e2.getKids());
00288 break;
00289 }
00290 if (d_convertArith) {
00291
00292 vector<Expr> terms;
00293 bool changed = false;
00294 int numConst = 0;
00295 r = 1;
00296 Expr::iterator i = e2.begin(), iend = e2.end();
00297 for(; i!=iend; ++i) {
00298 if ((*i).getKind() == MULT) {
00299 changed = true;
00300 Expr::iterator i2 = (*i).begin(), i2end = (*i).end();
00301 for (; i2 != i2end; ++i2) {
00302 if ((*i2).isRational()) {
00303 r *= (*i2).getRational();
00304 numConst++;
00305 }
00306 else terms.push_back(*i2);
00307 }
00308 }
00309 else {
00310 if ((*i).isRational()) {
00311 r *= (*i).getRational();
00312 numConst++;
00313 if (numConst > 1) changed = true;
00314 }
00315 else terms.push_back(*i);
00316 }
00317 }
00318 if (r == 0) {
00319 e2 = preprocessRec(d_em->newRatExpr(0), cache);
00320 break;
00321 }
00322 else if (terms.size() == 0) {
00323 e2 = preprocessRec(d_em->newRatExpr(r), cache);
00324 break;
00325 }
00326 else if (terms.size() == 1) {
00327 if (r == 1) {
00328 e2 = terms[0];
00329 break;
00330 }
00331 }
00332 if (changed) {
00333 if (r != 1) terms.push_back(d_em->newRatExpr(r));
00334 e2 = preprocessRec(Expr(MULT, terms), cache);
00335 break;
00336 }
00337 }
00338 goto arith_rewrites;
00339
00340 case POW:
00341 if (d_convertToBV) {
00342 FatalAssert(false, "Conversion of POW to BV not implemented");
00343 break;
00344 }
00345 if (d_convertArith && e2[0].isRational()) {
00346 r = e2[0].getRational();
00347 if (r.isInteger() && r.getNumerator() == 2) {
00348 e2 = preprocessRec(e2[1] * e2[1], cache);
00349 break;
00350 }
00351 }
00352
00353
00354 case LT:
00355 if (d_convertToBV) {
00356 e2 = Expr(BVSLT, e2[0], e2[1]);
00357 break;
00358 }
00359
00360 case GT:
00361 if (d_convertToBV) {
00362 e2 = Expr(BVSLT, e2[1], e2[0]);
00363 break;
00364 }
00365
00366 case LE:
00367 if (d_convertToBV) {
00368 e2 = Expr(BVSLE, e2[0], e2[1]);
00369 break;
00370 }
00371
00372 case GE:
00373 if (d_convertToBV) {
00374 e2 = Expr(BVSLE, e2[1], e2[0]);
00375 break;
00376 }
00377
00378
00379 case INTDIV:
00380 case MOD:
00381
00382 arith_rewrites:
00383 if (d_iteLiftArith) {
00384 diff = false;
00385 children.clear();
00386 vector<Expr> children2;
00387 Expr cond;
00388 for (int k = 0; k < e2.arity(); ++k) {
00389 if (e2[k].getKind() == ITE && !diff) {
00390 diff = true;
00391 cond = e2[k][0];
00392 children.push_back(e2[k][1]);
00393 children2.push_back(e2[k][2]);
00394 }
00395 else {
00396 children.push_back(e2[k]);
00397 children2.push_back(e2[k]);
00398 }
00399 }
00400 if (diff) {
00401 Expr thenpart = Expr(e2.getOp(), children);
00402 Expr elsepart = Expr(e2.getOp(), children2);
00403 e2 = cond.iteExpr(thenpart, elsepart);
00404 e2 = preprocessRec(e2, cache);
00405 break;
00406 }
00407 }
00408
00409 if (d_convertToDiff != "" && d_theoryArith->isAtomicArithFormula(e2)) {
00410 Expr e3 = d_theoryArith->rewriteToDiff(e2);
00411 if (e2 != e3) {
00412 DebugAssert(e3 == d_theoryArith->rewriteToDiff(e3), "Expected idempotent rewrite");
00413 e2 = preprocessRec(e3, cache);
00414 }
00415 break;
00416 }
00417
00418 break;
00419 default:
00420 if (d_convertToBV && isInt(e2.getType())) {
00421 FatalAssert(e2.isVar(), "Cannot convert non-variables yet");
00422 e2 = d_theoryCore->newVar(e2.getName()+"_bv", d_theoryBitvector->newBitvectorType(d_convertToBV));
00423 }
00424
00425 break;
00426 }
00427
00428
00429 switch (e2.getKind()) {
00430 case RATIONAL_EXPR:
00431 r = e2.getRational();
00432 if (r.isInteger()) {
00433 d_intConstUsed = true;
00434 }
00435 else {
00436 d_realUsed = true;
00437 }
00438 if (d_langUsed == NOT_USED) d_langUsed = TERMS_ONLY;
00439 break;
00440 case IS_INTEGER:
00441 d_unknown = true;
00442 break;
00443 case PLUS: {
00444 if (e2.arity() == 2) {
00445 int nonconst = 0, isconst = 0;
00446 Expr::iterator i = e2.begin(), iend = e2.end();
00447 for(; i!=iend; ++i) {
00448 if ((*i).isRational()) {
00449 if ((*i).getRational() <= 0) {
00450 d_UFIDL_ok = false;
00451 break;
00452 }
00453 else ++isconst;
00454 }
00455 else ++nonconst;
00456 }
00457 if (nonconst > 1 || isconst > 1)
00458 d_UFIDL_ok = false;
00459 }
00460 else d_UFIDL_ok = false;
00461 if (d_langUsed == NOT_USED) d_langUsed = TERMS_ONLY;
00462 break;
00463 }
00464 case MINUS:
00465 if (!e2[1].isRational() || e2[1].getRational() <= 0) {
00466 d_UFIDL_ok = false;
00467 }
00468 if (d_langUsed == NOT_USED) d_langUsed = TERMS_ONLY;
00469 break;
00470 case UMINUS:
00471 d_UFIDL_ok = false;
00472 if (d_langUsed == NOT_USED) d_langUsed = TERMS_ONLY;
00473 break;
00474 case MULT: {
00475 d_UFIDL_ok = false;
00476 if (d_langUsed == NONLINEAR) break;
00477 d_langUsed = LINEAR;
00478 bool nonconst = false;
00479 for (int i=0; i!=e2.arity(); ++i) {
00480 if (e2[i].isRational()) continue;
00481 if (nonconst) {
00482 d_langUsed = NONLINEAR;
00483 break;
00484 }
00485 nonconst = true;
00486 }
00487 break;
00488 }
00489 case POW:
00490 case DIVIDE:
00491 d_unknown = true;
00492 break;
00493
00494 case EQ:
00495 if (d_theoryArith->getBaseType(e2[0]) != d_theoryArith->realType() ||
00496 (e2[0].getType() == d_theoryArith->intType() && d_theoryCore->getFlags()["convert2array"].getBool()))
00497 break;
00498 case LT:
00499 case GT:
00500 case LE:
00501 case GE:
00502 if (d_langUsed >= LINEAR) break;
00503 if (!d_theoryArith->isAtomicArithFormula(e2)) {
00504 d_langUsed = LINEAR;
00505 break;
00506 }
00507 if (e2[0].getKind() == MINUS &&
00508 d_theoryArith->isLeaf(e2[0][0]) &&
00509 d_theoryArith->isLeaf(e2[0][1]) &&
00510 e2[1].isRational()) {
00511 d_langUsed = DIFF_ONLY;
00512 break;
00513 }
00514 if (d_theoryArith->isLeaf(e2[0]) &&
00515 d_theoryArith->isLeaf(e2[1])) {
00516 d_langUsed = DIFF_ONLY;
00517 break;
00518 }
00519 d_langUsed = LINEAR;
00520 break;
00521 default:
00522 break;
00523 }
00524
00525 switch (e2.getKind()) {
00526 case EQ:
00527 case NOT:
00528 break;
00529 case UCONST:
00530 if (e2.arity() == 0) break;
00531 default:
00532 d_theoryCore->theoryOf(e2)->setUsed();
00533 }
00534
00535 cache[e] = e2;
00536 return e2;
00537 }
00538
00539
00540 Expr Translator::preprocess(const Expr& e, ExprMap<Expr>& cache)
00541 {
00542 Expr result;
00543 try {
00544 result = preprocessRec(e, cache);
00545 } catch (SmtlibException& ex) {
00546 cerr << "Error while processing the formula:\n"
00547 << e.toString() << endl;
00548 throw ex;
00549 }
00550 return result;
00551 }
00552
00553
00554 Expr Translator::preprocess2Rec(const Expr& e, ExprMap<Expr>& cache, Type desiredType)
00555 {
00556 ExprMap<Expr>::iterator i(cache.find(e));
00557 if(i != cache.end()) {
00558 if ((desiredType.isNull() &&
00559 (*i).second.getType() != d_theoryArith->realType()) ||
00560 (*i).second.getType() == desiredType) {
00561 return (*i).second;
00562 }
00563 }
00564
00565 if (e.isClosure()) {
00566 Expr newBody = preprocess2Rec(e.getBody(), cache, Type());
00567 Expr e2(e);
00568 if (newBody != e.getBody()) {
00569 e2 = d_em->newClosureExpr(e.getKind(), e.getVars(), newBody);
00570 }
00571 cache[e] = e2;
00572 return e2;
00573 }
00574
00575 bool forceReal = false;
00576 if (desiredType == d_theoryArith->intType() &&
00577 e.getType() != d_theoryArith->intType()) {
00578 d_unknown = true;
00579
00580
00581
00582
00583 }
00584
00585
00586 switch (e.getKind()) {
00587 case EQ:
00588 case LT:
00589 case GT:
00590 case LE:
00591 case GE:
00592 if (e[0].getType() != e[1].getType()) {
00593 if (e[0].getType() != d_theoryArith->intType() &&
00594 e[1].getType() != d_theoryArith->intType()) {
00595 d_unknown = true;
00596 throw SmtlibException("Expected each side to be REAL or INT, but we got lhs: "+
00597 e[0].getType().getExpr().toString()+" and rhs: "+
00598 e[1].getType().getExpr().toString()+
00599 "\n\nwhile processing the term:\n"+
00600 e.toString());
00601 }
00602 forceReal = true;
00603 break;
00604 case ITE:
00605 case UMINUS:
00606 case PLUS:
00607 case MINUS:
00608 case MULT:
00609 if (desiredType == d_theoryArith->realType())
00610 forceReal = true;
00611 break;
00612 case DIVIDE:
00613 forceReal = true;
00614 break;
00615 default:
00616 break;
00617 }
00618 }
00619
00620 Expr e2(e);
00621 vector<Expr> children;
00622 bool diff = false;
00623
00624 Type funType;
00625 if (e.isApply()) {
00626 funType = e.getOpExpr().getType();
00627 if (funType.getExpr().getKind() == ANY_TYPE) funType = Type();
00628 }
00629
00630 for(int k = 0; k < e.arity(); ++k) {
00631 Type t;
00632 if (forceReal && e[k].getType() == d_theoryArith->intType())
00633 t = d_theoryArith->realType();
00634 else if (!funType.isNull()) t = funType[k];
00635
00636 Expr child = preprocess2Rec(e[k], cache, t);
00637 if (child != e[k]) diff = true;
00638 children.push_back(child);
00639 }
00640 if (diff) {
00641 e2 = Expr(e.getOp(), children);
00642 }
00643 else if (e2.getKind() == RATIONAL_EXPR) {
00644 if (e2.getType() == d_theoryArith->realType() ||
00645 (e2.getType() == d_theoryArith->intType() &&
00646 desiredType == d_theoryArith->realType()))
00647 e2 = Expr(REAL_CONST, e2);
00648 }
00649 if (!desiredType.isNull() && e2.getType() != desiredType) {
00650 d_unknown = true;
00651 throw SmtlibException("Type error: expected "+
00652 desiredType.getExpr().toString()+
00653 " but instead got "+
00654 e2.getType().getExpr().toString()+
00655 "\n\nwhile processing term:\n"+
00656 e.toString());
00657 }
00658
00659 cache[e] = e2;
00660 return e2;
00661 }
00662
00663
00664 Expr Translator::preprocess2(const Expr& e, ExprMap<Expr>& cache)
00665 {
00666 Expr result;
00667 try {
00668 result = preprocess2Rec(e, cache, Type());
00669 } catch (SmtlibException& ex) {
00670 cerr << "Error while processing the formula:\n"
00671 << e.toString() << endl;
00672 throw ex;
00673 }
00674 return result;
00675 }
00676
00677
00678
00679
00680 bool Translator::containsArray(const Expr& e)
00681 {
00682 if (e.getKind() == ARRAY) return true;
00683 Expr::iterator i = e.begin(), iend=e.end();
00684 for(; i!=iend; ++i) if (containsArray(*i)) return true;
00685 return false;
00686 }
00687
00688
00689 Translator::Translator(ExprManager* em,
00690 const bool& translate,
00691 const bool& real2int,
00692 const bool& convertArith,
00693 const string& convertToDiff,
00694 bool iteLiftArith,
00695 const string& expResult,
00696 const string& category,
00697 bool convertArray,
00698 bool combineAssump,
00699 int convertToBV)
00700 : d_em(em), d_translate(translate),
00701 d_real2int(real2int),
00702 d_convertArith(convertArith),
00703 d_convertToDiff(convertToDiff),
00704 d_iteLiftArith(iteLiftArith),
00705 d_expResult(expResult),
00706 d_category(category),
00707 d_convertArray(convertArray),
00708 d_combineAssump(combineAssump),
00709 d_dump(false), d_dumpFileOpen(false),
00710 d_intIntArray(false), d_intRealArray(false), d_intIntRealArray(false),
00711 d_ax(false), d_unknown(false),
00712 d_realUsed(false), d_intUsed(false), d_intConstUsed(false),
00713 d_langUsed(NOT_USED), d_UFIDL_ok(true), d_arithUsed(false),
00714 d_zeroVar(NULL), d_convertToBV(convertToBV)
00715 {
00716 d_arrayConvertMap = new map<string, Type>;
00717 }
00718
00719
00720 Translator::~Translator()
00721 {
00722 delete d_arrayConvertMap;
00723 }
00724
00725
00726 bool Translator::start(const string& dumpFile)
00727 {
00728 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00729 d_dump = true;
00730 if (dumpFile == "") {
00731 d_osdump = &cout;
00732 }
00733 else {
00734 d_osdumpFile.open(dumpFile.c_str());
00735 if(!d_osdumpFile)
00736 throw Exception("cannot open a log file: "+dumpFile);
00737 else {
00738 d_dumpFileOpen = true;
00739 d_osdump = &d_osdumpFile;
00740 }
00741 }
00742 *d_osdump <<
00743 "(benchmark " << fileToSMTLIBIdentifier(dumpFile) << endl <<
00744 " :source {" << endl;
00745 string tmpName;
00746 string::size_type pos = dumpFile.rfind("/");
00747 if (pos == string::npos) {
00748 tmpName = "README";
00749 }
00750 else {
00751 tmpName = dumpFile.substr(0,pos+1) + "README";
00752 }
00753 d_tmpFile.open(tmpName.c_str());
00754 char c;
00755 if (d_tmpFile.is_open()) {
00756 d_tmpFile.get(c);
00757 while (!d_tmpFile.eof()) {
00758 if (c == '{' || c == '}') *d_osdump << '\\';
00759 *d_osdump << c;
00760 d_tmpFile.get(c);
00761 }
00762 d_tmpFile.close();
00763 }
00764 else {
00765 *d_osdump << "Source unknown";
00766 }
00767 *d_osdump << endl;
00768
00769
00770 *d_osdump << "}" << endl;
00771
00772 }
00773 else {
00774 if (dumpFile == "") {
00775 if (d_translate) {
00776 d_osdump = &cout;
00777 d_dump = true;
00778 }
00779 }
00780 else {
00781 d_osdumpFile.open(dumpFile.c_str());
00782 if(!d_osdumpFile)
00783 throw Exception("cannot open a log file: "+dumpFile);
00784 else {
00785 d_dump = true;
00786 d_dumpFileOpen = true;
00787 d_osdump = &d_osdumpFile;
00788 }
00789 }
00790 }
00791 return d_dump;
00792 }
00793
00794
00795 void Translator::dump(const Expr& e, bool dumpOnly)
00796 {
00797 DebugAssert(d_dump, "dump called unexpectedly");
00798 if (!dumpOnly || !d_translate) {
00799 if (d_convertArray && e.getKind() == CONST &&
00800 e.arity() == 2) {
00801 if (e[1].getKind() == ARRAY) {
00802 if (containsArray(e[1][0]) ||
00803 containsArray(e[1][1])) {
00804 throw Exception("convertArray failed because of nested arrays in"+
00805 e[1].toString());
00806 }
00807 Expr funType = Expr(ARROW, e[1][0], e[1][1]);
00808 Expr outExpr = Expr(CONST, e[0], funType);
00809 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00810 d_dumpExprs.push_back(outExpr);
00811 }
00812 else {
00813 *d_osdump << outExpr << endl;
00814 }
00815 }
00816 else if (containsArray(e[1])) {
00817 throw Exception("convertArray failed becauase of use of arrays in"+
00818 e[1].toString());
00819 }
00820 else if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00821 d_dumpExprs.push_back(e);
00822 }
00823 else *d_osdump << e << endl;
00824 }
00825 else if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00826 d_dumpExprs.push_back(e);
00827 }
00828 else *d_osdump << e << endl;
00829 }
00830 }
00831
00832
00833 bool Translator::dumpAssertion(const Expr& e)
00834 {
00835 Expr outExpr = Expr(ASSERT, e);
00836 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00837 d_dumpExprs.push_back(outExpr);
00838 }
00839 else {
00840 *d_osdump << outExpr << endl;
00841 }
00842 return d_translate;
00843 }
00844
00845
00846 bool Translator::dumpQuery(const Expr& e)
00847 {
00848 Expr outExpr = Expr(QUERY, e);
00849 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00850 d_dumpExprs.push_back(outExpr);
00851 }
00852 else {
00853 *d_osdump << outExpr << endl;
00854 }
00855 return d_translate;
00856 }
00857
00858
00859 void Translator::dumpQueryResult(QueryResult qres)
00860 {
00861 if(d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00862 *d_osdump << " :status ";
00863 switch (qres) {
00864 case UNSATISFIABLE:
00865 *d_osdump << "unsat" << endl;
00866 break;
00867 case SATISFIABLE:
00868 *d_osdump << "sat" << endl;
00869 break;
00870 default:
00871 *d_osdump << "unknown" << endl;
00872 break;
00873 }
00874 }
00875 }
00876
00877
00878 Expr Translator::processType(const Expr& e)
00879 {
00880 switch (e.getKind()) {
00881 case TYPEDECL:
00882 return e;
00883 case INT:
00884 if (d_convertToBV) {
00885 return d_theoryBitvector->newBitvectorType(d_convertToBV).getExpr();
00886 }
00887 if (d_theoryCore->getFlags()["convert2array"].getBool()) {
00888 return d_elementType->getExpr();
00889 }
00890 d_intUsed = true;
00891 break;
00892 case REAL:
00893 if (d_real2int) {
00894 d_intUsed = true;
00895 return d_theoryArith->intType().getExpr();
00896 }
00897 else {
00898 d_realUsed = true;
00899 }
00900 break;
00901 case SUBRANGE:
00902 d_unknown = true;
00903 break;
00904 case ARRAY:
00905 if (d_theoryCore->getFlags()["convert2array"].getBool()) {
00906 d_ax = true;
00907 return d_arrayType->getExpr();
00908 }
00909 if (e[0].getKind() == TYPEDECL) {
00910 DebugAssert(e[0].arity() == 1, "expected arity 1");
00911 if (e[0][0].getString() == "Index") {
00912 if (e[1].getKind() == TYPEDECL) {
00913 DebugAssert(e[1].arity() == 1, "expected arity 1");
00914 if (e[1][0].getString() == "Element") {
00915 d_ax = true;
00916 break;
00917 }
00918 }
00919 }
00920 }
00921 else if (isInt(Type(e[0]))) {
00922 if (isInt(Type(e[1]))) {
00923 d_intIntArray = true;
00924 break;
00925 }
00926 else if (isReal(Type(e[1]))) {
00927 d_intRealArray = true;
00928 break;
00929 }
00930 else if (isArray(Type(e[1])) &&
00931 isInt(Type(e[1][0])) &&
00932 isReal(Type(e[1][1]))) {
00933 d_intIntRealArray = true;
00934 break;
00935 }
00936 }
00937 else if (e[0].getKind() == BITVECTOR &&
00938 e[1].getKind() == BITVECTOR) {
00939 break;
00940 }
00941 d_unknown = true;
00942 break;
00943 default:
00944 break;
00945 }
00946 d_theoryCore->theoryOf(e)->setUsed();
00947 if (e.arity() == 0) return e;
00948 bool changed = false;
00949 vector<Expr> vec;
00950 for (int i = 0; i < e.arity(); ++i) {
00951 vec.push_back(processType(e[i]));
00952 if (vec.back() != e[i]) changed = true;
00953 }
00954 if (changed)
00955 return Expr(e.getOp(), vec);
00956 return e;
00957 }
00958
00959
00960 void Translator::finish()
00961 {
00962 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00963
00964
00965
00966
00967 *d_osdump << " :status ";
00968 if (d_expResult == "invalid" ||
00969 d_expResult == "satisfiable")
00970 *d_osdump << "sat";
00971 else if (d_expResult == "valid" ||
00972 d_expResult == "unsatisfiable")
00973 *d_osdump << "unsat";
00974 else *d_osdump << "unknown";
00975 *d_osdump << endl;
00976
00977
00978 *d_osdump << " :difficulty { unknown }" << endl;
00979
00980
00981 *d_osdump << " :category { ";
00982 *d_osdump << d_category << " }" << endl;
00983
00984
00985 if (d_theoryCore->getFlags()["convert2array"].getBool()) {
00986 d_indexType = new Type(d_theoryCore->newTypeExpr("Index"));
00987 d_elementType = new Type(d_theoryCore->newTypeExpr("Element"));
00988 d_arrayType = new Type(arrayType(*d_indexType, *d_elementType));
00989 }
00990
00991
00992 bool qf_uf = false;
00993 {
00994 {
00995 ExprMap<Expr> cache;
00996
00997 vector<Expr>::iterator i = d_dumpExprs.begin(), iend = d_dumpExprs.end();
00998 for (; i != iend; ++i) {
00999 Expr e = *i;
01000 switch (e.getKind()) {
01001 case ASSERT: {
01002 Expr e2 = preprocess(e[0], cache);
01003 if (e[0] == e2) break;
01004 e2.getType();
01005 *i = Expr(ASSERT, e2);
01006 break;
01007 }
01008 case QUERY: {
01009 Expr e2 = preprocess(e[0].negate(), cache);
01010 if (e[0].negate() == e2) break;
01011 e2.getType();
01012 *i = Expr(QUERY, e2.negate());
01013 break;
01014 }
01015 case CONST: {
01016 DebugAssert(e.arity() == 2, "Expected CONST with arity 2");
01017 if (d_theoryCore->getFlags()["convert2array"].getBool()) break;
01018 Expr e2 = processType(e[1]);
01019 if (e[1] == e2) break;
01020 if (d_convertToBV) {
01021 Expr newName = Expr(ID, d_em->newStringExpr(e[0][0].getString()+"_bv"));
01022 *i = Expr(CONST, newName, e2);
01023 }
01024 else {
01025 *i = Expr(CONST, e[0], e2);
01026 }
01027 break;
01028 }
01029 default:
01030 break;
01031 }
01032 }
01033 }
01034
01035 if (d_zeroVar) {
01036 d_dumpExprs.insert(d_dumpExprs.begin(),
01037 Expr(CONST, Expr(ID, d_em->newStringExpr("cvc3Zero")),
01038 processType(d_zeroVar->getType().getExpr())));
01039 }
01040
01041
01042 if (!d_unknown && d_theoryCore->getFlags()["convert2array"].getBool()) {
01043 bool changed;
01044 do {
01045 changed = false;
01046 unsigned i;
01047 for (i = 0; i < d_equalities.size(); ++i) {
01048 if (d_equalities[i][0].getKind() == UCONST &&
01049 d_arrayConvertMap->find(d_equalities[i][0].getName()) == d_arrayConvertMap->end()) {
01050 if (d_equalities[i][1].getKind() == READ) {
01051 changed = true;
01052 (*d_arrayConvertMap)[d_equalities[i][0].getName()] = *d_elementType;
01053 }
01054 else if (d_equalities[i][1].getKind() == UCONST) {
01055 map<string, Type>::iterator it = d_arrayConvertMap->find(d_equalities[i][1].getName());
01056 if (it != d_arrayConvertMap->end()) {
01057 changed = true;
01058 (*d_arrayConvertMap)[d_equalities[i][0].getName()] = (*it).second;
01059 }
01060 }
01061 }
01062 else if (d_equalities[i][1].getKind() == UCONST &&
01063 d_arrayConvertMap->find(d_equalities[i][1].getName()) == d_arrayConvertMap->end()) {
01064 if (d_equalities[i][0].getKind() == READ) {
01065 changed = true;
01066 (*d_arrayConvertMap)[d_equalities[i][1].getName()] = *d_elementType;
01067 }
01068 else if (d_equalities[i][0].getKind() == UCONST) {
01069 map<string, Type>::iterator it = d_arrayConvertMap->find(d_equalities[i][0].getName());
01070 if (it != d_arrayConvertMap->end()) {
01071 changed = true;
01072 (*d_arrayConvertMap)[d_equalities[i][1].getName()] = (*it).second;
01073 }
01074 }
01075 }
01076 }
01077 } while (changed);
01078 }
01079
01080
01081 if ((!d_unknown && (d_intUsed && d_realUsed)) || (d_theoryCore->getFlags()["convert2array"].getBool())) {
01082 ExprMap<Expr> cache;
01083 vector<Expr>::iterator i = d_dumpExprs.begin(), iend = d_dumpExprs.end();
01084 for (; i != iend; ++i) {
01085 Expr e = *i;
01086 switch (e.getKind()) {
01087 case ASSERT: {
01088 if (d_theoryCore->getFlags()["convert2array"].getBool()) break;
01089 Expr e2 = preprocess2(e[0], cache);
01090 e2.getType();
01091 *i = Expr(ASSERT, e2);
01092 break;
01093 }
01094 case QUERY: {
01095 if (d_theoryCore->getFlags()["convert2array"].getBool()) break;
01096 Expr e2 = preprocess2(e[0].negate(), cache);
01097 e2.getType();
01098 *i = Expr(QUERY, e2.negate());
01099 break;
01100 }
01101 case CONST: {
01102 if (!d_theoryCore->getFlags()["convert2array"].getBool()) break;
01103 map<string, Type>::iterator it = d_arrayConvertMap->find(e[0][0].getString());
01104 if (it != d_arrayConvertMap->end()) {
01105 *i = Expr(CONST, e[0], (*it).second.getExpr());
01106 }
01107 else {
01108 Expr e2 = processType(e[1]);
01109 if (e[1] == e2) break;
01110 *i = Expr(CONST, e[0], e2);
01111 }
01112 break;
01113 }
01114 default:
01115 break;
01116 }
01117 }
01118 }
01119 d_arithUsed = d_realUsed || d_intUsed || d_intConstUsed || (d_langUsed != NOT_USED);
01120
01121
01122 *d_osdump << " :logic ";
01123 if (d_unknown ||
01124 d_theoryRecords->theoryUsed() ||
01125 d_theorySimulate->theoryUsed() ||
01126 d_theoryDatatype->theoryUsed()) {
01127 *d_osdump << "unknown";
01128 }
01129 else {
01130 if ((d_ax && (d_arithUsed ||
01131 d_theoryBitvector->theoryUsed() ||
01132 d_theoryUF->theoryUsed())) ||
01133 (d_intIntArray && d_realUsed) ||
01134 (d_arithUsed && d_theoryBitvector->theoryUsed())) {
01135 *d_osdump << "unknown";
01136 }
01137 else {
01138 bool QF = false;
01139 bool A = false;
01140 bool UF = false;
01141
01142 if (!d_theoryQuant->theoryUsed()) {
01143 QF = true;
01144 *d_osdump << "QF_";
01145 }
01146
01147 if (d_theoryArray->theoryUsed() && !d_convertArray) {
01148 A = true;
01149 *d_osdump << "A";
01150 }
01151
01152
01153
01154
01155
01156
01157
01158 if (d_theoryUF->theoryUsed() ||
01159 (d_theoryArray->theoryUsed() && d_convertArray)) {
01160 UF = true;
01161 *d_osdump << "UF";
01162 }
01163
01164
01165
01166
01167
01168
01169
01170
01171 if (d_arithUsed) {
01172 if (d_intUsed && d_realUsed) {
01173 if (d_langUsed < NONLINEAR) {
01174 *d_osdump << "LIRA";
01175 }
01176 else *d_osdump << "NIRA";
01177 }
01178 else if (d_realUsed) {
01179 if (d_langUsed <= DIFF_ONLY) {
01180
01181
01182
01183
01184
01185
01186 *d_osdump << "RDL";
01187 }
01188 else if (d_langUsed <= LINEAR) {
01189
01190
01191
01192
01193
01194
01195 *d_osdump << "LRA";
01196 }
01197 else {
01198
01199
01200
01201
01202
01203
01204 *d_osdump << "NRA";
01205 }
01206 }
01207 else {
01208 if (QF && !A && UF && d_langUsed <= LINEAR) {
01209 if (!d_realUsed && d_langUsed <= LINEAR && d_UFIDL_ok) {
01210 *d_osdump << "IDL";
01211 }
01212 else {
01213 *d_osdump << "LIA";
01214 }
01215 }
01216 else if (d_langUsed <= DIFF_ONLY) {
01217
01218
01219 if (!QF) {
01220 *d_osdump << "LIA";
01221 }
01222 else if (A) {
01223 if (!UF) {
01224 UF = true;
01225 *d_osdump << "UF";
01226 }
01227 *d_osdump << "LIA";
01228 } else
01229
01230 *d_osdump << "IDL";
01231 }
01232 else if (d_langUsed <= LINEAR) {
01233
01234
01235
01236
01237
01238
01239
01240 if (QF && !A && (!d_realUsed && d_langUsed <= LINEAR && d_UFIDL_ok)) {
01241 *d_osdump << "UFIDL";
01242 }
01243 else {
01244 *d_osdump << "LIA";
01245 }
01246 }
01247 else {
01248
01249
01250
01251
01252
01253
01254 *d_osdump << "NIA";
01255 }
01256 }
01257 }
01258 else if (d_theoryBitvector->theoryUsed()) {
01259
01260
01261 if (A && QF && !UF) {
01262 UF = true;
01263 *d_osdump << "UF";
01264 }
01265
01266 *d_osdump << "BV";
01267 }
01268 else {
01269
01270 if (d_ax) {
01271 *d_osdump << "X";
01272 }
01273
01274
01275 else if (!QF || (A && UF)) {
01276 *d_osdump << "LIA";
01277 } else {
01278
01279
01280 if (!A && !UF) {
01281 UF = true;
01282 *d_osdump << "UF";
01283 }
01284 qf_uf = QF && UF && (!A);
01285 }
01286 }
01287 }
01288 }
01289 }
01290 *d_osdump << endl;
01291
01292
01293
01294 vector<Expr>::const_iterator i = d_dumpExprs.begin(), iend = d_dumpExprs.end();
01295 vector<Expr> assumps;
01296 for (; i != iend; ++i) {
01297 Expr e = *i;
01298 switch (e.getKind()) {
01299 case ASSERT: {
01300 if (d_combineAssump) {
01301 assumps.push_back(e[0]);
01302 }
01303 else {
01304 *d_osdump << " :assumption" << endl;
01305 *d_osdump << e[0] << endl;
01306 }
01307 break;
01308 }
01309 case QUERY: {
01310 *d_osdump << " :formula" << endl;
01311 if (!assumps.empty()) {
01312 assumps.push_back(e[0].negate());
01313 e = Expr(AND, assumps);
01314 *d_osdump << e << endl;
01315 }
01316 else {
01317 *d_osdump << e[0].negate() << endl;
01318 }
01319 break;
01320 }
01321 default:
01322 if (qf_uf && e.getKind() == TYPE && e[0].getKind() == RAW_LIST &&
01323 e[0][0].getKind() == ID && e[0][0][0].getKind() == STRING_EXPR &&
01324 e[0][0][0].getString() == "U")
01325 break;
01326 *d_osdump << e << endl;
01327 break;
01328 }
01329 }
01330 *d_osdump << ")" << endl;
01331 }
01332
01333 if (d_dumpFileOpen) d_osdumpFile.close();
01334 if (d_zeroVar) delete d_zeroVar;
01335 }
01336
01337
01338 const string Translator::fixConstName(const string& s)
01339 {
01340 if (d_em->getOutputLang() == SMTLIB_LANG) {
01341 if (s[0] == '_') {
01342 return "smt"+s;
01343 }
01344 }
01345 return s;
01346 }
01347
01348
01349 bool Translator::printArrayExpr(ExprStream& os, const Expr& e)
01350 {
01351 if (e.getKind() == ARRAY) {
01352 if (d_convertArray) {
01353 os << Expr(ARROW, e[0], e[1]);
01354 return true;
01355 }
01356 if (d_em->getOutputLang() != SMTLIB_LANG) return false;
01357 if (e[0].getKind() == TYPEDECL) {
01358 DebugAssert(e[0].arity() == 1, "expected arity 1");
01359 if (e[0][0].getString() == "Index") {
01360 if (e[1].getKind() == TYPEDECL) {
01361 DebugAssert(e[1].arity() == 1, "expected arity 1");
01362 if (e[1][0].getString() == "Element") {
01363 os << "Array";
01364 return true;
01365 }
01366 }
01367 }
01368 }
01369 else if (isInt(Type(e[0]))) {
01370 if (isInt(Type(e[1]))) {
01371 d_intIntArray = true;
01372 os << "Array";
01373 return true;
01374 }
01375 else if (isReal(Type(e[1]))) {
01376 d_intRealArray = true;
01377 os << "Array1";
01378 return true;
01379 }
01380 else if (isArray(Type(e[1])) &&
01381 isInt(Type(e[1][0])) &&
01382 isReal(Type(e[1][1]))) {
01383 d_intIntRealArray = true;
01384 os << "Array2";
01385 return true;
01386 }
01387 }
01388 else if (e[0].getKind() == BITVECTOR &&
01389 e[1].getKind() == BITVECTOR) {
01390 os << "Array[";
01391 os << d_theoryBitvector->getBitvectorTypeParam(Type(e[0]));
01392 os << ":";
01393 os << d_theoryBitvector->getBitvectorTypeParam(Type(e[1]));
01394 os << "]";
01395 return true;
01396 }
01397 os << "UnknownArray";
01398 d_unknown = true;
01399 return true;
01400 }
01401
01402 switch (e.getKind()) {
01403 case READ:
01404 if (d_convertArray) {
01405 if (e[0].getKind() == UCONST) {
01406 os << Expr(d_em->newSymbolExpr(e[0].getName(), UFUNC).mkOp(), e[1]);
01407 return true;
01408 }
01409 else if (e[0].getKind() == WRITE) {
01410 throw Exception("READ of WRITE not implemented yet for convertArray");
01411 }
01412 else {
01413 throw Exception("Unexpected case for convertArray");
01414 }
01415 }
01416 break;
01417 case WRITE:
01418 if (d_convertArray) {
01419 throw Exception("WRITE expression encountered while attempting "
01420 "to convert arrays to uninterpreted functions");
01421 }
01422 break;
01423 case ARRAY_LITERAL:
01424 if (d_convertArray) {
01425 throw Exception("ARRAY_LITERAL expression encountered while attempting"
01426 " to convert arrays to uninterpreted functions");
01427 }
01428 break;
01429 default:
01430 throw Exception("Unexpected case in printArrayExpr");
01431 break;
01432 }
01433 return false;
01434 }
01435
01436
01437 Expr Translator::zeroVar()
01438 {
01439 if (!d_zeroVar) {
01440 d_zeroVar = new Expr();
01441 if (d_convertToDiff == "int") {
01442 *d_zeroVar = d_theoryCore->newVar("cvc3Zero", d_theoryArith->intType().getExpr());
01443 }
01444 else if (d_convertToDiff == "real") {
01445 *d_zeroVar = d_theoryCore->newVar("cvc3Zero", d_theoryArith->realType().getExpr());
01446 }
01447 }
01448 return *d_zeroVar;
01449 }