Browse Source
Added singleton utility class for CUDD-based things. Added some first methods to expression classes to generate ADDs, but this should be moved to a separate class implementing the expression visitor pattern.
tempestpy_adaptions
Added singleton utility class for CUDD-based things. Added some first methods to expression classes to generate ADDs, but this should be moved to a separate class implementing the expression visitor pattern.
tempestpy_adaptions
dehnert
12 years ago
20 changed files with 487 additions and 7 deletions
-
115src/adapters/SymbolicModelAdapter.h
-
4src/ir/expressions/BaseExpression.h
-
14src/ir/expressions/BinaryBooleanFunctionExpression.h
-
16src/ir/expressions/BinaryNumericalFunctionExpression.h
-
22src/ir/expressions/BinaryRelationExpression.h
-
12src/ir/expressions/BooleanConstantExpression.h
-
5src/ir/expressions/BooleanLiteral.h
-
10src/ir/expressions/DoubleConstantExpression.h
-
5src/ir/expressions/DoubleLiteral.h
-
44src/ir/expressions/ExpressionVisitor.h
-
9src/ir/expressions/Expressions.h
-
10src/ir/expressions/IntegerConstantExpression.h
-
5src/ir/expressions/IntegerLiteral.h
-
5src/ir/expressions/UnaryBooleanFunctionExpression.h
-
7src/ir/expressions/UnaryNumericalFunctionExpression.h
-
26src/ir/expressions/VariableExpression.h
-
2src/parser/PrismParser.cpp
-
1src/storm.cpp
-
125src/utility/CuddUtility.cpp
-
57src/utility/CuddUtility.h
@ -0,0 +1,115 @@ |
|||
/* |
|||
* SymbolicModelAdapter.h |
|||
* |
|||
* Created on: 25.01.2013 |
|||
* Author: Christian Dehnert |
|||
*/ |
|||
|
|||
#ifndef STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ |
|||
#define STORM_ADAPTERS_SYMBOLICMODELADAPTER_H_ |
|||
|
|||
#include "src/exceptions/WrongFileFormatException.h" |
|||
|
|||
#include "src/utility/CuddUtility.h" |
|||
#include "src/ir/expressions/ExpressionVisitor.h" |
|||
|
|||
#include "cuddObj.hh" |
|||
#include <iostream> |
|||
|
|||
namespace storm { |
|||
|
|||
namespace adapters { |
|||
|
|||
class SymbolicModelAdapter { |
|||
public: |
|||
|
|||
SymbolicModelAdapter() : cuddUtility(storm::utility::cuddUtilityInstance()) { |
|||
|
|||
} |
|||
|
|||
void toMTBDD(storm::ir::Program const& program) { |
|||
LOG4CPLUS_INFO(logger, "Creating MTBDD representation for probabilistic program."); |
|||
createDecisionDiagramVariables(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.getNumberOfCommands(); ++j) { |
|||
storm::ir::Command const& command = module.getCommand(j); |
|||
|
|||
|
|||
} |
|||
} |
|||
|
|||
LOG4CPLUS_INFO(logger, "Done creating MTBDD representation for probabilistic program."); |
|||
} |
|||
|
|||
private: |
|||
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; |
|||
|
|||
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::WrongFileFormatException() << "Range of variable " |
|||
<< integerVariable.getName() << " is empty or negativ."; |
|||
} |
|||
uint_fast64_t numberOfDecisionDiagramVariables = static_cast<uint_fast64_t>(std::ceil(std::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_ */ |
@ -0,0 +1,44 @@ |
|||
/* |
|||
* ExpressionVisitor.h |
|||
* |
|||
* Created on: 26.01.2013 |
|||
* Author: Christian Dehnert |
|||
*/ |
|||
|
|||
#ifndef STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_ |
|||
#define STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_ |
|||
|
|||
#include "Expressions.h" |
|||
|
|||
namespace storm { |
|||
|
|||
namespace ir { |
|||
|
|||
namespace expressions { |
|||
|
|||
class ExpressionVisitor { |
|||
public: |
|||
virtual void visit(BaseExpression expression) = 0; |
|||
virtual void visit(BinaryBooleanFunctionExpression expression) = 0; |
|||
virtual void visit(BinaryNumericalFunctionExpression expression) = 0; |
|||
virtual void visit(BinaryRelationExpression expression) = 0; |
|||
virtual void visit(BooleanConstantExpression expression) = 0; |
|||
virtual void visit(BooleanLiteral expression) = 0; |
|||
virtual void visit(ConstantExpression expression) = 0; |
|||
virtual void visit(DoubleConstantExpression expression) = 0; |
|||
virtual void visit(DoubleLiteral expression) = 0; |
|||
virtual void visit(IntegerConstantExpression expression) = 0; |
|||
virtual void visit(IntegerLiteral expression) = 0; |
|||
virtual void visit(UnaryBooleanFunctionExpression expression) = 0; |
|||
virtual void visit(UnaryNumericalFunctionExpression expression) = 0; |
|||
virtual void visit(VariableExpression expression) = 0; |
|||
}; |
|||
|
|||
} // namespace expressions |
|||
|
|||
} // namespace ir |
|||
|
|||
} // namespace storm |
|||
|
|||
|
|||
#endif /* STORM_IR_EXPRESSIONS_EXPRESSIONVISITOR_H_ */ |
@ -0,0 +1,125 @@ |
|||
/*
|
|||
* CuddUtility.cpp |
|||
* |
|||
* Created on: 26.01.2013 |
|||
* Author: Christian Dehnert |
|||
*/ |
|||
|
|||
#include "CuddUtility.h"
|
|||
#include "src/exceptions/InvalidArgumentException.h"
|
|||
|
|||
#include "log4cplus/logger.h"
|
|||
#include "log4cplus/loggingmacros.h"
|
|||
|
|||
extern log4cplus::Logger logger; |
|||
|
|||
#include <stdio.h>
|
|||
#include <iostream>
|
|||
|
|||
namespace storm { |
|||
|
|||
namespace utility { |
|||
|
|||
storm::utility::CuddUtility* storm::utility::CuddUtility::instance = nullptr; |
|||
|
|||
ADD* CuddUtility::getNewAddVariable() { |
|||
ADD* result = new ADD(manager.addVar()); |
|||
allDecisionDiagramVariables.push_back(result); |
|||
return result; |
|||
} |
|||
|
|||
ADD* CuddUtility::getAddVariable(int index) const { |
|||
return new ADD(manager.addVar(index)); |
|||
} |
|||
|
|||
ADD* CuddUtility::getConstantEncoding(uint_fast64_t constant, std::vector<ADD*>& variables) const { |
|||
if ((constant >> variables.size()) != 0) { |
|||
LOG4CPLUS_ERROR(logger, "Cannot create encoding for constant " << constant << " with " |
|||
<< variables.size() << " variables."); |
|||
throw storm::exceptions::InvalidArgumentException() << "Cannot create encoding" |
|||
<< " for constant " << constant << " with " << variables.size() |
|||
<< " variables."; |
|||
} |
|||
|
|||
// Determine whether the new ADD will be rooted by the first variable or its complement.
|
|||
ADD initialNode; |
|||
if ((constant & (1 << (variables.size() - 1))) != 0) { |
|||
initialNode = *variables[0]; |
|||
} else { |
|||
initialNode = ~(*variables[0]); |
|||
} |
|||
ADD* result = new ADD(initialNode); |
|||
|
|||
// Add (i.e. multiply) the other variables as well according to whether their bit is set or not.
|
|||
for (uint_fast64_t i = 1; i < variables.size(); ++i) { |
|||
if ((constant & (1 << (variables.size() - i - 1))) != 0) { |
|||
*result *= *variables[i]; |
|||
} else { |
|||
*result *= ~(*variables[i]); |
|||
} |
|||
} |
|||
|
|||
return result; |
|||
} |
|||
|
|||
ADD* CuddUtility::addValueForEncodingOfConstant(ADD* add, uint_fast64_t constant, std::vector<ADD*>& variables, double value) const { |
|||
if ((constant >> variables.size()) != 0) { |
|||
LOG4CPLUS_ERROR(logger, "Cannot create encoding for constant " << constant << " with " |
|||
<< variables.size() << " variables."); |
|||
throw storm::exceptions::InvalidArgumentException() << "Cannot create encoding" |
|||
<< " for constant " << constant << " with " << variables.size() |
|||
<< " variables."; |
|||
} |
|||
|
|||
// Determine whether the new ADD will be rooted by the first variable or its complement.
|
|||
ADD initialNode; |
|||
if ((constant & (1 << (variables.size() - 1))) != 0) { |
|||
initialNode = *variables[0]; |
|||
} else { |
|||
initialNode = ~(*variables[0]); |
|||
} |
|||
ADD* encoding = new ADD(initialNode); |
|||
|
|||
// Add (i.e. multiply) the other variables as well according to whether their bit is set or not.
|
|||
for (uint_fast64_t i = 1; i < variables.size(); ++i) { |
|||
if ((constant & (1 << (variables.size() - i - 1))) != 0) { |
|||
*encoding *= *variables[i]; |
|||
} else { |
|||
*encoding *= ~(*variables[i]); |
|||
} |
|||
} |
|||
|
|||
ADD* result = new ADD(add->Ite(manager.constant(value), *add)); |
|||
return result; |
|||
} |
|||
|
|||
ADD* CuddUtility::getConstant(double value) const { |
|||
return new ADD(manager.constant(value)); |
|||
} |
|||
|
|||
void CuddUtility::dumpDotToFile(ADD* add, std::string filename) const { |
|||
std::vector<ADD> nodes; |
|||
nodes.push_back(*add); |
|||
|
|||
FILE* filePtr; |
|||
filePtr = fopen(filename.c_str(), "w"); |
|||
manager.DumpDot(nodes, 0, 0, filePtr); |
|||
fclose(filePtr); |
|||
} |
|||
|
|||
Cudd const& CuddUtility::getManager() const { |
|||
return manager; |
|||
} |
|||
|
|||
CuddUtility* cuddUtilityInstance() { |
|||
if (CuddUtility::instance != nullptr) { |
|||
CuddUtility::instance = new CuddUtility(); |
|||
} |
|||
return CuddUtility::instance; |
|||
} |
|||
|
|||
} // namespace utility
|
|||
|
|||
} // namespace storm
|
|||
|
|||
|
@ -0,0 +1,57 @@ |
|||
/* |
|||
* CuddUtility.h |
|||
* |
|||
* Created on: 26.01.2013 |
|||
* Author: Christian Dehnert |
|||
*/ |
|||
|
|||
#ifndef STORM_UTILITY_CUDDUTILITY_H_ |
|||
#define STORM_UTILITY_CUDDUTILITY_H_ |
|||
|
|||
#include "cuddObj.hh" |
|||
|
|||
namespace storm { |
|||
|
|||
namespace utility { |
|||
|
|||
class CuddUtility { |
|||
public: |
|||
~CuddUtility() { |
|||
for (auto element : allDecisionDiagramVariables) { |
|||
delete element; |
|||
} |
|||
} |
|||
|
|||
ADD* getNewAddVariable(); |
|||
ADD* getAddVariable(int index) const; |
|||
|
|||
ADD* getConstantEncoding(uint_fast64_t constant, std::vector<ADD*>& variables) const; |
|||
|
|||
ADD* addValueForEncodingOfConstant(ADD* add, uint_fast64_t constant, std::vector<ADD*>& variables, double value) const; |
|||
|
|||
ADD* getConstant(double value) const; |
|||
|
|||
void dumpDotToFile(ADD* add, std::string filename) const; |
|||
|
|||
Cudd const& getManager() const; |
|||
|
|||
friend CuddUtility* cuddUtilityInstance(); |
|||
|
|||
private: |
|||
CuddUtility() : manager(0, 0), allDecisionDiagramVariables() { |
|||
|
|||
} |
|||
|
|||
Cudd manager; |
|||
std::vector<ADD*> allDecisionDiagramVariables; |
|||
|
|||
static CuddUtility* instance; |
|||
}; |
|||
|
|||
CuddUtility* cuddUtilityInstance(); |
|||
|
|||
} // namespace utility |
|||
|
|||
} // namespace storm |
|||
|
|||
#endif /* STORM_UTILITY_CUDDUTILITY_H_ */ |
Write
Preview
Loading…
Cancel
Save
Reference in new issue