16 changed files with 339 additions and 289 deletions
-
1src/adapters/extendedCarl.h
-
47src/builder/ExplicitPrismModelBuilder.cpp
-
14src/builder/ExplicitPrismModelBuilder.h
-
6src/modelchecker/reachability/CollectConstraints.h
-
4src/models/Dtmc.h
-
209src/storage/expressions/ExpressionEvaluation.h
-
36src/storage/expressions/ExpressionEvaluator.cpp
-
43src/storage/expressions/ExpressionEvaluator.h
-
12src/storage/expressions/ExpressionEvaluatorBase.cpp
-
3src/storage/expressions/ExpressionEvaluatorBase.h
-
51src/storage/expressions/ExprtkExpressionEvaluator.cpp
-
39src/storage/expressions/ExprtkExpressionEvaluator.h
-
102src/storage/expressions/ToRationalFunctionVisitor.cpp
-
53src/storage/expressions/ToRationalFunctionVisitor.h
-
6src/storage/parameters.h
-
2src/stormParametric.cpp
@ -1,209 +0,0 @@ |
|||
/** |
|||
* @file: ExpressionEvaluation.h |
|||
* @author: Sebastian Junges |
|||
* |
|||
* @since April 4, 2014 |
|||
*/ |
|||
|
|||
#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATION_H_ |
|||
#define STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATION_H_ |
|||
|
|||
#include "ExpressionVisitor.h" |
|||
#include "BaseExpression.h" |
|||
#include "IfThenElseExpression.h" |
|||
#include "DoubleLiteralExpression.h" |
|||
#include "BinaryNumericalFunctionExpression.h" |
|||
|
|||
#include "src/storage/parameters.h" |
|||
#include "IntegerLiteralExpression.h" |
|||
#include "BinaryExpression.h" |
|||
#include "src/storage/parameters.h" |
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
|
|||
template<typename T> |
|||
struct StateType |
|||
{ |
|||
typedef int type; |
|||
}; |
|||
|
|||
#ifdef PARAMETRIC_SYSTEMS |
|||
template<> |
|||
struct StateType<Polynomial> |
|||
{ |
|||
typedef std::map<std::string, carl::Variable> type; |
|||
}; |
|||
|
|||
template<> |
|||
struct StateType<RationalFunction> |
|||
{ |
|||
typedef std::map<std::string, carl::Variable> type; |
|||
}; |
|||
#endif |
|||
|
|||
template<typename T, typename S> |
|||
class ExpressionEvaluationVisitor : public ExpressionVisitor |
|||
{ |
|||
public: |
|||
ExpressionEvaluationVisitor(S* sharedState) |
|||
: mSharedState(sharedState), cache(new carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>()) |
|||
{ |
|||
|
|||
} |
|||
|
|||
ExpressionEvaluationVisitor(S* sharedState, std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache) |
|||
: mSharedState(sharedState), cache(cache) |
|||
{ |
|||
|
|||
} |
|||
|
|||
|
|||
virtual ~ExpressionEvaluationVisitor() { |
|||
|
|||
} |
|||
|
|||
virtual void visit(IfThenElseExpression const* expression) |
|||
{ |
|||
std::cout << "ite" << std::endl; |
|||
|
|||
} |
|||
|
|||
virtual void visit(BinaryBooleanFunctionExpression const* expression) |
|||
{ |
|||
std::cout << "bbf" << std::endl; |
|||
} |
|||
virtual void visit(BinaryNumericalFunctionExpression const* expression) |
|||
{ |
|||
ExpressionEvaluationVisitor* visitor = new ExpressionEvaluationVisitor(mSharedState, this->cache); |
|||
expression->getFirstOperand()->accept(visitor); |
|||
mValue = visitor->value(); |
|||
expression->getSecondOperand()->accept(visitor); |
|||
switch(expression->getOperatorType()) |
|||
{ |
|||
case BinaryNumericalFunctionExpression::OperatorType::Plus: |
|||
mValue += visitor->value(); |
|||
break; |
|||
case BinaryNumericalFunctionExpression::OperatorType::Minus: |
|||
mValue -= visitor->value(); |
|||
break; |
|||
case BinaryNumericalFunctionExpression::OperatorType::Times: |
|||
mValue *= visitor->value(); |
|||
break; |
|||
case BinaryNumericalFunctionExpression::OperatorType::Divide: |
|||
mValue /= visitor->value(); |
|||
break; |
|||
default: |
|||
// TODO exception. |
|||
assert(false); |
|||
} |
|||
|
|||
delete visitor; |
|||
} |
|||
virtual void visit(BinaryRelationExpression const* expression) |
|||
{ |
|||
std::cout << "br" << std::endl; |
|||
} |
|||
virtual void visit(VariableExpression const* expression) |
|||
{ |
|||
std::string const& varName= expression->getVariableName(); |
|||
auto it = mSharedState->find(varName); |
|||
if(it != mSharedState->end()) |
|||
{ |
|||
mValue = convertVariableToPolynomial(it->second); |
|||
// mValue = T(typename T::PolyType(typename T::PolyType::PolyType(it->second), cache)); |
|||
} |
|||
else |
|||
{ |
|||
carl::Variable nVar = carl::VariablePool::getInstance().getFreshVariable(varName); |
|||
mSharedState->emplace(varName,nVar); |
|||
mValue = convertVariableToPolynomial(nVar); |
|||
} |
|||
} |
|||
virtual void visit(UnaryBooleanFunctionExpression const* expression) |
|||
{ |
|||
std::cout << "ubf" << std::endl; |
|||
} |
|||
virtual void visit(UnaryNumericalFunctionExpression const* expression) |
|||
{ |
|||
std::cout << "unf" << std::endl; |
|||
} |
|||
virtual void visit(BooleanLiteralExpression const* expression) |
|||
{ |
|||
std::cout << "bl" << std::endl; |
|||
} |
|||
virtual void visit(IntegerLiteralExpression const* expression) |
|||
{ |
|||
mValue = T(typename T::PolyType(typename T::CoeffType(expression->getValue()))); |
|||
} |
|||
virtual void visit(DoubleLiteralExpression const* expression) |
|||
{ |
|||
std::stringstream str; |
|||
str << std::fixed << std::setprecision( 3 ) << expression->getValue(); |
|||
mValue = T(carl::rationalize<cln::cl_RA>(str.str())); |
|||
} |
|||
|
|||
template<typename TP = typename T::PolyType, carl::EnableIf<carl::needs_cache<TP>> = carl::dummy> |
|||
T convertVariableToPolynomial(carl::Variable const& nVar) { |
|||
return T(typename T::PolyType(typename T::PolyType::PolyType(nVar), cache)); |
|||
} |
|||
|
|||
template<typename TP = typename T::PolyType, carl::DisableIf<carl::needs_cache<TP>> = carl::dummy> |
|||
T convertVariableToPolynomial(carl::Variable const& nVar) { |
|||
return T(nVar); |
|||
} |
|||
|
|||
const T& value() const |
|||
{ |
|||
return mValue; |
|||
} |
|||
|
|||
private: |
|||
S* mSharedState; |
|||
T mValue; |
|||
std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache; |
|||
}; |
|||
|
|||
template<typename T> |
|||
class ExpressionEvaluation |
|||
{ |
|||
public: |
|||
ExpressionEvaluation() : mState(), cache(new carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>(100000)) |
|||
{ |
|||
// Intentionally left empty. |
|||
} |
|||
|
|||
|
|||
T evaluate(Expression const& expr, storm::expressions::SimpleValuation const* val) |
|||
{ |
|||
ExpressionEvaluationVisitor<T, typename StateType<T>::type>* visitor = new ExpressionEvaluationVisitor<T, typename StateType<T>::type>(&mState, cache); |
|||
Expression expressionToTranslate = expr.substitute(*val); |
|||
expressionToTranslate.getBaseExpression().accept(visitor); |
|||
T result = visitor->value(); |
|||
// result.simplify(); |
|||
delete visitor; |
|||
return result; |
|||
} |
|||
|
|||
protected: |
|||
typename StateType<T>::type mState; |
|||
std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache; |
|||
}; |
|||
|
|||
/** |
|||
* For doubles, we keep using the getValueAs from the expressions, as this should be more efficient. |
|||
*/ |
|||
template<> |
|||
class ExpressionEvaluation<double> |
|||
{ |
|||
public: |
|||
double evaluate(Expression const& expr, storm::expressions::SimpleValuation const* val) const |
|||
{ |
|||
return expr.evaluateAsDouble(val); |
|||
} |
|||
}; |
|||
|
|||
} |
|||
} |
|||
|
|||
#endif |
@ -0,0 +1,36 @@ |
|||
#include "src/storage/expressions/ExpressionEvaluator.h"
|
|||
#include "src/storage/expressions/ExpressionManager.h"
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
ExpressionEvaluator<double>::ExpressionEvaluator(storm::expressions::ExpressionManager const& manager) : ExprtkExpressionEvaluator(manager) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
#ifdef PARAMETRIC_SYSTEMS
|
|||
ExpressionEvaluator<RationalFunction>::ExpressionEvaluator(storm::expressions::ExpressionManager const& manager) : ExprtkExpressionEvaluatorBase<RationalFunction>(manager) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
void ExpressionEvaluator<RationalFunction>::setBooleanValue(storm::expressions::Variable const& variable, bool value) { |
|||
ExprtkExpressionEvaluatorBase::setBooleanValue(variable, value); |
|||
this->variableToExpressionMap[variable] = this->getManager().boolean(value); |
|||
} |
|||
|
|||
void ExpressionEvaluator<RationalFunction>::setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) { |
|||
ExprtkExpressionEvaluatorBase::setIntegerValue(variable, value); |
|||
this->variableToExpressionMap[variable] = this->getManager().integer(value); |
|||
} |
|||
|
|||
void ExpressionEvaluator<RationalFunction>::setRationalValue(storm::expressions::Variable const& variable, double value) { |
|||
ExprtkExpressionEvaluatorBase::setRationalValue(variable, value); |
|||
this->variableToExpressionMap[variable] = this->getManager().rational(value); |
|||
} |
|||
|
|||
RationalFunction ExpressionEvaluator<RationalFunction>::asRational(Expression const& expression) const { |
|||
Expression substitutedExpression = expression.substitute(variableToExpressionMap); |
|||
return this->rationalFunctionVisitor.toRationalFunction(substitutedExpression); |
|||
} |
|||
#endif
|
|||
} |
|||
} |
@ -1,11 +1,46 @@ |
|||
#ifndef STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATOR_H_ |
|||
#define STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATOR_H_ |
|||
|
|||
#include <unordered_map> |
|||
|
|||
#include "src/storage/parameters.h" |
|||
#include "src/storage/expressions/Variable.h" |
|||
#include "src/storage/expressions/Expression.h" |
|||
#include "src/storage/expressions/ExprtkExpressionEvaluator.h" |
|||
#include "src/storage/expressions/ToRationalFunctionVisitor.h" |
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
template<RationalType> |
|||
template<typename RationalType> |
|||
class ExpressionEvaluator; |
|||
|
|||
template<> |
|||
class ExpressionEvaluator<double> { |
|||
class ExpressionEvaluator<double> : public ExprtkExpressionEvaluator { |
|||
public: |
|||
ExpressionEvaluator(storm::expressions::ExpressionManager const& manager); |
|||
}; |
|||
|
|||
#ifdef STORM_HAVE_CARL |
|||
template<> |
|||
class ExpressionEvaluator<RationalFunction> : public ExprtkExpressionEvaluatorBase<RationalFunction> { |
|||
public: |
|||
ExpressionEvaluator(storm::expressions::ExpressionManager const& manager); |
|||
|
|||
void setBooleanValue(storm::expressions::Variable const& variable, bool value) override; |
|||
void setIntegerValue(storm::expressions::Variable const& variable, int_fast64_t value) override; |
|||
void setRationalValue(storm::expressions::Variable const& variable, double value) override; |
|||
|
|||
RationalFunction asRational(Expression const& expression) const override; |
|||
|
|||
private: |
|||
// A mapping of variables to their expressions. |
|||
std::unordered_map<storm::expressions::Variable, storm::expressions::Expression> variableToExpressionMap; |
|||
|
|||
} |
|||
// A visitor that can be used to translate expressions to rational functions. |
|||
mutable ToRationalFunctionVisitor<RationalFunction> rationalFunctionVisitor; |
|||
}; |
|||
#endif |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endif /* STORM_STORAGE_EXPRESSIONS_EXPRESSIONEVALUATOR_H_ */ |
@ -1,15 +1,23 @@ |
|||
#include "src/storage/expressions/ExpressionEvaluatorBase.h"
|
|||
|
|||
#include "src/storage/expressions/ExpressionManager.h"
|
|||
#include "src/storage/parameters.h"
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
ExpressionEvaluatorBase::ExpressionEvaluatorBase(storm::expressions::ExpressionManager const& manager) : manager(manager.getSharedPointer()) { |
|||
template<typename RationalType> |
|||
ExpressionEvaluatorBase<RationalType>::ExpressionEvaluatorBase(storm::expressions::ExpressionManager const& manager) : manager(manager.getSharedPointer()) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
storm::expressions::ExpressionManager const& ExpressionEvaluatorBase::getManager() const { |
|||
template<typename RationalType> |
|||
storm::expressions::ExpressionManager const& ExpressionEvaluatorBase<RationalType>::getManager() const { |
|||
return *manager; |
|||
} |
|||
|
|||
template class ExpressionEvaluatorBase<double>; |
|||
#ifdef STORM_HAVE_CARL
|
|||
template class ExpressionEvaluatorBase<RationalFunction>; |
|||
#endif
|
|||
} |
|||
} |
@ -0,0 +1,102 @@ |
|||
#include "src/storage/expressions/ToRationalFunctionVisitor.h"
|
|||
|
|||
#include <sstream>
|
|||
|
|||
#include "src/utility/macros.h"
|
|||
|
|||
#ifdef STORM_HAVE_CARL
|
|||
|
|||
namespace storm { |
|||
namespace expressions { |
|||
template<typename RationalFunctionType> |
|||
ToRationalFunctionVisitor<RationalFunctionType>::ToRationalFunctionVisitor() : ExpressionVisitor(), cache(new carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>()) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
RationalFunctionType ToRationalFunctionVisitor<RationalFunctionType>::toRationalFunction(Expression const& expression) { |
|||
return boost::any_cast<RationalFunctionType>(expression.accept(*this)); |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(IfThenElseExpression const& expression) { |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryBooleanFunctionExpression const& expression) { |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryNumericalFunctionExpression const& expression) { |
|||
RationalFunctionType firstOperandAsRationalFunction = boost::any_cast<RationalFunctionType>(expression.getFirstOperand()->accept(*this)); |
|||
RationalFunctionType secondOperandAsRationalFunction = boost::any_cast<RationalFunctionType>(expression.getSecondOperand()->accept(*this)); |
|||
switch(expression.getOperatorType()) { |
|||
case BinaryNumericalFunctionExpression::OperatorType::Plus: |
|||
return firstOperandAsRationalFunction + secondOperandAsRationalFunction; |
|||
break; |
|||
case BinaryNumericalFunctionExpression::OperatorType::Minus: |
|||
return firstOperandAsRationalFunction - secondOperandAsRationalFunction; |
|||
break; |
|||
case BinaryNumericalFunctionExpression::OperatorType::Times: |
|||
return firstOperandAsRationalFunction * secondOperandAsRationalFunction; |
|||
break; |
|||
case BinaryNumericalFunctionExpression::OperatorType::Divide: |
|||
return firstOperandAsRationalFunction / secondOperandAsRationalFunction; |
|||
break; |
|||
default: |
|||
STORM_LOG_ASSERT(false, "Illegal operator type."); |
|||
} |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BinaryRelationExpression const& expression) { |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(VariableExpression const& expression) { |
|||
auto variablePair = variableToVariableMap.find(expression.getVariable()); |
|||
if (variablePair != variableToVariableMap.end()) { |
|||
return convertVariableToPolynomial(variablePair->second); |
|||
} else { |
|||
carl::Variable carlVariable = carl::VariablePool::getInstance().getFreshVariable(expression.getVariableName()); |
|||
variableToVariableMap.emplace(expression.getVariable(), carlVariable); |
|||
return convertVariableToPolynomial(carlVariable); |
|||
} |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(UnaryBooleanFunctionExpression const& expression) { |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(UnaryNumericalFunctionExpression const& expression) { |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(BooleanLiteralExpression const& expression) { |
|||
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Expression cannot be translated into a rational function."); |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(IntegerLiteralExpression const& expression) { |
|||
return RationalFunctionType(typename RationalFunctionType::PolyType(typename RationalFunctionType::CoeffType(expression.getValue()))); |
|||
} |
|||
|
|||
template<typename RationalFunctionType> |
|||
boost::any ToRationalFunctionVisitor<RationalFunctionType>::visit(DoubleLiteralExpression const& expression) { |
|||
std::stringstream str; |
|||
str << std::fixed << std::setprecision(3) << expression.getValue(); |
|||
return RationalFunctionType(carl::rationalize<cln::cl_RA>(str.str())); |
|||
} |
|||
|
|||
template class ToRationalFunctionVisitor<storm::RationalFunction>; |
|||
|
|||
} |
|||
} |
|||
|
|||
#endif
|
@ -0,0 +1,53 @@ |
|||
#ifndef STORM_STORAGE_EXPRESSIONS_TORATIONALFUNCTIONVISITOR_H_ |
|||
#define STORM_STORAGE_EXPRESSIONS_TORATIONALFUNCTIONVISITOR_H_ |
|||
|
|||
#include "src/storage/parameters.h" |
|||
#include "src/storage/expressions/Expression.h" |
|||
#include "src/storage/expressions/Expressions.h" |
|||
#include "src/storage/expressions/ExpressionVisitor.h" |
|||
#include "src/storage/expressions/Variable.h" |
|||
|
|||
#ifdef STORM_HAVE_CARL |
|||
namespace storm { |
|||
namespace expressions { |
|||
|
|||
template<typename RationalFunctionType> |
|||
class ToRationalFunctionVisitor : public ExpressionVisitor { |
|||
public: |
|||
ToRationalFunctionVisitor(); |
|||
|
|||
RationalFunctionType toRationalFunction(Expression const& expression); |
|||
|
|||
virtual boost::any visit(IfThenElseExpression const& expression) override; |
|||
virtual boost::any visit(BinaryBooleanFunctionExpression const& expression) override; |
|||
virtual boost::any visit(BinaryNumericalFunctionExpression const& expression) override; |
|||
virtual boost::any visit(BinaryRelationExpression const& expression) override; |
|||
virtual boost::any visit(VariableExpression const& expression) override; |
|||
virtual boost::any visit(UnaryBooleanFunctionExpression const& expression) override; |
|||
virtual boost::any visit(UnaryNumericalFunctionExpression const& expression) override; |
|||
virtual boost::any visit(BooleanLiteralExpression const& expression) override; |
|||
virtual boost::any visit(IntegerLiteralExpression const& expression) override; |
|||
virtual boost::any visit(DoubleLiteralExpression const& expression) override; |
|||
|
|||
private: |
|||
template<typename TP = typename RationalFunctionType::PolyType, carl::EnableIf<carl::needs_cache<TP>> = carl::dummy> |
|||
RationalFunctionType convertVariableToPolynomial(carl::Variable const& variable) { |
|||
return RationalFunctionType(typename RationalFunctionType::PolyType(typename RationalFunctionType::PolyType::PolyType(variable), cache)); |
|||
} |
|||
|
|||
template<typename TP = typename RationalFunctionType::PolyType, carl::DisableIf<carl::needs_cache<TP>> = carl::dummy> |
|||
RationalFunctionType convertVariableToPolynomial(carl::Variable const& variable) { |
|||
return RationalFunctionType(variable); |
|||
} |
|||
|
|||
// A mapping from our variables to carl's. |
|||
std::unordered_map<storm::expressions::Variable, carl::Variable> variableToVariableMap; |
|||
|
|||
// The cache that is used in case the underlying type needs a cache. |
|||
std::shared_ptr<carl::Cache<carl::PolynomialFactorizationPair<RawPolynomial>>> cache; |
|||
}; |
|||
} |
|||
} |
|||
#endif |
|||
|
|||
#endif /* STORM_STORAGE_EXPRESSIONS_TORATIONALFUNCTIONVISITOR_H_ */ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue