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
- 
					5src/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