Browse Source
Intermediate commit: integrating MTBDD model generation/model checking to main tool.
Intermediate commit: integrating MTBDD model generation/model checking to main tool.
Former-commit-id: a312d3a425
main
16 changed files with 1988 additions and 525 deletions
-
172src/adapters/DdExpressionAdapter.cpp
-
43src/adapters/DdExpressionAdapter.h
-
199src/adapters/StormAdapter.h
-
299src/adapters/SymbolicModelAdapter.h
-
1442src/builder/DdPrismModelBuilder.cpp
-
282src/builder/DdPrismModelBuilder.h
-
3src/builder/ExplicitPrismModelBuilder.cpp
-
4src/storage/dd/CuddDd.cpp
-
7src/storage/dd/CuddDd.h
-
2src/storage/dd/CuddDdForwardIterator.cpp
-
4src/storage/dd/CuddDdForwardIterator.h
-
12src/storage/dd/CuddDdManager.cpp
-
12src/storage/dd/CuddDdManager.h
-
2src/storage/dd/CuddOdd.cpp
-
22src/utility/math.h
-
6src/utility/prism.h
@ -0,0 +1,172 @@ |
|||||
|
#include "src/adapters/DdExpressionAdapter.h"
|
||||
|
|
||||
|
#include "src/utility/macros.h"
|
||||
|
#include "src/exceptions/ExpressionEvaluationException.h"
|
||||
|
|
||||
|
#include "src/storage/dd/CuddDdManager.h"
|
||||
|
|
||||
|
namespace storm { |
||||
|
namespace adapters { |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
SymbolicExpressionAdapter<Type>::SymbolicExpressionAdapter(storm::dd::DdManager<Type> const& ddManager, std::map<storm::expressions::Variable, storm::expressions::Variable> const& variableMapping) : ddManager(ddManager), variableMapping(variableMapping) { |
||||
|
// Intentionally left empty.
|
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
storm::dd::Dd<Type> SymbolicExpressionAdapter<Type>::translateExpression(storm::expressions::Expression const& expression) { |
||||
|
return boost::any_cast<storm::dd::Dd<Type>>(expression.accept(*this)); |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::IfThenElseExpression const& expression) { |
||||
|
storm::dd::Dd<Type> elseDd = boost::any_cast<storm::dd::Dd<Type>>(expression.getElseExpression()->accept(*this)); |
||||
|
storm::dd::Dd<Type> thenDd = boost::any_cast<storm::dd::Dd<Type>>(expression.getThenExpression()->accept(*this)); |
||||
|
storm::dd::Dd<Type> conditionDd = boost::any_cast<storm::dd::Dd<Type>>(expression.getCondition()->accept(*this)); |
||||
|
return conditionDd.ite(thenDd, elseDd); |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::BinaryBooleanFunctionExpression const& expression) { |
||||
|
storm::dd::Dd<Type> leftResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getFirstOperand()->accept(*this)); |
||||
|
storm::dd::Dd<Type> rightResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getSecondOperand()->accept(*this)); |
||||
|
|
||||
|
storm::dd::Dd<Type> result; |
||||
|
switch (expression.getOperatorType()) { |
||||
|
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::And: |
||||
|
result = leftResult && rightResult; |
||||
|
break; |
||||
|
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Or: |
||||
|
result = leftResult || rightResult; |
||||
|
break; |
||||
|
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Iff: |
||||
|
result = leftResult.equals(rightResult); |
||||
|
break; |
||||
|
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Implies: |
||||
|
result = !leftResult || rightResult; |
||||
|
break; |
||||
|
case storm::expressions::BinaryBooleanFunctionExpression::OperatorType::Xor: |
||||
|
result = (leftResult && !rightResult) || (!leftResult && rightResult); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::BinaryNumericalFunctionExpression const& expression) { |
||||
|
storm::dd::Dd<Type> leftResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getFirstOperand()->accept(*this)); |
||||
|
storm::dd::Dd<Type> rightResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getSecondOperand()->accept(*this)); |
||||
|
|
||||
|
storm::dd::Dd<Type> result; |
||||
|
switch (expression.getOperatorType()) { |
||||
|
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Plus: |
||||
|
result = leftResult + rightResult; |
||||
|
break; |
||||
|
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Minus: |
||||
|
result = leftResult - rightResult; |
||||
|
break; |
||||
|
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Times: |
||||
|
result = leftResult * rightResult; |
||||
|
break; |
||||
|
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Divide: |
||||
|
result = leftResult / rightResult; |
||||
|
break; |
||||
|
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Max: |
||||
|
result = leftResult.maximum(rightResult); |
||||
|
break; |
||||
|
case storm::expressions::BinaryNumericalFunctionExpression::OperatorType::Min: |
||||
|
result = leftResult.minimum(rightResult); |
||||
|
break; |
||||
|
default: |
||||
|
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Cannot translate expression containing power operator."); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::BinaryRelationExpression const& expression) { |
||||
|
storm::dd::Dd<Type> leftResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getFirstOperand()->accept(*this)); |
||||
|
storm::dd::Dd<Type> rightResult = boost::any_cast<storm::dd::Dd<Type>>(expression.getSecondOperand()->accept(*this)); |
||||
|
|
||||
|
storm::dd::Dd<Type> result; |
||||
|
switch (expression.getRelationType()) { |
||||
|
case storm::expressions::BinaryRelationExpression::RelationType::Equal: |
||||
|
result = leftResult.equals(rightResult); |
||||
|
break; |
||||
|
case storm::expressions::BinaryRelationExpression::RelationType::NotEqual: |
||||
|
result = leftResult.notEquals(rightResult); |
||||
|
break; |
||||
|
case storm::expressions::BinaryRelationExpression::RelationType::Less: |
||||
|
result = leftResult.less(rightResult); |
||||
|
break; |
||||
|
case storm::expressions::BinaryRelationExpression::RelationType::LessOrEqual: |
||||
|
result = leftResult.lessOrEqual(rightResult); |
||||
|
break; |
||||
|
case storm::expressions::BinaryRelationExpression::RelationType::Greater: |
||||
|
result = leftResult.greater(rightResult); |
||||
|
break; |
||||
|
case storm::expressions::BinaryRelationExpression::RelationType::GreaterOrEqual: |
||||
|
result = leftResult.greaterOrEqual(rightResult); |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::VariableExpression const& expression) { |
||||
|
auto const& variablePair = variableMapping.find(expression.getVariable()); |
||||
|
STORM_LOG_THROW(variablePair != variableMapping.end(), storm::exceptions::InvalidArgumentException, "Cannot translate the given expression, because it contains th variable '" << expression.getVariableName() << "' for which no DD counterpart is known."); |
||||
|
return ddManager.getIdentity(variablePair->second); |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::UnaryBooleanFunctionExpression const& expression) { |
||||
|
storm::dd::Dd<Type> result = boost::any_cast<storm::dd::Dd<Type>>(expression.getOperand()->accept(*this)); |
||||
|
|
||||
|
switch (expression.getOperatorType()) { |
||||
|
case storm::expressions::UnaryBooleanFunctionExpression::OperatorType::Not: |
||||
|
result = !result; |
||||
|
break; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::UnaryNumericalFunctionExpression const& expression) { |
||||
|
storm::dd::Dd<Type> result = boost::any_cast<storm::dd::Dd<Type>>(expression.getOperand()->accept(*this)); |
||||
|
|
||||
|
switch (expression.getOperatorType()) { |
||||
|
case storm::expressions::UnaryNumericalFunctionExpression::OperatorType::Minus: |
||||
|
result = -result; |
||||
|
break; |
||||
|
default: |
||||
|
STORM_LOG_THROW(false, storm::exceptions::InvalidArgumentException, "Cannot translate expression containing floor/ceil operator."); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::BooleanLiteralExpression const& expression) { |
||||
|
return ddManager.getConstant(expression.getValue()); |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::IntegerLiteralExpression const& expression) { |
||||
|
return ddManager.getConstant(expression.getValue()); |
||||
|
} |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
boost::any SymbolicExpressionAdapter<Type>::visit(storm::expressions::DoubleLiteralExpression const& expression) { |
||||
|
return ddManager.getConstant(expression.getValue()); |
||||
|
} |
||||
|
|
||||
|
// Explicitly instantiate the symbolic expression adapter
|
||||
|
template class SymbolicExpressionAdapter<storm::dd::DdType::CUDD>; |
||||
|
|
||||
|
} // namespace adapters
|
||||
|
} // namespace storm
|
@ -0,0 +1,43 @@ |
|||||
|
#ifndef STORM_ADAPTERS_DDEXPRESSIONADAPTER_H_ |
||||
|
#define STORM_ADAPTERS_DDEXPRESSIONADAPTER_H_ |
||||
|
|
||||
|
#include "src/storage/expressions/Variable.h" |
||||
|
#include "src/storage/expressions/Expressions.h" |
||||
|
#include "storage/expressions/ExpressionVisitor.h" |
||||
|
|
||||
|
#include "src/storage/dd/Dd.h" |
||||
|
#include "src/storage/dd/DdManager.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace adapters { |
||||
|
|
||||
|
template<storm::dd::DdType Type> |
||||
|
class SymbolicExpressionAdapter : public storm::expressions::ExpressionVisitor { |
||||
|
public: |
||||
|
SymbolicExpressionAdapter(storm::dd::DdManager<Type> const& ddManager, std::map<storm::expressions::Variable, storm::expressions::Variable> const& variableMapping); |
||||
|
|
||||
|
storm::dd::Dd<Type> translateExpression(storm::expressions::Expression const& expression); |
||||
|
|
||||
|
virtual boost::any visit(storm::expressions::IfThenElseExpression const& expression) override; |
||||
|
virtual boost::any visit(storm::expressions::BinaryBooleanFunctionExpression const& expression) override; |
||||
|
virtual boost::any visit(storm::expressions::BinaryNumericalFunctionExpression const& expression) override; |
||||
|
virtual boost::any visit(storm::expressions::BinaryRelationExpression const& expression) override; |
||||
|
virtual boost::any visit(storm::expressions::VariableExpression const& expression) override; |
||||
|
virtual boost::any visit(storm::expressions::UnaryBooleanFunctionExpression const& expression) override; |
||||
|
virtual boost::any visit(storm::expressions::UnaryNumericalFunctionExpression const& expression) override; |
||||
|
virtual boost::any visit(storm::expressions::BooleanLiteralExpression const& expression) override; |
||||
|
virtual boost::any visit(storm::expressions::IntegerLiteralExpression const& expression) override; |
||||
|
virtual boost::any visit(storm::expressions::DoubleLiteralExpression const& expression) override; |
||||
|
|
||||
|
private: |
||||
|
// The manager responsible for the DDs built by this adapter. |
||||
|
storm::dd::DdManager<Type> const& ddManager; |
||||
|
|
||||
|
// This member maps the variables used in the expressions to the variables used by the DD manager. |
||||
|
std::map<storm::expressions::Variable, storm::expressions::Variable> const& variableMapping; |
||||
|
}; |
||||
|
|
||||
|
} // namespace adapters |
||||
|
} // namespace storm |
||||
|
|
||||
|
#endif /* STORM_ADAPTERS_DDEXPRESSIONADAPTER_H_ */ |
@ -1,199 +0,0 @@ |
|||||
/* |
|
||||
* StormAdapter.h |
|
||||
* |
|
||||
* Created on: 02.03.2013 |
|
||||
* Author: Philipp Berger |
|
||||
*/ |
|
||||
|
|
||||
#ifndef STORM_ADAPTERS_STORMADAPTER_H_ |
|
||||
#define STORM_ADAPTERS_STORMADAPTER_H_ |
|
||||
|
|
||||
#include "gmm/gmm_matrix.h" |
|
||||
#include "Eigen/Sparse" |
|
||||
#include "src/storage/SparseMatrix.h" |
|
||||
|
|
||||
#include "log4cplus/logger.h" |
|
||||
#include "log4cplus/loggingmacros.h" |
|
||||
|
|
||||
extern log4cplus::Logger logger; |
|
||||
|
|
||||
namespace storm { |
|
||||
|
|
||||
namespace adapters { |
|
||||
|
|
||||
class StormAdapter { |
|
||||
public: |
|
||||
/*! |
|
||||
* Converts a sparse matrix into a sparse matrix in the storm format. |
|
||||
* @return A pointer to a row-major sparse matrix in storm format. |
|
||||
*/ |
|
||||
template<class T> |
|
||||
static storm::storage::SparseMatrix<T>* toStormSparseMatrix(gmm::csr_matrix<T> const& matrix) { |
|
||||
uint_fast64_t realNonZeros = gmm::nnz(matrix); |
|
||||
LOG4CPLUS_DEBUG(logger, "Converting matrix with " << realNonZeros << " non-zeros from gmm++ format into Storm."); |
|
||||
|
|
||||
// Prepare the resulting matrix. |
|
||||
storm::storage::SparseMatrix<T>* result = new storm::storage::SparseMatrix<T>(matrix.ncols(), matrix.jc, matrix.ir, matrix.pr); |
|
||||
|
|
||||
LOG4CPLUS_DEBUG(logger, "Done converting matrix to storm format."); |
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
|
|
||||
/*! |
|
||||
* Helper function to determine whether the given Eigen matrix is in RowMajor |
|
||||
* format. Always returns true, but is overloaded, so the compiler will |
|
||||
* only call it in case the Eigen matrix is in RowMajor format. |
|
||||
* @return True. |
|
||||
*/ |
|
||||
template<typename _Scalar, typename _Index> |
|
||||
static bool isEigenRowMajor(Eigen::SparseMatrix<_Scalar, Eigen::RowMajor, _Index>) { |
|
||||
return true; |
|
||||
} |
|
||||
|
|
||||
/*! |
|
||||
* Helper function to determine whether the given Eigen matrix is in RowMajor |
|
||||
* format. Always returns false, but is overloaded, so the compiler will |
|
||||
* only call it in case the Eigen matrix is in ColMajor format. |
|
||||
* @return False. |
|
||||
*/ |
|
||||
template<typename _Scalar, typename _Index> |
|
||||
static bool isEigenRowMajor( |
|
||||
Eigen::SparseMatrix<_Scalar, Eigen::ColMajor, _Index>) { |
|
||||
return false; |
|
||||
} |
|
||||
|
|
||||
/*! |
|
||||
* Converts a sparse matrix in the eigen format to Storm Sparse Matrix format. |
|
||||
* @return A pointer to a row-major sparse matrix in our format. |
|
||||
*/ |
|
||||
template<class T, int _Options, typename _Index> |
|
||||
static storm::storage::SparseMatrix<T>* toStormSparseMatrix(Eigen::SparseMatrix<T, _Options, _Index> const& matrix) { |
|
||||
uint_fast64_t realNonZeros = matrix.nonZeros(); |
|
||||
LOG4CPLUS_DEBUG(logger, "Converting matrix with " << realNonZeros << " non-zeros from Eigen3 format into Storm."); |
|
||||
|
|
||||
// Throw an error in case the matrix is not in compressed format. |
|
||||
if (!matrix.isCompressed()) { |
|
||||
LOG4CPLUS_ERROR(logger, "Trying to convert from an Eigen matrix that is not in compressed form."); |
|
||||
return nullptr; |
|
||||
} |
|
||||
|
|
||||
/* |
|
||||
* Try to prepare the internal storage and throw an error in case of |
|
||||
* failure. |
|
||||
*/ |
|
||||
|
|
||||
// Get necessary pointers to the contents of the Eigen matrix. |
|
||||
const T* valuePtr = matrix.valuePtr(); |
|
||||
const _Index* indexPtr = matrix.innerIndexPtr(); |
|
||||
const _Index* outerPtr = matrix.outerIndexPtr(); |
|
||||
|
|
||||
const uint_fast64_t outerSize = matrix.outerSize(); |
|
||||
|
|
||||
storm::storage::SparseMatrix<T>* result = nullptr; |
|
||||
|
|
||||
// If the given matrix is in RowMajor format, copying can simply |
|
||||
// be done by adding all values in order. |
|
||||
// Direct copying is, however, prevented because we have to |
|
||||
// separate the diagonal entries from others. |
|
||||
if (isEigenRowMajor(matrix)) { |
|
||||
/* Because of the RowMajor format outerSize evaluates to the |
|
||||
* number of rows. |
|
||||
* Prepare the resulting matrix. |
|
||||
*/ |
|
||||
result = new storm::storage::SparseMatrix<T>(matrix.outerSize(), matrix.innerSize()); |
|
||||
|
|
||||
// Set internal NonZero Counter |
|
||||
result->nonZeroEntryCount = realNonZeros; |
|
||||
result->setState(result->Initialized); |
|
||||
|
|
||||
if (!result->prepareInternalStorage(false)) { |
|
||||
LOG4CPLUS_ERROR(logger, "Unable to allocate internal storage while converting Eigen3 RM Matrix to Storm."); |
|
||||
delete result; |
|
||||
return nullptr; |
|
||||
} else { |
|
||||
|
|
||||
// Copy Row Indications |
|
||||
std::copy(outerPtr, outerPtr + outerSize, std::back_inserter(result->rowIndications)); |
|
||||
// Copy Columns Indications |
|
||||
std::copy(indexPtr, indexPtr + realNonZeros, std::back_inserter(result->columnIndications)); |
|
||||
// And do the same thing with the actual values. |
|
||||
std::copy(valuePtr, valuePtr + realNonZeros, std::back_inserter(result->valueStorage)); |
|
||||
|
|
||||
// This is our Sentinel Element. |
|
||||
result->rowIndications.push_back(realNonZeros); |
|
||||
|
|
||||
result->currentSize = realNonZeros; |
|
||||
result->lastRow = outerSize - 1; |
|
||||
} |
|
||||
} else { |
|
||||
/* Because of the RowMajor format outerSize evaluates to the |
|
||||
* number of columns. |
|
||||
* Prepare the resulting matrix. |
|
||||
*/ |
|
||||
const uint_fast64_t colCount = matrix.outerSize(); |
|
||||
result = new storm::storage::SparseMatrix<T>(matrix.innerSize(), colCount); |
|
||||
|
|
||||
// Set internal NonZero Counter |
|
||||
result->nonZeroEntryCount = realNonZeros; |
|
||||
result->setState(result->Initialized); |
|
||||
if (!result->prepareInternalStorage()) { |
|
||||
LOG4CPLUS_ERROR(logger, "Unable to allocate internal storage while converting Eigen3 CM Matrix to Storm."); |
|
||||
delete result; |
|
||||
return nullptr; |
|
||||
} else { |
|
||||
// Set internal NonZero Counter |
|
||||
result->nonZeroEntryCount = realNonZeros; |
|
||||
result->setState(result->Initialized); |
|
||||
|
|
||||
// Create an array to remember which elements have to still |
|
||||
// be searched in each column and initialize it with the starting |
|
||||
// index for every column. |
|
||||
_Index* positions = new _Index[colCount](); |
|
||||
for (_Index i = 0; i < colCount; ++i) { |
|
||||
positions[i] = outerPtr[i]; |
|
||||
} |
|
||||
|
|
||||
// Now copy the elements. As the matrix is in ColMajor format, |
|
||||
// we need to iterate over the columns to find the next non-zero |
|
||||
// entry. |
|
||||
uint_fast64_t i = 0; |
|
||||
int currentRow = 0; |
|
||||
int currentColumn = 0; |
|
||||
while (i < realNonZeros) { |
|
||||
// If the current element belongs the the current column, |
|
||||
// add it in case it is also in the current row. |
|
||||
if ((positions[currentColumn] < outerPtr[currentColumn + 1]) |
|
||||
&& (indexPtr[positions[currentColumn]] == currentRow)) { |
|
||||
result->addNextValue(currentRow, currentColumn, valuePtr[positions[currentColumn]]); |
|
||||
// Remember that we found one more non-zero element. |
|
||||
++i; |
|
||||
// Mark this position as "used". |
|
||||
++positions[currentColumn]; |
|
||||
} |
|
||||
|
|
||||
// Now we can advance to the next column and also row, |
|
||||
// in case we just iterated through the last column. |
|
||||
++currentColumn; |
|
||||
if (currentColumn == colCount) { |
|
||||
currentColumn = 0; |
|
||||
++currentRow; |
|
||||
} |
|
||||
} |
|
||||
delete[] positions; |
|
||||
} |
|
||||
} |
|
||||
result->setState(result->Initialized); |
|
||||
result->finalize(); |
|
||||
|
|
||||
LOG4CPLUS_DEBUG(logger, "Done converting matrix to storm format."); |
|
||||
|
|
||||
return result; |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} //namespace adapters |
|
||||
|
|
||||
} //namespace storm |
|
||||
|
|
||||
#endif /* STORM_ADAPTERS_STORMADAPTER_H_ */ |
|
@ -1,299 +0,0 @@ |
|||||
/* |
|
||||
* SymbolicModelAdapter.h |
|
||||
* |
|
||||
* Created on: 25.01.2013 |
|
||||
* Author: Christian Dehnert |
|
||||
*/ |
|
||||
|
|
||||
#ifndef STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ |
|
||||
#define STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ |
|
||||
|
|
||||
#include "src/exceptions/WrongFormatException.h" |
|
||||
|
|
||||
#include "src/utility/CuddUtility.h" |
|
||||
#include "SymbolicExpressionAdapter.h" |
|
||||
|
|
||||
#include "cuddObj.hh" |
|
||||
#include <iostream> |
|
||||
#include <unordered_map> |
|
||||
#include <cmath> |
|
||||
|
|
||||
namespace storm { |
|
||||
|
|
||||
namespace adapters { |
|
||||
|
|
||||
class SymbolicModelAdapter { |
|
||||
public: |
|
||||
|
|
||||
SymbolicModelAdapter(storm::ir::Program const& program) : program(program), cuddUtility(storm::utility::cuddUtilityInstance()), allDecisionDiagramVariables(), |
|
||||
allRowDecisionDiagramVariables(), allColumnDecisionDiagramVariables(), booleanRowDecisionDiagramVariables(), |
|
||||
integerRowDecisionDiagramVariables(), booleanColumnDecisionDiagramVariables(), integerColumnDecisionDiagramVariables(), |
|
||||
variableToRowDecisionDiagramVariableMap(), variableToColumnDecisionDiagramVariableMap(), |
|
||||
variableToIdentityDecisionDiagramMap(), |
|
||||
rowExpressionAdapter(program, variableToRowDecisionDiagramVariableMap), columnExpressionAdapter(program, variableToColumnDecisionDiagramVariableMap) { |
|
||||
|
|
||||
} |
|
||||
|
|
||||
void toMTBDD() { |
|
||||
LOG4CPLUS_INFO(logger, "Creating MTBDD representation for probabilistic program."); |
|
||||
createDecisionDiagramVariables(program); |
|
||||
createIdentityDecisionDiagrams(program); |
|
||||
|
|
||||
ADD* systemAdd = cuddUtility->getZero(); |
|
||||
for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { |
|
||||
storm::ir::Module const& module = program.getModule(i); |
|
||||
|
|
||||
ADD* moduleAdd = cuddUtility->getZero(); |
|
||||
for (uint_fast64_t j = 0; j < module.getNumberOfCommands(); ++j) { |
|
||||
storm::ir::Command const& command = module.getCommand(j); |
|
||||
|
|
||||
ADD* commandAdd = cuddUtility->getZero(); |
|
||||
|
|
||||
ADD* guard = rowExpressionAdapter.translateExpression(command.getGuard()); |
|
||||
if (*guard != *cuddUtility->getZero()) { |
|
||||
for (uint_fast64_t i = 0; i < command.getNumberOfUpdates(); ++i) { |
|
||||
ADD* updateAdd = cuddUtility->getOne(); |
|
||||
|
|
||||
storm::ir::Update const& update = command.getUpdate(i); |
|
||||
|
|
||||
std::map<std::string, storm::ir::Assignment> booleanAssignments = update.getBooleanAssignments(); |
|
||||
for (auto assignmentPair : booleanAssignments) { |
|
||||
ADD* updateExpr = rowExpressionAdapter.translateExpression(assignmentPair.second.getExpression()); |
|
||||
|
|
||||
ADD* temporary = cuddUtility->getZero(); |
|
||||
cuddUtility->setValueAtIndex(temporary, 0, variableToColumnDecisionDiagramVariableMap[assignmentPair.first], 0); |
|
||||
cuddUtility->setValueAtIndex(temporary, 1, variableToColumnDecisionDiagramVariableMap[assignmentPair.first], 1); |
|
||||
|
|
||||
ADD* result = new ADD(*updateExpr * *guard); |
|
||||
result = new ADD(result->Equals(*temporary)); |
|
||||
|
|
||||
*updateAdd = *updateAdd * *result; |
|
||||
} |
|
||||
|
|
||||
std::map<std::string, storm::ir::Assignment> integerAssignments = update.getIntegerAssignments(); |
|
||||
for (auto assignmentPair : integerAssignments) { |
|
||||
ADD* updateExpr = rowExpressionAdapter.translateExpression(assignmentPair.second.getExpression()); |
|
||||
|
|
||||
ADD* temporary = cuddUtility->getZero(); |
|
||||
|
|
||||
uint_fast64_t variableIndex = module.getIntegerVariableIndex(assignmentPair.first); |
|
||||
storm::ir::IntegerVariable integerVariable = module.getIntegerVariable(variableIndex); |
|
||||
int_fast64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr); |
|
||||
int_fast64_t high = integerVariable.getUpperBound()->getValueAsInt(nullptr); |
|
||||
|
|
||||
for (int_fast64_t i = low; i <= high; ++i) { |
|
||||
cuddUtility->setValueAtIndex(temporary, i - low, variableToColumnDecisionDiagramVariableMap[assignmentPair.first], static_cast<double>(i)); |
|
||||
} |
|
||||
|
|
||||
ADD* result = new ADD(*updateExpr * *guard); |
|
||||
result = new ADD(result->Equals(*temporary)); |
|
||||
*result *= *guard; |
|
||||
|
|
||||
*updateAdd = *updateAdd * *result; |
|
||||
} |
|
||||
for (uint_fast64_t i = 0; i < module.getNumberOfBooleanVariables(); ++i) { |
|
||||
storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(i); |
|
||||
|
|
||||
if (update.getBooleanAssignments().find(booleanVariable.getName()) == update.getBooleanAssignments().end()) { |
|
||||
*updateAdd = *updateAdd * *variableToIdentityDecisionDiagramMap[booleanVariable.getName()]; |
|
||||
} |
|
||||
} |
|
||||
for (uint_fast64_t i = 0; i < module.getNumberOfIntegerVariables(); ++i) { |
|
||||
storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(i); |
|
||||
|
|
||||
if (update.getIntegerAssignments().find(integerVariable.getName()) == update.getIntegerAssignments().end()) { |
|
||||
*updateAdd = *updateAdd * *variableToIdentityDecisionDiagramMap[integerVariable.getName()]; |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
*commandAdd += *updateAdd * *cuddUtility->getConstant(update.getLikelihoodExpression()->getValueAsDouble(nullptr)); |
|
||||
} |
|
||||
*moduleAdd += *commandAdd; |
|
||||
} else { |
|
||||
LOG4CPLUS_WARN(logger, "Guard " << command.getGuard()->toString() << " is unsatisfiable."); |
|
||||
} |
|
||||
} |
|
||||
*systemAdd += *moduleAdd; |
|
||||
} |
|
||||
|
|
||||
performReachability(program, systemAdd); |
|
||||
|
|
||||
LOG4CPLUS_INFO(logger, "Done creating MTBDD representation for probabilistic program."); |
|
||||
} |
|
||||
|
|
||||
private: |
|
||||
storm::ir::Program const& program; |
|
||||
storm::utility::CuddUtility* cuddUtility; |
|
||||
|
|
||||
std::vector<ADD*> allDecisionDiagramVariables; |
|
||||
std::vector<ADD*> allRowDecisionDiagramVariables; |
|
||||
std::vector<ADD*> allColumnDecisionDiagramVariables; |
|
||||
std::vector<ADD*> booleanRowDecisionDiagramVariables; |
|
||||
std::vector<ADD*> integerRowDecisionDiagramVariables; |
|
||||
std::vector<ADD*> booleanColumnDecisionDiagramVariables; |
|
||||
std::vector<ADD*> integerColumnDecisionDiagramVariables; |
|
||||
std::unordered_map<std::string, std::vector<ADD*>> variableToRowDecisionDiagramVariableMap; |
|
||||
std::unordered_map<std::string, std::vector<ADD*>> variableToColumnDecisionDiagramVariableMap; |
|
||||
|
|
||||
std::unordered_map<std::string, ADD*> variableToIdentityDecisionDiagramMap; |
|
||||
|
|
||||
SymbolicExpressionAdapter rowExpressionAdapter; |
|
||||
SymbolicExpressionAdapter columnExpressionAdapter; |
|
||||
|
|
||||
// As log2 is not part of C90, only of C99 which no Compiler fully supports, this feature is unavailable on MSVC |
|
||||
inline double log2(uint_fast64_t number) { |
|
||||
# include "src/utility/OsDetection.h" |
|
||||
# ifndef WINDOWS |
|
||||
return std::log2(number); |
|
||||
# else |
|
||||
return std::log(number) / std::log(2); |
|
||||
# endif |
|
||||
} |
|
||||
|
|
||||
ADD* getInitialStateDecisionDiagram(storm::ir::Program const& program) { |
|
||||
ADD* initialStates = cuddUtility->getOne(); |
|
||||
for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { |
|
||||
storm::ir::Module const& module = program.getModule(i); |
|
||||
|
|
||||
for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { |
|
||||
storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(j); |
|
||||
*initialStates *= *cuddUtility->getConstantEncoding(1, variableToRowDecisionDiagramVariableMap[booleanVariable.getName()]); |
|
||||
} |
|
||||
for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { |
|
||||
storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(j); |
|
||||
int_fast64_t initialValue = integerVariable.getInitialValue()->getValueAsInt(nullptr); |
|
||||
int_fast64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr); |
|
||||
*initialStates *= *cuddUtility->getConstantEncoding(initialValue - low, variableToRowDecisionDiagramVariableMap[integerVariable.getName()]); |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
cuddUtility->dumpDotToFile(initialStates, "initstates.add"); |
|
||||
return initialStates; |
|
||||
} |
|
||||
|
|
||||
void performReachability(storm::ir::Program const& program, ADD* systemAdd) { |
|
||||
ADD* systemAdd01 = new ADD(systemAdd->GreaterThan(*cuddUtility->getZero())); |
|
||||
cuddUtility->dumpDotToFile(systemAdd01, "system01.add"); |
|
||||
|
|
||||
cuddUtility->dumpDotToFile(systemAdd, "reachtransold.add"); |
|
||||
ADD* reachableStates = getInitialStateDecisionDiagram(program); |
|
||||
cuddUtility->dumpDotToFile(reachableStates, "init.add"); |
|
||||
ADD* newReachableStates = new ADD(*reachableStates); |
|
||||
|
|
||||
ADD* rowCube = cuddUtility->getOne(); |
|
||||
for (auto variablePtr : allRowDecisionDiagramVariables) { |
|
||||
*rowCube *= *variablePtr; |
|
||||
} |
|
||||
|
|
||||
bool changed; |
|
||||
do { |
|
||||
changed = false; |
|
||||
*newReachableStates = *reachableStates * *systemAdd01; |
|
||||
newReachableStates = new ADD(newReachableStates->ExistAbstract(*rowCube)); |
|
||||
|
|
||||
cuddUtility->dumpDotToFile(newReachableStates, "reach1.add"); |
|
||||
|
|
||||
newReachableStates = cuddUtility->permuteVariables(newReachableStates, allColumnDecisionDiagramVariables, allRowDecisionDiagramVariables, static_cast<int>(allDecisionDiagramVariables.size())); |
|
||||
|
|
||||
*newReachableStates += *reachableStates; |
|
||||
newReachableStates = new ADD(newReachableStates->GreaterThan(*cuddUtility->getZero())); |
|
||||
|
|
||||
if (*newReachableStates != *reachableStates) changed = true; |
|
||||
*reachableStates = *newReachableStates; |
|
||||
} while (changed); |
|
||||
|
|
||||
*systemAdd *= *reachableStates; |
|
||||
std::cout << "got " << systemAdd->nodeCount() << " nodes" << std::endl; |
|
||||
std::cout << "and " << systemAdd->CountMinterm(static_cast<int>(allRowDecisionDiagramVariables.size() + allColumnDecisionDiagramVariables.size())) << std::endl; |
|
||||
} |
|
||||
|
|
||||
void createIdentityDecisionDiagrams(storm::ir::Program const& program) { |
|
||||
for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { |
|
||||
storm::ir::Module const& module = program.getModule(i); |
|
||||
|
|
||||
for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { |
|
||||
storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(j); |
|
||||
ADD* identity = cuddUtility->getZero(); |
|
||||
cuddUtility->setValueAtIndices(identity, 0, 0, |
|
||||
variableToRowDecisionDiagramVariableMap[booleanVariable.getName()], |
|
||||
variableToColumnDecisionDiagramVariableMap[booleanVariable.getName()], 1); |
|
||||
cuddUtility->setValueAtIndices(identity, 1, 1, |
|
||||
variableToRowDecisionDiagramVariableMap[booleanVariable.getName()], |
|
||||
variableToColumnDecisionDiagramVariableMap[booleanVariable.getName()], 1); |
|
||||
variableToIdentityDecisionDiagramMap[booleanVariable.getName()] = identity; |
|
||||
} |
|
||||
|
|
||||
for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { |
|
||||
storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(j); |
|
||||
|
|
||||
ADD* identity = cuddUtility->getZero(); |
|
||||
|
|
||||
int_fast64_t low = integerVariable.getLowerBound()->getValueAsInt(nullptr); |
|
||||
int_fast64_t high = integerVariable.getUpperBound()->getValueAsInt(nullptr); |
|
||||
|
|
||||
for (int_fast64_t i = low; i <= high; ++i) { |
|
||||
cuddUtility->setValueAtIndices(identity, i - low, i - low, |
|
||||
variableToRowDecisionDiagramVariableMap[integerVariable.getName()], |
|
||||
variableToColumnDecisionDiagramVariableMap[integerVariable.getName()], 1); |
|
||||
} |
|
||||
variableToIdentityDecisionDiagramMap[integerVariable.getName()] = identity; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
|
|
||||
void createDecisionDiagramVariables(storm::ir::Program const& program) { |
|
||||
for (uint_fast64_t i = 0; i < program.getNumberOfModules(); ++i) { |
|
||||
storm::ir::Module const& module = program.getModule(i); |
|
||||
|
|
||||
for (uint_fast64_t j = 0; j < module.getNumberOfBooleanVariables(); ++j) { |
|
||||
storm::ir::BooleanVariable const& booleanVariable = module.getBooleanVariable(j); |
|
||||
|
|
||||
ADD* newRowDecisionDiagramVariable = cuddUtility->getNewAddVariable(); |
|
||||
variableToRowDecisionDiagramVariableMap[booleanVariable.getName()].push_back(newRowDecisionDiagramVariable); |
|
||||
booleanRowDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); |
|
||||
allRowDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); |
|
||||
allDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); |
|
||||
|
|
||||
ADD* newColumnDecisionDiagramVariable = cuddUtility->getNewAddVariable(); |
|
||||
variableToColumnDecisionDiagramVariableMap[booleanVariable.getName()].push_back(newColumnDecisionDiagramVariable); |
|
||||
booleanColumnDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); |
|
||||
allColumnDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); |
|
||||
allDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); |
|
||||
} |
|
||||
|
|
||||
for (uint_fast64_t j = 0; j < module.getNumberOfIntegerVariables(); ++j) { |
|
||||
storm::ir::IntegerVariable const& integerVariable = module.getIntegerVariable(j); |
|
||||
uint_fast64_t integerRange = integerVariable.getUpperBound()->getValueAsInt(nullptr) - integerVariable.getLowerBound()->getValueAsInt(nullptr); |
|
||||
if (integerRange <= 0) { |
|
||||
throw storm::exceptions::WrongFormatException() << "Range of variable " |
|
||||
<< integerVariable.getName() << " is empty or negativ."; |
|
||||
} |
|
||||
uint_fast64_t numberOfDecisionDiagramVariables = static_cast<uint_fast64_t>(std::ceil(log2(integerRange))); |
|
||||
|
|
||||
std::vector<ADD*> allRowDecisionDiagramVariablesForVariable; |
|
||||
std::vector<ADD*> allColumnDecisionDiagramVariablesForVariable; |
|
||||
for (uint_fast64_t k = 0; k < numberOfDecisionDiagramVariables; ++k) { |
|
||||
ADD* newRowDecisionDiagramVariable = cuddUtility->getNewAddVariable(); |
|
||||
allRowDecisionDiagramVariablesForVariable.push_back(newRowDecisionDiagramVariable); |
|
||||
integerRowDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); |
|
||||
allRowDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); |
|
||||
allDecisionDiagramVariables.push_back(newRowDecisionDiagramVariable); |
|
||||
|
|
||||
ADD* newColumnDecisionDiagramVariable = cuddUtility->getNewAddVariable(); |
|
||||
allColumnDecisionDiagramVariablesForVariable.push_back(newColumnDecisionDiagramVariable); |
|
||||
integerColumnDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); |
|
||||
allColumnDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); |
|
||||
allDecisionDiagramVariables.push_back(newColumnDecisionDiagramVariable); |
|
||||
} |
|
||||
variableToRowDecisionDiagramVariableMap[integerVariable.getName()] = allRowDecisionDiagramVariablesForVariable; |
|
||||
variableToColumnDecisionDiagramVariableMap[integerVariable.getName()] = allColumnDecisionDiagramVariablesForVariable; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
}; |
|
||||
|
|
||||
} // namespace adapters |
|
||||
|
|
||||
} // namespace storm |
|
||||
|
|
||||
#endif /* STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ */ |
|
1442
src/builder/DdPrismModelBuilder.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,282 @@ |
|||||
|
#ifndef STORM_BUILDER_DDPRISMMODELBUILDER_H_ |
||||
|
#define STORM_BUILDER_DDPRISMMODELBUILDER_H_ |
||||
|
|
||||
|
#include <map> |
||||
|
#include <boost/optional.hpp> |
||||
|
|
||||
|
#include "src/logic/Formulas.h" |
||||
|
#include "src/storage/prism/Program.h" |
||||
|
#include "src/adapters/DdExpressionAdapter.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace adapters { |
||||
|
|
||||
|
template <storm::dd::DdType Type> |
||||
|
class DdPrismModelBuilder { |
||||
|
public: |
||||
|
struct Options { |
||||
|
/*! |
||||
|
* Creates an object representing the default building options. |
||||
|
*/ |
||||
|
Options(); |
||||
|
|
||||
|
/*! Creates an object representing the suggested building options assuming that the given formula is the |
||||
|
* only one to check. |
||||
|
* |
||||
|
* @param formula The formula based on which to choose the building options. |
||||
|
*/ |
||||
|
Options(storm::logic::Formula const& formula); |
||||
|
|
||||
|
/*! |
||||
|
* Sets the constants definitions from the given string. The string must be of the form 'X=a,Y=b,Z=c', |
||||
|
* etc. where X,Y,Z are the variable names and a,b,c are the values of the constants. |
||||
|
* |
||||
|
* @param program The program managing the constants that shall be defined. Note that the program itself |
||||
|
* is not modified whatsoever. |
||||
|
* @param constantDefinitionString The string from which to parse the constants' values. |
||||
|
*/ |
||||
|
void addConstantDefinitionsFromString(storm::prism::Program const& program, std::string const& constantDefinitionString); |
||||
|
|
||||
|
// A flag that indicates whether or not a reward model is to be built. |
||||
|
bool buildRewards; |
||||
|
|
||||
|
// An optional string, that, if given, indicates which of the reward models is to be built. |
||||
|
boost::optional<std::string> rewardModelName; |
||||
|
|
||||
|
// An optional mapping that, if given, contains defining expressions for undefined constants. |
||||
|
boost::optional<std::map<storm::expressions::Variable, storm::expressions::Expression>> constantDefinitions; |
||||
|
|
||||
|
// An optional set of labels that, if given, restricts the labels that are built. |
||||
|
boost::optional<std::set<std::string>> labelsToBuild; |
||||
|
|
||||
|
// An optional set of expressions for which labels need to be built. |
||||
|
boost::optional<std::vector<storm::expressions::Expression>> expressionLabels; |
||||
|
}; |
||||
|
|
||||
|
/*! |
||||
|
* Translates the given program into a model that stores the transition relation as a decision diagram. |
||||
|
* |
||||
|
* @param program The program to translate. |
||||
|
*/ |
||||
|
static void translateProgram(storm::prism::Program const& program, Options const& options = Options()); |
||||
|
|
||||
|
private: |
||||
|
// This structure can store the decision diagrams representing a particular action. |
||||
|
struct ActionDecisionDiagram { |
||||
|
ActionDecisionDiagram(storm::dd::DdManager<Type> const& manager) : guardDd(manager.getZero()), transitionsDd(manager.getZero()), numberOfUsedNondeterminismVariables(0) { |
||||
|
// Intentionally left empty. |
||||
|
} |
||||
|
|
||||
|
// The guard of the action. |
||||
|
storm::dd::Dd<Type> guardDd; |
||||
|
|
||||
|
// The actual transitions (source and target states). |
||||
|
storm::dd::Dd<Type> transitionsDd; |
||||
|
|
||||
|
// The number of variables that are used to encode the nondeterminism. |
||||
|
uint_fast64_t numberOfUsedNondeterminismVariables; |
||||
|
}; |
||||
|
|
||||
|
// This structure holds all decision diagrams related to a module. |
||||
|
struct ModuleDecisionDiagram { |
||||
|
ModuleDecisionDiagram(storm::dd::DdManager<Type> const& manager) : independantAction(manager), synchronizingActionToDecisionDiagramMap(), identity(manager.getZero()) { |
||||
|
// Intentionally left empty. |
||||
|
} |
||||
|
|
||||
|
// The decision diagram for the independant action. |
||||
|
ActionDecisionDiagram independantAction; |
||||
|
|
||||
|
// A mapping from synchronizing action indices to the decision diagram. |
||||
|
std::map<uint_fast64_t, ActionDecisionDiagram> synchronizingActionToDecisionDiagramMap; |
||||
|
|
||||
|
// A decision diagram that represents the identity of this module. |
||||
|
storm::dd::Dd<Type> identity; |
||||
|
}; |
||||
|
|
||||
|
/*! |
||||
|
* Structure to store all information required to generate the model from the program. |
||||
|
*/ |
||||
|
class GenerationInformation { |
||||
|
GenerationInformation(storm::prism::Program const& program) : program(program), manager(std::make_shared<storm::dd::DdManager<Type>>()), rowMetaVariables(), columnMetaVariables(), metaVariablePairs(), numberOfNondetVariables(0), variableToIdentityMap(), moduleToIdentityMap(), allSynchronizingActionIndices(), labelToStateDdMap() { |
||||
|
// Initializes variables and identity DDs. |
||||
|
createMetaVariables(); |
||||
|
createIdentities(); |
||||
|
} |
||||
|
|
||||
|
private: |
||||
|
/*! |
||||
|
* Creates the required meta variables. |
||||
|
*/ |
||||
|
void createMetaVariables(); |
||||
|
|
||||
|
/*! |
||||
|
* Creates identity DDs for all variables and all modules. |
||||
|
*/ |
||||
|
void createIdentities(); |
||||
|
|
||||
|
// The program that is currently translated. |
||||
|
storm::prism::Program const& program; |
||||
|
|
||||
|
// The manager used to build the decision diagrams. |
||||
|
std::shared_ptr<storm::dd::DdManager<Type>> manager; |
||||
|
|
||||
|
// The meta variables for the row encoding. |
||||
|
std::vector<storm::expressions::Variable> rowMetaVariables; |
||||
|
|
||||
|
// The meta variables for the column encoding. |
||||
|
std::vector<storm::expressions::Variable> columnMetaVariables; |
||||
|
|
||||
|
// Pairs of meta variables (row, column). |
||||
|
std::vector<std::pair<storm::expressions::Variable, storm::expressions::Variable>> metaVariablePairs; |
||||
|
|
||||
|
// Number of variables used to encode the nondeterminism. |
||||
|
uint_fast64_t numberOfNondetVariables; |
||||
|
|
||||
|
// DDs representing the identity for each variable. |
||||
|
std::map<storm::expressions::Variable, storm::dd::Dd<Type>> variableToIdentityMap; |
||||
|
|
||||
|
// DDs representing the identity for each module (index). |
||||
|
std::map<uint_fast64_t, storm::dd::Dd<Type>> moduleToIdentityMap; |
||||
|
|
||||
|
// All synchronizing actions |
||||
|
std::set<uint_fast64_t> allSynchronizingActionIndices; |
||||
|
|
||||
|
// DDs representing the identity matrix for each module |
||||
|
std::unordered_map<std::string, storm::dd::Dd<Type>> labelToStateDdMap; |
||||
|
}; |
||||
|
|
||||
|
private: |
||||
|
|
||||
|
// /*! |
||||
|
// * Creates system DD (full parallel) |
||||
|
// * |
||||
|
// * @return A DD representing the whole system |
||||
|
// */ |
||||
|
// static storm::dd::Dd<Type> createSystemDecisionDiagramm(GenerationInformation & generationInfo); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Combines all DDs to one DD (including independent/synchronized actions) |
||||
|
// * |
||||
|
// * @param systemDds DDs representing the whole system |
||||
|
// * @return System DDs with combined independent/synchronized actions |
||||
|
// */ |
||||
|
// static SystemComponentDecisionDiagram<Type> combineSystem(GenerationInformation const & generationInfo, SystemComponentDecisionDiagram<Type> systemDds); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Combines 2 modules with/without synchronizing actions |
||||
|
// * |
||||
|
// * @param synchronizing Synchronizing actions or not |
||||
|
// * @param module1 First module |
||||
|
// * @param module1 Second module |
||||
|
// * @param identity1 Identity matrix of first module |
||||
|
// * @param identity2 Identity matrix of second module |
||||
|
// * @return A module DD representing the combination of both modules |
||||
|
// */ |
||||
|
// static ModuleDecisionDiagram<Type> combineModules(GenerationInformation const & generationInfo, bool synchronizing, ModuleDecisionDiagram<Type> moduleDd1, ModuleDecisionDiagram<Type> moduleDd2, storm::dd::Dd<Type> const& identityDd1, storm::dd::Dd<Type> const& identityDd2); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Combines 2 modules and solves non-determinism (MDP) |
||||
|
// * |
||||
|
// * @param module1 First module |
||||
|
// * @param module1 Second module |
||||
|
// * @return A module DD representing the combination of both modules |
||||
|
// */ |
||||
|
// static ModuleDecisionDiagram<Type> combineModulesMDP(GenerationInformation const & generationInfo, ModuleDecisionDiagram<Type> moduleDd1, ModuleDecisionDiagram<Type> moduleDd2); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Creates a system component DD (module) |
||||
|
// * |
||||
|
// * @param module Module |
||||
|
// * @param usedNondetVariablesVector Number of used nondet. variables |
||||
|
// * @return A system component DD storing all required module information |
||||
|
// */ |
||||
|
// static SystemComponentDecisionDiagram<Type> createSystemComponentDecisionDiagramm(GenerationInformation const & generationInfo, storm::prism::Module const & module, std::vector<uint_fast64_t> usedNondetVariablesVector); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Combines commands (with guards) to a module DD (DTMC) |
||||
|
// * |
||||
|
// * @param numberOfCommands Number of commands in the current module |
||||
|
// * @param commandDds DDs containing all updates for each command |
||||
|
// * @param guardDds Guard DDs for each command |
||||
|
// * @return A DD representing the module. |
||||
|
// */ |
||||
|
// static ModuleDecisionDiagram<Type> combineCommandsDTMC(std::shared_ptr<storm::dd::DdManager<Type>> const & manager, uint_fast64_t numberOfCommands, std::vector<storm::dd::Dd<Type>> const& commandDds, std::vector<storm::dd::Dd<Type>> const& guardDds); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Combines commands (with guards) to a module DD (MDP) |
||||
|
// * |
||||
|
// * @param numberOfCommands Number of commands in the current module |
||||
|
// * @param commandDds DDs containing all updates for each command |
||||
|
// * @param guardDds Guard DDs for each command |
||||
|
// * @param usedNondetVariables Number of used nondet. variables |
||||
|
// * @return A DD representing the module. |
||||
|
// */ |
||||
|
// static ModuleDecisionDiagram<Type> combineCommandsMDP(std::shared_ptr<storm::dd::DdManager<Type>> const & manager, uint_fast64_t numberOfCommands, std::vector<storm::dd::Dd<Type>> const& commandDds, std::vector<storm::dd::Dd<Type>> const& guardDds, uint_fast64_t usedNondetVariables); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Creates a module DD |
||||
|
// * |
||||
|
// * @param module Module |
||||
|
// * @param synchronizingAction Name of the synchronizing action ("" = no synchronization) |
||||
|
// * @param usedNondetVariables Number of used nondet. variables |
||||
|
// * @return A DD representing the module (with/without synchronized actions). |
||||
|
// */ |
||||
|
// static ModuleDecisionDiagram<Type> createModuleDecisionDiagramm(GenerationInformation const & generationInfo, storm::prism::Module const& module, std::string const& synchronizingAction, uint_fast64_t usedNondetVariables); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Creates a command DD |
||||
|
// * |
||||
|
// * @param module Current module |
||||
|
// * @param guard Command guard |
||||
|
// * @param update Command expression |
||||
|
// * @return A DD representing the command. |
||||
|
// */ |
||||
|
// static storm::dd::Dd<Type> createCommandDecisionDiagramm(GenerationInformation const & generationInfo, storm::prism::Module const& module, storm::dd::Dd<Type> const& guard, storm::prism::Command const& command); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Creates an update DD |
||||
|
// * |
||||
|
// * @param module Current module |
||||
|
// * @param guard Command guard |
||||
|
// * @param update Update expression |
||||
|
// * @return A DD representing the update. |
||||
|
// */ |
||||
|
// static storm::dd::Dd<Type> createUpdateDecisionDiagramm(GenerationInformation const & generationInfo, storm::prism::Module const& module, storm::dd::Dd<Type> const& guard, storm::prism::Update const& update); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Creates initial state DD |
||||
|
// * |
||||
|
// * @return A DD representing the initial state. |
||||
|
// */ |
||||
|
// static storm::dd::Dd<Type> getInitialStateDecisionDiagram(GenerationInformation const & generationInfo); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Calculates the reachable states of the given transition matrix |
||||
|
// * |
||||
|
// * @param systemDd The transition matrix DD |
||||
|
// * @param initialStateDd All initial states |
||||
|
// * @return A DD representing all reachable states |
||||
|
// */ |
||||
|
// static storm::dd::Dd<Type> performReachability(GenerationInformation & generationInfo, storm::dd::Dd<Type> const& systemDd, storm::dd::Dd<Type> const& initialStateDd); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Adds a self-loop to deadlock states |
||||
|
// * |
||||
|
// * @param systemDd The given DD |
||||
|
// * @param reachableStatesDd DD representing all reachable states |
||||
|
// * @return A DD with fixed deadlocks. |
||||
|
// */ |
||||
|
// static storm::dd::Dd<Type> findDeadlocks(GenerationInformation const & generationInfo, storm::dd::Dd<Type> systemDd, storm::dd::Dd<Type> const& reachableStatesDd); |
||||
|
// |
||||
|
// /*! |
||||
|
// * Computes state and transition rewards |
||||
|
// * |
||||
|
// * @param systemDds System DDs |
||||
|
// */ |
||||
|
// static std::pair<std::vector<storm::dd::Dd<Type>>, std::vector<storm::dd::Dd<Type>>> computeRewards(GenerationInformation const & generationInfo, SystemComponentDecisionDiagram<Type> const& systemDds); |
||||
|
}; |
||||
|
|
||||
|
} // namespace adapters |
||||
|
} // namespace storm |
||||
|
|
||||
|
#endif /* STORM_BUILDER_DDPRISMMODELBUILDER_H_ */ |
@ -0,0 +1,22 @@ |
|||||
|
#ifndef STORM_UTILITY_MATH_H_ |
||||
|
#define STORM_UTILITY_MATH_H_ |
||||
|
|
||||
|
#include <cmath> |
||||
|
|
||||
|
#include "src/utility/OsDetection.h" |
||||
|
|
||||
|
namespace storm { |
||||
|
namespace math { |
||||
|
// We provide this method explicitly, because MSVC does not offer it (non-C99 compliant). |
||||
|
template<typename ValueType> |
||||
|
static inline double log2(ValueType number) { |
||||
|
# ifndef WINDOWS |
||||
|
return std::log2(number); |
||||
|
# else |
||||
|
return std::log(number) / std::log(2); |
||||
|
# endif |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
#endif /* STORM_UTILITY_MATH_H_ */ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue