00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <fstream>
00022 #include "os.h"
00023 #include "vcl.h"
00024 #include "parser.h"
00025 #include "vc_cmd.h"
00026 #include "search_simple.h"
00027 #include "search_fast.h"
00028 #include "search_sat.h"
00029 #include "theory_core.h"
00030 #include "theory_uf.h"
00031 #include "theory_arith_old.h"
00032 #include "theory_arith_new.h"
00033 #include "theory_arith3.h"
00034 #include "theory_bitvector.h"
00035 #include "theory_array.h"
00036 #include "theory_quant.h"
00037 #include "theory_records.h"
00038 #include "theory_simulate.h"
00039 #include "theory_datatype.h"
00040 #include "theory_datatype_lazy.h"
00041 #include "translator.h"
00042 #include "typecheck_exception.h"
00043 #include "eval_exception.h"
00044 #include "expr_transform.h"
00045 #include "theorem_manager.h"
00046 #include "assumptions.h"
00047 #include "parser_exception.h"
00048
00049
00050 using namespace std;
00051 using namespace CVC3;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063 ValidityChecker* ValidityChecker::create(const CLFlags& flags)
00064 {
00065 return new VCL(flags);
00066 }
00067
00068
00069 CLFlags ValidityChecker::createFlags() {
00070 CLFlags flags;
00071
00072
00073
00074
00075 flags.addFlag("timeout", CLFlag(0, "Kill cvc3 process after given number of seconds (0==no limit)"));
00076 flags.addFlag("stimeout", CLFlag(0, "Set time resource limit in tenths of seconds for a query(0==no limit)"));
00077 flags.addFlag("resource", CLFlag(0, "Set finite resource limit (0==no limit)"));
00078 flags.addFlag("mm", CLFlag("chunks", "Memory manager (chunks, malloc)"));
00079
00080
00081 flags.addFlag("help",CLFlag(true, "print usage information and exit"));
00082 flags.addFlag("unsupported",CLFlag(true, "print usage for old/unsupported/experimental options"));
00083 flags.addFlag("version",CLFlag(true, "print version information and exit"));
00084 flags.addFlag("interactive", CLFlag(false, "Interactive mode"));
00085 flags.addFlag("stats", CLFlag(false, "Print run-time statistics"));
00086 flags.addFlag("seed", CLFlag(1, "Set the seed for random sequence"));
00087 flags.addFlag("printResults", CLFlag(true, "Print results of interactive commands."));
00088 flags.addFlag("dump-log", CLFlag("", "Dump API call log in CVC3 input "
00089 "format to given file "
00090 "(off when file name is \"\")"));
00091
00092
00093 flags.addFlag("expResult", CLFlag("", "For smtlib translation. Give the expected result", false));
00094 flags.addFlag("category", CLFlag("unknown", "For smtlib translation. Give the category", false));
00095 flags.addFlag("translate", CLFlag(false, "Produce a complete translation from "
00096 "the input language to output language. "));
00097 flags.addFlag("real2int", CLFlag(false, "When translating, convert reals to integers.", false));
00098 flags.addFlag("convertArith", CLFlag(false, "When translating, try to rewrite arith terms into smt-lib subset", false));
00099 flags.addFlag("convert2diff", CLFlag("", "When translating, try to force into difference logic. Legal values are int and real.", false));
00100 flags.addFlag("iteLiftArith", CLFlag(false, "For translation. If true, ite's are lifted out of arith exprs.", false));
00101 flags.addFlag("convertArray", CLFlag(false, "For translation. If true, arrays are converted to uninterpreted functions if possible.", false));
00102 flags.addFlag("combineAssump", CLFlag(false, "For translation. If true, assumptions are combined into the query.", false));
00103 flags.addFlag("convert2array", CLFlag(false, "For translation. If true, try to convert to array-only theory", false));
00104 flags.addFlag("convertToBV",CLFlag(0, "For translation. Set to nonzero to convert ints to bv's of that length", false));
00105 flags.addFlag("convert-eq-iff",CLFlag(false, "Convert equality on Boolean expressions to iff.", false));
00106 flags.addFlag("preSimplify",CLFlag(false, "Simplify each assertion or query before translating it", false));
00107 flags.addFlag("dump-tcc", CLFlag(false, "Compute and dump TCC only"));
00108
00109
00110 flags.addFlag("old-func-syntax",CLFlag(false, "Enable parsing of old-style function syntax", false));
00111
00112
00113 flags.addFlag("dagify-exprs",
00114 CLFlag(true, "Print expressions with sharing as DAGs"));
00115 flags.addFlag("lang", CLFlag("presentation", "Input language "
00116 "(presentation, smtlib, internal)"));
00117 flags.addFlag("output-lang", CLFlag("", "Output language "
00118 "(presentation, smtlib, simplify, internal, lisp, tptp)"));
00119 flags.addFlag("indent", CLFlag(false, "Print expressions with indentation"));
00120 flags.addFlag("width", CLFlag(80, "Suggested line width for printing"));
00121 flags.addFlag("print-depth", CLFlag(-1, "Max. depth to print expressions "));
00122 flags.addFlag("print-assump", CLFlag(false, "Print assumptions in Theorems "));
00123
00124
00125 flags.addFlag("sat",CLFlag("minisat", "choose a SAT solver to use "
00126 "(sat, minisat)"));
00127 flags.addFlag("de",CLFlag("dfs", "choose a decision engine to use "
00128 "(dfs, sat)"));
00129
00130
00131 flags.addFlag("proofs", CLFlag(false, "Produce proofs"));
00132 flags.addFlag("check-proofs",
00133 CLFlag(IF_DEBUG(true ||) false, "Check proofs on-the-fly"));
00134 flags.addFlag("minimizeClauses", CLFlag(false, "Use brute-force minimization of clauses", false));
00135 flags.addFlag("dynack", CLFlag(false, "Use dynamic Ackermannization", false));
00136 flags.addFlag("smart-clauses", CLFlag(true, "Learn multiple clauses per conflict"));
00137
00138
00139
00140 flags.addFlag("tcc", CLFlag(false, "Check TCCs for each ASSERT and QUERY"));
00141 flags.addFlag("cnf", CLFlag(true, "Convert top-level Boolean formulas to CNF", false));
00142 flags.addFlag("ignore-cnf-vars", CLFlag(false, "Do not split on aux. CNF vars (with +cnf)", false));
00143 flags.addFlag("orig-formula", CLFlag(false, "Preserve the original formula with +cnf (for splitter heuristics)", false));
00144 flags.addFlag("iflift", CLFlag(false, "Translate if-then-else terms to CNF (with +cnf)", false));
00145 flags.addFlag("circuit", CLFlag(false, "With +cnf, use circuit propagation", false));
00146 flags.addFlag("un-ite-ify", CLFlag(false, "Unconvert ITE expressions", false));
00147 flags.addFlag("ite-cond-simp",
00148 CLFlag(false, "Replace ITE condition by TRUE/FALSE in subexprs", false));
00149 flags.addFlag("preprocess", CLFlag(true, "Preprocess queries"));
00150 flags.addFlag("pp-pushneg", CLFlag(false, "Push negation in preprocessor"));
00151 flags.addFlag("pp-bryant", CLFlag(false, "Enable Bryant algorithm for UF", false));
00152 flags.addFlag("pp-budget", CLFlag(0, "Budget for new preprocessing step", false));
00153 flags.addFlag("pp-care", CLFlag(true, "Enable care-set preprocessing step", false));
00154 flags.addFlag("simp-and", CLFlag(false, "Rewrite x&y to x&y[x/true]", false));
00155 flags.addFlag("simp-or", CLFlag(false, "Rewrite x|y to x|y[x/false]", false));
00156 flags.addFlag("pp-batch", CLFlag(false, "Ignore assumptions until query, then process all at once"));
00157
00158
00159 flags.addFlag("negate-query", CLFlag(true, "Negate the query when translate into TPTP format"));;
00160
00161
00162 flags.addFlag("counterexample", CLFlag(false, "Dump counterexample if formula is invalid or satisfiable"));
00163 flags.addFlag("model", CLFlag(false, "Dump model if formula is invalid or satisfiable"));
00164 flags.addFlag("unknown-check-model", CLFlag(false, "Try to generate model if formula is unknown"));
00165 flags.addFlag("applications", CLFlag(true, "Add relevant function applications and array accesses to the concrete countermodel"));
00166
00167
00168 vector<pair<string,bool> > sv;
00169 flags.addFlag("trace", CLFlag(sv, "Tracing. Multiple flags add up."));
00170 flags.addFlag("dump-trace", CLFlag("", "Dump debugging trace to "
00171 "given file (off when file name is \"\")"));
00172
00173
00174
00175
00176 flags.addFlag("arith-new",CLFlag(false, "Use new arithmetic dp", false));
00177 flags.addFlag("arith3",CLFlag(false, "Use old arithmetic dp that works well with combined theories", false));
00178 flags.addFlag("var-order",
00179 CLFlag(false, "Use simple variable order in arith", false));
00180 flags.addFlag("ineq-delay", CLFlag(0, "Accumulate this many inequalities before processing (-1 for don't process until necessary)"));
00181
00182 flags.addFlag("nonlinear-sign-split", CLFlag(true, "Whether to split on the signs of nontrivial nonlinear terms"));
00183
00184 flags.addFlag("grayshadow-threshold", CLFlag(-1, "Ignore gray shadows bigger than this (makes solver incomplete)"));
00185 flags.addFlag("pathlength-threshold", CLFlag(-1, "Ignore gray shadows bigger than this (makes solver incomplete)"));
00186
00187
00188 flags.addFlag("liftReadIte", CLFlag(true, "Lift read of ite"));
00189
00190
00191 flags.addFlag("cnf-formula", CLFlag(false, "the input is already in CNF. This option automatically enables -de sat and disable -preprocess"));
00192
00193
00194 flags.addFlag("max-quant-inst", CLFlag(200, "The maximum number of"
00195 " naive instantiations"));
00196
00197 flags.addFlag("quant-new",
00198 CLFlag(true, "If this option is false, only naive instantiation is called"));
00199
00200 flags.addFlag("quant-lazy", CLFlag(false, "Instantiate lazily", false));
00201
00202 flags.addFlag("quant-sem-match",
00203 CLFlag(false, "Attempt to match semantically when instantiating", false));
00204
00205
00206
00207
00208 flags.addFlag("quant-complete-inst",
00209 CLFlag(false, "Try complete instantiation heuristic. +pp-batch will be automatically enabled"));
00210
00211 flags.addFlag("quant-max-IL",
00212 CLFlag(100, "The maximum Instantiation Level allowed"));
00213
00214 flags.addFlag("quant-inst-lcache",
00215 CLFlag(true, "Cache instantiations"));
00216
00217 flags.addFlag("quant-inst-gcache",
00218 CLFlag(false, "Cache instantiations", false));
00219
00220 flags.addFlag("quant-inst-tcache",
00221 CLFlag(false, "Cache instantiations", false));
00222
00223
00224 flags.addFlag("quant-inst-true",
00225 CLFlag(true, "Ignore true instantiations"));
00226
00227 flags.addFlag("quant-pullvar",
00228 CLFlag(false, "Pull out vars", false));
00229
00230 flags.addFlag("quant-score",
00231 CLFlag(true, "Use instantiation level"));
00232
00233 flags.addFlag("quant-polarity",
00234 CLFlag(false, "Use polarity ", false));
00235
00236 flags.addFlag("quant-eqnew",
00237 CLFlag(true, "Use new equality matching"));
00238
00239 flags.addFlag("quant-max-score",
00240 CLFlag(0, "Maximum initial dynamic score"));
00241
00242 flags.addFlag("quant-trans3",
00243 CLFlag(true, "Use trans heuristic"));
00244
00245 flags.addFlag("quant-trans2",
00246 CLFlag(true, "Use trans2 heuristic"));
00247
00248 flags.addFlag("quant-naive-num",
00249 CLFlag(1000, "Maximum number to call naive instantiation"));
00250
00251 flags.addFlag("quant-naive-inst",
00252 CLFlag(true, "Use naive instantiation"));
00253
00254 flags.addFlag("quant-man-trig",
00255 CLFlag(true, "Use manual triggers"));
00256
00257 flags.addFlag("quant-gfact",
00258 CLFlag(false, "Send facts to core directly", false));
00259
00260 flags.addFlag("quant-glimit",
00261 CLFlag(1000, "Limit for gfacts", false));
00262
00263 flags.addFlag("print-var-type",
00264 CLFlag(false, "Print types for bound variables"));
00265
00266
00267 flags.addFlag("bv32-flag",
00268 CLFlag(false, "assume that all bitvectors are 32bits with no overflow", false));
00269
00270
00271 flags.addFlag("trans-closure",
00272 CLFlag(false,"enables transitive closure of binary relations", false));
00273
00274
00275 flags.addFlag("dt-smartsplits",
00276 CLFlag(true, "enables smart splitting in datatype theory", false));
00277 flags.addFlag("dt-lazy",
00278 CLFlag(false, "lazy splitting on datatypes", false));
00279
00280 return flags;
00281 }
00282
00283
00284 ValidityChecker* ValidityChecker::create()
00285 {
00286 return new VCL(createFlags());
00287 }
00288
00289
00290
00291
00292
00293
00294
00295 Theorem3 VCL::deriveClosure(const Theorem3& thm) {
00296 vector<Expr> assump;
00297 set<UserAssertion> assumpSet;
00298
00299
00300
00301
00302 Theorem3 res = thm;
00303 vector<Theorem> tccs;
00304 while(true) {
00305 {
00306 const Assumptions& a(res.getAssumptionsRef());
00307 if (a.empty()) break;
00308 assump.clear();
00309 assumpSet.clear();
00310 Assumptions::iterator i=a.begin(), iend=a.end();
00311 if(i!=iend) i->clearAllFlags();
00312
00313 for(; i!=iend; ++i)
00314 getAssumptionsRec(*i, assumpSet, false);
00315
00316
00317 if(getFlags()["tcc"].getBool()) {
00318 tccs.clear();
00319 for(set<UserAssertion>::iterator i=assumpSet.begin(),
00320 iend=assumpSet.end(); i!=iend; ++i) {
00321 assump.push_back(i->thm().getExpr());
00322 tccs.push_back(i->tcc());
00323 }
00324 }
00325 }
00326
00327 res = d_se->getCommonRules()->implIntro3(res, assump, tccs);
00328 }
00329 return res;
00330 }
00331
00332
00333
00334
00335
00336
00337
00338 void VCL::getAssumptionsRec(const Theorem& thm,
00339 set<UserAssertion>& assumptions,
00340 bool addTCCs) {
00341 if(thm.isNull() || thm.isRefl() || thm.isFlagged()) return;
00342 thm.setFlag();
00343 if(thm.isAssump()) {
00344 if(d_userAssertions->count(thm.getExpr())>0) {
00345 const UserAssertion& a = (*d_userAssertions)[thm.getExpr()];
00346 assumptions.insert(a);
00347 if(addTCCs) {
00348 DebugAssert(!a.tcc().isNull(), "getAssumptionsRec(a="
00349 +a.thm().toString()+", thm = "+thm.toString()+")");
00350 getAssumptionsRec(a.tcc(), assumptions, true);
00351 }
00352 } else {
00353 UserAssertion a(thm, Theorem(), d_nextIdx++);
00354 assumptions.insert(a);
00355 }
00356 }
00357 else {
00358 const Assumptions& a(thm.getAssumptionsRef());
00359 for(Assumptions::iterator i=a.begin(), iend=a.end(); i!=iend; ++i)
00360 getAssumptionsRec(*i, assumptions, addTCCs);
00361 }
00362 }
00363
00364
00365 void VCL::getAssumptions(const Assumptions& a, vector<Expr>& assumptions)
00366 {
00367 set<UserAssertion> assumpSet;
00368 if(a.empty()) return;
00369 Assumptions::iterator i=a.begin(), iend=a.end();
00370 if(i!=iend) i->clearAllFlags();
00371 for(; i!=iend; ++i)
00372 getAssumptionsRec(*i, assumpSet, getFlags()["tcc"].getBool());
00373
00374 for(set<UserAssertion>::iterator i=assumpSet.begin(), iend=assumpSet.end();
00375 i!=iend; ++i)
00376 assumptions.push_back(i->thm().getExpr());
00377 }
00378
00379
00380 IF_DEBUG(
00381 void VCL::dumpTrace(int scope) {
00382 vector<StrPair> fields;
00383 fields.push_back(strPair("scope", int2string(scope)));
00384 debugger.dumpTrace("scope", fields);
00385 }
00386 )
00387
00388
00389
00390
00391
00392
00393
00394 VCL::VCL(const CLFlags& flags)
00395 : d_flags(new CLFlags(flags))
00396 {
00397
00398
00399 if ((*d_flags)["dump-tcc"].getBool()) {
00400 d_flags->setFlag("translate", true);
00401 d_flags->setFlag("pp-batch", true);
00402 d_flags->setFlag("tcc", true);
00403 }
00404
00405 if ((*d_flags)["translate"].getBool()) {
00406 d_flags->setFlag("printResults", false);
00407 }
00408
00409 if ((*d_flags)["pp-bryant"].getBool()) {
00410 d_flags->setFlag("pp-batch", true);
00411 }
00412
00413
00414 if ((*d_flags)["quant-complete-inst"].getBool()) {
00415 d_flags->setFlag("pp-batch", true);
00416 }
00417
00418
00419 if ((*d_flags)["cnf-formula"].getBool()) {
00420 d_flags->setFlag("de", "sat");
00421 d_flags->setFlag("preprocess", false);
00422 }
00423
00424
00425 IF_DEBUG(
00426 CVC3::debugger.init(&((*d_flags)["trace"].getStrVec()),
00427 &((*d_flags)["dump-trace"].getString()));
00428 )
00429 init();
00430 }
00431
00432
00433 void VCL::init()
00434 {
00435 d_nextIdx = 0;
00436
00437 d_statistics = new Statistics();
00438
00439 d_cm = new ContextManager();
00440
00441
00442
00443 d_userAssertions = new(true) CDMap<Expr,UserAssertion>(getCurrentContext());
00444 d_batchedAssertions = new(true) CDList<Expr>(getCurrentContext());
00445 d_batchedAssertionsIdx = new(true) CDO<unsigned>(getCurrentContext(), 0);
00446
00447 d_em = new ExprManager(d_cm, *d_flags);
00448
00449 d_tm = new TheoremManager(d_cm, d_em, *d_flags);
00450 d_em->setTM(d_tm);
00451
00452 d_translator = new Translator(d_em,
00453 (*d_flags)["translate"].getBool(),
00454 (*d_flags)["real2int"].getBool(),
00455 (*d_flags)["convertArith"].getBool(),
00456 (*d_flags)["convert2diff"].getString(),
00457 (*d_flags)["iteLiftArith"].getBool(),
00458 (*d_flags)["expResult"].getString(),
00459 (*d_flags)["category"].getString(),
00460 (*d_flags)["convertArray"].getBool(),
00461 (*d_flags)["combineAssump"].getBool(),
00462 (*d_flags)["convertToBV"].getInt());
00463
00464 d_dump = d_translator->start((*d_flags)["dump-log"].getString());
00465
00466 d_theoryCore = new TheoryCore(d_cm, d_em, d_tm, d_translator, *d_flags, *d_statistics);
00467
00468 DebugAssert(d_theories.size() == 0, "Expected empty theories array");
00469 d_theories.push_back(d_theoryCore);
00470
00471
00472 falseExpr().setFind(d_theoryCore->reflexivityRule(falseExpr()));
00473 trueExpr().setFind(d_theoryCore->reflexivityRule(trueExpr()));
00474
00475 d_theories.push_back(d_theoryUF = new TheoryUF(d_theoryCore));
00476
00477 if ((*d_flags)["arith-new"].getBool()) {
00478 d_theories.push_back(d_theoryArith = new TheoryArithNew(d_theoryCore));
00479 }
00480 else if ((*d_flags)["arith3"].getBool()) {
00481 d_theories.push_back(d_theoryArith = new TheoryArith3(d_theoryCore));
00482 }
00483 else {
00484 d_theories.push_back(d_theoryArith = new TheoryArithOld(d_theoryCore));
00485 }
00486 d_theoryCore->getExprTrans()->setTheoryArith(d_theoryArith);
00487 d_theories.push_back(d_theoryArray = new TheoryArray(d_theoryCore));
00488 d_theories.push_back(d_theoryRecords = new TheoryRecords(d_theoryCore));
00489 d_theories.push_back(d_theorySimulate = new TheorySimulate(d_theoryCore));
00490 d_theories.push_back(d_theoryBitvector = new TheoryBitvector(d_theoryCore));
00491 if ((*d_flags)["dt-lazy"].getBool()) {
00492 d_theories.push_back(d_theoryDatatype = new TheoryDatatypeLazy(d_theoryCore));
00493 }
00494 else {
00495 d_theories.push_back(d_theoryDatatype = new TheoryDatatype(d_theoryCore));
00496 }
00497 d_theories.push_back(d_theoryQuant = new TheoryQuant(d_theoryCore));
00498
00499 d_translator->setTheoryCore(d_theoryCore);
00500 d_translator->setTheoryUF(d_theoryUF);
00501 d_translator->setTheoryArith(d_theoryArith);
00502 d_translator->setTheoryArray(d_theoryArray);
00503 d_translator->setTheoryQuant(d_theoryQuant);
00504 d_translator->setTheoryRecords(d_theoryRecords);
00505 d_translator->setTheorySimulate(d_theorySimulate);
00506 d_translator->setTheoryBitvector(d_theoryBitvector);
00507 d_translator->setTheoryDatatype(d_theoryDatatype);
00508
00509
00510
00511
00512 const string& satEngine = (*d_flags)["sat"].getString();
00513 if (satEngine == "simple")
00514 d_se = new SearchSimple(d_theoryCore);
00515 else if (satEngine == "fast")
00516 d_se = new SearchEngineFast(d_theoryCore);
00517 else if (satEngine == "sat" || satEngine == "minisat")
00518 d_se = new SearchSat(d_theoryCore, satEngine);
00519 else
00520 throw CLException("Unrecognized SAT solver name: "
00521 +(*d_flags)["sat"].getString());
00522
00523
00524 d_cm->push();
00525
00526 d_stackLevel = new(true) CDO<int>(d_cm->getCurrentContext(), 0);
00527
00528 d_theoryCore->setResourceLimit((unsigned)((*d_flags)["resource"].getInt()));
00529 d_theoryCore->setTimeLimit((unsigned)((*d_flags)["stimeout"].getInt()));
00530
00531
00532 }
00533
00534
00535 void VCL::destroy()
00536 {
00537 popto(0);
00538 d_cm->popto(0);
00539 delete d_stackLevel;
00540 free(d_stackLevel);
00541 d_translator->finish();
00542 delete d_translator;
00543
00544 TRACE_MSG("delete", "Deleting SearchEngine {");
00545 delete d_se;
00546 TRACE_MSG("delete", "Finished deleting SearchEngine }");
00547
00548
00549 TRACE_MSG("delete", "Deleting d_userAssertions {");
00550 delete d_batchedAssertionsIdx;
00551 free(d_batchedAssertionsIdx);
00552 delete d_batchedAssertions;
00553 free(d_batchedAssertions);
00554 delete d_userAssertions;
00555 free(d_userAssertions);
00556 TRACE_MSG("delete", "Finished deleting d_userAssertions }");
00557
00558 d_lastQuery = Theorem3();
00559 d_lastQueryTCC = Theorem();
00560 d_lastClosure = Theorem3();
00561
00562 TRACE_MSG("delete", "Clearing d_em {");
00563 d_em->clear();
00564 d_tm->clear();
00565 TRACE_MSG("delete", "Finished clearing d_em }");
00566
00567 for(size_t i=d_theories.size(); i!= 0; ) {
00568 --i;
00569 string name(d_theories[i]->getName());
00570 TRACE("delete", "Deleting Theory[", name, "] {");
00571 delete d_theories[i];
00572 TRACE("delete", "Finished deleting Theory[", name, "] }");
00573 }
00574 d_theories.clear();
00575
00576
00577
00578 TRACE_MSG("delete", "Deleting d_tm {");
00579 delete d_tm;
00580 TRACE_MSG("delete", "Finished deleting d_tm }");
00581
00582 TRACE_MSG("delete", "Deleting d_em {");
00583 delete d_em;
00584 TRACE_MSG("delete", "Finished deleting d_em }");
00585
00586 TRACE_MSG("delete", "Deleting d_cm {");
00587 delete d_cm;
00588 TRACE_MSG("delete", "Finished deleting d_cm }");
00589 delete d_statistics;
00590 TRACE_MSG("delete", "Finished deleting d_statistics }");
00591 }
00592
00593
00594 VCL::~VCL()
00595 {
00596 destroy();
00597 TRACE_MSG("delete", "Deleting d_flags [end of ~VCL()]");
00598 delete d_flags;
00599
00600
00601
00602
00603 IF_DEBUG(
00604 CVC3::debugger.finalize();
00605 )
00606 }
00607
00608
00609 void VCL::reprocessFlags() {
00610 if (d_se->getName() != (*d_flags)["sat"].getString()) {
00611 delete d_se;
00612 const string& satEngine = (*d_flags)["sat"].getString();
00613 if (satEngine == "simple")
00614 d_se = new SearchSimple(d_theoryCore);
00615 else if (satEngine == "fast")
00616 d_se = new SearchEngineFast(d_theoryCore);
00617 else if (satEngine == "sat" || satEngine == "minisat")
00618 d_se = new SearchSat(d_theoryCore, satEngine);
00619 else
00620 throw CLException("Unrecognized SAT solver name: "
00621 +(*d_flags)["sat"].getString());
00622 }
00623
00624 int arithCur;
00625 if (d_theoryArith->getName() == "ArithmeticOld") arithCur = 1;
00626 else if (d_theoryArith->getName() == "ArithmeticNew") arithCur = 2;
00627 else {
00628 DebugAssert(d_theoryArith->getName() == "Arithmetic3", "unexpected name");
00629 arithCur = 3;
00630 }
00631
00632 int arithNext;
00633 if ((*d_flags)["arith-new"].getBool()) arithNext = 2;
00634 else if ((*d_flags)["arith3"].getBool()) arithNext = 3;
00635 else arithNext = 1;
00636
00637 if (arithCur != arithNext) {
00638 delete d_theoryArith;
00639 switch (arithNext) {
00640 case 1:
00641 d_theoryArith = new TheoryArithOld(d_theoryCore);
00642 break;
00643 case 2:
00644 d_theoryArith = new TheoryArithNew(d_theoryCore);
00645 break;
00646 case 3:
00647 d_theoryArith = new TheoryArith3(d_theoryCore);
00648 break;
00649 }
00650 d_theories[2] = d_theoryArith;
00651 d_translator->setTheoryArith(d_theoryArith);
00652 }
00653
00654 if ((*d_flags)["dump-tcc"].getBool()) {
00655 d_flags->setFlag("translate", true);
00656 d_flags->setFlag("pp-batch", true);
00657 d_flags->setFlag("tcc", true);
00658 }
00659
00660 if ((*d_flags)["translate"].getBool()) {
00661 d_flags->setFlag("printResults", false);
00662 }
00663
00664 if ((*d_flags)["pp-bryant"].getBool()) {
00665 d_flags->setFlag("pp-batch", true);
00666 }
00667
00668
00669 if ((*d_flags)["quant-complete-inst"].getBool()) {
00670 d_flags->setFlag("pp-batch", true);
00671 }
00672
00673 if ((*d_flags)["cnf-formula"].getBool()) {
00674 d_flags->setFlag("de", "sat");
00675 d_flags->setFlag("preprocess", false);
00676 }
00677
00678
00679
00680 }
00681
00682 TheoryCore* VCL::core(){
00683 return d_theoryCore;
00684 }
00685
00686 Type VCL::boolType(){
00687 return d_theoryCore->boolType();
00688 }
00689
00690
00691 Type VCL::realType()
00692 {
00693 return d_theoryArith->realType();
00694 }
00695
00696
00697 Type VCL::intType() {
00698 return d_theoryArith->intType();
00699 }
00700
00701
00702 Type VCL::subrangeType(const Expr& l, const Expr& r) {
00703 return d_theoryArith->subrangeType(l, r);
00704 }
00705
00706
00707 Type VCL::subtypeType(const Expr& pred, const Expr& witness)
00708 {
00709 return d_theoryCore->newSubtypeExpr(pred, witness);
00710 }
00711
00712
00713 Type VCL::tupleType(const Type& type0, const Type& type1)
00714 {
00715 vector<Type> types;
00716 types.push_back(type0);
00717 types.push_back(type1);
00718 return d_theoryRecords->tupleType(types);
00719 }
00720
00721
00722 Type VCL::tupleType(const Type& type0, const Type& type1, const Type& type2)
00723 {
00724 vector<Type> types;
00725 types.push_back(type0);
00726 types.push_back(type1);
00727 types.push_back(type2);
00728 return d_theoryRecords->tupleType(types);
00729 }
00730
00731
00732 Type VCL::tupleType(const vector<Type>& types)
00733 {
00734 return d_theoryRecords->tupleType(types);
00735 }
00736
00737
00738 Type VCL::recordType(const string& field, const Type& type)
00739 {
00740 vector<string> fields;
00741 vector<Type> kids;
00742 fields.push_back(field);
00743 kids.push_back(type);
00744 return Type(d_theoryRecords->recordType(fields, kids));
00745 }
00746
00747
00748 Type VCL::recordType(const string& field0, const Type& type0,
00749 const string& field1, const Type& type1) {
00750 vector<string> fields;
00751 vector<Type> kids;
00752 fields.push_back(field0);
00753 fields.push_back(field1);
00754 kids.push_back(type0);
00755 kids.push_back(type1);
00756 sort2(fields, kids);
00757 return Type(d_theoryRecords->recordType(fields, kids));
00758 }
00759
00760
00761 Type VCL::recordType(const string& field0, const Type& type0,
00762 const string& field1, const Type& type1,
00763 const string& field2, const Type& type2)
00764 {
00765 vector<string> fields;
00766 vector<Type> kids;
00767 fields.push_back(field0);
00768 fields.push_back(field1);
00769 fields.push_back(field2);
00770 kids.push_back(type0);
00771 kids.push_back(type1);
00772 kids.push_back(type2);
00773 sort2(fields, kids);
00774 return Type(d_theoryRecords->recordType(fields, kids));
00775 }
00776
00777
00778 Type VCL::recordType(const vector<string>& fields,
00779 const vector<Type>& types)
00780 {
00781 DebugAssert(fields.size() == types.size(),
00782 "VCL::recordType: number of fields is different \n"
00783 "from the number of types");
00784
00785 vector<string> fs(fields);
00786 vector<Type> ts(types);
00787 sort2(fs, ts);
00788 return Type(d_theoryRecords->recordType(fs, ts));
00789 }
00790
00791
00792 Type VCL::dataType(const string& name,
00793 const string& constructor,
00794 const vector<string>& selectors, const vector<Expr>& types)
00795 {
00796 vector<string> constructors;
00797 constructors.push_back(constructor);
00798
00799 vector<vector<string> > selectorsVec;
00800 selectorsVec.push_back(selectors);
00801
00802 vector<vector<Expr> > typesVec;
00803 typesVec.push_back(types);
00804
00805 return dataType(name, constructors, selectorsVec, typesVec);
00806 }
00807
00808
00809 Type VCL::dataType(const string& name,
00810 const vector<string>& constructors,
00811 const vector<vector<string> >& selectors,
00812 const vector<vector<Expr> >& types)
00813 {
00814 Expr res = d_theoryDatatype->dataType(name, constructors, selectors, types);
00815 if(d_dump) {
00816 d_translator->dump(res);
00817 }
00818 return Type(res[0]);
00819 }
00820
00821
00822 void VCL::dataType(const vector<string>& names,
00823 const vector<vector<string> >& constructors,
00824 const vector<vector<vector<string> > >& selectors,
00825 const vector<vector<vector<Expr> > >& types,
00826 vector<Type>& returnTypes)
00827 {
00828 Expr res = d_theoryDatatype->dataType(names, constructors, selectors, types);
00829 if(d_dump) {
00830 d_translator->dump(res);
00831 }
00832 for (int i = 0; i < res.arity(); ++i) {
00833 returnTypes.push_back(Type(res[i]));
00834 }
00835 }
00836
00837
00838 Type VCL::arrayType(const Type& typeIndex, const Type& typeData)
00839 {
00840 return ::arrayType(typeIndex, typeData);
00841 }
00842
00843
00844 Type VCL::bitvecType(int n)
00845 {
00846 return d_theoryBitvector->newBitvectorType(n);
00847 }
00848
00849
00850 Type VCL::funType(const Type& typeDom, const Type& typeRan)
00851 {
00852 return typeDom.funType(typeRan);
00853 }
00854
00855
00856 Type VCL::funType(const vector<Type>& typeDom, const Type& typeRan) {
00857 DebugAssert(typeDom.size() >= 1, "VCL::funType: missing domain types");
00858 return Type::funType(typeDom, typeRan);
00859 }
00860
00861
00862 Type VCL::createType(const string& typeName)
00863 {
00864 if(d_dump) {
00865 d_translator->dump(Expr(TYPE, listExpr(idExpr(typeName))));
00866 }
00867 return d_theoryCore->newTypeExpr(typeName);
00868 }
00869
00870
00871 Type VCL::createType(const string& typeName, const Type& def)
00872 {
00873 if (d_dump) {
00874 d_translator->dump(Expr(TYPE, idExpr(typeName), def.getExpr()), true);
00875 }
00876 return d_theoryCore->newTypeExpr(typeName, def);
00877 }
00878
00879
00880 Type VCL::lookupType(const string& typeName)
00881 {
00882 return d_theoryCore->lookupTypeExpr(typeName);
00883 }
00884
00885
00886 Expr VCL::varExpr(const string& name, const Type& type)
00887 {
00888
00889 if(d_dump) {
00890 d_translator->dump(Expr(CONST, idExpr(name), type.getExpr()));
00891 }
00892 return d_theoryCore->newVar(name, type);
00893 }
00894
00895
00896 Expr VCL::varExpr(const string& name, const Type& type, const Expr& def)
00897 {
00898
00899 if(d_dump) {
00900 d_translator->dump(Expr(CONST, idExpr(name), type.getExpr(), def), true);
00901 }
00902
00903 if(getFlags()["tcc"].getBool()) {
00904 Type tpDef(def.getType()), tpVar(type);
00905
00906
00907 if(tpDef != tpVar) {
00908
00909 if(getBaseType(tpDef) != getBaseType(type)) {
00910 throw TypecheckException("Type mismatch in constant definition:\n"
00911 "Constant "+name+
00912 " is declared with type:\n "
00913 +type.toString()
00914 +"\nBut the type of definition is\n "
00915 +tpDef.toString());
00916 }
00917 TRACE("tccs", "CONST def: "+name+" : "+tpVar.toString()
00918 +" := <value> : ", tpDef, ";");
00919 vector<Expr> boundVars;
00920 boundVars.push_back(boundVarExpr(name, "tcc", tpDef));
00921 Expr body(boundVars[0].eqExpr(def).impExpr(getTypePred(tpVar, boundVars[0])));
00922 Expr quant(forallExpr(boundVars, body));
00923 try {
00924 checkTCC(quant);
00925 } catch(TypecheckException&) {
00926 throw TypecheckException
00927 ("Type mismatch in constant definition:\n"
00928 "Constant "+name+
00929 " is declared with type:\n "
00930 +type.toString()
00931 +"\nBut the type of definition is\n "
00932 +def.getType().toString()
00933 +"\n\n which is not a subtype of the constant");
00934 }
00935 }
00936 }
00937 return d_theoryCore->newVar(name, type, def);
00938 }
00939
00940
00941 Expr VCL::lookupVar(const string& name, Type* type)
00942 {
00943 return d_theoryCore->lookupVar(name, type);
00944 }
00945
00946
00947 Type VCL::getType(const Expr& e)
00948 {
00949 return e.getType();
00950 }
00951
00952
00953 Type VCL::getBaseType(const Expr& e)
00954 {
00955 return d_theoryCore->getBaseType(e);
00956 }
00957
00958
00959 Type VCL::getBaseType(const Type& t)
00960 {
00961 return d_theoryCore->getBaseType(t);
00962 }
00963
00964
00965 Expr VCL::getTypePred(const Type&t, const Expr& e)
00966 {
00967 return d_theoryCore->getTypePred(t, e);
00968 }
00969
00970
00971 Expr VCL::stringExpr(const string& str) {
00972 return getEM()->newStringExpr(str);
00973 }
00974
00975
00976 Expr VCL::idExpr(const string& name) {
00977 return Expr(ID, stringExpr(name));
00978 }
00979
00980
00981 Expr VCL::listExpr(const vector<Expr>& kids) {
00982 return Expr(RAW_LIST, kids, getEM());
00983 }
00984
00985
00986 Expr VCL::listExpr(const Expr& e1) {
00987 return Expr(RAW_LIST, e1);
00988 }
00989
00990
00991 Expr VCL::listExpr(const Expr& e1, const Expr& e2) {
00992 return Expr(RAW_LIST, e1, e2);
00993 }
00994
00995
00996 Expr VCL::listExpr(const Expr& e1, const Expr& e2, const Expr& e3) {
00997 return Expr(RAW_LIST, e1, e2, e3);
00998 }
00999
01000
01001 Expr VCL::listExpr(const string& op, const vector<Expr>& kids) {
01002 vector<Expr> newKids;
01003 newKids.push_back(idExpr(op));
01004 newKids.insert(newKids.end(), kids.begin(), kids.end());
01005 return listExpr(newKids);
01006 }
01007
01008
01009 Expr VCL::listExpr(const string& op, const Expr& e1) {
01010 return Expr(RAW_LIST, idExpr(op), e1);
01011 }
01012
01013
01014 Expr VCL::listExpr(const string& op, const Expr& e1,
01015 const Expr& e2) {
01016 return Expr(RAW_LIST, idExpr(op), e1, e2);
01017 }
01018
01019
01020 Expr VCL::listExpr(const string& op, const Expr& e1,
01021 const Expr& e2, const Expr& e3) {
01022 vector<Expr> kids;
01023 kids.push_back(idExpr(op));
01024 kids.push_back(e1);
01025 kids.push_back(e2);
01026 kids.push_back(e3);
01027 return listExpr(kids);
01028 }
01029
01030
01031 void VCL::printExpr(const Expr& e) {
01032 printExpr(e, cout);
01033 }
01034
01035
01036 void VCL::printExpr(const Expr& e, ostream& os) {
01037 os << e << endl;
01038 }
01039
01040
01041 Expr VCL::parseExpr(const Expr& e) {
01042 return d_theoryCore->parseExprTop(e);
01043 }
01044
01045
01046 Type VCL::parseType(const Expr& e) {
01047 return Type(d_theoryCore->parseExpr(e));
01048 }
01049
01050
01051 Expr VCL::importExpr(const Expr& e)
01052 {
01053 return d_em->rebuild(e);
01054 }
01055
01056
01057 Type VCL::importType(const Type& t)
01058 {
01059 return Type(d_em->rebuild(t.getExpr()));
01060 }
01061
01062 void VCL::cmdsFromString(const std::string& s, InputLanguage lang=PRESENTATION_LANG)
01063 {
01064 stringstream ss(s,stringstream::in);
01065 return loadFile(ss,lang,false);
01066 }
01067
01068 Expr VCL::exprFromString(const std::string& s)
01069 {
01070 stringstream ss("PRINT " + s + ";",stringstream::in);
01071 Parser p(this,PRESENTATION_LANG,ss);
01072 Expr e = p.next();
01073 if( e.isNull() ) {
01074 throw ParserException("Parser result is null: '" + s + "'");
01075 }
01076 DebugAssert(e.getKind() == RAW_LIST, "Expected list expression");
01077 DebugAssert(e.arity() == 2, "Expected two children");
01078 return parseExpr(e[1]);
01079 }
01080
01081 Expr VCL::trueExpr()
01082 {
01083 return d_em->trueExpr();
01084 }
01085
01086
01087 Expr VCL::falseExpr()
01088 {
01089 return d_em->falseExpr();
01090 }
01091
01092
01093 Expr VCL::notExpr(const Expr& child)
01094 {
01095 return !child;
01096 }
01097
01098
01099 Expr VCL::andExpr(const Expr& left, const Expr& right)
01100 {
01101 return left && right;
01102 }
01103
01104
01105 Expr VCL::andExpr(const vector<Expr>& children)
01106 {
01107 if (children.size() == 0)
01108 throw Exception("andExpr requires at least one child");
01109 return Expr(AND, children);
01110 }
01111
01112
01113 Expr VCL::orExpr(const Expr& left, const Expr& right)
01114 {
01115 return left || right;
01116 }
01117
01118
01119 Expr VCL::orExpr(const vector<Expr>& children)
01120 {
01121 if (children.size() == 0)
01122 throw Exception("orExpr requires at least one child");
01123 return Expr(OR, children);
01124 }
01125
01126
01127 Expr VCL::impliesExpr(const Expr& hyp, const Expr& conc)
01128 {
01129 return hyp.impExpr(conc);
01130 }
01131
01132
01133 Expr VCL::iffExpr(const Expr& left, const Expr& right)
01134 {
01135 return left.iffExpr(right);
01136 }
01137
01138
01139 Expr VCL::eqExpr(const Expr& child0, const Expr& child1)
01140 {
01141 return child0.eqExpr(child1);
01142 }
01143
01144 Expr VCL::distinctExpr(const std::vector<Expr>& children)
01145 {
01146 return Expr(DISTINCT, children);
01147 }
01148
01149 Expr VCL::iteExpr(const Expr& ifpart, const Expr& thenpart, const Expr& elsepart)
01150 {
01151 return ifpart.iteExpr(thenpart, elsepart);
01152 }
01153
01154
01155 Op VCL::createOp(const string& name, const Type& type)
01156 {
01157 if (!type.isFunction())
01158 throw Exception("createOp: expected function type");
01159 if(d_dump) {
01160 d_translator->dump(Expr(CONST, idExpr(name), type.getExpr()));
01161 }
01162 return d_theoryCore->newFunction(name, type,
01163 getFlags()["trans-closure"].getBool());
01164 }
01165
01166
01167 Op VCL::createOp(const string& name, const Type& type, const Expr& def)
01168 {
01169 if (!type.isFunction())
01170 throw TypecheckException
01171 ("Type error in createOp:\n"
01172 "Constant "+name+
01173 " is declared with type:\n "
01174 +type.toString()
01175 +"\n which is not a function type");
01176 if (getBaseType(type) != getBaseType(def.getType()))
01177 throw TypecheckException
01178 ("Type mismatch in createOp:\n"
01179 "Function "+name+
01180 " is declared with type:\n "
01181 +type.toString()
01182 +"\nBut the type of definition is\n "
01183 +def.getType().toString()
01184 +"\n\n which does not match");
01185 if(d_dump) {
01186 d_translator->dump(Expr(CONST, idExpr(name), type.getExpr(), def), true);
01187 }
01188
01189 if(getFlags()["tcc"].getBool()) {
01190 Type tpDef(def.getType());
01191
01192
01193 if(tpDef != type) {
01194 vector<Expr> boundVars;
01195 for (int i = 0; i < type.arity()-1; ++i) {
01196 boundVars.push_back(d_em->newBoundVarExpr(type[i]));
01197 }
01198 Expr app = Expr(def.mkOp(), boundVars);
01199 Expr body(getTypePred(type[type.arity()-1], app));
01200 Expr quant(forallExpr(boundVars, body));
01201 Expr tcc = quant.andExpr(d_theoryCore->getTCC(quant));
01202
01203 bool typesMatch = true;
01204 try {
01205 checkTCC(tcc);
01206 } catch (TypecheckException&) {
01207 typesMatch = false;
01208 }
01209 if(!typesMatch) {
01210 throw TypecheckException
01211 ("Type mismatch in createOp:\n"
01212 "Function "+name+
01213 " is declared with type:\n "
01214 +type.toString()
01215 +"\nBut the definition is\n "
01216 +def.toString()
01217 +"\n\nwhose type could not be proved to be a subtype");
01218 }
01219 }
01220 }
01221 return d_theoryCore->newFunction(name, type, def);
01222 }
01223
01224
01225 Op VCL::lookupOp(const string& name, Type* type)
01226 {
01227 return d_theoryCore->lookupFunction(name, type);
01228 }
01229
01230
01231 Expr VCL::funExpr(const Op& op, const Expr& child)
01232 {
01233 return Expr(op, child);
01234 }
01235
01236
01237 Expr VCL::funExpr(const Op& op, const Expr& left, const Expr& right)
01238 {
01239 return Expr(op, left, right);
01240 }
01241
01242
01243 Expr VCL::funExpr(const Op& op, const Expr& child0, const Expr& child1, const Expr& child2)
01244 {
01245 return Expr(op, child0, child1, child2);
01246 }
01247
01248
01249 Expr VCL::funExpr(const Op& op, const vector<Expr>& children)
01250 {
01251 return Expr(op, children);
01252 }
01253
01254 bool VCL::addPairToArithOrder(const Expr& smaller, const Expr& bigger)
01255 {
01256 if (d_dump) {
01257 d_translator->dump(Expr(ARITH_VAR_ORDER, smaller, bigger), true);
01258 }
01259 return d_theoryArith->addPairToArithOrder(smaller, bigger);
01260 }
01261
01262 Expr VCL::ratExpr(int n, int d)
01263 {
01264 DebugAssert(d != 0,"denominator cannot be 0");
01265 return d_em->newRatExpr(Rational(n,d));
01266 }
01267
01268
01269 Expr VCL::ratExpr(const string& n, const string& d, int base)
01270 {
01271 return d_em->newRatExpr(Rational(n.c_str(), d.c_str(), base));
01272 }
01273
01274
01275 Expr VCL::ratExpr(const string& n, int base)
01276 {
01277 string::size_type pos = n.rfind(".");
01278 if (pos == string::npos) {
01279 return d_em->newRatExpr(Rational(n.c_str(), base));
01280 }
01281 string afterdec = n.substr(pos+1);
01282 string beforedec = n.substr(0, pos);
01283 if (afterdec.size() == 0 || beforedec.size() == 0) {
01284 throw Exception("Cannot convert string to rational: "+n);
01285 }
01286 pos = beforedec.rfind(".");
01287 if (pos != string::npos) {
01288 throw Exception("Cannot convert string to rational: "+n);
01289 }
01290 Rational r = Rational(beforedec.c_str(), base);
01291 Rational fracPart = Rational(afterdec.c_str(), base);
01292 if( r < 0 ) {
01293 r = r - (fracPart / pow(afterdec.size(), base));
01294 }
01295 else {
01296 r = r + (fracPart / pow(afterdec.size(), base));
01297 }
01298 return d_em->newRatExpr(r);
01299 }
01300
01301
01302 Expr VCL::uminusExpr(const Expr& child)
01303 {
01304 return -child;
01305 }
01306
01307
01308 Expr VCL::plusExpr(const Expr& left, const Expr& right)
01309 {
01310 return left + right;
01311 }
01312
01313 Expr VCL::plusExpr(const std::vector<Expr>& children)
01314 {
01315 return Expr(PLUS, children);
01316 }
01317
01318
01319 Expr VCL::minusExpr(const Expr& left, const Expr& right)
01320 {
01321 return left - right;
01322 }
01323
01324
01325 Expr VCL::multExpr(const Expr& left, const Expr& right)
01326 {
01327 return left * right;
01328 }
01329
01330
01331 Expr VCL::powExpr(const Expr& x, const Expr& n)
01332 {
01333 return ::powExpr(n, x);
01334 }
01335
01336
01337 Expr VCL::divideExpr(const Expr& num, const Expr& denom)
01338 {
01339 return ::divideExpr(num,denom);
01340 }
01341
01342
01343 Expr VCL::ltExpr(const Expr& left, const Expr& right)
01344 {
01345 return ::ltExpr(left, right);
01346 }
01347
01348
01349 Expr VCL::leExpr(const Expr& left, const Expr& right)
01350 {
01351 return ::leExpr(left, right);
01352 }
01353
01354
01355 Expr VCL::gtExpr(const Expr& left, const Expr& right)
01356 {
01357 return ::gtExpr(left, right);
01358 }
01359
01360
01361 Expr VCL::geExpr(const Expr& left, const Expr& right)
01362 {
01363 return ::geExpr(left, right);
01364 }
01365
01366
01367 Expr VCL::recordExpr(const string& field, const Expr& expr)
01368 {
01369 vector<string> fields;
01370 vector<Expr> kids;
01371 kids.push_back(expr);
01372 fields.push_back(field);
01373 return d_theoryRecords->recordExpr(fields, kids);
01374 }
01375
01376
01377 Expr VCL::recordExpr(const string& field0, const Expr& expr0,
01378 const string& field1, const Expr& expr1)
01379 {
01380 vector<string> fields;
01381 vector<Expr> kids;
01382 fields.push_back(field0);
01383 fields.push_back(field1);
01384 kids.push_back(expr0);
01385 kids.push_back(expr1);
01386 sort2(fields, kids);
01387 return d_theoryRecords->recordExpr(fields, kids);
01388 }
01389
01390
01391 Expr VCL::recordExpr(const string& field0, const Expr& expr0,
01392 const string& field1, const Expr& expr1,
01393 const string& field2, const Expr& expr2)
01394 {
01395 vector<string> fields;
01396 vector<Expr> kids;
01397 fields.push_back(field0);
01398 fields.push_back(field1);
01399 fields.push_back(field2);
01400 kids.push_back(expr0);
01401 kids.push_back(expr1);
01402 kids.push_back(expr2);
01403 sort2(fields, kids);
01404 return d_theoryRecords->recordExpr(fields, kids);
01405 }
01406
01407
01408 Expr VCL::recordExpr(const vector<string>& fields,
01409 const vector<Expr>& exprs)
01410 {
01411 DebugAssert(fields.size() > 0, "VCL::recordExpr()");
01412 DebugAssert(fields.size() == exprs.size(),"VCL::recordExpr()");
01413
01414 vector<string> fs(fields);
01415 vector<Expr> es(exprs);
01416 sort2(fs, es);
01417 return d_theoryRecords->recordExpr(fs, es);
01418 }
01419
01420
01421 Expr VCL::recSelectExpr(const Expr& record, const string& field)
01422 {
01423 return d_theoryRecords->recordSelect(record, field);
01424 }
01425
01426
01427 Expr VCL::recUpdateExpr(const Expr& record, const string& field,
01428 const Expr& newValue)
01429 {
01430 return d_theoryRecords->recordUpdate(record, field, newValue);
01431 }
01432
01433
01434 Expr VCL::readExpr(const Expr& array, const Expr& index)
01435 {
01436 return Expr(READ, array, index);
01437 }
01438
01439
01440 Expr VCL::writeExpr(const Expr& array, const Expr& index, const Expr& newValue)
01441 {
01442 return Expr(WRITE, array, index, newValue);
01443 }
01444
01445
01446 Expr VCL::newBVConstExpr(const std::string& s, int base)
01447 {
01448 return d_theoryBitvector->newBVConstExpr(s, base);
01449 }
01450
01451
01452 Expr VCL::newBVConstExpr(const std::vector<bool>& bits)
01453 {
01454 return d_theoryBitvector->newBVConstExpr(bits);
01455 }
01456
01457
01458 Expr VCL::newBVConstExpr(const Rational& r, int len)
01459 {
01460 return d_theoryBitvector->newBVConstExpr(r, len);
01461 }
01462
01463
01464 Expr VCL::newConcatExpr(const Expr& t1, const Expr& t2)
01465 {
01466 return d_theoryBitvector->newConcatExpr(t1, t2);
01467 }
01468
01469
01470 Expr VCL::newConcatExpr(const std::vector<Expr>& kids)
01471 {
01472 return d_theoryBitvector->newConcatExpr(kids);
01473 }
01474
01475
01476 Expr VCL::newBVExtractExpr(const Expr& e, int hi, int low)
01477 {
01478 return d_theoryBitvector->newBVExtractExpr(e, hi, low);
01479 }
01480
01481
01482 Expr VCL::newBVNegExpr(const Expr& t1)
01483 {
01484 return d_theoryBitvector->newBVNegExpr(t1);
01485 }
01486
01487
01488 Expr VCL::newBVAndExpr(const Expr& t1, const Expr& t2)
01489 {
01490 return d_theoryBitvector->newBVAndExpr(t1, t2);
01491 }
01492
01493
01494 Expr VCL::newBVAndExpr(const std::vector<Expr>& kids)
01495 {
01496 return d_theoryBitvector->newBVAndExpr(kids);
01497 }
01498
01499
01500 Expr VCL::newBVOrExpr(const Expr& t1, const Expr& t2)
01501 {
01502 return d_theoryBitvector->newBVOrExpr(t1, t2);
01503 }
01504
01505
01506 Expr VCL::newBVOrExpr(const std::vector<Expr>& kids)
01507 {
01508 return d_theoryBitvector->newBVOrExpr(kids);
01509 }
01510
01511
01512 Expr VCL::newBVXorExpr(const Expr& t1, const Expr& t2)
01513 {
01514 return d_theoryBitvector->newBVXorExpr(t1, t2);
01515 }
01516
01517
01518 Expr VCL::newBVXorExpr(const std::vector<Expr>& kids)
01519 {
01520 return d_theoryBitvector->newBVXorExpr(kids);
01521 }
01522
01523
01524 Expr VCL::newBVXnorExpr(const Expr& t1, const Expr& t2)
01525 {
01526 return d_theoryBitvector->newBVXnorExpr(t1, t2);
01527 }
01528
01529
01530 Expr VCL::newBVXnorExpr(const std::vector<Expr>& kids)
01531 {
01532 return d_theoryBitvector->newBVXnorExpr(kids);
01533 }
01534
01535
01536 Expr VCL::newBVNandExpr(const Expr& t1, const Expr& t2)
01537 {
01538 return d_theoryBitvector->newBVNandExpr(t1, t2);
01539 }
01540
01541
01542 Expr VCL::newBVNorExpr(const Expr& t1, const Expr& t2)
01543 {
01544 return d_theoryBitvector->newBVNorExpr(t1, t2);
01545 }
01546
01547
01548 Expr VCL::newBVCompExpr(const Expr& t1, const Expr& t2)
01549 {
01550 return d_theoryBitvector->newBVCompExpr(t1, t2);
01551 }
01552
01553
01554 Expr VCL::newBVLTExpr(const Expr& t1, const Expr& t2)
01555 {
01556 return d_theoryBitvector->newBVLTExpr(t1, t2);
01557 }
01558
01559
01560 Expr VCL::newBVLEExpr(const Expr& t1, const Expr& t2)
01561 {
01562 return d_theoryBitvector->newBVLEExpr(t1, t2);
01563 }
01564
01565
01566 Expr VCL::newBVSLTExpr(const Expr& t1, const Expr& t2)
01567 {
01568 return d_theoryBitvector->newBVSLTExpr(t1, t2);
01569 }
01570
01571
01572 Expr VCL::newBVSLEExpr(const Expr& t1, const Expr& t2)
01573 {
01574 return d_theoryBitvector->newBVSLEExpr(t1, t2);
01575 }
01576
01577
01578 Expr VCL::newSXExpr(const Expr& t1, int len)
01579 {
01580 return d_theoryBitvector->newSXExpr(t1, len);
01581 }
01582
01583
01584 Expr VCL::newBVUminusExpr(const Expr& t1)
01585 {
01586 return d_theoryBitvector->newBVUminusExpr(t1);
01587 }
01588
01589
01590 Expr VCL::newBVSubExpr(const Expr& t1, const Expr& t2)
01591 {
01592 return d_theoryBitvector->newBVSubExpr(t1, t2);
01593 }
01594
01595
01596 Expr VCL::newBVPlusExpr(int numbits, const std::vector<Expr>& k)
01597 {
01598 return d_theoryBitvector->newBVPlusPadExpr(numbits, k);
01599 }
01600
01601 Expr VCL::newBVPlusExpr(int numbits, const Expr& t1, const Expr& t2)
01602 {
01603 std::vector<Expr> k;
01604 k.push_back(t1);
01605 k.push_back(t2);
01606 return newBVPlusExpr(numbits, k);
01607 }
01608
01609
01610 Expr VCL::newBVMultExpr(int numbits, const Expr& t1, const Expr& t2)
01611 {
01612 return d_theoryBitvector->newBVMultPadExpr(numbits, t1, t2);
01613 }
01614
01615 Expr VCL::newBVUDivExpr(const Expr& t1, const Expr& t2)
01616 {
01617 return d_theoryBitvector->newBVUDivExpr(t1, t2);
01618 }
01619
01620 Expr VCL::newBVURemExpr(const Expr& t1, const Expr& t2)
01621 {
01622 return d_theoryBitvector->newBVURemExpr(t1, t2);
01623 }
01624
01625 Expr VCL::newBVSDivExpr(const Expr& t1, const Expr& t2)
01626 {
01627 return d_theoryBitvector->newBVSDivExpr(t1, t2);
01628 }
01629
01630 Expr VCL::newBVSRemExpr(const Expr& t1, const Expr& t2)
01631 {
01632 return d_theoryBitvector->newBVSRemExpr(t1, t2);
01633 }
01634
01635 Expr VCL::newBVSModExpr(const Expr& t1, const Expr& t2)
01636 {
01637 return d_theoryBitvector->newBVSModExpr(t1, t2);
01638 }
01639
01640
01641 Expr VCL::newFixedLeftShiftExpr(const Expr& t1, int r)
01642 {
01643 return d_theoryBitvector->newFixedLeftShiftExpr(t1, r);
01644 }
01645
01646
01647 Expr VCL::newFixedConstWidthLeftShiftExpr(const Expr& t1, int r)
01648 {
01649 return d_theoryBitvector->newFixedConstWidthLeftShiftExpr(t1, r);
01650 }
01651
01652
01653 Expr VCL::newFixedRightShiftExpr(const Expr& t1, int r)
01654 {
01655 return d_theoryBitvector->newFixedRightShiftExpr(t1, r);
01656 }
01657
01658
01659 Rational VCL::computeBVConst(const Expr& e)
01660 {
01661 return d_theoryBitvector->computeBVConst(e);
01662 }
01663
01664
01665 Expr VCL::tupleExpr(const vector<Expr>& exprs) {
01666 DebugAssert(exprs.size() > 0, "VCL::tupleExpr()");
01667 return d_theoryRecords->tupleExpr(exprs);
01668 }
01669
01670
01671 Expr VCL::tupleSelectExpr(const Expr& tuple, int index)
01672 {
01673 return d_theoryRecords->tupleSelect(tuple, index);
01674 }
01675
01676
01677 Expr VCL::tupleUpdateExpr(const Expr& tuple, int index, const Expr& newValue)
01678 {
01679 return d_theoryRecords->tupleUpdate(tuple, index, newValue);
01680 }
01681
01682
01683 Expr VCL::datatypeConsExpr(const string& constructor, const vector<Expr>& args)
01684 {
01685 return d_theoryDatatype->datatypeConsExpr(constructor, args);
01686 }
01687
01688
01689 Expr VCL::datatypeSelExpr(const string& selector, const Expr& arg)
01690 {
01691 return d_theoryDatatype->datatypeSelExpr(selector, arg);
01692 }
01693
01694
01695 Expr VCL::datatypeTestExpr(const string& constructor, const Expr& arg)
01696 {
01697 return d_theoryDatatype->datatypeTestExpr(constructor, arg);
01698 }
01699
01700
01701 Expr VCL::boundVarExpr(const string& name, const string& uid,
01702 const Type& type) {
01703 return d_em->newBoundVarExpr(name, uid, type);
01704 }
01705
01706
01707 Expr VCL::forallExpr(const vector<Expr>& vars, const Expr& body) {
01708 DebugAssert(vars.size() > 0, "VCL::foralLExpr()");
01709 return d_em->newClosureExpr(FORALL, vars, body);
01710 }
01711
01712 Expr VCL::forallExpr(const vector<Expr>& vars, const Expr& body,
01713 const vector<vector<Expr> >& triggers) {
01714 DebugAssert(vars.size() > 0, "VCL::foralLExpr()");
01715 return d_em->newClosureExpr(FORALL, vars, body, triggers);
01716 }
01717
01718 void VCL::setTriggers(const Expr& e, const std::vector< std::vector<Expr> >& triggers) {
01719 e.setTriggers(triggers);
01720 }
01721
01722
01723 Expr VCL::existsExpr(const vector<Expr>& vars, const Expr& body) {
01724 return d_em->newClosureExpr(EXISTS, vars, body);
01725 }
01726
01727
01728 Op VCL::lambdaExpr(const vector<Expr>& vars, const Expr& body) {
01729 return d_em->newClosureExpr(LAMBDA, vars, body).mkOp();
01730 }
01731
01732 Op VCL::transClosure(const Op& op) {
01733 const string& name = op.getExpr().getName();
01734 return d_em->newSymbolExpr(name, TRANS_CLOSURE).mkOp();
01735 }
01736
01737
01738 Expr VCL::simulateExpr(const Expr& f, const Expr& s0,
01739 const vector<Expr>& inputs, const Expr& n) {
01740 vector<Expr> kids;
01741 kids.push_back(f);
01742 kids.push_back(s0);
01743 kids.insert(kids.end(), inputs.begin(), inputs.end());
01744 kids.push_back(n);
01745 return Expr(SIMULATE, kids);
01746 }
01747
01748
01749 void VCL::setResourceLimit(unsigned limit)
01750 {
01751 d_theoryCore->setResourceLimit(limit);
01752 }
01753
01754
01755 Theorem VCL::checkTCC(const Expr& tcc)
01756 {
01757 Theorem tccThm;
01758 d_se->push();
01759 QueryResult res = d_se->checkValid(tcc, tccThm);
01760 switch (res) {
01761 case VALID:
01762 d_lastQueryTCC = tccThm;
01763 d_se->pop();
01764 break;
01765 case INVALID:
01766 throw TypecheckException("Failed TCC:\n\n "
01767 +tcc.toString()
01768 +"\n\nWhich simplified to:\n\n "
01769 +simplify(tcc).toString()
01770 +"\n\nAnd the last formula is not valid "
01771 "in the current context.");
01772 case ABORT:
01773 throw TypecheckException("Budget exceeded:\n\n "
01774 "Unable to verify TCC:\n\n "
01775 +tcc.toString()
01776 +"\n\nWhich simplified to:\n\n "
01777 +simplify(tcc).toString());
01778 case UNKNOWN:
01779 throw TypecheckException("Result unknown:\n\n "
01780 "Unable to verify TCC:\n\n "
01781 +tcc.toString()
01782 +"\n\nWhich simplified to:\n\n "
01783 +simplify(tcc).toString()
01784 +"\n\nAnd the last formula is unknown "
01785 "in the current context.");
01786 default:
01787 FatalAssert(false, "Unexpected case");
01788 }
01789 return tccThm;
01790 }
01791
01792
01793 void VCL::assertFormula(const Expr& e)
01794 {
01795
01796 if(!e.getType().isBool()) {
01797 throw TypecheckException("Non-BOOLEAN formula in ASSERT:\n "
01798 +Expr(ASSERT, e).toString()
01799 +"\nDerived type of the formula:\n "
01800 +e.getType().toString());
01801 }
01802
01803 if (getFlags()["pp-batch"].getBool()) {
01804 d_batchedAssertions->push_back(e);
01805 }
01806 else {
01807
01808 if(d_dump) {
01809 Expr e2 = e;
01810 if (getFlags()["preSimplify"].getBool()) {
01811 e2 = simplify(e);
01812 }
01813 if (d_translator->dumpAssertion(e2)) return;
01814 }
01815
01816 TRACE("vclassertFormula", "VCL::assertFormula(", e, ") {");
01817
01818
01819 if(d_userAssertions->count(e) > 0) {
01820 TRACE_MSG("vclassertFormula", "VCL::assertFormula[repeated assertion] => }");
01821 return;
01822 }
01823
01824 Theorem tccThm;
01825 if(getFlags()["tcc"].getBool()) {
01826 Expr tcc(d_theoryCore->getTCC(e));
01827 tccThm = checkTCC(tcc);
01828 }
01829
01830 Theorem thm = d_se->newUserAssumption(e);
01831 (*d_userAssertions)[e] = UserAssertion(thm, tccThm, d_nextIdx++);
01832 }
01833 TRACE_MSG("vclassertFormula", "VCL::assertFormula => }");
01834 }
01835
01836
01837 void VCL::registerAtom(const Expr& e)
01838 {
01839
01840 d_se->registerAtom(e);
01841 }
01842
01843
01844 Expr VCL::getImpliedLiteral()
01845 {
01846
01847 Theorem thm = d_se->getImpliedLiteral();
01848 if (thm.isNull()) return Expr();
01849 return thm.getExpr();
01850 }
01851
01852
01853 Expr VCL::simplify(const Expr& e) {
01854
01855 return simplifyThm(e).getRHS();
01856 }
01857
01858
01859 Theorem VCL::simplifyThm(const Expr& e)
01860 {
01861 e.getType();
01862 Theorem res = d_theoryCore->getExprTrans()->preprocess(e);
01863 Theorem simpThm = d_theoryCore->simplify(res.getRHS());
01864 res = d_theoryCore->transitivityRule(res, simpThm);
01865 return res;
01866 }
01867
01868
01869 QueryResult VCL::query(const Expr& e)
01870 {
01871 TRACE("query", "VCL::query(", e,") {");
01872
01873 if(!e.getType().isBool()) {
01874 throw TypecheckException("Non-BOOLEAN formula in QUERY:\n "
01875 +Expr(QUERY, e).toString()
01876 +"\nDerived type of the formula:\n "
01877 +e.getType().toString());
01878 }
01879
01880 Expr qExpr = e;
01881 if (getFlags()["pp-batch"].getBool()) {
01882
01883 vector<Expr> kids;
01884 for (; (*d_batchedAssertionsIdx) < d_batchedAssertions->size();
01885 (*d_batchedAssertionsIdx) = (*d_batchedAssertionsIdx) + 1) {
01886 kids.push_back((*d_batchedAssertions)[(*d_batchedAssertionsIdx)]);
01887 }
01888 if (kids.size() > 0) {
01889 qExpr = kids.size() == 1 ? kids[0] : Expr(AND, kids);
01890 qExpr = qExpr.impExpr(e);
01891 }
01892 }
01893
01894 if (d_dump && !getFlags()["dump-tcc"].getBool()) {
01895 Expr e2 = qExpr;
01896 if (getFlags()["preSimplify"].getBool()) {
01897 e2 = simplify(qExpr);
01898 }
01899 if (d_translator->dumpQuery(e2)) return UNKNOWN;
01900 }
01901
01902
01903 Theorem tccThm = d_se->getCommonRules()->trueTheorem();
01904 if(getFlags()["tcc"].getBool()) {
01905 Expr tcc(d_theoryCore->getTCC(qExpr));
01906 if (getFlags()["dump-tcc"].getBool()) {
01907 Expr e2 = tcc;
01908 if (getFlags()["preSimplify"].getBool()) {
01909 e2 = simplify(tcc);
01910 }
01911 if (d_translator->dumpQuery(e2)) return UNKNOWN;
01912 }
01913
01914 tccThm = checkTCC(tcc);
01915 }
01916 Theorem res;
01917 QueryResult qres = d_se->checkValid(qExpr, res);
01918 switch (qres) {
01919 case VALID:
01920 d_lastQuery = d_se->getCommonRules()->queryTCC(res, tccThm);
01921 break;
01922 default:
01923 d_lastQueryTCC = Theorem();
01924 d_lastQuery = Theorem3();
01925 d_lastClosure = Theorem3();
01926 }
01927 TRACE("query", "VCL::query => ",
01928 qres == VALID ? "VALID" :
01929 qres == INVALID ? "INVALID" :
01930 qres == ABORT ? "ABORT" : "UNKNOWN", " }");
01931
01932 if (d_dump) d_translator->dumpQueryResult(qres);
01933
01934 return qres;
01935 }
01936
01937
01938 QueryResult VCL::checkUnsat(const Expr& e)
01939 {
01940 return query(e.negate());
01941 }
01942
01943
01944 QueryResult VCL::checkContinue()
01945 {
01946 if(d_dump) {
01947 d_translator->dump(d_em->newLeafExpr(CONTINUE), true);
01948 }
01949 vector<Expr> assertions;
01950 d_se->getCounterExample(assertions);
01951 Theorem thm;
01952 if (assertions.size() == 0) {
01953 return d_se->restart(falseExpr(), thm);
01954 }
01955 Expr eAnd = assertions.size() == 1 ? assertions[0] : andExpr(assertions);
01956 return d_se->restart(!eAnd, thm);
01957 }
01958
01959
01960 QueryResult VCL::restart(const Expr& e)
01961 {
01962 if (d_dump) {
01963 d_translator->dump(Expr(RESTART, e), true);
01964 }
01965 Theorem thm;
01966 return d_se->restart(e, thm);
01967 }
01968
01969
01970 void VCL::returnFromCheck()
01971 {
01972
01973 d_se->returnFromCheck();
01974 }
01975
01976
01977 void VCL::getUserAssumptions(vector<Expr>& assumptions)
01978 {
01979
01980 d_se->getUserAssumptions(assumptions);
01981 }
01982
01983
01984 void VCL::getInternalAssumptions(vector<Expr>& assumptions)
01985 {
01986
01987 d_se->getInternalAssumptions(assumptions);
01988 }
01989
01990
01991 void VCL::getAssumptions(vector<Expr>& assumptions)
01992 {
01993 if(d_dump) {
01994 d_translator->dump(d_em->newLeafExpr(ASSUMPTIONS), true);
01995 }
01996 d_se->getAssumptions(assumptions);
01997 }
01998
01999
02000
02001 Expr VCL::getProofQuery()
02002 {
02003 if (d_lastQuery.isNull()){
02004 throw EvalException
02005 ("Invalid Query,n");
02006 }
02007 return d_lastQuery.getExpr();
02008
02009
02010
02011
02012 }
02013
02014
02015 void VCL::getAssumptionsUsed(vector<Expr>& assumptions)
02016 {
02017 throw EvalException ("getAssumptionsUsed not currently supported");
02018 if(d_dump) {
02019 d_translator->dump(d_em->newLeafExpr(DUMP_ASSUMPTIONS), true);
02020 }
02021 Theorem thm = d_se->lastThm();
02022 if (thm.isNull()) return;
02023 thm.getLeafAssumptions(assumptions);
02024 }
02025
02026
02027 void VCL::getCounterExample(vector<Expr>& assertions, bool inOrder)
02028 {
02029 if(d_dump) {
02030 d_translator->dump(d_em->newLeafExpr(COUNTEREXAMPLE), true);
02031 }
02032 if (!(*d_flags)["translate"].getBool())
02033 d_se->getCounterExample(assertions, inOrder);
02034 }
02035
02036
02037 void VCL::getConcreteModel(ExprMap<Expr> & m)
02038 {
02039 if(d_dump) {
02040 d_translator->dump(d_em->newLeafExpr(COUNTERMODEL), true);
02041 }
02042 if (!(*d_flags)["translate"].getBool())
02043 d_se->getConcreteModel(m);
02044 }
02045
02046 QueryResult VCL::tryModelGeneration() {
02047 if (!d_theoryCore->incomplete()) throw Exception("Model generation should be called only after an UNKNOWN result");
02048 QueryResult qres = UNKNOWN;
02049 int scopeLevel = d_cm->scopeLevel();
02050 try {
02051 while (qres == UNKNOWN)
02052 {
02053 Theorem thm;
02054 d_se->push();
02055
02056 if (d_se->tryModelGeneration(thm))
02057
02058 qres = INVALID;
02059 else
02060 {
02061
02062 vector<Expr> assumptions;
02063 thm.getLeafAssumptions(assumptions, true );
02064 if (!thm.getExpr().isFalse()) assumptions.push_back(thm.getExpr());
02065
02066 while (d_cm->scopeLevel() > scopeLevel) d_se->pop();
02067
02068 qres = restart(orExpr(assumptions));
02069
02070 scopeLevel = d_cm->scopeLevel();
02071 }
02072 }
02073 } catch (Exception& e) {
02074
02075 while (d_cm->scopeLevel() > scopeLevel) d_se->pop();
02076 }
02077 return qres;
02078 }
02079
02080 FormulaValue VCL::value(const Expr& e) {
02081 DebugAssert(!e.isTerm(), "vcl::value: e is not a formula");
02082 return d_se->getValue(e);
02083 }
02084
02085 bool VCL::inconsistent(vector<Expr>& assumptions)
02086 {
02087
02088 if (d_theoryCore->inconsistent()) {
02089
02090 getAssumptions(d_theoryCore->inconsistentThm().getAssumptionsRef(),
02091 assumptions);
02092 return true;
02093 }
02094 return false;
02095 }
02096
02097 bool VCL::inconsistent()
02098 {
02099 return d_theoryCore->inconsistent();
02100 }
02101
02102
02103 bool VCL::incomplete() {
02104
02105
02106 return (d_lastQuery.isNull() && d_theoryCore->incomplete());
02107 }
02108
02109
02110 bool VCL::incomplete(vector<string>& reasons) {
02111
02112
02113 return (d_lastQuery.isNull() && d_theoryCore->incomplete(reasons));
02114 }
02115
02116
02117 Proof VCL::getProof()
02118 {
02119 if(d_dump) {
02120 d_translator->dump(d_em->newLeafExpr(DUMP_PROOF), true);
02121 }
02122
02123 if(d_lastQuery.isNull())
02124 throw EvalException
02125 ("Method getProof() (or command DUMP_PROOF)\n"
02126 " must be called only after a Valid QUERY");
02127 return d_se->getProof();
02128 }
02129
02130
02131 Expr VCL::getTCC(){
02132 static Expr null;
02133 if(d_dump) {
02134 d_translator->dump(d_em->newLeafExpr(DUMP_TCC), true);
02135 }
02136 if(d_lastQueryTCC.isNull()) return null;
02137 else return d_lastQueryTCC.getExpr();
02138 }
02139
02140
02141 void VCL::getAssumptionsTCC(vector<Expr>& assumptions)
02142 {
02143 if(d_dump) {
02144 d_translator->dump(d_em->newLeafExpr(DUMP_TCC_ASSUMPTIONS), true);
02145 }
02146 if(d_lastQuery.isNull())
02147 throw EvalException
02148 ("Method getAssumptionsTCC() (or command DUMP_TCC_ASSUMPTIONS)\n"
02149 " must be called only after a Valid QUERY");
02150 getAssumptions(d_lastQueryTCC.getAssumptionsRef(), assumptions);
02151 }
02152
02153
02154 Proof VCL::getProofTCC() {
02155 static Proof null;
02156 if(d_dump) {
02157 d_translator->dump(d_em->newLeafExpr(DUMP_TCC_PROOF), true);
02158 }
02159 if(d_lastQueryTCC.isNull()) return null;
02160 else return d_lastQueryTCC.getProof();
02161 }
02162
02163
02164 Expr VCL::getClosure() {
02165 static Expr null;
02166 if(d_dump) {
02167 d_translator->dump(d_em->newLeafExpr(DUMP_CLOSURE), true);
02168 }
02169 if(d_lastClosure.isNull() && !d_lastQuery.isNull()) {
02170
02171 d_lastClosure = deriveClosure(d_lastQuery);
02172 }
02173 if(d_lastClosure.isNull()) return null;
02174 else return d_lastClosure.getExpr();
02175 }
02176
02177
02178 Proof VCL::getProofClosure() {
02179 static Proof null;
02180 if(d_dump) {
02181 d_translator->dump(d_em->newLeafExpr(DUMP_CLOSURE_PROOF), true);
02182 }
02183 if(d_lastClosure.isNull() && !d_lastQuery.isNull()) {
02184
02185 d_lastClosure = deriveClosure(d_lastQuery);
02186 }
02187 if(d_lastClosure.isNull()) return null;
02188 else return d_lastClosure.getProof();
02189 }
02190
02191
02192 int VCL::stackLevel()
02193 {
02194 return d_stackLevel->get();
02195 }
02196
02197
02198 void VCL::push()
02199 {
02200 if(d_dump) {
02201 d_translator->dump(d_em->newLeafExpr(PUSH), true);
02202 }
02203 d_se->push();
02204 d_stackLevel->set(stackLevel()+1);
02205 }
02206
02207
02208 void VCL::pop()
02209 {
02210 if(d_dump) {
02211 d_translator->dump(d_em->newLeafExpr(POP), true);
02212 }
02213 if (stackLevel() == 0) {
02214 throw EvalException
02215 ("POP called with no previous call to PUSH");
02216 }
02217 int level = stackLevel();
02218 while (level == stackLevel())
02219 d_se->pop();
02220 }
02221
02222
02223 void VCL::popto(int toLevel)
02224 {
02225
02226 if(d_dump) {
02227 d_translator->dump(Expr(POPTO, ratExpr(toLevel, 1)), true);
02228 }
02229 if (toLevel < 0) toLevel = 0;
02230 while (stackLevel() > toLevel) {
02231 d_se->pop();
02232 }
02233 }
02234
02235
02236 int VCL::scopeLevel()
02237 {
02238 return d_cm->scopeLevel();
02239 }
02240
02241
02242 void VCL::pushScope()
02243 {
02244 throw EvalException ("Scope-level push/pop is no longer supported");
02245 d_cm->push();
02246 if(d_dump) {
02247 d_translator->dump(d_em->newLeafExpr(PUSH_SCOPE), true);
02248 }
02249 IF_DEBUG(if((*d_flags)["dump-trace"].getString() != "")
02250 dumpTrace(scopeLevel());)
02251 }
02252
02253
02254 void VCL::popScope()
02255 {
02256 throw EvalException ("Scope-level push/pop is no longer supported");
02257 if(d_dump) {
02258 d_translator->dump(d_em->newLeafExpr(POP_SCOPE), true);
02259 }
02260 if (scopeLevel() == 1) {
02261 cout << "Cannot POP from scope level 1" << endl;
02262 }
02263 else d_cm->pop();
02264 IF_DEBUG(if((*d_flags)["dump-trace"].getString() != "")
02265 dumpTrace(scopeLevel());)
02266 }
02267
02268
02269 void VCL::poptoScope(int toLevel)
02270 {
02271 throw EvalException ("Scope-level push/pop is no longer supported");
02272 if(d_dump) {
02273 d_translator->dump(Expr(POPTO_SCOPE, ratExpr(toLevel, 1)), true);
02274 }
02275 if (toLevel < 1) {
02276 d_cm->popto(0);
02277 d_cm->push();
02278 }
02279 else d_cm->popto(toLevel);
02280 IF_DEBUG(if((*d_flags)["dump-trace"].getString() != "")
02281 dumpTrace(scopeLevel());)
02282 }
02283
02284
02285 Context* VCL::getCurrentContext()
02286 {
02287 return d_cm->getCurrentContext();
02288 }
02289
02290
02291 void VCL::reset()
02292 {
02293 destroy();
02294 init();
02295 }
02296
02297 void VCL::loadFile(const string& fileName, InputLanguage lang,
02298 bool interactive, bool calledFromParser) {
02299
02300 Parser parser(this, lang, interactive, fileName);
02301 VCCmd cmd(this, &parser, calledFromParser);
02302 cmd.processCommands();
02303 }
02304
02305
02306 void VCL::loadFile(istream& is, InputLanguage lang,
02307 bool interactive) {
02308
02309 Parser parser(this, lang, is, interactive);
02310 VCCmd cmd(this, &parser);
02311 cmd.processCommands();
02312 }
02313
02314
02315
02316
02317
02318
02319 unsigned long VCL::getMemory(int verbosity)
02320 {
02321 unsigned long memSelf = sizeof(VCL);
02322 unsigned long mem = 0;
02323
02324 mem += d_cm->getMemory(verbosity - 1);
02325 mem += d_em->getMemory(verbosity - 1);
02326
02327
02328
02329
02330
02331
02332
02333
02334
02335
02336
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348
02349
02350
02351 MemoryTracker::print("VCL", verbosity, memSelf, mem);
02352
02353 return mem + memSelf;
02354 }
02355
02356 void VCL::setTimeLimit(unsigned limit) {
02357 d_theoryCore->setTimeLimit(limit);
02358 }