Searcher.h
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef KLEE_SEARCHER_H
00011 #define KLEE_SEARCHER_H
00012
00013 #include <vector>
00014 #include <set>
00015 #include <map>
00016 #include <queue>
00017
00018
00019 #include <ostream>
00020
00021 namespace llvm {
00022 class BasicBlock;
00023 class Function;
00024 class Instruction;
00025 }
00026
00027 namespace klee {
00028 template<class T> class DiscretePDF;
00029 class ExecutionState;
00030 class Executor;
00031
00032 class Searcher {
00033 public:
00034 virtual ~Searcher();
00035
00036 virtual ExecutionState &selectState() = 0;
00037
00038 virtual void update(ExecutionState *current,
00039 const std::set<ExecutionState*> &addedStates,
00040 const std::set<ExecutionState*> &removedStates) = 0;
00041
00042 virtual bool empty() = 0;
00043
00044
00045
00046 virtual void printName(std::ostream &os) {
00047 os << "<unnamed searcher>\n";
00048 }
00049
00050
00051
00052
00053 virtual void activate() {};
00054 virtual void deactivate() {};
00055
00056
00057
00058 void addState(ExecutionState *es, ExecutionState *current = 0) {
00059 std::set<ExecutionState*> tmp;
00060 tmp.insert(es);
00061 update(current, tmp, std::set<ExecutionState*>());
00062 }
00063
00064 void removeState(ExecutionState *es, ExecutionState *current = 0) {
00065 std::set<ExecutionState*> tmp;
00066 tmp.insert(es);
00067 update(current, std::set<ExecutionState*>(), tmp);
00068 }
00069 };
00070
00071 class DFSSearcher : public Searcher {
00072 std::vector<ExecutionState*> states;
00073
00074 public:
00075 ExecutionState &selectState();
00076 void update(ExecutionState *current,
00077 const std::set<ExecutionState*> &addedStates,
00078 const std::set<ExecutionState*> &removedStates);
00079 bool empty() { return states.empty(); }
00080 void printName(std::ostream &os) {
00081 os << "DFSSearcher\n";
00082 }
00083 };
00084
00085 class RandomSearcher : public Searcher {
00086 std::vector<ExecutionState*> states;
00087
00088 public:
00089 ExecutionState &selectState();
00090 void update(ExecutionState *current,
00091 const std::set<ExecutionState*> &addedStates,
00092 const std::set<ExecutionState*> &removedStates);
00093 bool empty() { return states.empty(); }
00094 void printName(std::ostream &os) {
00095 os << "RandomSearcher\n";
00096 }
00097 };
00098
00099 class WeightedRandomSearcher : public Searcher {
00100 public:
00101 enum WeightType {
00102 Depth,
00103 QueryCost,
00104 InstCount,
00105 CPInstCount,
00106 MinDistToUncovered,
00107 CoveringNew
00108 };
00109
00110 private:
00111 Executor &executor;
00112 DiscretePDF<ExecutionState*> *states;
00113 WeightType type;
00114 bool updateWeights;
00115
00116 double getWeight(ExecutionState*);
00117
00118 public:
00119 WeightedRandomSearcher(Executor &executor, WeightType type);
00120 ~WeightedRandomSearcher();
00121
00122 ExecutionState &selectState();
00123 void update(ExecutionState *current,
00124 const std::set<ExecutionState*> &addedStates,
00125 const std::set<ExecutionState*> &removedStates);
00126 bool empty();
00127 void printName(std::ostream &os) {
00128 os << "WeightedRandomSearcher::";
00129 switch(type) {
00130 case Depth : os << "Depth\n"; return;
00131 case QueryCost : os << "QueryCost\n"; return;
00132 case InstCount : os << "InstCount\n"; return;
00133 case CPInstCount : os << "CPInstCount\n"; return;
00134 case MinDistToUncovered : os << "MinDistToUncovered\n"; return;
00135 case CoveringNew : os << "CoveringNew\n"; return;
00136 default : os << "<unknown type>\n"; return;
00137 }
00138 }
00139 };
00140
00141 class RandomPathSearcher : public Searcher {
00142 Executor &executor;
00143
00144 public:
00145 RandomPathSearcher(Executor &_executor);
00146 ~RandomPathSearcher();
00147
00148 ExecutionState &selectState();
00149 void update(ExecutionState *current,
00150 const std::set<ExecutionState*> &addedStates,
00151 const std::set<ExecutionState*> &removedStates);
00152 bool empty();
00153 void printName(std::ostream &os) {
00154 os << "RandomPathSearcher\n";
00155 }
00156 };
00157
00158 class MergingSearcher : public Searcher {
00159 Executor &executor;
00160 std::set<ExecutionState*> statesAtMerge;
00161 Searcher *baseSearcher;
00162 llvm::Function *mergeFunction;
00163
00164 private:
00165 llvm::Instruction *getMergePoint(ExecutionState &es);
00166
00167 public:
00168 MergingSearcher(Executor &executor, Searcher *baseSearcher);
00169 ~MergingSearcher();
00170
00171 ExecutionState &selectState();
00172 void update(ExecutionState *current,
00173 const std::set<ExecutionState*> &addedStates,
00174 const std::set<ExecutionState*> &removedStates);
00175 bool empty() { return baseSearcher->empty() && statesAtMerge.empty(); }
00176 void printName(std::ostream &os) {
00177 os << "MergingSearcher\n";
00178 }
00179 };
00180
00181 class BumpMergingSearcher : public Searcher {
00182 Executor &executor;
00183 std::map<llvm::Instruction*, ExecutionState*> statesAtMerge;
00184 Searcher *baseSearcher;
00185 llvm::Function *mergeFunction;
00186
00187 private:
00188 llvm::Instruction *getMergePoint(ExecutionState &es);
00189
00190 public:
00191 BumpMergingSearcher(Executor &executor, Searcher *baseSearcher);
00192 ~BumpMergingSearcher();
00193
00194 ExecutionState &selectState();
00195 void update(ExecutionState *current,
00196 const std::set<ExecutionState*> &addedStates,
00197 const std::set<ExecutionState*> &removedStates);
00198 bool empty() { return baseSearcher->empty() && statesAtMerge.empty(); }
00199 void printName(std::ostream &os) {
00200 os << "BumpMergingSearcher\n";
00201 }
00202 };
00203
00204 class BatchingSearcher : public Searcher {
00205 Searcher *baseSearcher;
00206 double timeBudget;
00207 unsigned instructionBudget;
00208
00209 ExecutionState *lastState;
00210 double lastStartTime;
00211 unsigned lastStartInstructions;
00212
00213 public:
00214 BatchingSearcher(Searcher *baseSearcher,
00215 double _timeBudget,
00216 unsigned _instructionBudget);
00217 ~BatchingSearcher();
00218
00219 ExecutionState &selectState();
00220 void update(ExecutionState *current,
00221 const std::set<ExecutionState*> &addedStates,
00222 const std::set<ExecutionState*> &removedStates);
00223 bool empty() { return baseSearcher->empty(); }
00224 void printName(std::ostream &os) {
00225 os << "<BatchingSearcher> timeBudget: " << timeBudget
00226 << ", instructionBudget: " << instructionBudget
00227 << ", baseSearcher:\n";
00228 baseSearcher->printName(os);
00229 os << "</BatchingSearcher>\n";
00230 }
00231 };
00232
00233 class IterativeDeepeningTimeSearcher : public Searcher {
00234 Searcher *baseSearcher;
00235 double time, startTime;
00236 std::set<ExecutionState*> pausedStates;
00237
00238 public:
00239 IterativeDeepeningTimeSearcher(Searcher *baseSearcher);
00240 ~IterativeDeepeningTimeSearcher();
00241
00242 ExecutionState &selectState();
00243 void update(ExecutionState *current,
00244 const std::set<ExecutionState*> &addedStates,
00245 const std::set<ExecutionState*> &removedStates);
00246 bool empty() { return baseSearcher->empty() && pausedStates.empty(); }
00247 void printName(std::ostream &os) {
00248 os << "IterativeDeepeningTimeSearcher\n";
00249 }
00250 };
00251
00252 class InterleavedSearcher : public Searcher {
00253 typedef std::vector<Searcher*> searchers_ty;
00254
00255 searchers_ty searchers;
00256 unsigned index;
00257
00258 public:
00259 explicit InterleavedSearcher(const searchers_ty &_searchers);
00260 ~InterleavedSearcher();
00261
00262 ExecutionState &selectState();
00263 void update(ExecutionState *current,
00264 const std::set<ExecutionState*> &addedStates,
00265 const std::set<ExecutionState*> &removedStates);
00266 bool empty() { return searchers[0]->empty(); }
00267 void printName(std::ostream &os) {
00268 os << "<InterleavedSearcher> containing "
00269 << searchers.size() << " searchers:\n";
00270 for (searchers_ty::iterator it = searchers.begin(), ie = searchers.end();
00271 it != ie; ++it)
00272 (*it)->printName(os);
00273 os << "</InterleavedSearcher>\n";
00274 }
00275 };
00276
00277 }
00278
00279 #endif