00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "expr_manager.h"
00022 #include "command_line_flags.h"
00023 #include "expr_stream.h"
00024 #include "pretty_printer.h"
00025 #include "memory_manager_malloc.h"
00026 #include "memory_manager_chunks.h"
00027
00028 using namespace CVC3;
00029
00030 using namespace std;
00031
00032
00033
00034 static void registerKinds(ExprManager& em);
00035
00036 void ExprManager::installExprValue(ExprValue* p_ev)
00037 {
00038 DebugAssert(isActive(), "ExprManager::installExprValue(ExprValue*)");
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065 d_exprSet.insert(p_ev);
00066 }
00067
00068
00069
00070 ExprManager::ExprManager(ContextManager* cm, const CLFlags& flags)
00071
00072 : d_cm(cm), d_index(0), d_flagCounter(1), d_prettyPrinter(NULL),
00073 d_printDepth(&(flags["print-depth"].getInt())),
00074 d_withIndentation(&(flags["indent"].getBool())),
00075 d_indent(0), d_indentTransient(0),
00076 d_lineWidth(&(flags["width"].getInt())),
00077 d_inputLang(&(flags["lang"].getString())),
00078 d_outputLang(&(flags["output-lang"].getString())),
00079 d_dagPrinting(&(flags["dagify-exprs"].getBool())),
00080 d_mmFlag(flags["mm"].getString()),
00081 d_exprSet(1024, HashEV(this), EqEV()),
00082 d_mm(EXPR_VALUE_TYPE_LAST),
00083 d_simpCacheTagCurrent(1), d_disableGC(false), d_postponeGC(false),
00084 d_inGC(false), d_typeComputer(NULL)
00085 {
00086
00087 d_notifyObj = new ExprManagerNotifyObj(this, d_cm->getCurrentContext());
00088
00089
00090 if(d_mmFlag == "chunks") {
00091 d_mm[EXPR_VALUE] = new MemoryManagerChunks(sizeof(ExprValue));
00092 d_mm[EXPR_NODE] = new MemoryManagerChunks(sizeof(ExprNode));
00093 d_mm[EXPR_APPLY] = new MemoryManagerChunks(sizeof(ExprApply));
00094 d_mm[EXPR_STRING] = new MemoryManagerChunks(sizeof(ExprString));
00095 d_mm[EXPR_RATIONAL] = new MemoryManagerChunks(sizeof(ExprRational));
00096 d_mm[EXPR_UCONST] = new MemoryManagerChunks(sizeof(ExprVar));
00097 d_mm[EXPR_SYMBOL] = new MemoryManagerChunks(sizeof(ExprSymbol));
00098 d_mm[EXPR_BOUND_VAR] = new MemoryManagerChunks(sizeof(ExprBoundVar));
00099 d_mm[EXPR_CLOSURE] = new MemoryManagerChunks(sizeof(ExprClosure));
00100 d_mm[EXPR_SKOLEM] = new MemoryManagerChunks(sizeof(ExprSkolem));
00101 } else {
00102 d_mm[EXPR_VALUE] = new MemoryManagerMalloc();
00103 d_mm[EXPR_NODE] = new MemoryManagerMalloc();
00104 d_mm[EXPR_APPLY] = new MemoryManagerMalloc();
00105 d_mm[EXPR_STRING] = new MemoryManagerMalloc();
00106 d_mm[EXPR_RATIONAL] = new MemoryManagerMalloc();
00107 d_mm[EXPR_UCONST] = new MemoryManagerMalloc();
00108 d_mm[EXPR_SYMBOL] = new MemoryManagerMalloc();
00109 d_mm[EXPR_BOUND_VAR] = new MemoryManagerMalloc();
00110 d_mm[EXPR_CLOSURE] = new MemoryManagerMalloc();
00111 d_mm[EXPR_SKOLEM] = new MemoryManagerMalloc();
00112 }
00113 registerKinds(*this);
00114
00115 d_bool = newLeafExpr(BOOLEAN);
00116 d_false = newLeafExpr(FALSE_EXPR);
00117 d_false.setType(Type::typeBool(this));
00118 d_true = newLeafExpr(TRUE_EXPR);
00119 d_true.setType(Type::typeBool(this));
00120
00121 IF_DEBUG(d_inRebuild = false;)
00122 }
00123
00124
00125 ExprManager::~ExprManager() {
00126 FatalAssert(d_emptyVec.size()==0, "~ExprManager()");
00127 delete d_notifyObj;
00128
00129 d_disableGC = false;
00130 clear();
00131 d_disableGC = true;
00132
00133 TRACE_MSG("delete", "~ExprManager: deleting d_mm's {");
00134 for(size_t i=0; i<d_mm.size(); ++i)
00135 delete d_mm[i];
00136
00137 TRACE_MSG("delete", "~ExprManager: finished deleting d_mm's }");
00138 }
00139
00140
00141 void ExprManager::clear() {
00142 FatalAssert(isActive(), "ExprManager::clear()");
00143
00144
00145 d_disableGC = true;
00146
00147 TRACE("delete", "clear: number of remaining Exprs: ",
00148 d_exprSet.size(), flush);
00149
00150 FatalAssert(d_nullExpr.isNull(), "ExprManager::clear()");
00151
00152
00153 d_bool = Expr();
00154 d_false = Expr();
00155 d_true = Expr();
00156
00157
00158
00159
00160 vector<ExprValue*> exprs;
00161 exprs.reserve(d_exprSet.size());
00162 TRACE_MSG("delete", "clear:() collecting exprs { ");
00163 IF_DEBUG(int n(0);)
00164 for(ExprValueSet::iterator i=d_exprSet.begin(), iend=d_exprSet.end();
00165 i!=iend; ++i) {
00166 TRACE("delete", "expr[", n++, "]");
00167 exprs.push_back(*i);
00168 }
00169 TRACE_MSG("delete", "clear(): finished collecting exprs }");
00170 d_exprSet.clear();
00171 TRACE_MSG("delete", "clear(): deleting exprs { ");
00172 for(vector<ExprValue*>::iterator i=exprs.begin(), iend=exprs.end();
00173 i!=iend; ++i) {
00174 ExprValue *pExpr= *i;
00175 size_t tp(pExpr->getMMIndex());
00176 delete (pExpr);
00177 d_mm[tp]->deleteData(pExpr);
00178 }
00179 TRACE_MSG("delete", "clear(): finished deleting exprs }");
00180
00181 }
00182
00183
00184 bool ExprManager::isActive() { return !d_disableGC; }
00185
00186
00187
00188 void ExprManager::gc(ExprValue* ev) {
00189 if(!d_disableGC) {
00190 d_exprSet.erase(ev);
00191 if (d_inGC) d_pending.push_back(ev);
00192 else if (d_postponeGC) d_postponed.push_back(ev);
00193 else {
00194 IF_DEBUG(FatalAssert(d_pending.size() == 0, "Expected size 1");)
00195 d_inGC = true;
00196 size_t tp = ev->getMMIndex();
00197 delete ev;
00198 d_mm[tp]->deleteData(ev);
00199 while (d_pending.size() > 0) {
00200 ev = d_pending.front();
00201 d_pending.pop_front();
00202 tp = ev->getMMIndex();
00203 delete ev;
00204 d_mm[tp]->deleteData(ev);
00205 }
00206 d_inGC = false;
00207 }
00208 }
00209 }
00210
00211 void
00212 ExprManager::resumeGC() {
00213 d_postponeGC = false;
00214 while(d_postponed.size()>0) {
00215 ExprValue* ev = d_postponed.back();
00216 size_t tp(ev->getMMIndex());
00217 d_postponed.pop_back();
00218 delete ev;
00219 d_mm[tp]->deleteData(ev);
00220 }
00221 }
00222
00223
00224
00225
00226 Expr ExprManager::rebuild(const Expr& e) {
00227
00228
00229 DebugAssert(!e.isNull(), "ExprManager::rebuild called on Null Expr");
00230
00231 DebugAssert(isActive() && e.getEM()->isActive(),
00232 "ExprManager::rebuild is called on inactive ExprManager");
00233
00234 if(e.isNull() || (e.getEM() == this)) {
00235
00236 return e;
00237 }
00238
00239 DebugAssert(!d_inRebuild, "ExprManager::rebuild()");
00240 IF_DEBUG(ScopeWatcher sw(&d_inRebuild);)
00241
00242 if(d_rebuildCache.size() > 0) d_rebuildCache.clear();
00243 Expr res = rebuildRec(e);
00244
00245 if(d_rebuildCache.size() > 0) d_rebuildCache.clear();
00246
00247 return res;
00248 }
00249
00250
00251 Expr ExprManager::rebuildRec(const Expr& e) {
00252 DebugAssert(d_inRebuild, "ExprManager::rebuildRec("+e.toString()+")");
00253
00254 ExprHashMap<Expr>::iterator j=d_rebuildCache.find(e),
00255 jend=d_rebuildCache.end();
00256 if(j!=jend) return (*j).second;
00257
00258 ExprValue* ev = e.d_expr->rebuild(this);
00259
00260 ExprValueSet::iterator i(d_exprSet.find(ev)), iend(d_exprSet.end());
00261 if(i != iend) {
00262 MemoryManager* mm = getMM(ev->getMMIndex());
00263 delete ev;
00264 mm->deleteData(ev);
00265 ev = *i;
00266 } else {
00267 ev->setIndex(nextIndex());
00268 d_exprSet.insert(ev);
00269 }
00270
00271 Expr res(ev);
00272
00273 d_rebuildCache[e] = res;
00274
00275
00276 Type t;
00277 if (!e.d_expr->d_type.isNull()) {
00278 t = Type(rebuildRec(e.d_expr->d_type.getExpr()));
00279 if (ev->d_type.isNull()) ev->d_type = t;
00280 if (ev->d_type != t) {
00281 throw Exception("Types don't match in rebuildRec");
00282 }
00283 }
00284 return res;
00285 }
00286
00287
00288 ExprValue* ExprManager::newExprValue(ExprValue* ev) {
00289 DebugAssert(isActive(), "ExprManager::newExprValue(ExprValue*)");
00290 ExprValueSet::iterator i(d_exprSet.find(ev)), iend(d_exprSet.end());
00291 if(i != iend) return (*i);
00292
00293
00294 ExprValue* p_ev = ev->copy(this, nextIndex());
00295 d_exprSet.insert(p_ev);
00296 return p_ev;
00297 }
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 int
00334 ExprManager::indent(int n, bool permanent) {
00335 int ret(d_indent);
00336 d_indentTransient = n;
00337 if(permanent) d_indent = n;
00338 return ret;
00339 }
00340
00341
00342
00343
00344 int
00345 ExprManager::incIndent(int n, bool permanent) {
00346 int ret(d_indent);
00347 d_indentTransient += n;
00348 if(permanent) d_indent = d_indentTransient;
00349 return ret;
00350 }
00351
00352
00353 InputLanguage
00354 ExprManager::getInputLang() const {
00355 return getLanguage(*d_inputLang);
00356 }
00357
00358
00359 InputLanguage
00360 ExprManager::getOutputLang() const {
00361 const std::string* langPtr
00362 = (*d_outputLang == "")? d_inputLang : d_outputLang;
00363 return getLanguage(*langPtr);
00364 }
00365
00366
00367 void ExprManager::newKind(int kind, const string &name, bool isType) {
00368 if(d_kindMap.count(kind) == 0) {
00369 d_kindMap[kind] = name;
00370 if(isType) d_typeKinds.insert(kind);
00371 }
00372 else if(d_kindMap[kind] != name) {
00373 DebugAssert(false, "CVC3::ExprManager::newKind(kind = "
00374 + int2string(kind) + ", name = " + name
00375 + "): \n" +
00376 "this kind is already registered with a different name: "
00377 + d_kindMap[kind]);
00378 }
00379 if(d_kindMapByName.count(name) == 0)
00380 d_kindMapByName[name] = kind;
00381 else if(d_kindMapByName[name] != kind) {
00382 DebugAssert(false, "CVC3::ExprManager::newKind(kind = "
00383 + int2string(kind) + ", name = " + name
00384 + "): \n" +
00385 "this kind name is already registered with a different index: "
00386 + int2string(d_kindMapByName[name]));
00387 }
00388 }
00389
00390
00391 void ExprManager::registerPrettyPrinter(PrettyPrinter& printer) {
00392 DebugAssert(d_prettyPrinter==NULL, "ExprManager:registerPrettyPrinter():"
00393 " printer is already registered");
00394 d_prettyPrinter = &printer;
00395 }
00396
00397
00398 void ExprManager::unregisterPrettyPrinter() {
00399 FatalAssert(d_prettyPrinter!=NULL, "ExprManager:unregisterPrettyPrinter():"
00400 " printer is not registered");
00401 d_prettyPrinter = NULL;
00402 }
00403
00404
00405 const string& ExprManager::getKindName(int kind) {
00406 DebugAssert(d_kindMap.count(kind) > 0,
00407 ("CVC3::ExprManager::getKindName(kind = "
00408 + int2string(kind) + "): kind is not registered.").c_str());
00409 return d_kindMap[kind];
00410 }
00411
00412 int ExprManager::getKind(const string& name) {
00413 std::hash_map<std::string, int, HashString>::iterator
00414 i=d_kindMapByName.find(name),
00415 iend=d_kindMapByName.end();
00416 if(i==iend) return NULL_KIND;
00417 else return (*i).second;
00418 }
00419
00420
00421 size_t ExprManager::registerSubclass(size_t sizeOfSubclass) {
00422 size_t idx(d_mm.size());
00423 if(d_mmFlag == "chunks")
00424 d_mm.push_back(new MemoryManagerChunks(sizeOfSubclass));
00425 else
00426 d_mm.push_back(new MemoryManagerMalloc());
00427
00428 FatalAssert(d_mm.back() != NULL, "Out of memory");
00429 return idx;
00430 }
00431
00432
00433 unsigned long ExprManager::getMemory(int verbosity)
00434 {
00435 unsigned long memSelf = sizeof(ExprManager);
00436 unsigned long mem = 0;
00437
00438
00439
00440
00441
00442
00443 mem += MemoryTracker::getString(verbosity - 1, d_mmFlag);
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 MemoryTracker::print("ExprManager", verbosity, memSelf, mem);
00460
00461 return mem + memSelf;
00462 }
00463
00464
00465 void ExprManager::computeType(const Expr& e) {
00466 DebugAssert(d_typeComputer, "No type computer installed");
00467 d_typeComputer->computeType(e);
00468 DebugAssert(!e.getType().getExpr().isNull(), "Type not set by computeType");
00469 }
00470
00471
00472 void ExprManager::checkType(const Expr& e) {
00473 DebugAssert(d_typeComputer, "No type computer installed");
00474 if (!e.isValidType()) d_typeComputer->checkType(e);
00475 DebugAssert(e.isValidType(), "Type not checked by checkType");
00476 }
00477
00478
00479 Cardinality ExprManager::finiteTypeInfo(Expr& e,
00480 Unsigned& n,
00481 bool enumerate,
00482 bool computeSize)
00483 {
00484 DebugAssert(d_typeComputer, "No type computer installed");
00485 return d_typeComputer->finiteTypeInfo(e, n, enumerate, computeSize);
00486 }
00487
00488
00489
00490 #define REG(k) em.newKind(k, #k)
00491 #define REG_TYPE(k) em.newKind(k, #k, true)
00492
00493 static void registerKinds(ExprManager& em) {
00494
00495 em.newKind(BOOLEAN, "_BOOLEAN", true);
00496
00497 em.newKind(ANY_TYPE, "_ANY_TYPE", true);
00498 em.newKind(ARROW, "_ARROW", true);
00499 em.newKind(TYPE, "_TYPE", true);
00500 em.newKind(TYPEDECL, "_TYPEDECL", true);
00501 em.newKind(TYPEDEF, "_TYPEDEF", true);
00502 em.newKind(SUBTYPE, "_SUBTYPE", true);
00503
00504
00505 em.newKind(NULL_KIND, "_NULL_KIND");
00506
00507 em.newKind(RAW_LIST, "_RAW_LIST");
00508 em.newKind(STRING_EXPR, "_STRING_EXPR");
00509 em.newKind(RATIONAL_EXPR, "_RATIONAL_EXPR");
00510 em.newKind(TRUE_EXPR, "_TRUE_EXPR");
00511 em.newKind(FALSE_EXPR, "_FALSE_EXPR");
00512
00513 em.newKind(EQ, "_EQ");
00514 em.newKind(NEQ, "_NEQ");
00515 em.newKind(DISTINCT, "_DISTINCT");
00516
00517 em.newKind(NOT, "_NOT");
00518 em.newKind(AND, "_AND");
00519 em.newKind(OR, "_OR");
00520 em.newKind(XOR, "_XOR");
00521 em.newKind(IFF, "_IFF");
00522 em.newKind(IMPLIES, "_IMPLIES");
00523
00524 em.newKind(AND_R, "_AND_R");
00525 em.newKind(IFF_R, "_IFF_R");
00526 em.newKind(ITE_R, "_ITE_R");
00527
00528 em.newKind(ITE, "_ITE");
00529
00530 em.newKind(FORALL, "_FORALL");
00531 em.newKind(EXISTS, "_EXISTS");
00532
00533 em.newKind(UFUNC, "_UFUNC");
00534 em.newKind(APPLY, "_APPLY");
00535
00536 em.newKind(ASSERT, "_ASSERT");
00537 em.newKind(QUERY, "_QUERY");
00538 em.newKind(CHECKSAT, "_CHECKSAT");
00539 em.newKind(CONTINUE, "_CONTINUE");
00540 em.newKind(RESTART, "_RESTART");
00541 em.newKind(DBG, "_DBG");
00542 em.newKind(TRACE, "_TRACE");
00543 em.newKind(UNTRACE, "_UNTRACE");
00544 em.newKind(OPTION, "_OPTION");
00545 em.newKind(HELP, "_HELP");
00546 em.newKind(TRANSFORM, "_TRANSFORM");
00547 em.newKind(PRINT, "_PRINT");
00548 em.newKind(CALL, "_CALL");
00549 em.newKind(ECHO, "_ECHO");
00550 em.newKind(INCLUDE, "_INCLUDE");
00551 em.newKind(DUMP_PROOF, "_DUMP_PROOF");
00552 em.newKind(DUMP_ASSUMPTIONS, "_DUMP_ASSUMPTIONS");
00553 em.newKind(DUMP_SIG, "_DUMP_SIG");
00554 em.newKind(DUMP_TCC, "_DUMP_TCC");
00555 em.newKind(DUMP_TCC_ASSUMPTIONS, "_DUMP_TCC_ASSUMPTIONS");
00556 em.newKind(DUMP_TCC_PROOF, "_DUMP_TCC_PROOF");
00557 em.newKind(DUMP_CLOSURE, "_DUMP_CLOSURE");
00558 em.newKind(DUMP_CLOSURE_PROOF, "_DUMP_CLOSURE_PROOF");
00559 em.newKind(WHERE, "_WHERE");
00560 em.newKind(ASSERTIONS, "_ASSERTIONS");
00561 em.newKind(ASSUMPTIONS, "_ASSUMPTIONS");
00562 em.newKind(COUNTEREXAMPLE, "_COUNTEREXAMPLE");
00563 em.newKind(COUNTERMODEL, "_COUNTERMODEL");
00564 em.newKind(PUSH, "_PUSH");
00565 em.newKind(POP, "_POP");
00566 em.newKind(POPTO, "_POPTO");
00567 em.newKind(PUSH_SCOPE, "_PUSH_SCOPE");
00568 em.newKind(POP_SCOPE, "_POP_SCOPE");
00569 em.newKind(POPTO_SCOPE, "_POPTO_SCOPE");
00570 em.newKind(RESET, "_RESET");
00571 em.newKind(CONTEXT, "_CONTEXT");
00572 em.newKind(FORGET, "_FORGET");
00573 em.newKind(GET_TYPE, "_GET_TYPE");
00574 em.newKind(CHECK_TYPE, "_CHECK_TYPE");
00575 em.newKind(GET_CHILD, "_GET_CHILD");
00576 em.newKind(SUBSTITUTE, "_SUBSTITUTE");
00577 em.newKind(SEQ, "_SEQ");
00578 em.newKind(ARITH_VAR_ORDER, "_ARITH_VAR_ORDER");
00579
00580
00581
00582 em.newKind(TCC, "_TCC");
00583 em.newKind(ID, "_ID");
00584 em.newKind(VARDECL, "_VARDECL");
00585 em.newKind(VARDECLS, "_VARDECLS");
00586
00587
00588 em.newKind(BOUND_VAR, "_BOUND_VAR");
00589 em.newKind(BOUND_ID, "_BOUND_ID");
00590
00591 em.newKind(SKOLEM_VAR, "_SKOLEM_VAR");
00592 em.newKind(THEOREM_KIND, "_THEOREM_KIND");
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 em.newKind(IF, "_IF");
00617 em.newKind(IFTHEN, "_IFTHEN");
00618 em.newKind(ELSE, "_ELSE");
00619 em.newKind(COND, "_COND");
00620
00621 em.newKind(LET, "_LET");
00622 em.newKind(LETDECLS, "_LETDECLS");
00623 em.newKind(LETDECL, "_LETDECL");
00624
00625 em.newKind(LAMBDA, "_LAMBDA");
00626 em.newKind(SIMULATE, "_SIMULATE");
00627
00628 em.newKind(CONST, "_CONST");
00629 em.newKind(VARLIST, "_VARLIST");
00630 em.newKind(UCONST, "_UCONST");
00631 em.newKind(DEFUN, "_DEFUN");
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
00651
00652
00653 }
00654
00655
00656 void ExprManagerNotifyObj::notifyPre() {
00657 d_em->postponeGC();
00658 }
00659
00660
00661 void ExprManagerNotifyObj::notify() {
00662 d_em->resumeGC();
00663 }