41 changed files with 998 additions and 18 deletions
-
6CHANGELOG.md
-
15src/storm-parsers/parser/ExpressionCreator.cpp
-
1src/storm-parsers/parser/ExpressionCreator.h
-
11src/storm-parsers/parser/ExpressionParser.cpp
-
15src/storm-parsers/parser/ExpressionParser.h
-
11src/storm-parsers/parser/PrismParser.h
-
8src/storm/storage/expressions/BaseExpression.cpp
-
4src/storm/storage/expressions/BaseExpression.h
-
32src/storm/storage/expressions/Expression.cpp
-
9src/storm/storage/expressions/Expression.h
-
11src/storm/storage/expressions/ExpressionVisitor.cpp
-
2src/storm/storage/expressions/ExpressionVisitor.h
-
1src/storm/storage/expressions/Expressions.h
-
3src/storm/storage/expressions/OperatorType.cpp
-
5src/storm/storage/expressions/OperatorType.h
-
100src/storm/storage/expressions/PredicateExpression.cpp
-
66src/storm/storage/expressions/PredicateExpression.h
-
171src/storm/storage/expressions/SimplificationVisitor.cpp
-
41src/storm/storage/expressions/SimplificationVisitor.h
-
20src/storm/storage/expressions/SubstitutionVisitor.cpp
-
3src/storm/storage/expressions/SubstitutionVisitor.h
-
291src/storm/storage/expressions/ToDiceStringVisitor.cpp
-
37src/storm/storage/expressions/ToDiceStringVisitor.h
-
4src/storm/storage/prism/Assignment.cpp
-
4src/storm/storage/prism/Assignment.h
-
4src/storm/storage/prism/BooleanVariable.cpp
-
3src/storm/storage/prism/BooleanVariable.h
-
12src/storm/storage/prism/Command.cpp
-
3src/storm/storage/prism/Command.h
-
9src/storm/storage/prism/Formula.cpp
-
1src/storm/storage/prism/Formula.h
-
4src/storm/storage/prism/IntegerVariable.cpp
-
4src/storm/storage/prism/IntegerVariable.h
-
9src/storm/storage/prism/Label.cpp
-
3src/storm/storage/prism/Label.h
-
22src/storm/storage/prism/Module.cpp
-
4src/storm/storage/prism/Module.h
-
46src/storm/storage/prism/Program.cpp
-
5src/storm/storage/prism/Program.h
-
14src/storm/storage/prism/Update.cpp
-
2src/storm/storage/prism/Update.h
@ -0,0 +1,11 @@ |
|||||
|
#include "storm/storage/expressions/ExpressionVisitor.h"
|
||||
|
#include "storm/utility/macros.h"
|
||||
|
#include "storm/exceptions/NotImplementedException.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace expressions { |
||||
|
boost::any ExpressionVisitor::visit(PredicateExpression const&, boost::any const&) { |
||||
|
STORM_LOG_THROW(false,storm::exceptions::NotImplementedException, "Predicate Expressions are not supported by this visitor"); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,100 @@ |
|||||
|
|
||||
|
#include "storm/storage/expressions/PredicateExpression.h"
|
||||
|
|
||||
|
#include "storm/storage/expressions/ExpressionVisitor.h"
|
||||
|
#include "storm/utility/macros.h"
|
||||
|
#include "storm/storage/BitVector.h"
|
||||
|
#include "storm/exceptions/InvalidTypeException.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace expressions { |
||||
|
OperatorType toOperatorType(PredicateExpression::PredicateType tp) { |
||||
|
switch (tp) { |
||||
|
case PredicateExpression::PredicateType::AtMostOneOf: return OperatorType::AtMostOneOf; |
||||
|
case PredicateExpression::PredicateType::AtLeastOneOf: return OperatorType::AtLeastOneOf; |
||||
|
case PredicateExpression::PredicateType::ExactlyOneOf: return OperatorType::ExactlyOneOf; |
||||
|
} |
||||
|
STORM_LOG_ASSERT(false, "Predicate type not supported"); |
||||
|
} |
||||
|
|
||||
|
PredicateExpression::PredicateExpression(ExpressionManager const &manager, Type const& type, std::vector <std::shared_ptr<BaseExpression const>> const &operands, PredicateType predicateType) : BaseExpression(manager, type), predicate(predicateType), operands(operands) {} |
||||
|
|
||||
|
// Override base class methods.
|
||||
|
storm::expressions::OperatorType PredicateExpression::getOperator() const { |
||||
|
return toOperatorType(predicate); |
||||
|
} |
||||
|
|
||||
|
bool PredicateExpression::evaluateAsBool(Valuation const *valuation) const { |
||||
|
STORM_LOG_THROW(this->hasBooleanType(), storm::exceptions::InvalidTypeException, "Unable to evaluate expression as boolean."); |
||||
|
storm::storage::BitVector results(operands.size()); |
||||
|
uint64_t i = 0; |
||||
|
for(auto const& operand : operands) { |
||||
|
results.set(i, operand->evaluateAsBool(valuation)); |
||||
|
++i; |
||||
|
} |
||||
|
switch(predicate) { |
||||
|
case PredicateType::ExactlyOneOf: return results.getNumberOfSetBits() == 1; |
||||
|
case PredicateType::AtMostOneOf: return results.getNumberOfSetBits() <= 1; |
||||
|
case PredicateType::AtLeastOneOf: return results.getNumberOfSetBits() >= 1; |
||||
|
} |
||||
|
STORM_LOG_ASSERT(false, "Unknown predicate type"); |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<BaseExpression const> PredicateExpression::simplify() const { |
||||
|
std::vector<std::shared_ptr<BaseExpression const>> simplifiedOperands; |
||||
|
for (auto const& operand : operands) { |
||||
|
simplifiedOperands.push_back(operand->simplify()); |
||||
|
} |
||||
|
return std::shared_ptr<BaseExpression>(new PredicateExpression(this->getManager(), this->getType(), simplifiedOperands, predicate)); |
||||
|
} |
||||
|
|
||||
|
boost::any PredicateExpression::accept(ExpressionVisitor &visitor, boost::any const &data) const { |
||||
|
return visitor.visit(*this, data); |
||||
|
} |
||||
|
|
||||
|
bool PredicateExpression::isPredicateExpression() const { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool PredicateExpression::isFunctionApplication() const { |
||||
|
return true; |
||||
|
} |
||||
|
|
||||
|
bool PredicateExpression::containsVariables() const { |
||||
|
for(auto const& operand : operands) { |
||||
|
if(operand->containsVariables()) { |
||||
|
return true; |
||||
|
} |
||||
|
} |
||||
|
return false; |
||||
|
} |
||||
|
|
||||
|
uint_fast64_t PredicateExpression::getArity() const { |
||||
|
return operands.size(); |
||||
|
} |
||||
|
|
||||
|
std::shared_ptr<BaseExpression const> PredicateExpression::getOperand(uint_fast64_t operandIndex) const { |
||||
|
STORM_LOG_ASSERT(operandIndex < this->getArity(), "Invalid operand access"); |
||||
|
return operands[operandIndex]; |
||||
|
} |
||||
|
|
||||
|
void PredicateExpression::gatherVariables(std::set<storm::expressions::Variable>& variables) const { |
||||
|
for(auto const& operand : operands) { |
||||
|
operand->gatherVariables(variables); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/*!
|
||||
|
* Retrieves the relation associated with the expression. |
||||
|
* |
||||
|
* @return The relation associated with the expression. |
||||
|
*/ |
||||
|
PredicateExpression::PredicateType PredicateExpression::getPredicateType() const { |
||||
|
return predicate; |
||||
|
} |
||||
|
|
||||
|
void PredicateExpression::printToStream(std::ostream& stream) const { |
||||
|
|
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include "storm/storage/expressions/BaseExpression.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace expressions { |
||||
|
/*! |
||||
|
* The base class of all binary expressions. |
||||
|
*/ |
||||
|
class PredicateExpression : public BaseExpression { |
||||
|
public: |
||||
|
enum class PredicateType { AtLeastOneOf, AtMostOneOf, ExactlyOneOf }; |
||||
|
|
||||
|
PredicateExpression(ExpressionManager const &manager,Type const& type, |
||||
|
std::vector <std::shared_ptr<BaseExpression const>> const &operands, |
||||
|
PredicateType predicateType); |
||||
|
|
||||
|
// Instantiate constructors and assignments with their default implementations. |
||||
|
PredicateExpression(PredicateExpression const &other) = default; |
||||
|
|
||||
|
PredicateExpression &operator=(PredicateExpression const &other) = delete; |
||||
|
|
||||
|
PredicateExpression(PredicateExpression &&) = default; |
||||
|
|
||||
|
PredicateExpression &operator=(PredicateExpression &&) = delete; |
||||
|
|
||||
|
virtual ~PredicateExpression() = default; |
||||
|
|
||||
|
// Override base class methods. |
||||
|
virtual storm::expressions::OperatorType getOperator() const override; |
||||
|
|
||||
|
virtual bool evaluateAsBool(Valuation const *valuation = nullptr) const override; |
||||
|
|
||||
|
virtual std::shared_ptr<BaseExpression const> simplify() const override; |
||||
|
|
||||
|
virtual boost::any accept(ExpressionVisitor &visitor, boost::any const &data) const override; |
||||
|
|
||||
|
virtual bool isPredicateExpression() const override; |
||||
|
|
||||
|
virtual bool isFunctionApplication() const override; |
||||
|
|
||||
|
virtual bool containsVariables() const override; |
||||
|
|
||||
|
virtual uint_fast64_t getArity() const override; |
||||
|
|
||||
|
virtual std::shared_ptr<BaseExpression const> getOperand(uint_fast64_t operandIndex) const override; |
||||
|
|
||||
|
virtual void gatherVariables(std::set<storm::expressions::Variable>& variables) const override; |
||||
|
|
||||
|
/*! |
||||
|
* Retrieves the relation associated with the expression. |
||||
|
* |
||||
|
* @return The relation associated with the expression. |
||||
|
*/ |
||||
|
PredicateType getPredicateType() const; |
||||
|
|
||||
|
protected: |
||||
|
// Override base class method. |
||||
|
virtual void printToStream(std::ostream& stream) const override; |
||||
|
|
||||
|
private: |
||||
|
PredicateType predicate; |
||||
|
std::vector<std::shared_ptr<BaseExpression const>> operands; |
||||
|
}; |
||||
|
} |
||||
|
} |
@ -0,0 +1,171 @@ |
|||||
|
#include <map>
|
||||
|
#include <unordered_map>
|
||||
|
#include <string>
|
||||
|
|
||||
|
#include "storm/storage/expressions/SimplificationVisitor.h"
|
||||
|
#include "storm/storage/expressions/Expressions.h"
|
||||
|
#include "storm/storage/expressions/PredicateExpression.h"
|
||||
|
#include "storm/storage/expressions/ExpressionManager.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace expressions { |
||||
|
SimplificationVisitor::SimplificationVisitor() { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
Expression SimplificationVisitor::substitute(Expression const &expression) { |
||||
|
return Expression(boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getBaseExpression().accept(*this, boost::none))); |
||||
|
} |
||||
|
|
||||
|
boost::any SimplificationVisitor::visit(IfThenElseExpression const &expression, boost::any const &data) { |
||||
|
std::shared_ptr<BaseExpression const> conditionExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getCondition()->accept(*this, data)); |
||||
|
std::shared_ptr<BaseExpression const> thenExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getThenExpression()->accept(*this, data)); |
||||
|
std::shared_ptr<BaseExpression const> elseExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getElseExpression()->accept(*this, data)); |
||||
|
|
||||
|
// If the arguments did not change, we simply push the expression itself.
|
||||
|
if (conditionExpression.get() == expression.getCondition().get() && |
||||
|
thenExpression.get() == expression.getThenExpression().get() && |
||||
|
elseExpression.get() == expression.getElseExpression().get()) { |
||||
|
return expression.getSharedPointer(); |
||||
|
} else { |
||||
|
return std::const_pointer_cast<BaseExpression const>(std::shared_ptr<BaseExpression>( |
||||
|
new IfThenElseExpression(expression.getManager(), expression.getType(), conditionExpression, |
||||
|
thenExpression, elseExpression))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
boost::any |
||||
|
SimplificationVisitor::visit(BinaryBooleanFunctionExpression const &expression, boost::any const &data) { |
||||
|
std::shared_ptr<BaseExpression const> firstExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getFirstOperand()->accept(*this, data)); |
||||
|
std::shared_ptr<BaseExpression const> secondExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getSecondOperand()->accept(*this, data)); |
||||
|
|
||||
|
// If the arguments did not change, we simply push the expression itself.
|
||||
|
if (firstExpression.get() == expression.getFirstOperand().get() && |
||||
|
secondExpression.get() == expression.getSecondOperand().get()) { |
||||
|
return expression.getSharedPointer(); |
||||
|
} else { |
||||
|
return std::const_pointer_cast<BaseExpression const>(std::shared_ptr<BaseExpression>( |
||||
|
new BinaryBooleanFunctionExpression(expression.getManager(), expression.getType(), |
||||
|
firstExpression, secondExpression, |
||||
|
expression.getOperatorType()))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
boost::any |
||||
|
SimplificationVisitor::visit(BinaryNumericalFunctionExpression const &expression, boost::any const &data) { |
||||
|
std::shared_ptr<BaseExpression const> firstExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getFirstOperand()->accept(*this, data)); |
||||
|
std::shared_ptr<BaseExpression const> secondExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getSecondOperand()->accept(*this, data)); |
||||
|
|
||||
|
// If the arguments did not change, we simply push the expression itself.
|
||||
|
if (firstExpression.get() == expression.getFirstOperand().get() && |
||||
|
secondExpression.get() == expression.getSecondOperand().get()) { |
||||
|
return expression.getSharedPointer(); |
||||
|
} else { |
||||
|
return std::const_pointer_cast<BaseExpression const>(std::shared_ptr<BaseExpression>( |
||||
|
new BinaryNumericalFunctionExpression(expression.getManager(), expression.getType(), |
||||
|
firstExpression, secondExpression, |
||||
|
expression.getOperatorType()))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
boost::any SimplificationVisitor::visit(BinaryRelationExpression const &expression, boost::any const &data) { |
||||
|
std::shared_ptr<BaseExpression const> firstExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getFirstOperand()->accept(*this, data)); |
||||
|
std::shared_ptr<BaseExpression const> secondExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getSecondOperand()->accept(*this, data)); |
||||
|
|
||||
|
// If the arguments did not change, we simply push the expression itself.
|
||||
|
if (firstExpression.get() == expression.getFirstOperand().get() && |
||||
|
secondExpression.get() == expression.getSecondOperand().get()) { |
||||
|
return expression.getSharedPointer(); |
||||
|
} else { |
||||
|
return std::const_pointer_cast<BaseExpression const>(std::shared_ptr<BaseExpression>( |
||||
|
new BinaryRelationExpression(expression.getManager(), expression.getType(), firstExpression, |
||||
|
secondExpression, expression.getRelationType()))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
boost::any SimplificationVisitor::visit(VariableExpression const &expression, boost::any const &) { |
||||
|
|
||||
|
return expression.getSharedPointer(); |
||||
|
|
||||
|
} |
||||
|
|
||||
|
boost::any |
||||
|
SimplificationVisitor::visit(UnaryBooleanFunctionExpression const &expression, boost::any const &data) { |
||||
|
std::shared_ptr<BaseExpression const> operandExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getOperand()->accept(*this, data)); |
||||
|
|
||||
|
// If the argument did not change, we simply push the expression itself.
|
||||
|
if (operandExpression.get() == expression.getOperand().get()) { |
||||
|
return expression.getSharedPointer(); |
||||
|
} else { |
||||
|
return std::const_pointer_cast<BaseExpression const>(std::shared_ptr<BaseExpression>( |
||||
|
new UnaryBooleanFunctionExpression(expression.getManager(), expression.getType(), |
||||
|
operandExpression, expression.getOperatorType()))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
boost::any |
||||
|
SimplificationVisitor::visit(UnaryNumericalFunctionExpression const &expression, boost::any const &data) { |
||||
|
std::shared_ptr<BaseExpression const> operandExpression = boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getOperand()->accept(*this, data)); |
||||
|
|
||||
|
// If the argument did not change, we simply push the expression itself.
|
||||
|
if (operandExpression.get() == expression.getOperand().get()) { |
||||
|
return expression.getSharedPointer(); |
||||
|
} else { |
||||
|
return std::const_pointer_cast<BaseExpression const>(std::shared_ptr<BaseExpression>( |
||||
|
new UnaryNumericalFunctionExpression(expression.getManager(), expression.getType(), |
||||
|
operandExpression, expression.getOperatorType()))); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
boost::any SimplificationVisitor::visit(PredicateExpression const &expression, boost::any const &data) { |
||||
|
std::vector<Expression> newExpressions; |
||||
|
for (uint64_t i = 0; i < expression.getArity(); ++i) { |
||||
|
newExpressions.emplace_back(boost::any_cast<std::shared_ptr<BaseExpression const>>( |
||||
|
expression.getOperand(i)->accept(*this, data))); |
||||
|
} |
||||
|
std::vector<Expression> newSumExpressions; |
||||
|
for (auto const &expr : newExpressions) { |
||||
|
newSumExpressions.push_back( |
||||
|
ite(expr, expression.getManager().integer(1), expression.getManager().integer(0))); |
||||
|
} |
||||
|
|
||||
|
storm::expressions::Expression finalexpr; |
||||
|
if (expression.getPredicateType() == PredicateExpression::PredicateType::AtLeastOneOf) { |
||||
|
finalexpr = storm::expressions::sum(newSumExpressions) > expression.getManager().integer(0); |
||||
|
} else if (expression.getPredicateType() == PredicateExpression::PredicateType::AtMostOneOf) { |
||||
|
finalexpr = storm::expressions::sum(newSumExpressions) <= expression.getManager().integer(1); |
||||
|
} else if (expression.getPredicateType() == PredicateExpression::PredicateType::ExactlyOneOf) { |
||||
|
finalexpr = storm::expressions::sum(newSumExpressions) == expression.getManager().integer(1); |
||||
|
} else { |
||||
|
STORM_LOG_ASSERT(false, "Unknown predicate type."); |
||||
|
} |
||||
|
return std::const_pointer_cast<BaseExpression const>(finalexpr.getBaseExpressionPointer()); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
boost::any SimplificationVisitor::visit(BooleanLiteralExpression const &expression, boost::any const &) { |
||||
|
return expression.getSharedPointer(); |
||||
|
} |
||||
|
|
||||
|
boost::any SimplificationVisitor::visit(IntegerLiteralExpression const &expression, boost::any const &) { |
||||
|
return expression.getSharedPointer(); |
||||
|
} |
||||
|
|
||||
|
boost::any SimplificationVisitor::visit(RationalLiteralExpression const &expression, boost::any const &) { |
||||
|
return expression.getSharedPointer(); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
@ -0,0 +1,41 @@ |
|||||
|
#pragma once |
||||
|
#include <stack> |
||||
|
|
||||
|
#include "storm/storage/expressions/Expression.h" |
||||
|
#include "storm/storage/expressions/ExpressionVisitor.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace expressions { |
||||
|
class SimplificationVisitor : public ExpressionVisitor { |
||||
|
public: |
||||
|
/*! |
||||
|
* Creates a new simplification visitor that replaces predicates by other (simpler?) predicates. |
||||
|
* |
||||
|
* Configuration: |
||||
|
* Currently, the visitor only replaces nonstandard predicates |
||||
|
* |
||||
|
*/ |
||||
|
SimplificationVisitor(); |
||||
|
|
||||
|
/*! |
||||
|
* Simplifies based on the configuration. |
||||
|
*/ |
||||
|
Expression substitute(Expression const& expression); |
||||
|
|
||||
|
virtual boost::any visit(IfThenElseExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(BinaryBooleanFunctionExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(BinaryNumericalFunctionExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(BinaryRelationExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(VariableExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(UnaryBooleanFunctionExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(UnaryNumericalFunctionExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(BooleanLiteralExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(IntegerLiteralExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(RationalLiteralExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(PredicateExpression const& expression, boost::any const& data) override; |
||||
|
|
||||
|
protected: |
||||
|
// |
||||
|
}; |
||||
|
} |
||||
|
} |
@ -0,0 +1,291 @@ |
|||||
|
#include "storm/exceptions/NotSupportedException.h"
|
||||
|
#include "storm/storage/expressions/ToDiceStringVisitor.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace expressions { |
||||
|
ToDiceStringVisitor::ToDiceStringVisitor(uint64 nrBits) : nrBits(nrBits) { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
std::string ToDiceStringVisitor::toString(Expression const& expression) { |
||||
|
return toString(expression.getBaseExpressionPointer().get()); |
||||
|
} |
||||
|
|
||||
|
std::string ToDiceStringVisitor::toString(BaseExpression const* expression) { |
||||
|
stream.str(""); |
||||
|
stream.clear(); |
||||
|
expression->accept(*this, boost::none); |
||||
|
return stream.str(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(IfThenElseExpression const& expression, boost::any const& data) { |
||||
|
stream << "if "; |
||||
|
expression.getCondition()->accept(*this, data); |
||||
|
stream << " then "; |
||||
|
expression.getThenExpression()->accept(*this, data); |
||||
|
stream << " else "; |
||||
|
expression.getElseExpression()->accept(*this, data); |
||||
|
stream << ""; |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(BinaryBooleanFunctionExpression const& expression, boost::any const& data) { |
||||
|
switch (expression.getOperatorType()) { |
||||
|
case BinaryBooleanFunctionExpression::OperatorType::And: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << " && "; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryBooleanFunctionExpression::OperatorType::Or: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << " || "; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryBooleanFunctionExpression::OperatorType::Xor: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << " ^ "; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryBooleanFunctionExpression::OperatorType::Implies: |
||||
|
stream << "(!("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << ") || "; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryBooleanFunctionExpression::OperatorType::Iff: |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << " <=> "; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
break; |
||||
|
} |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(BinaryNumericalFunctionExpression const& expression, boost::any const& data) { |
||||
|
switch (expression.getOperatorType()) { |
||||
|
case BinaryNumericalFunctionExpression::OperatorType::Plus: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << "+"; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryNumericalFunctionExpression::OperatorType::Minus: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << "-"; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryNumericalFunctionExpression::OperatorType::Times: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << "*"; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryNumericalFunctionExpression::OperatorType::Divide: { |
||||
|
STORM_LOG_THROW(expression.getSecondOperand()->isIntegerLiteralExpression(), |
||||
|
storm::exceptions::NotSupportedException, |
||||
|
"Dice does not support modulo with nonconst rhs"); |
||||
|
uint64_t denominator = expression.getSecondOperand()->evaluateAsInt(); |
||||
|
int shifts = 0; |
||||
|
while (denominator % 2 == 0) { |
||||
|
denominator = denominator >> 1; |
||||
|
shifts++; |
||||
|
} |
||||
|
denominator = denominator >> 1; |
||||
|
if (denominator > 0) { |
||||
|
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, |
||||
|
"Dice does not support division with non-powers of two"); |
||||
|
} |
||||
|
if (shifts > 0) { |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << " >> " << shifts; |
||||
|
stream << ")"; |
||||
|
} else { |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
break; |
||||
|
case BinaryNumericalFunctionExpression::OperatorType::Power: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << "^"; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryNumericalFunctionExpression::OperatorType::Modulo: |
||||
|
STORM_LOG_THROW(expression.getSecondOperand()->isIntegerLiteralExpression(), storm::exceptions::NotSupportedException, "Dice does not support modulo with nonconst rhs"); |
||||
|
STORM_LOG_THROW(expression.getSecondOperand()->evaluateAsInt() == 2, storm::exceptions::NotSupportedException, "Dice does not support modulo with rhs != 2"); |
||||
|
|
||||
|
stream << "( nth_bit(int(" << nrBits << "," << nrBits-1 << "), "; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << "))"; |
||||
|
break; |
||||
|
case BinaryNumericalFunctionExpression::OperatorType::Max: |
||||
|
stream << "max("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << ","; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryNumericalFunctionExpression::OperatorType::Min: |
||||
|
stream << "min("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << ","; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
} |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(BinaryRelationExpression const& expression, boost::any const& data) { |
||||
|
switch (expression.getRelationType()) { |
||||
|
case BinaryRelationExpression::RelationType::Equal: |
||||
|
if (expression.getFirstOperand()->isBinaryNumericalFunctionExpression()) { |
||||
|
if (expression.getFirstOperand()->asBinaryNumericalFunctionExpression().getOperatorType() == BinaryNumericalFunctionExpression::OperatorType::Modulo) { |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
} |
||||
|
} else { |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << "=="; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
} |
||||
|
|
||||
|
break; |
||||
|
case BinaryRelationExpression::RelationType::NotEqual: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << "!="; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryRelationExpression::RelationType::Less: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << "<"; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryRelationExpression::RelationType::LessOrEqual: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << "<="; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryRelationExpression::RelationType::Greater: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << ">"; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case BinaryRelationExpression::RelationType::GreaterOrEqual: |
||||
|
stream << "("; |
||||
|
expression.getFirstOperand()->accept(*this, data); |
||||
|
stream << ">="; |
||||
|
expression.getSecondOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
} |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(VariableExpression const& expression, boost::any const&) { |
||||
|
stream << expression.getVariable().getName(); |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(UnaryBooleanFunctionExpression const& expression, boost::any const& data) { |
||||
|
switch (expression.getOperatorType()) { |
||||
|
case UnaryBooleanFunctionExpression::OperatorType::Not: |
||||
|
stream << "!("; |
||||
|
expression.getOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
} |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(UnaryNumericalFunctionExpression const& expression, boost::any const& data) { |
||||
|
switch (expression.getOperatorType()) { |
||||
|
case UnaryNumericalFunctionExpression::OperatorType::Minus: |
||||
|
stream << "-("; |
||||
|
expression.getOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case UnaryNumericalFunctionExpression::OperatorType::Floor: |
||||
|
stream << "floor("; |
||||
|
expression.getOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
case UnaryNumericalFunctionExpression::OperatorType::Ceil: |
||||
|
stream << "ceil("; |
||||
|
expression.getOperand()->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
break; |
||||
|
} |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(PredicateExpression const& expression, boost::any const& data) { |
||||
|
auto pdt = expression.getPredicateType(); |
||||
|
STORM_LOG_ASSERT(pdt == PredicateExpression::PredicateType::ExactlyOneOf || pdt == PredicateExpression::PredicateType::AtLeastOneOf || pdt == PredicateExpression::PredicateType::AtMostOneOf, "Only some predicate types are supported."); |
||||
|
stream << "("; |
||||
|
if (expression.getPredicateType() == PredicateExpression::PredicateType::ExactlyOneOf || expression.getPredicateType() == PredicateExpression::PredicateType::AtMostOneOf) { |
||||
|
stream << "(true "; |
||||
|
for (uint64_t operandi = 0; operandi < expression.getArity(); ++operandi) { |
||||
|
for (uint64_t operandj = operandi + 1; operandj < expression.getArity(); ++operandj) { |
||||
|
stream << "&& !("; |
||||
|
expression.getOperand(operandi)->accept(*this, data); |
||||
|
stream << " && "; |
||||
|
expression.getOperand(operandj)->accept(*this, data); |
||||
|
stream << ")"; |
||||
|
} |
||||
|
} |
||||
|
stream << ")"; |
||||
|
} |
||||
|
if (expression.getPredicateType() == PredicateExpression::PredicateType::ExactlyOneOf) { |
||||
|
stream << " && "; |
||||
|
} |
||||
|
if (expression.getPredicateType() == PredicateExpression::PredicateType::ExactlyOneOf || expression.getPredicateType() == PredicateExpression::PredicateType::AtLeastOneOf) { |
||||
|
stream << "( false"; |
||||
|
for (uint64_t operandj = 0; operandj < expression.getArity(); ++operandj) { |
||||
|
stream << "|| "; |
||||
|
expression.getOperand(operandj)->accept(*this, data); |
||||
|
} |
||||
|
stream << ")"; |
||||
|
} |
||||
|
stream << ")"; |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(BooleanLiteralExpression const& expression, boost::any const&) { |
||||
|
stream << (expression.getValue() ? " true " : " false "); |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(IntegerLiteralExpression const& expression, boost::any const&) { |
||||
|
stream << "int(" << nrBits << "," << expression.getValue() << ")"; |
||||
|
return boost::any(); |
||||
|
} |
||||
|
|
||||
|
boost::any ToDiceStringVisitor::visit(RationalLiteralExpression const& expression, boost::any const&) { |
||||
|
stream << std::scientific << std::setprecision(std::numeric_limits<double>::max_digits10) << "(" << expression.getValueAsDouble() << ")"; |
||||
|
return boost::any(); |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,37 @@ |
|||||
|
#pragma once |
||||
|
|
||||
|
#include <sstream> |
||||
|
|
||||
|
#include "storm/storage/expressions/Expression.h" |
||||
|
#include "storm/storage/expressions/Expressions.h" |
||||
|
#include "storm/storage/expressions/ExpressionVisitor.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace expressions { |
||||
|
class ToDiceStringVisitor : public ExpressionVisitor { |
||||
|
public: |
||||
|
ToDiceStringVisitor(uint64 nrBits); |
||||
|
|
||||
|
std::string toString(Expression const& expression); |
||||
|
std::string toString(BaseExpression const* expression); |
||||
|
|
||||
|
virtual boost::any visit(IfThenElseExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(BinaryBooleanFunctionExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(BinaryNumericalFunctionExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(BinaryRelationExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(VariableExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(UnaryBooleanFunctionExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(UnaryNumericalFunctionExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(PredicateExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(BooleanLiteralExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(IntegerLiteralExpression const& expression, boost::any const& data) override; |
||||
|
virtual boost::any visit(RationalLiteralExpression const& expression, boost::any const& data) override; |
||||
|
|
||||
|
|
||||
|
private: |
||||
|
std::stringstream stream; |
||||
|
uint64_t nrBits; |
||||
|
}; |
||||
|
} |
||||
|
} |
||||
|
|
Write
Preview
Loading…
Cancel
Save
Reference in new issue