dehnert
8 years ago
20 changed files with 483 additions and 169 deletions
-
72src/storm/abstraction/AbstractionInformation.cpp
-
86src/storm/abstraction/AbstractionInformation.h
-
195src/storm/abstraction/ExpressionTranslator.cpp
-
53src/storm/abstraction/ExpressionTranslator.h
-
2src/storm/abstraction/LocalExpressionInformation.cpp
-
11src/storm/abstraction/MenuGameAbstractor.h
-
42src/storm/abstraction/StateSetAbstractor.cpp
-
2src/storm/abstraction/StateSetAbstractor.h
-
26src/storm/abstraction/jani/AutomatonAbstractor.cpp
-
20src/storm/abstraction/jani/AutomatonAbstractor.h
-
24src/storm/abstraction/jani/EdgeAbstractor.cpp
-
18src/storm/abstraction/jani/EdgeAbstractor.h
-
48src/storm/abstraction/jani/JaniAbstractionInformation.cpp
-
22src/storm/abstraction/jani/JaniMenuGameAbstractor.cpp
-
9src/storm/abstraction/jani/JaniMenuGameAbstractor.h
-
4src/storm/abstraction/prism/PrismMenuGameAbstractor.cpp
-
2src/storm/abstraction/prism/PrismMenuGameAbstractor.h
-
4src/storm/storage/expressions/BaseExpression.cpp
-
6src/storm/storage/expressions/BaseExpression.h
@ -0,0 +1,195 @@ |
|||
#include "storm/abstraction/ExpressionTranslator.h"
|
|||
|
|||
#include "storm/abstraction/AbstractionInformation.h"
|
|||
|
|||
#include "storm/storage/dd/DdManager.h"
|
|||
#include "storm/storage/dd/Bdd.h"
|
|||
|
|||
#include "storm/storage/expressions/Expression.h"
|
|||
|
|||
#include "storm/utility/macros.h"
|
|||
#include "storm/exceptions/NotSupportedException.h"
|
|||
|
|||
namespace storm { |
|||
namespace abstraction { |
|||
|
|||
using namespace storm::expressions; |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
ExpressionTranslator<DdType>::ExpressionTranslator(AbstractionInformation<DdType>& abstractionInformation, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver) : abstractionInformation(abstractionInformation), equivalenceChecker(std::move(smtSolver)), locationVariables(abstractionInformation.getSourceLocationVariables()), abstractedVariables(abstractionInformation.getAbstractedVariables()) { |
|||
// Intentionally left empty.
|
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
storm::dd::Bdd<DdType> ExpressionTranslator<DdType>::translate(storm::expressions::Expression const& expression) { |
|||
return boost::any_cast<storm::dd::Bdd<DdType>>(expression.accept(*this, boost::none)); |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(IfThenElseExpression const& expression, boost::any const& data) { |
|||
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Expressions of this kind are currently not supported by the abstraction expression translator."); |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(BinaryBooleanFunctionExpression const& expression, boost::any const& data) { |
|||
// Check whether the expression is either fully contained in the location variables fragment or the abstracted
|
|||
// variables fragment.
|
|||
std::set<storm::expressions::Variable> variablesInExpression; |
|||
expression.gatherVariables(variablesInExpression); |
|||
|
|||
std::set<storm::expressions::Variable> tmp; |
|||
std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), locationVariables.begin(), locationVariables.end(), std::inserter(tmp, tmp.begin())); |
|||
bool hasLocationVariables = !tmp.empty(); |
|||
|
|||
tmp.clear(); |
|||
std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), abstractedVariables.begin(), abstractedVariables.end(), std::inserter(tmp, tmp.begin())); |
|||
bool hasAbstractedVariables = !tmp.empty(); |
|||
|
|||
STORM_LOG_THROW(hasLocationVariables || hasAbstractedVariables, storm::exceptions::NotSupportedException, "Expressions without variables are currently not supported by the abstraction expression translator."); |
|||
|
|||
if (hasAbstractedVariables && !hasLocationVariables) { |
|||
for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { |
|||
if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { |
|||
return abstractionInformation.get().encodePredicateAsSource(predicateIndex); |
|||
} |
|||
} |
|||
|
|||
// At this point, none of the predicates was found to be equivalent, so we split the expression.
|
|||
} |
|||
|
|||
storm::dd::Bdd<DdType> left = boost::any_cast<storm::dd::Bdd<DdType>>(expression.getFirstOperand()->accept(*this, boost::none)); |
|||
storm::dd::Bdd<DdType> right = boost::any_cast<storm::dd::Bdd<DdType>>(expression.getFirstOperand()->accept(*this, boost::none)); |
|||
switch (expression.getOperatorType()) { |
|||
case BinaryBooleanFunctionExpression::OperatorType::And: return left && right; |
|||
case BinaryBooleanFunctionExpression::OperatorType::Or: return left || right; |
|||
case BinaryBooleanFunctionExpression::OperatorType::Xor: return left.exclusiveOr(right); |
|||
case BinaryBooleanFunctionExpression::OperatorType::Implies: return !left || right; |
|||
case BinaryBooleanFunctionExpression::OperatorType::Iff: return (left && right) || (!left && !right); |
|||
} |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(BinaryNumericalFunctionExpression const& expression, boost::any const& data) { |
|||
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Expressions of this kind are currently not supported by the abstraction expression translator."); |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(BinaryRelationExpression const& expression, boost::any const& data) { |
|||
// Check whether the expression is either fully contained in the location variables fragment or the abstracted
|
|||
// variables fragment.
|
|||
std::set<storm::expressions::Variable> variablesInExpression; |
|||
expression.gatherVariables(variablesInExpression); |
|||
|
|||
std::set<storm::expressions::Variable> tmp; |
|||
std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), locationVariables.begin(), locationVariables.end(), std::inserter(tmp, tmp.begin())); |
|||
bool hasLocationVariables = !tmp.empty(); |
|||
|
|||
tmp.clear(); |
|||
std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), abstractedVariables.begin(), abstractedVariables.end(), std::inserter(tmp, tmp.begin())); |
|||
bool hasAbstractedVariables = !tmp.empty(); |
|||
|
|||
STORM_LOG_THROW(hasLocationVariables || hasAbstractedVariables, storm::exceptions::NotSupportedException, "Expressions without variables are currently not supported by the abstraction expression translator."); |
|||
STORM_LOG_THROW(!hasLocationVariables || !hasAbstractedVariables, storm::exceptions::NotSupportedException, "Expressions with two types (location variables and abstracted variables) of variables are currently not supported by the abstraction expression translator."); |
|||
|
|||
if (hasLocationVariables) { |
|||
storm::dd::Add<DdType, double> left = boost::any_cast<storm::dd::Add<DdType, double>>(expression.getFirstOperand()->accept(*this, boost::none)); |
|||
storm::dd::Add<DdType, double> right = boost::any_cast<storm::dd::Add<DdType, double>>(expression.getFirstOperand()->accept(*this, boost::none)); |
|||
|
|||
switch (expression.getRelationType()) { |
|||
case BinaryRelationExpression::RelationType::Equal: return left.equals(right); |
|||
case BinaryRelationExpression::RelationType::NotEqual: return left.notEquals(right); |
|||
case BinaryRelationExpression::RelationType::Less: return left.less(right); |
|||
case BinaryRelationExpression::RelationType::LessOrEqual: return left.lessOrEqual(right); |
|||
case BinaryRelationExpression::RelationType::Greater: return left.greater(right); |
|||
case BinaryRelationExpression::RelationType::GreaterOrEqual: return left.greaterOrEqual(right); |
|||
} |
|||
} else { |
|||
for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { |
|||
if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { |
|||
return abstractionInformation.get().encodePredicateAsSource(predicateIndex); |
|||
} |
|||
} |
|||
|
|||
// At this point, none of the predicates was found to be equivalent, but there is no need to split as the subexpressions are not valid predicates.
|
|||
|
|||
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Expressions of this kind are currently not supported by the abstraction expression translator."); |
|||
} |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(VariableExpression const& expression, boost::any const& data) { |
|||
if (abstractedVariables.find(expression.getVariable()) != abstractedVariables.end()) { |
|||
for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { |
|||
if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { |
|||
return abstractionInformation.get().encodePredicateAsSource(predicateIndex); |
|||
} |
|||
} |
|||
|
|||
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Expressions of this kind are currently not supported by the abstraction expression translator."); |
|||
} else { |
|||
return abstractionInformation.get().getDdManager().template getIdentity<double>(expression.getVariable()); |
|||
} |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(UnaryBooleanFunctionExpression const& expression, boost::any const& data) { |
|||
// Check whether the expression is either fully contained in the location variables fragment or the abstracted
|
|||
// variables fragment.
|
|||
std::set<storm::expressions::Variable> variablesInExpression; |
|||
expression.gatherVariables(variablesInExpression); |
|||
|
|||
std::set<storm::expressions::Variable> tmp; |
|||
std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), locationVariables.begin(), locationVariables.end(), std::inserter(tmp, tmp.begin())); |
|||
bool hasLocationVariables = !tmp.empty(); |
|||
|
|||
tmp.clear(); |
|||
std::set_intersection(variablesInExpression.begin(), variablesInExpression.end(), abstractedVariables.begin(), abstractedVariables.end(), std::inserter(tmp, tmp.begin())); |
|||
bool hasAbstractedVariables = !tmp.empty(); |
|||
|
|||
STORM_LOG_THROW(hasLocationVariables || hasAbstractedVariables, storm::exceptions::NotSupportedException, "Expressions without variables are currently not supported by the abstraction expression translator."); |
|||
|
|||
if (hasAbstractedVariables && !hasLocationVariables) { |
|||
for (uint64_t predicateIndex = 0; predicateIndex < abstractionInformation.get().getNumberOfPredicates(); ++predicateIndex) { |
|||
if (equivalenceChecker.areEquivalent(abstractionInformation.get().getPredicateByIndex(predicateIndex), expression.toExpression())) { |
|||
return abstractionInformation.get().encodePredicateAsSource(predicateIndex); |
|||
} |
|||
} |
|||
|
|||
// At this point, none of the predicates was found to be equivalent, so we split the expression.
|
|||
} |
|||
|
|||
storm::dd::Bdd<DdType> sub = boost::any_cast<storm::dd::Bdd<DdType>>(expression.getOperand()->accept(*this, boost::none)); |
|||
switch (expression.getOperatorType()) { |
|||
case UnaryBooleanFunctionExpression::OperatorType::Not: return !sub; |
|||
} |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(UnaryNumericalFunctionExpression const& expression, boost::any const& data) { |
|||
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Expressions of this kind are currently not supported by the abstraction expression translator."); |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(BooleanLiteralExpression const& expression, boost::any const& data) { |
|||
if (expression.isTrue()) { |
|||
return abstractionInformation.get().getDdManager().getBddOne(); |
|||
} else { |
|||
return abstractionInformation.get().getDdManager().getBddZero(); |
|||
} |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(IntegerLiteralExpression const& expression, boost::any const& data) { |
|||
return abstractionInformation.get().getDdManager().template getConstant(expression.getValue()); |
|||
} |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
boost::any ExpressionTranslator<DdType>::visit(RationalLiteralExpression const& expression, boost::any const& data) { |
|||
STORM_LOG_THROW(false, storm::exceptions::NotSupportedException, "Expressions of this kind are currently not supported by the abstraction expression translator."); |
|||
} |
|||
|
|||
template class ExpressionTranslator<storm::dd::DdType::CUDD>; |
|||
template class ExpressionTranslator<storm::dd::DdType::Sylvan>; |
|||
|
|||
} |
|||
} |
@ -0,0 +1,53 @@ |
|||
#pragma once |
|||
|
|||
#include <set> |
|||
|
|||
#include "storm/storage/dd/DdType.h" |
|||
#include "storm/storage/expressions/ExpressionVisitor.h" |
|||
#include "storm/storage/expressions/EquivalenceChecker.h" |
|||
|
|||
#include "storm/solver/SmtSolver.h" |
|||
|
|||
namespace storm { |
|||
namespace dd { |
|||
template<storm::dd::DdType DdType> |
|||
class Bdd; |
|||
} |
|||
|
|||
namespace expressions { |
|||
class Expression; |
|||
} |
|||
|
|||
namespace abstraction { |
|||
|
|||
template<storm::dd::DdType DdType> |
|||
class AbstractionInformation; |
|||
|
|||
template <storm::dd::DdType DdType> |
|||
class ExpressionTranslator : public storm::expressions::ExpressionVisitor { |
|||
public: |
|||
ExpressionTranslator(AbstractionInformation<DdType>& abstractionInformation, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver); |
|||
|
|||
storm::dd::Bdd<DdType> translate(storm::expressions::Expression const& expression); |
|||
|
|||
virtual boost::any visit(storm::expressions::IfThenElseExpression const& expression, boost::any const& data); |
|||
virtual boost::any visit(storm::expressions::BinaryBooleanFunctionExpression const& expression, boost::any const& data); |
|||
virtual boost::any visit(storm::expressions::BinaryNumericalFunctionExpression const& expression, boost::any const& data); |
|||
virtual boost::any visit(storm::expressions::BinaryRelationExpression const& expression, boost::any const& data); |
|||
virtual boost::any visit(storm::expressions::VariableExpression const& expression, boost::any const& data); |
|||
virtual boost::any visit(storm::expressions::UnaryBooleanFunctionExpression const& expression, boost::any const& data); |
|||
virtual boost::any visit(storm::expressions::UnaryNumericalFunctionExpression const& expression, boost::any const& data); |
|||
virtual boost::any visit(storm::expressions::BooleanLiteralExpression const& expression, boost::any const& data); |
|||
virtual boost::any visit(storm::expressions::IntegerLiteralExpression const& expression, boost::any const& data); |
|||
virtual boost::any visit(storm::expressions::RationalLiteralExpression const& expression, boost::any const& data); |
|||
|
|||
private: |
|||
std::reference_wrapper<AbstractionInformation<DdType>> abstractionInformation; |
|||
storm::expressions::EquivalenceChecker equivalenceChecker; |
|||
|
|||
std::set<storm::expressions::Variable> locationVariables; |
|||
std::set<storm::expressions::Variable> abstractedVariables; |
|||
}; |
|||
|
|||
} |
|||
} |
@ -1,48 +0,0 @@ |
|||
#include "storm/abstraction/jani/JaniAbstractionInformation.h"
|
|||
|
|||
#include "storm/storage/dd/DdManager.h"
|
|||
|
|||
namespace storm { |
|||
namespace abstraction { |
|||
namespace jani { |
|||
|
|||
template<storm::dd::DdType DdType> |
|||
JaniAbstractionInformation<DdType>::JaniAbstractionInformation(storm::expressions::ExpressionManager& expressionManager, std::set<storm::expressions::Variable> const& allVariables, uint64_t numberOfLocations, std::unique_ptr<storm::solver::SmtSolver>&& smtSolver, std::shared_ptr<storm::dd::DdManager<DdType>> ddManager) : AbstractionInformation<DdType>(expressionManager, allVariables, std::move(smtSolver), ddManager) { |
|||
|
|||
// Create the location variable to have the appropriate dimension.
|
|||
if (numberOfLocations > 1) { |
|||
locationVariables = ddManager->addMetaVariable("loc", 0, numberOfLocations - 1); |
|||
sourceLocationVariables.insert(locationVariables.get().first); |
|||
successorLocationVariables.insert(locationVariables.get().second); |
|||
} |
|||
} |
|||
|
|||
template<storm::dd::DdType DdType> |
|||
storm::dd::Bdd<DdType> JaniAbstractionInformation<DdType>::encodeLocation(uint64_t locationIndex, bool source) const { |
|||
if (locationVariables) { |
|||
if (source) { |
|||
return this->getDdManager().getEncoding(locationVariables.get().first, locationIndex); |
|||
} else { |
|||
return this->getDdManager().getEncoding(locationVariables.get().second, locationIndex); |
|||
} |
|||
} else { |
|||
return this->getDdManager().getBddOne(); |
|||
} |
|||
} |
|||
|
|||
template<storm::dd::DdType DdType> |
|||
std::set<storm::expressions::Variable> const& JaniAbstractionInformation<DdType>::getSourceLocationVariables() const { |
|||
return sourceLocationVariables; |
|||
} |
|||
|
|||
template<storm::dd::DdType DdType> |
|||
std::set<storm::expressions::Variable> const& JaniAbstractionInformation<DdType>::getSuccessorLocationVariables() const { |
|||
return successorLocationVariables; |
|||
} |
|||
|
|||
template class JaniAbstractionInformation<storm::dd::DdType::CUDD>; |
|||
template class JaniAbstractionInformation<storm::dd::DdType::Sylvan>; |
|||
|
|||
} |
|||
} |
|||
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue