1 #ifndef Rose_BinaryAnalysis_SmtSolver_H
2 #define Rose_BinaryAnalysis_SmtSolver_H
3 #include <featureTests.h>
4 #ifdef ROSE_ENABLE_BINARY_ANALYSIS
6 #ifndef __STDC_FORMAT_MACROS
7 #define __STDC_FORMAT_MACROS
10 #include <BinarySymbolicExpr.h>
11 #include <boost/chrono.hpp>
12 #include <boost/lexical_cast.hpp>
13 #include <boost/noncopyable.hpp>
14 #include <boost/serialization/access.hpp>
15 #include <boost/thread/mutex.hpp>
16 #include <boost/unordered_map.hpp>
55 enum Type { NO_TYPE, BOOLEAN, BIT_VECTOR, MEM_STATE };
66 Exception(
const std::string &mesg): std::runtime_error(mesg) {}
72 ParseError(
const std::pair<size_t /*line*/, size_t /*col*/> &loc,
const std::string &mesg)
73 :
Exception(
"input line " + boost::lexical_cast<std::string>(loc.first+1) +
74 " column " + boost::lexical_cast<std::string>(loc.second+1) +
": " + mesg) {}
104 : ncalls(0), input_size(0), output_size(0), memoizationHits(0), nSolversCreated(0), nSolversDestroyed(0),
105 prepareTime(0.0), solveTime(0.0), evidenceTime(0.0), nSatisfied(0), nUnsatisfied(0), nUnknown(0) {
130 : solver_(solver), committed_(false) {
132 nLevels_ = solver->nLevels();
141 if (solver_ && !committed_) {
142 ASSERT_require2(solver_->nLevels() > nLevels_,
"something popped this transaction already");
143 while (solver_->nLevels() > nLevels_) {
144 if (solver_->nLevels() > 1) {
179 explicit SExpr(
const std::string &content): content_(content) {}
180 std::string content_;
181 std::vector<Ptr> children_;
183 static Ptr instance(
const std::string &content);
184 static Ptr instance(
size_t);
185 static Ptr instance(
const Ptr &a = Ptr(),
const Ptr &b = Ptr(),
const Ptr &c = Ptr(),
const Ptr &d = Ptr());
187 const std::string name()
const {
return content_; }
188 const std::vector<Ptr>& children()
const {
return children_; }
189 std::vector<Ptr>& children() {
return children_; }
190 void append(
const std::vector<Ptr>&);
191 void print(std::ostream&)
const;
194 typedef std::pair<SExpr::Ptr, Type> SExprTypePair;
196 typedef boost::unordered_map<SymbolicExpr::Hash, Satisfiable> Memoization;
200 std::vector<std::vector<SymbolicExpr::Ptr> > stack_;
206 std::vector<SExpr::Ptr> parsedOutput_;
207 TermNames termNames_;
208 Memoization memoization_;
214 static boost::mutex classStatsMutex;
215 static Stats classStats;
223 #ifdef ROSE_HAVE_BOOST_SERIALIZATION_LIB
224 friend class boost::serialization::access;
227 void serialize(S &s,
const unsigned ) {
228 s & BOOST_SERIALIZATION_NVP(name_);
229 s & BOOST_SERIALIZATION_NVP(stack_);
256 : name_(name), errorIfReset_(false), linkage_(
LM_NONE), doMemoization_(true), latestMemoizationId_(0) {
298 const std::string&
name()
const {
return name_; }
299 void name(
const std::string &s) { name_ = s; }
334 return latestMemoizationId_;
339 memoization_.clear();
344 return memoization_.size();
350 virtual void timeout(boost::chrono::duration<double> seconds) = 0;
388 virtual void reset();
397 return errorIfReset_;
427 virtual size_t nLevels()
const {
return stack_.size(); }
432 virtual size_t nAssertions(
size_t backtrackingLevel);
443 virtual void insert(
const std::vector<SymbolicExpr::Ptr>&);
449 virtual std::vector<SymbolicExpr::Ptr>
assertions()
const;
455 virtual std::vector<SymbolicExpr::Ptr>
assertions(
size_t level)
const;
484 return std::vector<std::string>();
517 ASSERT_require(ln && ln->isVariable2());
522 snprintf(buf,
sizeof buf,
"v%" PRIu64, varno);
592 virtual void generateFile(std::ostream&,
const std::vector<SymbolicExpr::Ptr> &exprs, Definitions*) = 0;
596 virtual std::string
getCommand(
const std::string &config_name) = 0;
611 static std::vector<SymbolicExpr::Ptr>
normalizeVariables(
const std::vector<SymbolicExpr::Ptr>&,
621 static std::vector<SymbolicExpr::Ptr>
undoNormalization(
const std::vector<SymbolicExpr::Ptr>&,
638 void init(
unsigned linkages);
648 virtual Satisfiable trivially_satisfiable(
const std::vector<SymbolicExpr::Ptr> &exprs)
649 ROSE_DEPRECATED(
"use triviallySatisfiable");
650 virtual SymbolicExpr::Ptr evidence_for_variable(uint64_t varno) ROSE_DEPRECATED(
"use evidenceForVariable");
653 virtual SymbolicExpr::
Ptr evidence_for_address(uint64_t addr) ROSE_DEPRECATED("use
evidenceForAddress");
655 virtual
void clear_evidence() ROSE_DEPRECATED("use
clearEvidence");
656 const Stats& get_stats() const ROSE_DEPRECATED("use
statistics");
661 virtual
void generate_file(
std::ostream&, const
std::vector<SymbolicExpr::
Ptr> &exprs, Definitions*)
663 virtual
std::
string get_command(const
std::
string &config_name) ROSE_DEPRECATED("use
getCommand");
664 virtual
void parse_evidence() ROSE_DEPRECATED("use
parseEvidence");
virtual void push()
Create a backtracking point.
SmtSolverPtr Ptr
Reference counting pointer for SMT solvers.
bool isCommitted() const
Whether the guard is canceled.
Sawyer::SharedPointer< Node > Ptr
Shared-ownership pointer to an expression Node.
S-Expr parsed from SMT solver text output.
uint64_t Hash
Hash of symbolic expression.
virtual Satisfiable checkLib()
Check satisfiability using a library API.
virtual void clearEvidence()
Clears evidence information.
Satisfiable and evidence of satisfiability may be available.
virtual SymbolicExpr::Ptr evidenceForVariable(const SymbolicExpr::Ptr &var)
Evidence of satisfiability for a bitvector variable.
virtual SymbolicExpr::Ptr evidenceForName(const std::string &)
Evidence of satisfiability for a variable or memory address.
Mapping from expression to expression.
virtual void insert(const SymbolicExpr::Ptr &)
Insert assertions.
size_t nUnsatisfied
Number of times the solver returned "unsatisfied".
static void printSExpression(std::ostream &, const SExpr::Ptr &)
Print an S-Expr for debugging.
size_t ncalls
Number of times satisfiable() was called.
void requireLinkage(LinkMode) const
Assert required linkage.
virtual void timeout(boost::chrono::duration< double > seconds)=0
Set the timeout for the solver.
virtual void reset()
Reset solver state.
std::string outputText_
Additional output obtained by satisfiable().
const std::string & name() const
Property: Name of solver for debugging.
LinkMode
Bit flags to indicate the kind of solver interface.
Main namespace for the ROSE library.
size_t nSolversCreated
Number of solvers created.
Sawyer::Container::Map< SymbolicExpr::Ptr, SymbolicExpr::Ptr > ExprExprMap
Maps one symbolic expression to another.
static Availability availability()
Availability of all known solvers.
std::set< uint64_t > Definitions
Free variables that have been defined.
Satisfiable
Satisfiability constants.
Sawyer::Container::Set< SymbolicExpr::LeafPtr, CompareLeavesByName > VariableSet
Set of variables.
Reference-counting intrusive smart pointer.
virtual Satisfiable check()
Check satisfiability of current stack.
void resetStatistics()
Resets statistics for this solver.
static std::vector< SymbolicExpr::Ptr > normalizeVariables(const std::vector< SymbolicExpr::Ptr > &, SymbolicExpr::ExprExprHashMap &index)
Normalize expressions by renaming variables.
size_t nSatisfied
Number of times the solver returned "satisified".
double prepareTime
Time spent creating assertions before solving.
bool errorIfReset() const
Property: Throw an exception if the solver is reset.
virtual size_t nAssertions() const
Total number of assertions across all backtracking levels.
virtual size_t nLevels() const
Number of backtracking levels.
Exceptions for all things SMT related.
static void resetClassStatistics()
Resets statistics for the class.
std::map< std::string, bool > Availability
Solver availability map.
virtual Ptr create() const =0
Virtual constructor.
static Ptr bestAvailable()
Best available solver.
static Ptr instance(const std::string &name)
Allocate a new solver by name.
void name(const std::string &s)
Property: Name of solver for debugging.
virtual void findVariables(const SymbolicExpr::Ptr &, VariableSet &)
Return all variables that need declarations.
void errorIfReset(bool b)
Property: Throw an exception if the solver is reset.
SymbolicExpr::Hash latestMemoizationId() const
Id for latest memoized result, or zero.
virtual void generateFile(std::ostream &, const std::vector< SymbolicExpr::Ptr > &exprs, Definitions *)=0
Generates an input file for for the solver.
static void initDiagnostics()
Initialize diagnostic output facilities.
bool memoization() const
Property: Perform memoization.
virtual Satisfiable checkExe()
Check satisfiability using text files and an executable.
~Transaction()
Destructor pops level unless canceled.
void memoization(bool b)
Property: Perform memoization.
Exception for parse errors when reading SMT solver output.
SmtSolver(const std::string &name, unsigned linkages)
Construct with name and linkage.
virtual SymbolicExpr::Ptr evidenceForAddress(uint64_t addr)
Evidence of satisfiability for a memory address.
void commit(bool b=true)
Cancel the popping during the destructor.
virtual Satisfiable triviallySatisfiable(const std::vector< SymbolicExpr::Ptr > &exprs)
Determines if expressions are trivially satisfiable or unsatisfiable.
Transaction(const SmtSolver::Ptr &solver)
Constructor pushes level if solver is non-null.
virtual void selfTest()
Unit tests.
const Stats & statistics() const
Property: Statistics for this solver.
virtual Satisfiable checkTrivial()
Check whether the stack of assertions is trivially satisfiable.
virtual void clearMemoization()
Clear memoization table.
An executable is available.
static std::vector< SymbolicExpr::Ptr > undoNormalization(const std::vector< SymbolicExpr::Ptr > &, const SymbolicExpr::ExprExprHashMap &index)
Undo the normalizations that were performed earlier.
Base class for reference counted objects.
A runtime library is available.
virtual void pop()
Pop a backtracking point.
Type
Type (sort) of expression.
size_t nSolversDestroyed
Number of solvers destroyed.
Could not be proved satisfiable or unsatisfiable.
SmtSolver::Ptr solver() const
Solver being protected.
virtual std::vector< SymbolicExpr::Ptr > assertions() const
All assertions.
double evidenceTime
Seconds to retrieve evidence of satisfiability.
virtual Satisfiable satisfiable(const SymbolicExpr::Ptr &)
Determines if the specified expressions are all satisfiable, unsatisfiable, or unknown.
double solveTime
Seconds spent in solver's solve function.
virtual std::vector< std::string > evidenceNames()
Names of items for which satisfiability evidence exists.
virtual std::string getCommand(const std::string &config_name)=0
Given the name of a configuration file, return the command that is needed to run the solver...
std::pair< std::string, Type > StringTypePair
Maps expression nodes to term names.
Interface to Satisfiability Modulo Theory (SMT) solvers.
size_t input_size
Bytes of input generated for satisfiable().
virtual size_t memoizationNEntries() const
Size of memoization table.
virtual void parseEvidence()
Parses evidence of satisfiability.
std::vector< SExpr::Ptr > parseSExpressions(const std::string &)
Parse all SExprs from the specified string.
static Stats classStatistics()
Property: Statistics across all solvers.
static LinkMode bestLinkage(unsigned linkages)
Given a bit vector of linkages, return the best one.
virtual SymbolicExpr::Ptr evidenceForVariable(uint64_t varno)
Evidence of satisfiability for a bitvector variable.
static Sawyer::Message::Facility mlog
Diagnostic facility.
size_t memoizationHits
Number of times memoization supplied a result.
std::shared_ptr< class SmtSolver > SmtSolverPtr
Reference-counting pointer for SMT solvers.
LinkMode linkage() const
Property: How ROSE communicates with the solver.
size_t nUnknown
Number of times the solver returned "unknown".
virtual std::string getErrorMessage(int exitStatus)
Error message from running a solver executable.
RAII guard for solver stack.
size_t output_size
Amount of output produced by the SMT solver.