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