You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

192 lines
4.7 KiB

/**
* @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)
{
}
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);
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 = T(it->second);
}
else
{
carl::Variable nVar = carl::VariablePool::getInstance().getFreshVariable(varName);
mSharedState->emplace(varName,nVar);
mValue = T(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::CoeffType(std::to_string(expression->getValue()), 10));
mValue = T(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()));
}
const T& value() const
{
return mValue;
}
private:
S* mSharedState;
T mValue;
};
template<typename T>
class ExpressionEvaluation
{
public:
ExpressionEvaluation() : mState()
{
}
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);
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;
};
/**
* 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