Browse Source

Intermediate commit: integrating MTBDD model generation/model checking to main tool.

Former-commit-id: a312d3a425
tempestpy_adaptions
dehnert 10 years ago
parent
commit
6347e19da8
  1. 172
      src/adapters/DdExpressionAdapter.cpp
  2. 43
      src/adapters/DdExpressionAdapter.h
  3. 199
      src/adapters/StormAdapter.h
  4. 299
      src/adapters/SymbolicModelAdapter.h
  5. 1442
      src/builder/DdPrismModelBuilder.cpp
  6. 282
      src/builder/DdPrismModelBuilder.h
  7. 3
      src/builder/ExplicitPrismModelBuilder.cpp
  8. 4
      src/storage/dd/CuddDd.cpp
  9. 7
      src/storage/dd/CuddDd.h
  10. 2
      src/storage/dd/CuddDdForwardIterator.cpp
  11. 4
      src/storage/dd/CuddDdForwardIterator.h
  12. 12
      src/storage/dd/CuddDdManager.cpp
  13. 12
      src/storage/dd/CuddDdManager.h
  14. 2
      src/storage/dd/CuddOdd.cpp
  15. 22
      src/utility/math.h
  16. 6
      src/utility/prism.h

172
src/adapters/DdExpressionAdapter.cpp

@ -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

43
src/adapters/DdExpressionAdapter.h

@ -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_ */

199
src/adapters/StormAdapter.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_ */

299
src/adapters/SymbolicModelAdapter.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

282
src/builder/DdPrismModelBuilder.h

@ -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_ */

3
src/builder/ExplicitPrismModelBuilder.cpp

@ -7,6 +7,7 @@
#include "src/models/Mdp.h"
#include "src/models/Ctmdp.h"
#include "src/utility/prism.h"
#include "src/utility/macros.h"
#include "src/exceptions/WrongFormatException.h"
@ -54,13 +55,11 @@ namespace storm {
// Intentionally left empty.
}
template <typename ValueType, typename IndexType>
ExplicitPrismModelBuilder<ValueType, IndexType>::Options::Options() : buildCommandLabels(false), buildRewards(false), rewardModelName(), constantDefinitions() {
// Intentionally left empty.
}
template <typename ValueType, typename IndexType>
ExplicitPrismModelBuilder<ValueType, IndexType>::Options::Options(storm::logic::Formula const& formula) : buildCommandLabels(false), buildRewards(formula.containsRewardOperator()), rewardModelName(), constantDefinitions(), labelsToBuild(std::set<std::string>()), expressionLabels(std::vector<storm::expressions::Expression>()) {
// Extract all the labels used in the formula.

4
src/storage/dd/CuddDd.cpp

@ -12,7 +12,7 @@
namespace storm {
namespace dd {
Dd<DdType::CUDD>::Dd(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::set<storm::expressions::Variable> const& containedMetaVariables) : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariables(containedMetaVariables) {
Dd<DdType::CUDD>::Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, ADD cuddAdd, std::set<storm::expressions::Variable> const& containedMetaVariables) : ddManager(ddManager), cuddAdd(cuddAdd), containedMetaVariables(containedMetaVariables) {
// Intentionally left empty.
}
@ -808,7 +808,7 @@ namespace storm {
this->getContainedMetaVariables().erase(metaVariable);
}
std::shared_ptr<DdManager<DdType::CUDD>> Dd<DdType::CUDD>::getDdManager() const {
std::shared_ptr<DdManager<DdType::CUDD> const> Dd<DdType::CUDD>::getDdManager() const {
return this->ddManager;
}

7
src/storage/dd/CuddDd.h

@ -563,7 +563,7 @@ namespace storm {
*
* A pointer to the manager that is responsible for this DD.
*/
std::shared_ptr<DdManager<DdType::CUDD>> getDdManager() const;
std::shared_ptr<DdManager<DdType::CUDD> const> getDdManager() const;
/*!
* Retrieves an iterator that points to the first meta variable assignment with a non-zero function value.
@ -604,6 +604,7 @@ namespace storm {
storm::expressions::Expression getMintermExpression() const;
friend std::ostream & operator<<(std::ostream& out, const Dd<DdType::CUDD>& dd);
private:
/*!
* Retrieves a reference to the CUDD ADD object associated with this DD.
@ -659,7 +660,7 @@ namespace storm {
* @param cuddAdd The CUDD ADD to store.
* @param containedMetaVariables The meta variables that appear in the DD.
*/
Dd(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, ADD cuddAdd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
Dd(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, ADD cuddAdd, std::set<storm::expressions::Variable> const& containedMetaVariables = std::set<storm::expressions::Variable>());
/*!
* Helper function to convert the DD into a (sparse) matrix.
@ -723,7 +724,7 @@ namespace storm {
std::vector<uint_fast64_t> getSortedVariableIndices() const;
// A pointer to the manager responsible for this DD.
std::shared_ptr<DdManager<DdType::CUDD>> ddManager;
std::shared_ptr<DdManager<DdType::CUDD> const> ddManager;
// The ADD created by CUDD.
ADD cuddAdd;

2
src/storage/dd/CuddDdForwardIterator.cpp

@ -9,7 +9,7 @@ namespace storm {
// Intentionally left empty.
}
DdForwardIterator<DdType::CUDD>::DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<storm::expressions::Variable> const* metaVariables, bool enumerateDontCareMetaVariables) : ddManager(ddManager), generator(generator), cube(cube), value(value), isAtEnd(isAtEnd), metaVariables(metaVariables), enumerateDontCareMetaVariables(enumerateDontCareMetaVariables), cubeCounter(), relevantDontCareDdVariables(), currentValuation(ddManager->getExpressionManager().getSharedPointer()) {
DdForwardIterator<DdType::CUDD>::DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<storm::expressions::Variable> const* metaVariables, bool enumerateDontCareMetaVariables) : ddManager(ddManager), generator(generator), cube(cube), value(value), isAtEnd(isAtEnd), metaVariables(metaVariables), enumerateDontCareMetaVariables(enumerateDontCareMetaVariables), cubeCounter(), relevantDontCareDdVariables(), currentValuation(ddManager->getExpressionManager().getSharedPointer()) {
// If the given generator is not yet at its end, we need to create the current valuation from the cube from
// scratch.
if (!this->isAtEnd) {

4
src/storage/dd/CuddDdForwardIterator.h

@ -85,7 +85,7 @@ namespace storm {
* @param enumerateDontCareMetaVariables If set to true, all meta variable assignments are enumerated, even
* if a meta variable does not at all influence the the function value.
*/
DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD>> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<storm::expressions::Variable> const* metaVariables = nullptr, bool enumerateDontCareMetaVariables = true);
DdForwardIterator(std::shared_ptr<DdManager<DdType::CUDD> const> ddManager, DdGen* generator, int* cube, double value, bool isAtEnd, std::set<storm::expressions::Variable> const* metaVariables = nullptr, bool enumerateDontCareMetaVariables = true);
/*!
* Recreates the internal information when a new cube needs to be treated.
@ -98,7 +98,7 @@ namespace storm {
void treatNextInCube();
// The manager responsible for the meta variables (and therefore the underlying DD).
std::shared_ptr<DdManager<DdType::CUDD>> ddManager;
std::shared_ptr<DdManager<DdType::CUDD> const> ddManager;
// The CUDD generator used to enumerate the cubes of the DD.
DdGen* generator;

12
src/storage/dd/CuddDdManager.cpp

@ -37,19 +37,19 @@ namespace storm {
}
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getOne() {
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getOne() const {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addOne());
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getZero() {
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getZero() const {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.addZero());
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getConstant(double value) {
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getConstant(double value) const {
return Dd<DdType::CUDD>(this->shared_from_this(), cuddManager.constant(value));
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getEncoding(storm::expressions::Variable const& variable, int_fast64_t value) {
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getEncoding(storm::expressions::Variable const& variable, int_fast64_t value) const {
DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(variable);
STORM_LOG_THROW(value >= metaVariable.getLow() && value <= metaVariable.getHigh(), storm::exceptions::InvalidArgumentException, "Illegal value " << value << " for meta variable '" << variable.getName() << "'.");
@ -77,7 +77,7 @@ namespace storm {
return result;
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getRange(storm::expressions::Variable const& variable) {
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getRange(storm::expressions::Variable const& variable) const {
storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(variable);
Dd<DdType::CUDD> result = this->getZero();
@ -88,7 +88,7 @@ namespace storm {
return result;
}
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getIdentity(storm::expressions::Variable const& variable) {
Dd<DdType::CUDD> DdManager<DdType::CUDD>::getIdentity(storm::expressions::Variable const& variable) const {
storm::dd::DdMetaVariable<DdType::CUDD> const& metaVariable = this->getMetaVariable(variable);
Dd<DdType::CUDD> result = this->getZero();

12
src/storage/dd/CuddDdManager.h

@ -40,21 +40,21 @@ namespace storm {
*
* @return A DD representing the constant one function.
*/
Dd<DdType::CUDD> getOne();
Dd<DdType::CUDD> getOne() const;
/*!
* Retrieves a DD representing the constant zero function.
*
* @return A DD representing the constant zero function.
*/
Dd<DdType::CUDD> getZero();
Dd<DdType::CUDD> getZero() const;
/*!
* Retrieves a DD representing the constant function with the given value.
*
* @return A DD representing the constant function with the given value.
*/
Dd<DdType::CUDD> getConstant(double value);
Dd<DdType::CUDD> getConstant(double value) const;
/*!
* Retrieves the DD representing the function that maps all inputs which have the given meta variable equal
@ -65,7 +65,7 @@ namespace storm {
* @return The DD representing the function that maps all inputs which have the given meta variable equal
* to the given value one.
*/
Dd<DdType::CUDD> getEncoding(storm::expressions::Variable const& variable, int_fast64_t value);
Dd<DdType::CUDD> getEncoding(storm::expressions::Variable const& variable, int_fast64_t value) const;
/*!
* Retrieves the DD representing the range of the meta variable, i.e., a function that maps all legal values
@ -74,7 +74,7 @@ namespace storm {
* @param variable The expression variable associated with the meta variable.
* @return The range of the meta variable.
*/
Dd<DdType::CUDD> getRange(storm::expressions::Variable const& variable);
Dd<DdType::CUDD> getRange(storm::expressions::Variable const& variable) const;
/*!
* Retrieves the DD representing the identity of the meta variable, i.e., a function that maps all legal
@ -83,7 +83,7 @@ namespace storm {
* @param variable The expression variable associated with the meta variable.
* @return The identity of the meta variable.
*/
Dd<DdType::CUDD> getIdentity(storm::expressions::Variable const& variable);
Dd<DdType::CUDD> getIdentity(storm::expressions::Variable const& variable) const;
/*!
* Adds an integer meta variable with the given range.

2
src/storage/dd/CuddOdd.cpp

@ -8,7 +8,7 @@
namespace storm {
namespace dd {
Odd<DdType::CUDD>::Odd(Dd<DdType::CUDD> const& dd) {
std::shared_ptr<DdManager<DdType::CUDD>> manager = dd.getDdManager();
std::shared_ptr<DdManager<DdType::CUDD> const> manager = dd.getDdManager();
// First, we need to determine the involved DD variables indices.
std::vector<uint_fast64_t> ddVariableIndices = dd.getSortedVariableIndices();

22
src/utility/math.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_ */

6
src/utility/PrismUtility.h → src/utility/prism.h

@ -1,5 +1,5 @@
#ifndef STORM_UTILITY_PRISMUTILITY
#define STORM_UTILITY_PRISMUTILITY
#ifndef STORM_UTILITY_PRISM_H_
#define STORM_UTILITY_PRISM_H_
#include <memory>
#include <boost/algorithm/string.hpp>
@ -236,4 +236,4 @@ namespace storm {
} // namespace utility
} // namespace storm
#endif /* STORM_UTILITY_PRISMUTILITY_H_ */
#endif /* STORM_UTILITY_PRISM_H_ */
Loading…
Cancel
Save