Searcher.h

Go to the documentation of this file.
00001 //===-- Searcher.h ----------------------------------------------*- C++ -*-===//
00002 //
00003 //                     The KLEE Symbolic Virtual Machine
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
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 // FIXME: Move out of header, use llvm streams.
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     // prints name of searcher as a klee_message()
00045     // TODO: could probably make prettier or more flexible
00046     virtual void printName(std::ostream &os) { 
00047       os << "<unnamed searcher>\n";
00048     }
00049 
00050     // pgbovine - to be called when a searcher gets activated and
00051     // deactivated, say, by a higher-level searcher; most searchers
00052     // don't need this functionality, so don't have to override.
00053     virtual void activate() {};
00054     virtual void deactivate() {};
00055 
00056     // utility functions
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

Generated on Fri Jun 5 03:31:32 2009 for klee by  doxygen 1.5.8