Browse Source
started Smtlib Solver interface and some 'prototypy' method to check parameter regions
started Smtlib Solver interface and some 'prototypy' method to check parameter regions
Former-commit-id: e3cf6528d9
tempestpy_adaptions
TimQu
10 years ago
8 changed files with 806 additions and 14 deletions
-
165src/adapters/Smt2ExpressionAdapter.h
-
311src/modelchecker/reachability/SparseDtmcEliminationModelChecker.cpp
-
24src/modelchecker/reachability/SparseDtmcEliminationModelChecker.h
-
5src/settings/modules/GeneralSettings.cpp
-
8src/settings/modules/GeneralSettings.h
-
136src/solver/Smt2SmtSolver.cpp
-
112src/solver/Smt2SmtSolver.h
-
31src/utility/cli.h
@ -0,0 +1,165 @@ |
|||||
|
#ifndef STORM_ADAPTERS_SMT2EXPRESSIONADAPTER_H_ |
||||
|
#define STORM_ADAPTERS_SMT2EXPRESSIONADAPTER_H_ |
||||
|
|
||||
|
#include <unordered_map> |
||||
|
|
||||
|
#include "storm-config.h" |
||||
|
#include "src/adapters/CarlAdapter.h" |
||||
|
#include "src/storage/expressions/Expressions.h" |
||||
|
#include "src/storage/expressions/ExpressionManager.h" |
||||
|
#include "src/utility/macros.h" |
||||
|
#include "src/exceptions/ExpressionEvaluationException.h" |
||||
|
#include "src/exceptions/InvalidTypeException.h" |
||||
|
#include "src/exceptions/InvalidArgumentException.h" |
||||
|
#include "src/exceptions/NotImplementedException.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace adapters { |
||||
|
|
||||
|
class Smt2ExpressionAdapter{ |
||||
|
public: |
||||
|
/*! |
||||
|
* Creates an expression adapter that can translate expressions to the format of Smt2. |
||||
|
* |
||||
|
* @param manager The manager that can be used to build expressions. |
||||
|
* @param useReadableVarNames sets whether the expressions should use human readable names for the variables or the internal representation |
||||
|
*/ |
||||
|
Smt2ExpressionAdapter(storm::expressions::ExpressionManager& manager, bool useReadableVarNames) : manager(manager), useReadableVarNames(useReadableVarNames) { |
||||
|
declaredVariables.emplace_back(std::set<std::string>()); |
||||
|
} |
||||
|
|
||||
|
/*! |
||||
|
* Translates the given expression to an equivalent expression for Smt2. |
||||
|
* |
||||
|
* @param expression The expression to translate. |
||||
|
* @return An equivalent expression for Smt2. |
||||
|
*/ |
||||
|
std::string translateExpression(storm::expressions::Expression const& expression) { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
#ifdef STORM_HAVE_CARL |
||||
|
/*! |
||||
|
* Translates the given constraint "leftHandSide relation rightHandSide" to an equivalent expression for Smt2. |
||||
|
|
||||
|
* @param leftHandSide |
||||
|
* @param relation |
||||
|
* @param RightHandSide |
||||
|
* @return An equivalent expression for Smt2. |
||||
|
*/ |
||||
|
std::string translateExpression(storm::RationalFunction const& leftHandSide, storm::CompareRelation const& relation, storm::RationalFunction const& rightHandSide) { |
||||
|
|
||||
|
return "(" + carl::toString(relation) + |
||||
|
" (/ " + |
||||
|
leftHandSide.nominator().toString(false, useReadableVarNames) + " " + |
||||
|
leftHandSide.denominator().toString(false, useReadableVarNames) + |
||||
|
") (/ " + |
||||
|
rightHandSide.nominator().toString(false, useReadableVarNames) + " " + |
||||
|
rightHandSide.denominator().toString(false, useReadableVarNames) + |
||||
|
") " + |
||||
|
")"; |
||||
|
} |
||||
|
|
||||
|
/*! |
||||
|
* Translates the given constraint "leftHandSide relation 0" to an equivalent expression for Smt2. |
||||
|
|
||||
|
* @param constraint |
||||
|
* @return An equivalent expression for Smt2. |
||||
|
*/ |
||||
|
std::string translateExpression(carl::Constraint<storm::RawPolynomial> const& constraint) { |
||||
|
|
||||
|
return "(" + carl::toString(constraint.rel()) + " " + |
||||
|
constraint.lhs().toString(false, useReadableVarNames) + " " + |
||||
|
"0 " + |
||||
|
")"; |
||||
|
} |
||||
|
#endif |
||||
|
/*! |
||||
|
* Translates the given variable to an equivalent expression for Smt2. |
||||
|
* |
||||
|
* @param variable The variable to translate. |
||||
|
* @return An equivalent expression for smt2. |
||||
|
*/ |
||||
|
std::string translateExpression(storm::expressions::Variable const& variable) { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
/*! |
||||
|
* Finds the counterpart to the given smt2 variable declaration. |
||||
|
* |
||||
|
* @param smt2Declaration The declaration for which to find the equivalent. |
||||
|
* @return The equivalent counterpart. |
||||
|
*/ |
||||
|
storm::expressions::Variable const& getVariable(std::string smt2Declaration) { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
void increaseScope(uint_fast64_t n=1){ |
||||
|
for(uint_fast64_t i=0; i<n; ++i){ |
||||
|
declaredVariables.emplace_back(std::set<std::string>()); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void decreaseScope(uint_fast64_t n=1){ |
||||
|
STORM_LOG_THROW(declaredVariables.size()>=n, storm::exceptions::InvalidArgumentException, "Scope increased too much. Too many calls of pop()?"); |
||||
|
for(uint_fast64_t i=0; i<n; ++i){ |
||||
|
declaredVariables.pop_back(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#ifdef STORM_HAVE_CARL |
||||
|
/*! Checks whether the variables in the given set are already declared and creates them if necessary |
||||
|
* @param variables the set of variables to check |
||||
|
*/ |
||||
|
std::vector<std::string> const checkForUndeclaredVariables(std::set<storm::Variable> const& variables){ |
||||
|
std::vector<std::string> result; |
||||
|
carl::VariablePool& vPool = carl::VariablePool::getInstance(); |
||||
|
for (storm::Variable const& variableToCheck : variables){ |
||||
|
std::string const& variableString = vPool.getName(variableToCheck, useReadableVarNames); |
||||
|
// first check if this variable is already declared |
||||
|
bool alreadyDeclared=false; |
||||
|
for(std::set<std::string> const& variables : declaredVariables){ |
||||
|
if(variables.find(variableString)!=variables.end()){ |
||||
|
alreadyDeclared=true; |
||||
|
break; |
||||
|
} |
||||
|
} |
||||
|
// secondly, declare the variable if necessary |
||||
|
if(!alreadyDeclared){ |
||||
|
STORM_LOG_DEBUG("Declaring the variable " + variableString); |
||||
|
declaredVariables.back().insert(variableString); |
||||
|
std::string varDeclaration = "( declare-fun " + variableString + " () "; |
||||
|
switch (variableToCheck.getType()){ |
||||
|
case carl::VariableType::VT_BOOL: |
||||
|
varDeclaration += "Bool"; |
||||
|
break; |
||||
|
case carl::VariableType::VT_REAL: |
||||
|
varDeclaration += "Real"; |
||||
|
break; |
||||
|
case carl::VariableType::VT_INT: |
||||
|
varDeclaration += "Int"; |
||||
|
break; |
||||
|
default: |
||||
|
STORM_LOG_THROW(false, storm::exceptions::InvalidTypeException, "The type of the variable is not supported"); |
||||
|
} |
||||
|
varDeclaration += " )"; |
||||
|
result.push_back(varDeclaration); |
||||
|
} |
||||
|
} |
||||
|
return result; |
||||
|
} |
||||
|
#endif |
||||
|
|
||||
|
private: |
||||
|
// The manager that can be used to build expressions. |
||||
|
storm::expressions::ExpressionManager& manager; |
||||
|
// A flag to decide whether readable var names should be used instead of intern representation |
||||
|
bool useReadableVarNames; |
||||
|
// the declared variables for the different scopes |
||||
|
std::vector<std::set<std::string>> declaredVariables; |
||||
|
}; |
||||
|
} // namespace adapters |
||||
|
} // namespace storm |
||||
|
|
||||
|
#endif /* STORM_ADAPTERS_SMT2EXPRESSIONADAPTER_H_ */ |
@ -0,0 +1,136 @@ |
|||||
|
#include "src/solver/Smt2SmtSolver.h"
|
||||
|
|
||||
|
#include "src/exceptions/NotSupportedException.h"
|
||||
|
#include "src/exceptions/InvalidStateException.h"
|
||||
|
#include "src/exceptions/NotImplementedException.h"
|
||||
|
#include "utility/macros.h"
|
||||
|
#include "adapters/CarlAdapter.h"
|
||||
|
#include "exceptions/IllegalArgumentException.h"
|
||||
|
#include "exceptions/IllegalFunctionCallException.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace solver { |
||||
|
|
||||
|
Smt2SmtSolver::Smt2ModelReference::Smt2ModelReference(storm::expressions::ExpressionManager const& manager, storm::adapters::Smt2ExpressionAdapter& expressionAdapter) : ModelReference(manager), expressionAdapter(expressionAdapter){ |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
bool Smt2SmtSolver::Smt2ModelReference::getBooleanValue(storm::expressions::Variable const& variable) const { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
int_fast64_t Smt2SmtSolver::Smt2ModelReference::getIntegerValue(storm::expressions::Variable const& variable) const { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
double Smt2SmtSolver::Smt2ModelReference::getRationalValue(storm::expressions::Variable const& variable) const { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
Smt2SmtSolver::Smt2SmtSolver(storm::expressions::ExpressionManager& manager, bool useCarlExpressions) : SmtSolver(manager), expressionAdapter(nullptr), lastCheckAssumptions(false), lastResult(CheckResult::Unknown), useCarlExpressions(useCarlExpressions) { |
||||
|
#ifndef STORM_HAVE_CARL
|
||||
|
STORM_LOG_THROW(!useCarlExpressions, storm::exceptions::IllegalArgumentException, "Tried to use carl expressions but storm is not linked with CARL"); |
||||
|
#endif
|
||||
|
expressionAdapter = std::unique_ptr<storm::adapters::Smt2ExpressionAdapter>(new storm::adapters::Smt2ExpressionAdapter(this->getManager(), true)); |
||||
|
init(); |
||||
|
} |
||||
|
|
||||
|
Smt2SmtSolver::~Smt2SmtSolver() { |
||||
|
writeCommand("( exit )"); |
||||
|
//todo make sure that the process exits
|
||||
|
} |
||||
|
|
||||
|
void Smt2SmtSolver::push() { |
||||
|
expressionAdapter->increaseScope(); |
||||
|
writeCommand("( push 1 ) "); |
||||
|
} |
||||
|
|
||||
|
void Smt2SmtSolver::pop() { |
||||
|
expressionAdapter->decreaseScope(); |
||||
|
writeCommand("( pop 1 ) "); |
||||
|
} |
||||
|
|
||||
|
void Smt2SmtSolver::pop(uint_fast64_t n) { |
||||
|
expressionAdapter->decreaseScope(n); |
||||
|
writeCommand("( pop " + std::to_string(n) + " ) "); |
||||
|
} |
||||
|
|
||||
|
void Smt2SmtSolver::reset() { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
void Smt2SmtSolver::add(storm::expressions::Expression const& assertion) { |
||||
|
STORM_LOG_THROW(!useCarlExpressions, storm::exceptions::IllegalFunctionCallException, "This solver was initialized without allowing carl expressions"); |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
#ifdef STORM_HAVE_CARL
|
||||
|
void Smt2SmtSolver::add(storm::RationalFunction const& leftHandSide, storm::CompareRelation const& relation, storm::RationalFunction const& rightHandSide) { |
||||
|
STORM_LOG_THROW(useCarlExpressions, storm::exceptions::IllegalFunctionCallException, "This solver was initialized without allowing carl expressions"); |
||||
|
//if some of the occurring variables are not declared yet, we will have to.
|
||||
|
std::set<storm::Variable> variables; |
||||
|
leftHandSide.gatherVariables(variables); |
||||
|
rightHandSide.gatherVariables(variables); |
||||
|
std::vector<std::string> const varDeclarations = expressionAdapter->checkForUndeclaredVariables(variables); |
||||
|
for (auto declaration : varDeclarations){ |
||||
|
writeCommand(declaration); |
||||
|
} |
||||
|
writeCommand("( assert " + expressionAdapter->translateExpression(leftHandSide, relation, rightHandSide) + " )"); |
||||
|
} |
||||
|
|
||||
|
template<> |
||||
|
void Smt2SmtSolver::add(carl::Constraint<storm::RationalFunction> const& constraint) { |
||||
|
add(constraint.lhs(), constraint.rel()); |
||||
|
} |
||||
|
|
||||
|
template<> |
||||
|
void Smt2SmtSolver::add(carl::Constraint<storm::RawPolynomial> const& constraint) { |
||||
|
//if some of the occurring variables are not declared yet, we will have to.
|
||||
|
std::set<storm::Variable> variables = constraint.lhs().gatherVariables(); |
||||
|
std::vector<std::string> const varDeclarations = expressionAdapter->checkForUndeclaredVariables(variables); |
||||
|
for (auto declaration : varDeclarations){ |
||||
|
writeCommand(declaration); |
||||
|
} |
||||
|
writeCommand("( assert " + expressionAdapter->translateExpression(constraint) + " )"); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
#endif
|
||||
|
|
||||
|
SmtSolver::CheckResult Smt2SmtSolver::check() { |
||||
|
writeCommand("( check-sat )"); |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
SmtSolver::CheckResult Smt2SmtSolver::checkWithAssumptions(std::set<storm::expressions::Expression> const& assumptions) { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
|
||||
|
#ifndef WINDOWS
|
||||
|
|
||||
|
SmtSolver::CheckResult Smt2SmtSolver::checkWithAssumptions(std::initializer_list<storm::expressions::Expression> const& assumptions) { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotImplementedException, "functionality not (yet) implemented"); |
||||
|
} |
||||
|
#endif
|
||||
|
|
||||
|
void Smt2SmtSolver::init() { |
||||
|
//hard coded output file.. for now
|
||||
|
commandFile.open("/home/tim/Desktop/smtlibcommand.txt", std::ios::trunc); |
||||
|
STORM_LOG_THROW(commandFile.is_open(), storm::exceptions::InvalidArgumentException, "The file where the smt2commands should be written to could not be opened"); |
||||
|
|
||||
|
//some initial commands
|
||||
|
writeCommand("( set-logic QF_NRA )"); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
void Smt2SmtSolver::writeCommand(std::string smt2Command) { |
||||
|
if (commandFile.is_open()) { |
||||
|
commandFile << smt2Command << std::endl; |
||||
|
} else{ |
||||
|
std::cout << "COMMAND FILE IS CLOSED" <<std::endl; |
||||
|
} |
||||
|
|
||||
|
//todo actually write to the solver
|
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,112 @@ |
|||||
|
#ifndef STORM_SOLVER_SMT2SMTSOLVER |
||||
|
#define STORM_SOLVER_SMT2SMTSOLVER |
||||
|
|
||||
|
#include <iostream> |
||||
|
#include <fstream> |
||||
|
|
||||
|
#include "storm-config.h" |
||||
|
#include "src/solver/SmtSolver.h" |
||||
|
#include "src/adapters/Smt2ExpressionAdapter.h" |
||||
|
#include "src/adapters/CarlAdapter.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace solver { |
||||
|
|
||||
|
class Smt2SmtSolver : public SmtSolver { |
||||
|
public: |
||||
|
|
||||
|
class Smt2ModelReference : public SmtSolver::ModelReference { |
||||
|
public: |
||||
|
Smt2ModelReference(storm::expressions::ExpressionManager const& manager, storm::adapters::Smt2ExpressionAdapter& expressionAdapter); |
||||
|
virtual bool getBooleanValue(storm::expressions::Variable const& variable) const override; |
||||
|
virtual int_fast64_t getIntegerValue(storm::expressions::Variable const& variable) const override; |
||||
|
virtual double getRationalValue(storm::expressions::Variable const& variable) const override; |
||||
|
|
||||
|
private: |
||||
|
|
||||
|
// The expression adapter that is used to translate the variable names. |
||||
|
storm::adapters::Smt2ExpressionAdapter& expressionAdapter; |
||||
|
}; |
||||
|
|
||||
|
public: |
||||
|
/*! |
||||
|
* Creates a new solver with the given manager. |
||||
|
* In addition to storm expressions, this solver also allows carl expressions (but not both). |
||||
|
* Hence, there is a flag to chose between the two |
||||
|
*/ |
||||
|
Smt2SmtSolver(storm::expressions::ExpressionManager& manager, bool useCarlExpressions = false); |
||||
|
virtual ~Smt2SmtSolver(); |
||||
|
|
||||
|
virtual void push() override; |
||||
|
|
||||
|
virtual void pop() override; |
||||
|
|
||||
|
virtual void pop(uint_fast64_t n) override; |
||||
|
|
||||
|
virtual void reset() override; |
||||
|
|
||||
|
virtual void add(storm::expressions::Expression const& assertion) override; |
||||
|
#ifdef STORM_HAVE_CARL |
||||
|
//adds the constraint "leftHandSide relation rightHandSide" |
||||
|
virtual void add(storm::RationalFunction const& leftHandSide, storm::CompareRelation const& relation, storm::RationalFunction const& rightHandSide=storm::RationalFunction(0)); |
||||
|
|
||||
|
//adds the given carl constraint |
||||
|
template<typename FunctionType> |
||||
|
void add(typename carl::Constraint<FunctionType> const& constraint); |
||||
|
#endif |
||||
|
|
||||
|
virtual CheckResult check() override; |
||||
|
|
||||
|
virtual CheckResult checkWithAssumptions(std::set<storm::expressions::Expression> const& assumptions) override; |
||||
|
|
||||
|
#ifndef WINDOWS |
||||
|
virtual CheckResult checkWithAssumptions(std::initializer_list<storm::expressions::Expression> const& assumptions) override; |
||||
|
#endif |
||||
|
//Todo: some of these might be added in the future |
||||
|
//virtual storm::expressions::SimpleValuation getModelAsValuation() override; |
||||
|
|
||||
|
//virtual std::shared_ptr<SmtSolver::ModelReference> getModel() override; |
||||
|
|
||||
|
// virtual std::vector<storm::expressions::SimpleValuation> allSat(std::vector<storm::expressions::Variable> const& important) override; |
||||
|
|
||||
|
// virtual uint_fast64_t allSat(std::vector<storm::expressions::Variable> const& important, std::function<bool(storm::expressions::SimpleValuation&)> const& callback) override; |
||||
|
|
||||
|
// virtual uint_fast64_t allSat(std::vector<storm::expressions::Variable> const& important, std::function<bool(ModelReference&)> const& callback) override; |
||||
|
|
||||
|
// virtual std::vector<storm::expressions::Expression> getUnsatAssumptions() override; |
||||
|
|
||||
|
private: |
||||
|
|
||||
|
|
||||
|
/*! |
||||
|
* Initializes the solver |
||||
|
*/ |
||||
|
void init(); |
||||
|
|
||||
|
|
||||
|
/*! Writes the given command to the solver |
||||
|
* @param smt2Command the command that the solver will receive |
||||
|
*/ |
||||
|
void writeCommand(std::string smt2Command); |
||||
|
|
||||
|
|
||||
|
|
||||
|
// a filestream where the commands that we send to the solver will be stored (can be used for debugging purposes) |
||||
|
std::ofstream commandFile; |
||||
|
|
||||
|
// An expression adapter that is used for translating the expression into Smt2's format. |
||||
|
std::unique_ptr<storm::adapters::Smt2ExpressionAdapter> expressionAdapter; |
||||
|
|
||||
|
// A flag storing whether the last call to a check method provided aussumptions. |
||||
|
bool lastCheckAssumptions; |
||||
|
|
||||
|
// The last result that was returned by any of the check methods. |
||||
|
CheckResult lastResult; |
||||
|
|
||||
|
// A flag that states whether we want to use carl expressions. |
||||
|
bool useCarlExpressions; |
||||
|
|
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
#endif // STORM_SOLVER_SMT2SMTSOLVER |
Write
Preview
Loading…
Cancel
Save
Reference in new issue