PCLoggingSolver.cpp

Go to the documentation of this file.
00001 //===-- PCLoggingSolver.cpp -----------------------------------------------===//
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 #include "klee/Solver.h"
00011 
00012 // FIXME: This should not be here.
00013 #include "klee/ExecutionState.h"
00014 #include "klee/Expr.h"
00015 #include "klee/SolverImpl.h"
00016 #include "klee/Statistics.h"
00017 #include "klee/util/ExprPPrinter.h"
00018 #include "klee/Internal/Support/QueryLog.h"
00019 #include "klee/Internal/System/Time.h"
00020 
00021 #include "llvm/Support/CommandLine.h"
00022 
00023 #include <fstream>
00024 
00025 using namespace klee;
00026 using namespace llvm;
00027 using namespace klee::util;
00028 
00030 
00031 class PCLoggingSolver : public SolverImpl {
00032   Solver *solver;
00033   std::ofstream os;
00034   ExprPPrinter *printer;
00035   unsigned queryCount;
00036   double startTime;
00037 
00038   void startQuery(const Query& query, const char *typeName,
00039                   const ref<Expr> *evalExprsBegin = 0,
00040                   const ref<Expr> *evalExprsEnd = 0,
00041                   const Array * const* evalArraysBegin = 0,
00042                   const Array * const* evalArraysEnd = 0) {
00043     Statistic *S = theStatisticManager->getStatisticByName("Instructions");
00044     uint64_t instructions = S ? S->getValue() : 0;
00045     os << "# Query " << queryCount++ << " -- "
00046        << "Type: " << typeName << ", "
00047        << "Instructions: " << instructions << "\n";
00048     printer->printQuery(os, query.constraints, query.expr,
00049                         evalExprsBegin, evalExprsEnd,
00050                         evalArraysBegin, evalArraysEnd);
00051     
00052     startTime = getWallTime();
00053   }
00054 
00055   void finishQuery(bool success) {
00056     double delta = getWallTime() - startTime;
00057     os << "#   " << (success ? "OK" : "FAIL") << " -- "
00058        << "Elapsed: " << delta << "\n";
00059   }
00060   
00061 public:
00062   PCLoggingSolver(Solver *_solver, std::string path) 
00063   : solver(_solver),
00064     os(path.c_str(), std::ios::trunc),
00065     printer(ExprPPrinter::create(os)),
00066     queryCount(0) {
00067   }                                                      
00068   ~PCLoggingSolver() {
00069     delete printer;
00070     delete solver;
00071   }
00072   
00073   bool computeTruth(const Query& query, bool &isValid) {
00074     startQuery(query, "Truth");
00075     bool success = solver->impl->computeTruth(query, isValid);
00076     finishQuery(success);
00077     if (success)
00078       os << "#   Is Valid: " << (isValid ? "true" : "false") << "\n";
00079     os << "\n";
00080     return success;
00081   }
00082 
00083   bool computeValidity(const Query& query, Solver::Validity &result) {
00084     startQuery(query, "Validity");
00085     bool success = solver->impl->computeValidity(query, result);
00086     finishQuery(success);
00087     if (success)
00088       os << "#   Validity: " << result << "\n";
00089     os << "\n";
00090     return success;
00091   }
00092 
00093   bool computeValue(const Query& query, ref<Expr> &result) {
00094     startQuery(query.withFalse(), "Value", 
00095                &query.expr, &query.expr + 1);
00096     bool success = solver->impl->computeValue(query, result);
00097     finishQuery(success);
00098     if (success)
00099       os << "#   Result: " << result << "\n";
00100     os << "\n";
00101     return success;
00102   }
00103 
00104   bool computeInitialValues(const Query& query,
00105                             const std::vector<const Array*> &objects,
00106                             std::vector< std::vector<unsigned char> > &values,
00107                             bool &hasSolution) {
00108     const ref<Expr> *evalExprBegin = 0, *evalExprEnd = 0;
00109     if (!query.expr->isFalse()) {
00110       evalExprBegin = &query.expr;
00111       evalExprEnd = evalExprBegin + 1;
00112     } 
00113     if (objects.empty()) {
00114       startQuery(query.withFalse(), "InitialValues",
00115                  evalExprBegin, evalExprEnd);
00116     } else {
00117       startQuery(query.withFalse(), "InitialValues",
00118                  evalExprBegin, evalExprEnd,
00119                  &objects[0], &objects[0] + objects.size());
00120     }
00121     bool success = solver->impl->computeInitialValues(query, objects, 
00122                                                       values, hasSolution);
00123     finishQuery(success);
00124     if (success) {
00125       os << "#   Solvable: " << (hasSolution ? "true" : "false") << "\n";
00126       if (hasSolution) {
00127         std::vector< std::vector<unsigned char> >::iterator
00128           values_it = values.begin();
00129         for (std::vector<const Array*>::const_iterator i = objects.begin(),
00130                e = objects.end(); i != e; ++i, ++values_it) {
00131           const Array *array = *i;
00132           std::vector<unsigned char> &data = *values_it;
00133           os << "#     arr" << array->id << " = [";
00134           for (unsigned j = 0; j < array->size; j++) {
00135             os << (int) data[j];
00136             if (j+1 < array->size)
00137               os << ",";
00138           }
00139           os << "]\n";
00140         }
00141       }
00142     }
00143     os << "\n";
00144     return success;
00145   }
00146 };
00147 
00149 
00150 Solver *klee::createPCLoggingSolver(Solver *_solver, std::string path) {
00151   return new Solver(new PCLoggingSolver(_solver, path));
00152 }

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