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
			
			
				main
			
			
		
				 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
- 
					59src/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