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