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