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 #include "decision_engine_caching.h"
00028 #include "theory_core.h"
00029 #include "search.h"
00030
00031
00032 using namespace std;
00033 using namespace CVCL;
00034
00035 #define CACHE_SIZE 20
00036 #define BASE_TRUST_LEVEL 2
00037 #define TURNOVER_RATE 10
00038
00039 bool DecisionEngineCaching::isBetter(const Expr& e1, const Expr& e2)
00040 {
00041 ExprMap<int>::iterator it1 = d_index.find(e1.getSimpFrom());
00042 ExprMap<int>::iterator it2 = d_index.find(e2.getSimpFrom());
00043
00044 if (it1 != d_index.end() &&
00045 (d_cache[it1->second].d_trust + BASE_TRUST_LEVEL >= d_height) &&
00046 (it2 == d_index.end() ||
00047 d_cache[it1->second].d_rank < d_cache[it2->second].d_rank ||
00048 d_cache[it2->second].d_trust + BASE_TRUST_LEVEL < d_height))
00049 return true;
00050 else
00051 return false;
00052 }
00053
00054
00055 DecisionEngineCaching::DecisionEngineCaching(TheoryCore* core, SearchImplBase* se)
00056 : DecisionEngine(core, se),
00057 d_startLevel(core->getCM()->scopeLevel()),
00058 d_bottomLevel(0),
00059 d_topLevel(0),
00060 d_topLevelLock(false),
00061 d_height(0),
00062 d_cache(CACHE_SIZE)
00063 {
00064 }
00065
00066
00067 Expr DecisionEngineCaching::findSplitter(const Expr& e) {
00068 d_visited.clear();
00069 Expr splitter;
00070 if (!e.isNull())
00071 {
00072 d_height = e.getHeight() - 1;
00073
00074
00075
00076 if (!d_topLevelLock)
00077 {
00078 d_topLevel = d_core->getCM()->scopeLevel();
00079 d_topLevelLock = true;
00080 }
00081
00082 splitter = findSplitterRec(e);
00083 DebugAssert(!splitter.isNull(),
00084 "findSplitter: can't find splitter in non-literal: "
00085 + e.toString());
00086 IF_DEBUG(debugger.counter("splitters from non-literals")++);
00087 }
00088 TRACE("splitters verbose", "findSplitter() => ", splitter, "");
00089 return splitter;
00090 }
00091
00092
00093 void DecisionEngineCaching::goalSatisfied()
00094 {
00095 if (d_core->getCM()->scopeLevel() - d_bottomLevel != 0)
00096 {
00097 d_bottomLevel = d_core->getCM()->scopeLevel();
00098 return;
00099 }
00100
00101 if (d_splitters.size() == 0)
00102 return;
00103
00104 if (!d_topLevelLock)
00105 d_topLevel = d_bottomLevel - 1;
00106 d_topLevelLock = false;
00107
00108 int numInterestingSplitters = min(d_bottomLevel - d_startLevel - 1, TURNOVER_RATE);
00109 int numSplitters = min(CACHE_SIZE, numInterestingSplitters);
00110
00111 vector<CacheEntry> newCache(CACHE_SIZE);
00112 ExprMap<int> newIndex;
00113
00114 int end = d_splitters.size();
00115 int start = end - numSplitters;
00116 if (start < 0)
00117 start = 0;
00118
00119 for (int i = end - 1, j = 0; i >= start; i--, j++)
00120 {
00121 const Expr& s = d_splitters[i];
00122 Expr splitter = s.getSimpFrom();
00123 if(!splitter.isAbsAtomicFormula()) splitter = s;
00124 newCache[j].d_expr = splitter;
00125 newCache[j].d_rank = (numSplitters - j) % numSplitters;
00126 newIndex[splitter] = j;
00127
00128 ExprMap<int>::iterator it = d_index.find(splitter);
00129 if (it != d_index.end())
00130 {
00131 if (j == 0)
00132 newCache[j].d_trust = d_cache[it->second].d_trust + 1;
00133 else
00134 newCache[j].d_trust = d_cache[it->second].d_trust;
00135 }
00136 }
00137
00138 int i = numSplitters;
00139 int rank = numSplitters;
00140 for (int j = 0; i < CACHE_SIZE && !d_cache[j].d_expr.isNull(); j++)
00141 {
00142 if (!newIndex.count(d_cache[j].d_expr))
00143 {
00144 newCache[i] = d_cache[j];
00145 newCache[i].d_rank = rank++;
00146 newIndex[newCache[i].d_expr] = i;
00147 i++;
00148 }
00149 }
00150
00151 d_cache = newCache;
00152 d_index = newIndex;
00153 d_bestByExpr.clear();
00154 }