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
00037
00038 using namespace std;
00039 using namespace CVC3;
00040
00041
00042 string Translator::fileToSMTLIBIdentifier(const string& filename)
00043 {
00044 string tmpName;
00045 string::size_type pos = filename.rfind("/");
00046 if (pos == string::npos) {
00047 tmpName = filename;
00048 }
00049 else {
00050 tmpName = filename.substr(pos+1);
00051 }
00052 char c = tmpName[0];
00053 string res;
00054 if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z')) {
00055 res = "B_";
00056 }
00057 for (unsigned i = 0; i < tmpName.length(); ++i) {
00058 c = tmpName[i];
00059 if ((c < 'A' || c > 'Z') && (c < 'a' || c > 'z') &&
00060 (c < '0' || c > '9') && (c != '.' && c != '_')) {
00061 c = '_';
00062 }
00063 res += c;
00064 }
00065 return res;
00066 }
00067
00068
00069 Expr Translator::preprocessRec(const Expr& e, ExprMap<Expr>& cache)
00070 {
00071 ExprMap<Expr>::iterator i(cache.find(e));
00072 if(i != cache.end()) {
00073 return (*i).second;
00074 }
00075
00076 if (e.isClosure()) {
00077 Expr newBody = preprocessRec(e.getBody(), cache);
00078 Expr e2(e);
00079 if (newBody != e.getBody()) {
00080 e2 = d_em->newClosureExpr(e.getKind(), e.getVars(), newBody);
00081 }
00082 d_theoryCore->theoryOf(e2)->setUsed();
00083 cache[e] = e2;
00084 return e2;
00085 }
00086
00087 Expr e2(e);
00088 vector<Expr> children;
00089 bool diff = false;
00090
00091 for(int k = 0; k < e.arity(); ++k) {
00092
00093 Expr child = preprocessRec(e[k], cache);
00094 if (child != e[k]) diff = true;
00095 children.push_back(child);
00096 }
00097 if (diff) {
00098 e2 = Expr(e.getOp(), children);
00099 }
00100
00101 Rational r;
00102 switch (e2.getKind()) {
00103 case APPLY:
00104
00105 if (e2.getOpKind() == LAMBDA) {
00106 Expr lambda(e2.getOpExpr());
00107 Expr body(lambda.getBody());
00108 const vector<Expr>& vars = lambda.getVars();
00109 FatalAssert(vars.size() == (size_t)e2.arity(),
00110 "wrong number of arguments applied to lambda\n");
00111 body = body.substExpr(vars, e2.getKids());
00112 e2 = preprocessRec(body, cache);
00113 }
00114 break;
00115 case EQ:
00116 if (d_theoryArith->getBaseType(e2[0]) != d_theoryArith->realType())
00117 break;
00118 goto arith_rewrites;
00119
00120 case UMINUS:
00121 if (d_theoryArith->isSyntacticRational(e2, r)) {
00122 e2 = preprocessRec(d_em->newRatExpr(r), cache);
00123 break;
00124 }
00125 goto arith_rewrites;
00126
00127 case DIVIDE:
00128 if (d_theoryArith->isSyntacticRational(e2, r)) {
00129 e2 = preprocessRec(d_em->newRatExpr(r), cache);
00130 break;
00131 }
00132 else if (d_convertArith && e2[1].isRational()) {
00133 r = e2[1].getRational();
00134 if (r != 0) {
00135 e2 = d_em->newRatExpr(1/r) * e2[0];
00136 e2 = preprocessRec(e2, cache);
00137 break;
00138 }
00139 }
00140 goto arith_rewrites;
00141
00142 case PLUS:
00143 if (d_convertArith) {
00144
00145 vector<Expr> terms;
00146 bool changed = false;
00147 r = 0;
00148 Expr::iterator i = e2.begin(), iend = e2.end();
00149 for(; i!=iend; ++i) {
00150 if ((*i).getKind() == PLUS) {
00151 changed = true;
00152 Expr::iterator i2 = (*i).begin(), i2end = (*i).end();
00153 for (; i2 != i2end; ++i2) {
00154 if ((*i2).isRational()) r += (*i2).getRational();
00155 else terms.push_back(*i2);
00156 }
00157 }
00158 else {
00159 if ((*i).isRational()) {
00160 if (r != 0) changed = true;
00161 r += (*i).getRational();
00162 }
00163 else terms.push_back(*i);
00164 }
00165 }
00166 if (terms.size() == 0) {
00167 e2 = preprocessRec(d_em->newRatExpr(r), cache);
00168 break;
00169 }
00170 else if (terms.size() == 1) {
00171 if (r == 0) {
00172 e2 = terms[0];
00173 break;
00174 }
00175 else if (r < 0) {
00176 e2 = preprocessRec(Expr(MINUS, terms[0], d_em->newRatExpr(-r)), cache);
00177 break;
00178 }
00179 }
00180 if (changed) {
00181 if (r != 0) terms.push_back(d_em->newRatExpr(r));
00182 e2 = preprocessRec(Expr(PLUS, terms), cache);
00183 break;
00184 }
00185 }
00186 goto arith_rewrites;
00187
00188 case POW:
00189 if (d_convertArith && e2[0].isRational()) {
00190 r = e2[0].getRational();
00191 if (r.isInteger() && r.getNumerator() == 2) {
00192 e2 = preprocessRec(e2[1] * e2[1], cache);
00193 break;
00194 }
00195 }
00196
00197
00198 case LT:
00199 case GT:
00200 case LE:
00201 case GE:
00202 case MINUS:
00203 case MULT:
00204 case INTDIV:
00205 case MOD:
00206
00207 arith_rewrites:
00208 if (d_iteLiftArith) {
00209 diff = false;
00210 children.clear();
00211 vector<Expr> children2;
00212 Expr cond;
00213 for (int k = 0; k < e2.arity(); ++k) {
00214 if (e2[k].getKind() == ITE && !diff) {
00215 diff = true;
00216 cond = e2[k][0];
00217 children.push_back(e2[k][1]);
00218 children2.push_back(e2[k][2]);
00219 }
00220 else {
00221 children.push_back(e2[k]);
00222 children2.push_back(e2[k]);
00223 }
00224 }
00225 if (diff) {
00226 Expr thenpart = Expr(e2.getOp(), children);
00227 Expr elsepart = Expr(e2.getOp(), children2);
00228 e2 = cond.iteExpr(thenpart, elsepart);
00229 e2 = preprocessRec(e2, cache);
00230 break;
00231 }
00232 }
00233
00234 if (d_convertToDiff != "" && d_theoryArith->isAtomicArithFormula(e2)) {
00235 Expr e3 = d_theoryArith->rewriteToDiff(e2);
00236 if (e2 != e3) {
00237 DebugAssert(e3 == d_theoryArith->rewriteToDiff(e3), "Expected idempotent rewrite");
00238 e2 = preprocessRec(e3, cache);
00239 }
00240 break;
00241 }
00242
00243 break;
00244 default:
00245 break;
00246 }
00247
00248
00249 switch (e2.getKind()) {
00250 case RATIONAL_EXPR:
00251 r = e2.getRational();
00252 if (r.isInteger()) {
00253 d_intConstUsed = true;
00254 }
00255 else {
00256 d_realUsed = true;
00257 }
00258 if (d_langUsed == NOT_USED) d_langUsed = TERMS_ONLY;
00259 break;
00260 case IS_INTEGER:
00261 d_unknown = true;
00262 break;
00263 case PLUS: {
00264 if (e2.arity() == 2) {
00265 int nonconst = 0, isconst = 0;
00266 Expr::iterator i = e2.begin(), iend = e2.end();
00267 for(; i!=iend; ++i) {
00268 if ((*i).isRational()) {
00269 if ((*i).getRational() <= 0) {
00270 d_UFIDL_ok = false;
00271 break;
00272 }
00273 else ++isconst;
00274 }
00275 else ++nonconst;
00276 }
00277 if (nonconst > 1 || isconst > 1)
00278 d_UFIDL_ok = false;
00279 }
00280 else d_UFIDL_ok = false;
00281 if (d_langUsed == NOT_USED) d_langUsed = TERMS_ONLY;
00282 break;
00283 }
00284 case MINUS:
00285 if (!e2[1].isRational() || e2[1].getRational() <= 0) {
00286 d_UFIDL_ok = false;
00287 }
00288 if (d_langUsed == NOT_USED) d_langUsed = TERMS_ONLY;
00289 break;
00290 case UMINUS:
00291 d_UFIDL_ok = false;
00292 if (d_langUsed == NOT_USED) d_langUsed = TERMS_ONLY;
00293 break;
00294 case MULT: {
00295 d_UFIDL_ok = false;
00296 if (d_langUsed == NONLINEAR) break;
00297 d_langUsed = LINEAR;
00298 bool nonconst = false;
00299 for (int i=0; i!=e2.arity(); ++i) {
00300 if (e2[i].isRational()) continue;
00301 if (nonconst) {
00302 d_langUsed = NONLINEAR;
00303 break;
00304 }
00305 nonconst = true;
00306 }
00307 break;
00308 }
00309 case POW:
00310 case DIVIDE:
00311 d_unknown = true;
00312 break;
00313
00314 case EQ:
00315 if (d_theoryArith->getBaseType(e2[0]) != d_theoryArith->realType())
00316 break;
00317 case LT:
00318 case GT:
00319 case LE:
00320 case GE:
00321 if (d_langUsed >= LINEAR) break;
00322 if (!d_theoryArith->isAtomicArithFormula(e2)) {
00323 d_langUsed = LINEAR;
00324 break;
00325 }
00326 if (e2[0].getKind() == MINUS &&
00327 d_theoryArith->isLeaf(e2[0][0]) &&
00328 d_theoryArith->isLeaf(e2[0][1]) &&
00329 e2[1].isRational()) {
00330 d_langUsed = DIFF_ONLY;
00331 break;
00332 }
00333 if (d_theoryArith->isLeaf(e2[0]) &&
00334 d_theoryArith->isLeaf(e2[1])) {
00335 d_langUsed = DIFF_ONLY;
00336 break;
00337 }
00338 d_langUsed = LINEAR;
00339 break;
00340 default:
00341 break;
00342 }
00343
00344 d_theoryCore->theoryOf(e2)->setUsed();
00345
00346 cache[e] = e2;
00347 return e2;
00348 }
00349
00350
00351 Expr Translator::preprocess(const Expr& e, ExprMap<Expr>& cache)
00352 {
00353 Expr result;
00354 try {
00355 result = preprocessRec(e, cache);
00356 } catch (SmtlibException& ex) {
00357 cerr << "Error while processing the formula:\n"
00358 << e.toString() << endl;
00359 throw ex;
00360 }
00361 return result;
00362 }
00363
00364
00365 Expr Translator::preprocess2Rec(const Expr& e, ExprMap<Expr>& cache, Type desiredType)
00366 {
00367 ExprMap<Expr>::iterator i(cache.find(e));
00368 if(i != cache.end()) {
00369 if ((desiredType.isNull() &&
00370 (*i).second.getType() != d_theoryArith->realType()) ||
00371 (*i).second.getType() == desiredType) {
00372 return (*i).second;
00373 }
00374 }
00375
00376 if (e.isClosure()) {
00377 Expr newBody = preprocess2Rec(e.getBody(), cache, Type());
00378 Expr e2(e);
00379 if (newBody != e.getBody()) {
00380 e2 = d_em->newClosureExpr(e.getKind(), e.getVars(), newBody);
00381 }
00382 cache[e] = e2;
00383 return e2;
00384 }
00385
00386 bool forceReal = false;
00387 if (desiredType == d_theoryArith->intType() &&
00388 e.getType() != d_theoryArith->intType()) {
00389 d_unknown = true;
00390
00391
00392
00393
00394 }
00395
00396
00397 switch (e.getKind()) {
00398 case EQ:
00399 case LT:
00400 case GT:
00401 case LE:
00402 case GE:
00403 if (e[0].getType() != e[1].getType()) {
00404 if (e[0].getType() != d_theoryArith->intType() &&
00405 e[1].getType() != d_theoryArith->intType()) {
00406 d_unknown = true;
00407 throw SmtlibException("Expected each side to be REAL or INT, but we got lhs: "+
00408 e[0].getType().getExpr().toString()+" and rhs: "+
00409 e[1].getType().getExpr().toString()+
00410 "\n\nwhile processing the term:\n"+
00411 e.toString());
00412 }
00413 forceReal = true;
00414 break;
00415 case ITE:
00416 case UMINUS:
00417 case PLUS:
00418 case MINUS:
00419 case MULT:
00420 if (desiredType == d_theoryArith->realType())
00421 forceReal = true;
00422 break;
00423 case DIVIDE:
00424 forceReal = true;
00425 break;
00426 default:
00427 break;
00428 }
00429 }
00430
00431 Expr e2(e);
00432 vector<Expr> children;
00433 bool diff = false;
00434
00435 Type funType;
00436 if (e.isApply()) {
00437 funType = e.getOpExpr().getType();
00438 if (funType.getExpr().getKind() == ANY_TYPE) funType = Type();
00439 }
00440
00441 for(int k = 0; k < e.arity(); ++k) {
00442 Type t;
00443 if (forceReal && e[k].getType() == d_theoryArith->intType())
00444 t = d_theoryArith->realType();
00445 else if (!funType.isNull()) t = funType[k];
00446
00447 Expr child = preprocess2Rec(e[k], cache, t);
00448 if (child != e[k]) diff = true;
00449 children.push_back(child);
00450 }
00451 if (diff) {
00452 e2 = Expr(e.getOp(), children);
00453 }
00454 else if (e2.getKind() == RATIONAL_EXPR) {
00455 if (e2.getType() == d_theoryArith->realType() ||
00456 (e2.getType() == d_theoryArith->intType() &&
00457 desiredType == d_theoryArith->realType()))
00458 e2 = Expr(REAL_CONST, e2);
00459 }
00460 if (!desiredType.isNull() && e2.getType() != desiredType) {
00461 d_unknown = true;
00462 throw SmtlibException("Type error: expected "+
00463 desiredType.getExpr().toString()+
00464 " but instead got "+
00465 e2.getType().getExpr().toString()+
00466 "\n\nwhile processing term:\n"+
00467 e.toString());
00468 }
00469
00470 cache[e] = e2;
00471 return e2;
00472 }
00473
00474
00475 Expr Translator::preprocess2(const Expr& e, ExprMap<Expr>& cache)
00476 {
00477 Expr result;
00478 try {
00479 result = preprocess2Rec(e, cache, Type());
00480 } catch (SmtlibException& ex) {
00481 cerr << "Error while processing the formula:\n"
00482 << e.toString() << endl;
00483 throw ex;
00484 }
00485 return result;
00486 }
00487
00488
00489
00490
00491 bool Translator::containsArray(const Expr& e)
00492 {
00493 if (e.getKind() == ARRAY) return true;
00494 Expr::iterator i = e.begin(), iend=e.end();
00495 for(; i!=iend; ++i) if (containsArray(*i)) return true;
00496 return false;
00497 }
00498
00499
00500 Translator::Translator(ExprManager* em,
00501 const bool& translate,
00502 const bool& real2int,
00503 const bool& convertArith,
00504 const string& convertToDiff,
00505 bool iteLiftArith,
00506 const string& expResult,
00507 const string& category,
00508 bool convertArray,
00509 bool combineAssump)
00510 : d_em(em), d_translate(translate),
00511 d_real2int(real2int),
00512 d_convertArith(convertArith),
00513 d_convertToDiff(convertToDiff),
00514 d_iteLiftArith(iteLiftArith),
00515 d_expResult(expResult),
00516 d_category(category),
00517 d_convertArray(convertArray),
00518 d_combineAssump(combineAssump),
00519 d_dump(false), d_dumpFileOpen(false),
00520 d_intIntArray(false), d_intRealArray(false), d_intIntRealArray(false),
00521 d_ax(false), d_unknown(false),
00522 d_realUsed(false), d_intUsed(false), d_intConstUsed(false),
00523 d_langUsed(NOT_USED), d_UFIDL_ok(true), d_arithUsed(false),
00524 d_zeroVar(NULL)
00525 {}
00526
00527
00528 bool Translator::start(const string& dumpFile)
00529 {
00530 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00531 d_dump = true;
00532 if (dumpFile == "") {
00533 d_osdump = &cout;
00534 }
00535 else {
00536 d_osdumpFile.open(dumpFile.c_str());
00537 if(!d_osdumpFile)
00538 throw Exception("cannot open a log file: "+dumpFile);
00539 else {
00540 d_dumpFileOpen = true;
00541 d_osdump = &d_osdumpFile;
00542 }
00543 }
00544 *d_osdump <<
00545 "(benchmark " << fileToSMTLIBIdentifier(dumpFile) << endl <<
00546 " :source {" << endl;
00547 string tmpName;
00548 string::size_type pos = dumpFile.rfind("/");
00549 if (pos == string::npos) {
00550 tmpName = "README";
00551 }
00552 else {
00553 tmpName = dumpFile.substr(0,pos+1) + "README";
00554 }
00555 d_tmpFile.open(tmpName.c_str());
00556 char c;
00557 if (d_tmpFile.is_open()) {
00558 d_tmpFile.get(c);
00559 while (!d_tmpFile.eof()) {
00560 if (c == '{' || c == '}') *d_osdump << '\\';
00561 *d_osdump << c;
00562 d_tmpFile.get(c);
00563 }
00564 d_tmpFile.close();
00565 }
00566 else {
00567 *d_osdump << "Source unknown";
00568 }
00569 *d_osdump << endl;
00570
00571
00572 *d_osdump << "}" << endl;
00573
00574 }
00575 else {
00576 if (dumpFile == "") {
00577 if (d_translate) {
00578 d_osdump = &cout;
00579 d_dump = true;
00580 }
00581 }
00582 else {
00583 d_osdumpFile.open(dumpFile.c_str());
00584 if(!d_osdumpFile)
00585 throw Exception("cannot open a log file: "+dumpFile);
00586 else {
00587 d_dump = true;
00588 d_dumpFileOpen = true;
00589 d_osdump = &d_osdumpFile;
00590 }
00591 }
00592 }
00593 return d_dump;
00594 }
00595
00596
00597 void Translator::dump(const Expr& e, bool dumpOnly)
00598 {
00599 DebugAssert(d_dump, "dump called unexpectedly");
00600 if (!dumpOnly || !d_translate) {
00601 if (d_convertArray && e.getKind() == CONST &&
00602 e.arity() == 2) {
00603 if (e[1].getKind() == ARRAY) {
00604 if (containsArray(e[1][0]) ||
00605 containsArray(e[1][1])) {
00606 throw Exception("convertArray failed because of nested arrays in"+
00607 e[1].toString());
00608 }
00609 Expr funType = Expr(ARROW, e[1][0], e[1][1]);
00610 Expr outExpr = Expr(CONST, e[0], funType);
00611 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00612 d_dumpExprs.push_back(outExpr);
00613 }
00614 else {
00615 *d_osdump << outExpr << endl;
00616 }
00617 }
00618 else if (containsArray(e[1])) {
00619 throw Exception("convertArray failed becauase of use of arrays in"+
00620 e[1].toString());
00621 }
00622 else if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00623 d_dumpExprs.push_back(e);
00624 }
00625 else *d_osdump << e << endl;
00626 }
00627 else if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00628 d_dumpExprs.push_back(e);
00629 }
00630 else *d_osdump << e << endl;
00631 }
00632 }
00633
00634
00635 bool Translator::dumpAssertion(const Expr& e)
00636 {
00637 Expr outExpr = Expr(ASSERT, e);
00638 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00639 d_dumpExprs.push_back(outExpr);
00640 }
00641 else {
00642 *d_osdump << outExpr << endl;
00643 }
00644 return d_translate;
00645 }
00646
00647
00648 bool Translator::dumpQuery(const Expr& e)
00649 {
00650 Expr outExpr = Expr(QUERY, e);
00651 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00652 d_dumpExprs.push_back(outExpr);
00653 }
00654 else {
00655 *d_osdump << outExpr << endl;
00656 }
00657 return d_translate;
00658 }
00659
00660
00661 void Translator::dumpQueryResult(QueryResult qres)
00662 {
00663 if(d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00664 *d_osdump << " :status ";
00665 switch (qres) {
00666 case UNSATISFIABLE:
00667 *d_osdump << "unsat" << endl;
00668 break;
00669 case SATISFIABLE:
00670 *d_osdump << "sat" << endl;
00671 break;
00672 default:
00673 *d_osdump << "unknown" << endl;
00674 break;
00675 }
00676 }
00677 }
00678
00679
00680 Expr Translator::processType(const Expr& e)
00681 {
00682 switch (e.getKind()) {
00683 case INT:
00684 d_intUsed = true;
00685 break;
00686 case REAL:
00687 if (d_real2int) {
00688 d_intUsed = true;
00689 return d_theoryArith->intType().getExpr();
00690 }
00691 else {
00692 d_realUsed = true;
00693 }
00694 break;
00695 case SUBRANGE:
00696 d_unknown = true;
00697 break;
00698 default:
00699 break;
00700 }
00701 d_theoryCore->theoryOf(e)->setUsed();
00702 if (e.arity() == 0) return e;
00703 bool changed = false;
00704 vector<Expr> vec;
00705 for (int i = 0; i < e.arity(); ++i) {
00706 vec.push_back(processType(e[i]));
00707 if (vec.back() != e[i]) changed = true;
00708 }
00709 if (changed)
00710 return Expr(e.getOp(), vec);
00711 return e;
00712 }
00713
00714
00715 void Translator::finish()
00716 {
00717 if (d_translate && d_em->getOutputLang() == SMTLIB_LANG) {
00718
00719
00720
00721
00722 *d_osdump << " :status ";
00723 if (d_expResult == "invalid" ||
00724 d_expResult == "satisfiable")
00725 *d_osdump << "sat";
00726 else if (d_expResult == "valid" ||
00727 d_expResult == "unsatisfiable")
00728 *d_osdump << "unsat";
00729 else *d_osdump << "unknown";
00730 *d_osdump << endl;
00731
00732
00733 *d_osdump << " :difficulty { unknown }" << endl;
00734
00735
00736 *d_osdump << " :category { ";
00737 *d_osdump << d_category << " }" << endl;
00738
00739
00740 bool qf_uf = false;
00741 {
00742 {
00743 ExprMap<Expr> cache;
00744
00745 vector<Expr>::iterator i = d_dumpExprs.begin(), iend = d_dumpExprs.end();
00746 for (; i != iend; ++i) {
00747 Expr e = *i;
00748 switch (e.getKind()) {
00749 case ASSERT: {
00750 Expr e2 = preprocess(e[0], cache);
00751 if (e[0] == e2) break;
00752 e2.getType();
00753 *i = Expr(ASSERT, e2);
00754 break;
00755 }
00756 case QUERY: {
00757 Expr e2 = preprocess(e[0].negate(), cache);
00758 if (e[0].negate() == e2) break;
00759 e2.getType();
00760 *i = Expr(QUERY, e2.negate());
00761 break;
00762 }
00763 case CONST: {
00764 DebugAssert(e.arity() == 2, "Expected CONST with arity 2");
00765 Expr e2 = processType(e[1]);
00766 if (e[1] == e2) break;
00767 *i = Expr(CONST, e[0], e2);
00768 break;
00769 }
00770 default:
00771 break;
00772 }
00773 }
00774 }
00775
00776 if (d_zeroVar) {
00777 d_dumpExprs.insert(d_dumpExprs.begin(),
00778 Expr(CONST, Expr(ID, d_em->newStringExpr("cvc3Zero")),
00779 processType(d_zeroVar->getType().getExpr())));
00780 }
00781
00782
00783 if (!d_unknown && d_intUsed && d_realUsed) {
00784 ExprMap<Expr> cache;
00785 vector<Expr>::iterator i = d_dumpExprs.begin(), iend = d_dumpExprs.end();
00786 for (; i != iend; ++i) {
00787 Expr e = *i;
00788 switch (e.getKind()) {
00789 case ASSERT: {
00790 Expr e2 = preprocess2(e[0], cache);
00791 e2.getType();
00792 *i = Expr(ASSERT, e2);
00793 break;
00794 }
00795 case QUERY: {
00796 Expr e2 = preprocess2(e[0].negate(), cache);
00797 e2.getType();
00798 *i = Expr(QUERY, e2.negate());
00799 break;
00800 }
00801 default:
00802 break;
00803 }
00804 }
00805 }
00806 d_arithUsed = d_realUsed || d_intUsed || d_intConstUsed || (d_langUsed != NOT_USED);
00807
00808
00809 *d_osdump << " :logic ";
00810 if (d_unknown ||
00811 d_theoryRecords->theoryUsed() ||
00812 d_theorySimulate->theoryUsed() ||
00813 d_theoryDatatype->theoryUsed()) {
00814 *d_osdump << "unknown";
00815 }
00816 else {
00817 if ((d_ax && (d_arithUsed ||
00818 d_theoryBitvector->theoryUsed() ||
00819 d_theoryUF->theoryUsed())) ||
00820 (d_intIntArray && d_realUsed) ||
00821 (d_arithUsed && d_theoryBitvector->theoryUsed())) {
00822 *d_osdump << "unknown";
00823 }
00824 else {
00825 bool QF = false;
00826 bool A = false;
00827 bool UF = false;
00828
00829 if (!d_theoryQuant->theoryUsed()) {
00830 QF = true;
00831 *d_osdump << "QF_";
00832 }
00833
00834 if (d_theoryArray->theoryUsed() && !d_convertArray) {
00835 A = true;
00836 *d_osdump << "A";
00837 }
00838
00839
00840 else if (!QF && !d_theoryBitvector->theoryUsed()) {
00841 A = true;
00842 *d_osdump << "A";
00843 }
00844
00845 if (d_theoryUF->theoryUsed() ||
00846 (d_theoryArray->theoryUsed() && d_convertArray)) {
00847 UF = true;
00848 *d_osdump << "UF";
00849 }
00850
00851
00852 else if (!QF &&
00853 !d_theoryBitvector->theoryUsed()) {
00854 UF = true;
00855 *d_osdump << "UF";
00856 }
00857
00858 if (d_arithUsed) {
00859 if (d_intUsed && d_realUsed) {
00860 if (d_langUsed < NONLINEAR) {
00861 *d_osdump << "LIRA";
00862 }
00863 else *d_osdump << "NIRA";
00864 }
00865 else if (d_realUsed) {
00866 if (d_langUsed <= DIFF_ONLY) {
00867
00868
00869 if (!QF) {
00870 *d_osdump << "LIRA";
00871 } else
00872
00873 *d_osdump << "RDL";
00874 }
00875 else if (d_langUsed <= LINEAR) {
00876
00877
00878 if (!QF) {
00879 *d_osdump << "LIRA";
00880 } else
00881
00882 *d_osdump << "LRA";
00883 }
00884 else {
00885
00886
00887 if (!QF) {
00888 *d_osdump << "NIRA";
00889 } else
00890
00891 *d_osdump << "NRA";
00892 }
00893 }
00894 else {
00895 if (QF && !A && UF && d_langUsed <= LINEAR) {
00896 if (!d_realUsed && d_langUsed <= LINEAR && d_UFIDL_ok) {
00897 *d_osdump << "IDL";
00898 }
00899 else {
00900 *d_osdump << "LIA";
00901 }
00902 }
00903 else if (d_langUsed <= DIFF_ONLY) {
00904
00905
00906 if (!QF) {
00907 *d_osdump << "LIA";
00908 }
00909 else if (A) {
00910 if (!UF) {
00911 UF = true;
00912 *d_osdump << "UF";
00913 }
00914 *d_osdump << "LIA";
00915 } else
00916
00917 *d_osdump << "IDL";
00918 }
00919 else if (d_langUsed <= LINEAR) {
00920
00921
00922 if (QF && A && !UF) {
00923 UF = true;
00924 *d_osdump << "UF";
00925 }
00926
00927 if (QF && !A && (!d_realUsed && d_langUsed <= LINEAR && d_UFIDL_ok)) {
00928 *d_osdump << "UFIDL";
00929 }
00930 else {
00931 *d_osdump << "LIA";
00932 }
00933 }
00934 else {
00935
00936
00937 if (!QF) {
00938 *d_osdump << "NIRA";
00939 } else
00940
00941 *d_osdump << "NIA";
00942 }
00943 }
00944 }
00945 else if (d_theoryBitvector->theoryUsed()) {
00946
00947
00948 if (A && QF && !UF) {
00949 UF = true;
00950 *d_osdump << "UF";
00951 }
00952
00953 *d_osdump << "BV";
00954 }
00955 else {
00956
00957 if (d_ax) {
00958 *d_osdump << "X";
00959 }
00960
00961
00962 else if (!QF || (A && UF)) {
00963 *d_osdump << "LIA";
00964 } else {
00965
00966
00967 if (!A && !UF) {
00968 UF = true;
00969 *d_osdump << "UF";
00970 }
00971 qf_uf = QF && UF && (!A);
00972 }
00973 }
00974 }
00975 }
00976 }
00977 *d_osdump << endl;
00978
00979
00980
00981 vector<Expr>::const_iterator i = d_dumpExprs.begin(), iend = d_dumpExprs.end();
00982 vector<Expr> assumps;
00983 for (; i != iend; ++i) {
00984 Expr e = *i;
00985 switch (e.getKind()) {
00986 case ASSERT: {
00987 if (d_combineAssump) {
00988 assumps.push_back(e[0]);
00989 }
00990 else {
00991 *d_osdump << " :assumption" << endl;
00992 *d_osdump << e[0] << endl;
00993 }
00994 break;
00995 }
00996 case QUERY: {
00997 *d_osdump << " :formula" << endl;
00998 if (!assumps.empty()) {
00999 assumps.push_back(e[0].negate());
01000 e = Expr(AND, assumps);
01001 *d_osdump << e << endl;
01002 }
01003 else {
01004 *d_osdump << e[0].negate() << endl;
01005 }
01006 break;
01007 }
01008 default:
01009 if (qf_uf && e.getKind() == TYPE && e[0].getKind() == RAW_LIST &&
01010 e[0][0].getKind() == ID && e[0][0][0].getKind() == STRING_EXPR &&
01011 e[0][0][0].getString() == "U")
01012 break;
01013 *d_osdump << e << endl;
01014 break;
01015 }
01016 }
01017 *d_osdump << ")" << endl;
01018 }
01019
01020 if (d_dumpFileOpen) d_osdumpFile.close();
01021 if (d_zeroVar) delete d_zeroVar;
01022 }
01023
01024
01025 const string Translator::fixConstName(const string& s)
01026 {
01027 if (d_em->getOutputLang() == SMTLIB_LANG) {
01028 if (s[0] == '_') {
01029 return "smt"+s;
01030 }
01031 }
01032 return s;
01033 }
01034
01035
01036 bool Translator::printArrayExpr(ExprStream& os, const Expr& e)
01037 {
01038 if (e.getKind() == ARRAY) {
01039 if (d_convertArray) {
01040 os << Expr(ARROW, e[0], e[1]);
01041 return true;
01042 }
01043 if (d_em->getOutputLang() != SMTLIB_LANG) return false;
01044 if (e[0].getKind() == TYPEDECL) {
01045 DebugAssert(e[0].arity() == 1, "expected arity 1");
01046 if (e[0][0].getString() == "Index") {
01047 if (e[1].getKind() == TYPEDECL) {
01048 DebugAssert(e[1].arity() == 1, "expected arity 1");
01049 if (e[1][0].getString() == "Element") {
01050 d_ax = true;
01051 os << "Array";
01052 return true;
01053 }
01054 }
01055 }
01056 }
01057 else if (isInt(Type(e[0]))) {
01058 if (isInt(Type(e[1]))) {
01059 d_intIntArray = true;
01060 os << "Array";
01061 return true;
01062 }
01063 else if (isReal(Type(e[1]))) {
01064 d_intRealArray = true;
01065 os << "Array1";
01066 return true;
01067 }
01068 else if (isArray(Type(e[1])) &&
01069 isInt(Type(e[1][0])) &&
01070 isReal(Type(e[1][1]))) {
01071 d_intIntRealArray = true;
01072 os << "Array2";
01073 return true;
01074 }
01075 }
01076 else if (e[0].getKind() == BITVECTOR &&
01077 e[1].getKind() == BITVECTOR) {
01078 os << "Array[";
01079 os << d_theoryBitvector->getBitvectorTypeParam(Type(e[0]));
01080 os << ":";
01081 os << d_theoryBitvector->getBitvectorTypeParam(Type(e[1]));
01082 os << "]";
01083 return true;
01084 }
01085 os << "Array";
01086 d_unknown = true;
01087 return true;
01088 }
01089
01090 switch (e.getKind()) {
01091 case READ:
01092 if (d_convertArray) {
01093 if (e[0].getKind() == UCONST) {
01094 os << Expr(d_em->newSymbolExpr(e[0].getName(), UFUNC).mkOp(), e[1]);
01095 return true;
01096 }
01097 else if (e[0].getKind() == WRITE) {
01098 throw Exception("READ of WRITE not implemented yet for convertArray");
01099 }
01100 else {
01101 throw Exception("Unexpected case for convertArray");
01102 }
01103 }
01104 break;
01105 case WRITE:
01106 if (d_convertArray) {
01107 throw Exception("WRITE expression encountered while attempting "
01108 "to convert arrays to uninterpreted functions");
01109 }
01110 break;
01111 case ARRAY_LITERAL:
01112 if (d_convertArray) {
01113 throw Exception("ARRAY_LITERAL expression encountered while attempting"
01114 " to convert arrays to uninterpreted functions");
01115 }
01116 break;
01117 default:
01118 throw Exception("Unexpected case in printArrayExpr");
01119 break;
01120 }
01121 return false;
01122 }
01123
01124
01125 Expr Translator::zeroVar()
01126 {
01127 if (!d_zeroVar) {
01128 d_zeroVar = new Expr();
01129 if (d_convertToDiff == "int") {
01130 *d_zeroVar = d_theoryCore->newVar("cvc3Zero", d_theoryArith->intType().getExpr());
01131 }
01132 else if (d_convertToDiff == "real") {
01133 *d_zeroVar = d_theoryCore->newVar("cvc3Zero", d_theoryArith->realType().getExpr());
01134 }
01135 }
01136 return *d_zeroVar;
01137 }